expressive 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- expressive (0.0.8)
4
+ expressive (0.0.9)
5
5
  awesome_print (~> 1.0.2)
6
6
  json
7
7
  polyglot (~> 0.3.3)
@@ -3,6 +3,8 @@ require 'treetop'
3
3
  require 'awesome_print'
4
4
  require 'rest_client'
5
5
  require File.join(File.dirname(__FILE__), 'scope')
6
+ require File.join(File.dirname(__FILE__), 'extended_value')
7
+ require File.join(File.dirname(__FILE__), 'webhook')
6
8
 
7
9
  Treetop.load File.join(File.dirname(__FILE__), 'expressive_grammar.treetop')
8
10
 
@@ -18,7 +20,7 @@ module Expressive
18
20
  end
19
21
 
20
22
  def self.all_symbols
21
- %w(+ - * / = set sum post >= > < <= and or if date get put)
23
+ %w(+ - * / = set sum post >= > < <= and or if date get put lookup)
22
24
  end
23
25
 
24
26
  module Boolean
@@ -1,3 +1,3 @@
1
1
  module Expressive
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
@@ -0,0 +1,21 @@
1
+ module Expressive
2
+
3
+ class ExtendedValue
4
+ attr_accessor :setter, :adder
5
+ def initialize(property_name, scope)
6
+ @scope = scope
7
+ @property_name = property_name.to_s
8
+
9
+ @scope[@property_name] = self
10
+ end
11
+
12
+ def set(value)
13
+ setter.call value, @scope
14
+ end
15
+
16
+ def <<(value)
17
+ adder.call value, @scope
18
+ end
19
+ end
20
+
21
+ end
@@ -1,9 +1,25 @@
1
1
  module Expressive
2
2
  require 'json'
3
+
3
4
  class Scope
5
+ attr_reader :lookups
4
6
  def initialize(parent = {})
5
7
  @parent = parent
6
8
  @symbols = {}
9
+ @lookups = {}
10
+ end
11
+
12
+ def add_lookup_table(lookup_table_name, lookups)
13
+ @lookups[lookup_table_name] = {} unless @lookups.include?(lookup_table_name)
14
+ @lookups[lookup_table_name].merge!(lookups)
15
+ end
16
+
17
+ def add_lookup_function(lookup_function_name, passed_in_options, &func_proc)
18
+ @lookups[lookup_function_name] = [passed_in_options, func_proc]
19
+ end
20
+
21
+ def clear_lookup_tables
22
+ @lookups.clear
7
23
  end
8
24
 
9
25
  def [](name)
@@ -11,7 +27,20 @@ module Expressive
11
27
  end
12
28
 
13
29
  def []=(name, value)
14
- @symbols[name] = value
30
+ if value
31
+ if value.is_a?(ExtendedValue)
32
+ @symbols[name] = value unless @symbols.include?(name)
33
+ else
34
+ current_value = @symbols[name]
35
+ if current_value and current_value.is_a?(ExtendedValue)
36
+ current_value.set(value)
37
+ else
38
+ @symbols[name] = value
39
+ end
40
+ end
41
+ else
42
+ @symbols[name] = value
43
+ end
15
44
  end
16
45
 
17
46
  def merge(scope)
@@ -36,36 +65,6 @@ module Expressive
36
65
  end
37
66
  end
38
67
 
39
- class Webhook
40
-
41
- def initialize(verb, url, params, headers)
42
- @verb, @url, @params, @headers = verb, url, params, headers
43
- end
44
-
45
- def execute
46
- self.send(@verb)
47
- end
48
-
49
- private
50
-
51
- def post
52
- headers = {:content_type => :json, :accept => :json}
53
- headers = headers.merge(@headers) if @headers
54
- RestClient.post(@url, @params.to_json, headers)
55
- end
56
-
57
- def get
58
- headers = {:params => @params}
59
- headers = headers.merge(@headers) if @headers
60
- RestClient.get(@url, headers)
61
- end
62
-
63
- def put
64
- RestClient.put(@url, @params)
65
- end
66
-
67
- end
68
-
69
68
  class TopLevel < Scope
70
69
 
71
70
  def initialize
@@ -75,6 +74,20 @@ module Expressive
75
74
  scope[cells.first.text_value] = cells[1].eval(scope)
76
75
  end
77
76
 
77
+ syntax('lookup') do |scope, cells|
78
+ lookup_result = scope.lookups[cells.first.text_value]
79
+ if lookup_result
80
+ key = cells[1].text_value[1..-2]
81
+ if lookup_result.is_a?(Hash)
82
+ lookup_result[key]
83
+ elsif lookup_result.is_a?(Array)
84
+ options = lookup_result.first
85
+ the_proc = lookup_result.last
86
+ the_proc.call(options, key)
87
+ end
88
+ end
89
+ end
90
+
78
91
  syntax('post') do |scope, cells|
79
92
  perform_webhook(:post, scope, cells)
80
93
  end
@@ -0,0 +1,29 @@
1
+ module Expressive
2
+ class Webhook
3
+
4
+ def initialize(verb, url, params, headers)
5
+ @verb, @url, @params, @headers = verb, url, params, headers
6
+ end
7
+
8
+ def execute
9
+ self.send(@verb)
10
+ end
11
+
12
+ private
13
+ def post
14
+ headers = {:content_type => :json, :accept => :json}
15
+ headers = headers.merge(@headers) if @headers
16
+ RestClient.post(@url, @params.to_json, headers)
17
+ end
18
+
19
+ def get
20
+ headers = {:params => @params}
21
+ headers = headers.merge(@headers) if @headers
22
+ RestClient.get(@url, headers)
23
+ end
24
+
25
+ def put
26
+ RestClient.put(@url, @params)
27
+ end
28
+ end
29
+ end
@@ -6,7 +6,7 @@ describe "Expressive" do
6
6
  end
7
7
 
8
8
  describe "all_symbols" do
9
- it { Expressive.all_symbols.should =~ %w(+ - * / = set sum get put post >= > < <= and or if date) }
9
+ it { Expressive.all_symbols.should =~ %w(+ - * / = set sum get put post >= > < <= and or if date lookup) }
10
10
  end
11
11
 
12
12
  describe "understands booleans" do
@@ -95,9 +95,10 @@ describe "Expressive" do
95
95
  end
96
96
 
97
97
  it "using multiple set commands" do
98
- Expressive.run('(and (set vsi "vsi1234") (set vso "vso1234"))', @scope).should eql true
98
+ Expressive.run('(and (set vsi "vsi1234") (set vso "vso1234") (set vsbool true))', @scope).should eql true
99
99
  @scope['vsi'].should eql 'vsi1234'
100
100
  @scope['vso'].should eql 'vso1234'
101
+ @scope['vsbool'].should be_true
101
102
  end
102
103
  end
103
104
 
@@ -115,6 +116,40 @@ describe "Expressive" do
115
116
  end
116
117
  end
117
118
 
119
+ describe "understands using lookup tables" do
120
+ before(:each) do
121
+ @user1 = mock(:user, id:1, login: "user1", display_name: "User 1")
122
+ @user2 = mock(:user, id:2, login: "user2", display_name: "User 2")
123
+ @scope.add_lookup_table("users", @user1.login => @user1, @user2.login => @user2)
124
+ @scope.add_lookup_table("users", "x_current" => @user2)
125
+ end
126
+
127
+ it "will return a value from a lookup table" do
128
+ Expressive.run('(lookup users "x_current")', @scope).should eql @user2
129
+ Expressive.run('(lookup users "user1")', @scope).should eql @user1
130
+ end
131
+ it "will set multiple values based on results of a lookup" do
132
+ @owned_by_ext_value = Expressive::ExtendedValue.new(:x_owned_by, @scope)
133
+ @owned_by_ext_value.setter = Proc.new do |value, scope|
134
+ scope["owned_by_id"] = value.id
135
+ scope["owned_by_type"] = value.class.to_s
136
+ end
137
+
138
+ Expressive.run('(set x_owned_by (lookup users "x_current"))', @scope)
139
+ @scope["owned_by_id"].should eql @user2.id
140
+ @scope["owned_by_type"].should eql "RSpec::Mocks::Mock"
141
+ end
142
+ end
143
+
144
+ describe "understands using lookup functions" do
145
+ it "should perform the lookup function (add account and reverse login)" do
146
+ @scope.add_lookup_function("account_reverse_login", account: "ea") do |options, login|
147
+ "#{options[:account]}-#{login.reverse}"
148
+ end
149
+ Expressive.run('(lookup account_reverse_login "ijonas")', @scope).should eql "ea-sanoji"
150
+ end
151
+ end
152
+
118
153
  describe "understands web-hook statements" do
119
154
  context "put" do
120
155
  it_should_behave_like "a webhook", :put
@@ -1,12 +1,56 @@
1
1
  require "spec_helper"
2
2
 
3
- describe "TopLevel" do
3
+ module Expressive
4
+ describe TopLevel do
5
+
6
+ describe "#to_hash" do
7
+ it "return only the hash data" do
8
+ @scope = TopLevel.new
9
+ @scope["hello"] = "world"
10
+ @scope.to_hash.should eql({"hello" => "world"})
11
+ end
12
+ end
13
+
14
+ end
15
+
16
+ describe ExtendedValue do
17
+ it "sets the multiple values of a ExtendedValue" do
18
+ @scope = TopLevel.new
19
+
20
+ @owned_by_ext_value = ExtendedValue.new(:x_owned_by, @scope)
21
+ @owned_by_ext_value.setter = Proc.new do |value, scope|
22
+ scope["owned_by_id"] = value.id
23
+ scope["owned_by_type"] = value.class.to_s
24
+ end
25
+
26
+ @scope["x_owned_by"] = mock(:current_user, id: 1)
27
+ @scope["owned_by_id"].should eql 1
28
+ @scope["owned_by_type"].should eql "RSpec::Mocks::Mock"
29
+
30
+
31
+ @current_state_ext_value = ExtendedValue.new(:x_current_state, @scope)
32
+ @current_state_ext_value.setter = Proc.new do |value, scope|
33
+ scope["current_state"] = value.state
34
+ scope["current_state_id"] = value.id
35
+ end
36
+
37
+ @scope["x_current_state"] = mock(:some_state, id: 1, state: "Pending")
38
+ @scope["current_state_id"].should eql 1
39
+ @scope["current_state"].should eql "Pending"
40
+ end
41
+ it "add values to a Set construct" do
42
+ @scope = TopLevel.new
43
+
44
+ @participating_teams_ext_value = ExtendedValue.new(:x_participating_teams, @scope)
45
+ @participating_teams_ext_value.adder = Proc.new do |value, scope|
46
+ scope["participating_teams"] << value.id unless scope["participating_teams"].include?(value.id)
47
+ end
48
+
49
+ @scope["participating_teams"] = [1]
50
+ @scope["x_participating_teams"] << mock(:some_team, id: 2, display_name: "The B-Team")
51
+ @scope["x_participating_teams"] << mock(:some_team, id: 2, display_name: "The B-Team")
52
+ @scope["participating_teams"].should =~ [1,2]
4
53
 
5
- describe "to_hash" do
6
- it "return only the hash data" do
7
- @scope = Expressive::TopLevel.new
8
- @scope["hello"] = "world"
9
- @scope.to_hash.should eql({"hello" => "world"})
10
54
  end
11
55
  end
12
56
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expressive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-21 00:00:00.000000000 Z
12
+ date: 2012-11-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ruby_gntp
@@ -273,7 +273,9 @@ files:
273
273
  - lib/expressive.rb
274
274
  - lib/expressive/version.rb
275
275
  - lib/expressive_grammar.treetop
276
+ - lib/extended_value.rb
276
277
  - lib/scope.rb
278
+ - lib/webhook.rb
277
279
  - spec/expressive_spec.rb
278
280
  - spec/scope_spec.rb
279
281
  - spec/spec_helper.rb
@@ -292,7 +294,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
292
294
  version: '0'
293
295
  segments:
294
296
  - 0
295
- hash: 871214623463249366
297
+ hash: 275595429222270530
296
298
  required_rubygems_version: !ruby/object:Gem::Requirement
297
299
  none: false
298
300
  requirements:
@@ -301,7 +303,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
301
303
  version: '0'
302
304
  segments:
303
305
  - 0
304
- hash: 871214623463249366
306
+ hash: 275595429222270530
305
307
  requirements: []
306
308
  rubyforge_project:
307
309
  rubygems_version: 1.8.23