msfl_visitors 0.1.0.rc3 → 0.3.0.dev

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +2 -2
  4. data/README.md +9 -17
  5. data/lib/msfl_visitors/nodes/and.rb +0 -17
  6. data/lib/msfl_visitors/nodes/base.rb +3 -1
  7. data/lib/msfl_visitors/nodes/binary.rb +0 -7
  8. data/lib/msfl_visitors/nodes/dataset.rb +7 -0
  9. data/lib/msfl_visitors/nodes/equal.rb +17 -0
  10. data/lib/msfl_visitors/nodes/explicit_filter.rb +7 -0
  11. data/lib/msfl_visitors/nodes/filter.rb +16 -15
  12. data/lib/msfl_visitors/nodes/foreign.rb +7 -0
  13. data/lib/msfl_visitors/nodes/given.rb +7 -0
  14. data/lib/msfl_visitors/nodes/iterator.rb +7 -1
  15. data/lib/msfl_visitors/nodes/named_value.rb +16 -0
  16. data/lib/msfl_visitors/nodes/partial.rb +7 -0
  17. data/lib/msfl_visitors/nodes/set.rb +23 -0
  18. data/lib/msfl_visitors/nodes.rb +7 -9
  19. data/lib/msfl_visitors/parsers/msfl_parser.rb +33 -4
  20. data/lib/msfl_visitors/visitor.rb +165 -6
  21. data/lib/msfl_visitors.rb +0 -2
  22. data/msfl_visitors.gemspec +3 -3
  23. data/spec/nodes/iterator_spec.rb +21 -3
  24. data/spec/parsers/msfl_parser_spec.rb +61 -4
  25. data/spec/spec_helper.rb +5 -1
  26. data/spec/visitors/chewy_term_filter_spec.rb +460 -53
  27. metadata +11 -24
  28. data/lib/msfl_visitors/collectors/chewy/term_filter.rb +0 -19
  29. data/lib/msfl_visitors/collectors.rb +0 -1
  30. data/lib/msfl_visitors/nodes/binary_and.rb +0 -7
  31. data/lib/msfl_visitors/nodes/constant_value.rb +0 -11
  32. data/lib/msfl_visitors/nodes/grouping/close.rb +0 -9
  33. data/lib/msfl_visitors/nodes/grouping/grouping.rb +0 -24
  34. data/lib/msfl_visitors/nodes/grouping/open.rb +0 -9
  35. data/lib/msfl_visitors/nodes/set/close.rb +0 -9
  36. data/lib/msfl_visitors/nodes/set/delimiter.rb +0 -9
  37. data/lib/msfl_visitors/nodes/set/open.rb +0 -9
  38. data/lib/msfl_visitors/nodes/set/set.rb +0 -43
  39. data/lib/msfl_visitors/renderers/chewy/term_filter.rb +0 -59
  40. data/spec/renderers/chewy/term_filter_spec.rb +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 388743fe79552e7461242c26d68feb0be8160148
4
- data.tar.gz: 02aad6d1b455f84874473030b0ce7770837c7d4e
3
+ metadata.gz: 172130f160936dc67e1d5658a17276f9e1bd6b9d
4
+ data.tar.gz: b86ec5deb1e85c048e418a39a3d5fa003bd36c6a
5
5
  SHA512:
6
- metadata.gz: b181c89aac58514f15df5c045a40fcdb7434522a48e63c0bc2f84dc61e096163f0aa4ffb736a58b0b3ac453c6ce936d4524dcf22eb0f4042ca3cdd71b485f2ec
7
- data.tar.gz: 5a394966b78902288dc6da7707f6a592c701cf9b51cd2d0b39a964a9489f2b71edf124de104151c78cd110559d00b7fa1279b29ea580782592c256c844ceb8ed
6
+ metadata.gz: 86d580b40f4198b2a7f62370be7c0cae80d4c374ea4e29ee04b477ab1efb1a77b889b00e38400a83e2c6d4f6e0981b24f29dbbe7285cc9bd7babcb5a676ee310
7
+ data.tar.gz: f336cc01362a4f87ccc8a0265c7588c517ecb1b117a735fe293b4518a661d295b29ee1b3a1f5c81630ba7976821c5a5a0c377840f5a1df2f00d7d33ffcf84d62
data/Gemfile CHANGED
@@ -3,4 +3,4 @@ gem 'simplecov', :require => false, :group => :test # MIT https://gith
3
3
  gem 'yard' # MIT https://github.com/lsegal/yard/blob/master/LICENSE + Ruby license for one file from the Ruby source lib/parser/ruby/legacy/ruby_lex.rb
4
4
  gem 'rspec' # MIT https://github.com/rspec/rspec/blob/master/License.txt
5
5
  gem 'byebug'
6
- gem 'msfl', "~> 1.1"
6
+ gem 'msfl', "1.2.0.dev4"
data/Gemfile.lock CHANGED
@@ -7,7 +7,7 @@ GEM
7
7
  diff-lcs (1.2.5)
8
8
  docile (1.1.5)
9
9
  json (1.8.2)
10
- msfl (1.1.6)
10
+ msfl (1.2.0.dev4)
11
11
  json (~> 1.7)
12
12
  rspec (3.2.0)
13
13
  rspec-core (~> 3.2.0)
@@ -34,7 +34,7 @@ PLATFORMS
34
34
 
35
35
  DEPENDENCIES
36
36
  byebug
37
- msfl (~> 1.1)
37
+ msfl (= 1.2.0.dev4)
38
38
  rspec
39
39
  simplecov
40
40
  yard
data/README.md CHANGED
@@ -5,23 +5,18 @@ A visitor pattern based approach for converting MSFL to other forms
5
5
 
6
6
  ## Usage
7
7
 
8
- ```ruby
9
- # This is not actually working code yet! @todo revisit once Matt's refactor branch is merged.
10
- require 'msfl_visitor'
8
+ ```ruby
9
+ require 'msfl_visitor'
11
10
 
12
- filter = { make: "Toyota" }
11
+ filter = { make: "Toyota" }
13
12
 
14
- collector = String.new
13
+ visitor = MSFLVisitors::Visitor.new
15
14
 
16
- renderer = MSFLVisitors::Renderers::Chewy::TermFilter.new
15
+ visitor.visit_tree MSFLVisitors::AST.new(filter)
17
16
 
18
- visitor = MSFLVisitors::Visitor.new collector, renderer
17
+ => [{clause: 'make == "Toyota"'}]
19
18
 
20
- MSFLVisitors::AST.new(filter).accept(visitor)
21
-
22
- => 'make == "Toyota"'
23
-
24
- ```
19
+ ```
25
20
 
26
21
  ## Architecture
27
22
 
@@ -54,11 +49,8 @@ multiple output DSLs.
54
49
 
55
50
  ## collector
56
51
 
57
- During traversal the output from each node needs to be stored or buffered somewhere. The collector serves this role.
58
- It can be as simple as a String or an Array, or it can be more elaborate. Ultimately it must respond to the shovel
59
- operator (<<)
52
+ Removed as of 0.3
60
53
 
61
54
  ## renderer
62
55
 
63
- The logic for rendering the AST nodes into the output DSL is codified in a renderer. The two principle renderers at
64
- this time are Chewy::TermFilter and Chewy:QueryStringFilter
56
+ Removed as of 0.3
@@ -2,23 +2,6 @@ require_relative 'iterator'
2
2
  module MSFLVisitors
3
3
  module Nodes
4
4
  class And < Iterator
5
-
6
- def accept(visitor)
7
- nodes = Array.new
8
- if set.count > 1
9
- set.each do |item|
10
- nodes << MSFLVisitors::Nodes::Grouping::Grouping.new(item)
11
- nodes << BinaryAnd.new
12
- end
13
- nodes.pop
14
- elsif set.count == 1
15
- nodes << set.first
16
- end
17
-
18
- nodes.each do |node|
19
- node.accept visitor
20
- end
21
- end
22
5
  end
23
6
  end
24
7
  end
@@ -1,7 +1,9 @@
1
1
  module MSFLVisitors
2
2
  module Nodes
3
3
  class Base
4
-
4
+ def accept(visitor)
5
+ visitor.visit(self)
6
+ end
5
7
  end
6
8
  end
7
9
  end
@@ -2,15 +2,8 @@ require_relative 'base'
2
2
  module MSFLVisitors
3
3
  module Nodes
4
4
  class Binary < Base
5
-
6
5
  attr_accessor :left, :right
7
6
 
8
- def accept(visitor)
9
- left.accept visitor
10
- visitor.visit self
11
- right.accept visitor
12
- end
13
-
14
7
  def initialize(left, right)
15
8
  self.left = left
16
9
  self.right = right
@@ -0,0 +1,7 @@
1
+ require_relative 'value'
2
+ module MSFLVisitors
3
+ module Nodes
4
+ class Dataset < Value
5
+ end
6
+ end
7
+ end
@@ -2,6 +2,23 @@ require_relative 'comparison'
2
2
  module MSFLVisitors
3
3
  module Nodes
4
4
  class Equal < Comparison
5
+
6
+ def accept(visitor)
7
+ visitor.visit self
8
+ #
9
+ # case visitor.current_visitor
10
+ # when Visitors::Chewy::TermFilter
11
+ # super
12
+ #
13
+ # when Visitors::Chewy::Aggregations
14
+ # @value = { left.accept(visitor) => right.accept(visitor) }
15
+ # visitor.visit(self)
16
+ #
17
+ # else
18
+ # fail ArgumentError, "Unknown current visitor type."
19
+ # end
20
+ end
21
+
5
22
  end
6
23
  end
7
24
  end
@@ -0,0 +1,7 @@
1
+ require_relative 'filter'
2
+ module MSFLVisitors
3
+ module Nodes
4
+ class ExplicitFilter < Filter
5
+ end
6
+ end
7
+ end
@@ -1,20 +1,21 @@
1
- require_relative 'set/set'
1
+ require_relative 'base'
2
2
  module MSFLVisitors
3
3
  module Nodes
4
- class Filter < Set::Set
5
- def accept(visitor)
6
- nodes = Array.new
7
- if contents.count > 0
8
- contents.each do |item|
9
- nodes << item
10
- nodes << Set::Delimiter.new
11
- end
12
- # Remove the last (and therefore extra) delimiter
13
- nodes.pop
14
- end
15
- nodes.each do |node|
16
- node.accept visitor
17
- end
4
+ class Filter < Base
5
+ extend Forwardable
6
+
7
+ attr_accessor :contents
8
+
9
+ def_delegators :contents, :count, :first, :each
10
+
11
+ # @param nodes [Array<MSFL::Nodes::Base>] the nodes that the filter surrounds
12
+ def initialize(nodes)
13
+ self.contents = Array(nodes)
14
+ end
15
+
16
+ def ==(other)
17
+ self.class == other.class &&
18
+ contents == other.contents
18
19
  end
19
20
  end
20
21
  end
@@ -0,0 +1,7 @@
1
+ require_relative 'binary'
2
+ module MSFLVisitors
3
+ module Nodes
4
+ class Foreign < Binary
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'filter'
2
+ module MSFLVisitors
3
+ module Nodes
4
+ class Given < Filter
5
+ end
6
+ end
7
+ end
@@ -5,8 +5,14 @@ module MSFLVisitors
5
5
 
6
6
  attr_accessor :set
7
7
 
8
- # @param set [MSFLVisitors::Nodes::Set::Set] a set node that allows its elements to be iterated over
8
+ # Be extra defensive, because even after adding previous comment I still tend to make the mistake of
9
+ # passing in an array.
10
+ #
11
+ # @param set [MSFLVisitors::Nodes::Set] a set node that allows its elements to be iterated over
9
12
  def initialize(set)
13
+ unless set.is_a? MSFLVisitors::Nodes::Set
14
+ fail ArgumentError, "Argument to Iterator initialize must be instance of MSFLVisitors::Nodes::Set"
15
+ end
10
16
  self.set = set
11
17
  end
12
18
 
@@ -0,0 +1,16 @@
1
+ module MSFLVisitors
2
+ module Nodes
3
+ class NamedValue
4
+ attr_accessor :name, :value
5
+
6
+ def initialize(name, value)
7
+ self.name = name
8
+ self.value = value
9
+ end
10
+
11
+ def accept(visitor)
12
+ visitor.visit(self)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'binary'
2
+ module MSFLVisitors
3
+ module Nodes
4
+ class Partial < Binary
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'base'
2
+ module MSFLVisitors
3
+ module Nodes
4
+ class Set < Base
5
+
6
+ extend Forwardable
7
+
8
+ attr_accessor :contents
9
+
10
+ def_delegators :contents, :count, :first, :each
11
+
12
+ # @param nodes [Array<MSFL::Nodes::Base>] the nodes that the filter surrounds
13
+ def initialize(nodes)
14
+ self.contents = Array(nodes)
15
+ end
16
+
17
+ def ==(other)
18
+ self.class == other.class &&
19
+ contents == other.contents
20
+ end
21
+ end
22
+ end
23
+ end
@@ -2,30 +2,28 @@
2
2
  require_relative 'nodes/and'
3
3
  require_relative 'nodes/base'
4
4
  require_relative 'nodes/binary'
5
- require_relative 'nodes/binary_and'
6
5
  require_relative 'nodes/boolean'
7
6
  require_relative 'nodes/comparison'
8
- require_relative 'nodes/constant_value'
9
7
  require_relative 'nodes/containment'
8
+ require_relative 'nodes/dataset'
10
9
  require_relative 'nodes/date'
11
10
  require_relative 'nodes/date_time'
12
11
  require_relative 'nodes/equal'
12
+ require_relative 'nodes/explicit_filter'
13
13
  require_relative 'nodes/field'
14
14
  require_relative 'nodes/filter'
15
+ require_relative 'nodes/foreign'
16
+ require_relative 'nodes/given'
15
17
  require_relative 'nodes/iterator'
16
18
  require_relative 'nodes/greater_than'
17
19
  require_relative 'nodes/greater_than_equal'
18
- require_relative 'nodes/grouping/close'
19
- require_relative 'nodes/grouping/grouping'
20
- require_relative 'nodes/grouping/open'
21
20
  require_relative 'nodes/less_than'
22
21
  require_relative 'nodes/less_than_equal'
22
+ require_relative 'nodes/named_value'
23
23
  require_relative 'nodes/number'
24
+ require_relative 'nodes/partial'
24
25
  require_relative 'nodes/range_value'
25
- require_relative 'nodes/set/close'
26
- require_relative 'nodes/set/delimiter'
27
- require_relative 'nodes/set/set'
28
- require_relative 'nodes/set/open'
26
+ require_relative 'nodes/set'
29
27
  require_relative 'nodes/time'
30
28
  require_relative 'nodes/value'
31
29
  require_relative 'nodes/word'
@@ -10,6 +10,11 @@ module MSFLVisitors
10
10
  lt: Nodes::LessThan,
11
11
  lte: Nodes::LessThanEqual,
12
12
  in: Nodes::Containment,
13
+ foreign: Nodes::Foreign,
14
+ dataset: Nodes::Dataset,
15
+ filter: Nodes::ExplicitFilter,
16
+ given: Nodes::Given,
17
+ partial: Nodes::Partial,
13
18
 
14
19
  }
15
20
 
@@ -34,10 +39,14 @@ module MSFLVisitors
34
39
  end
35
40
 
36
41
 
37
-
42
+ def initialize(dataset = nil)
43
+ @dataset = dataset
44
+ end
38
45
 
39
46
  private
40
47
 
48
+ attr_accessor :dataset
49
+
41
50
  def parse_Hash(obj, lhs = false)
42
51
  nodes = Array.new
43
52
  obj.each do |k, v|
@@ -57,14 +66,34 @@ module MSFLVisitors
57
66
  obj.each do |item|
58
67
  nodes << parse(item)
59
68
  end
60
- MSFLVisitors::Nodes::Set::Set.new nodes
69
+ MSFLVisitors::Nodes::Set.new nodes
61
70
  end
62
71
 
72
+ # A key/value pair needs to be parsed and handled while iterating across the Hash that the key/value pair belong to
73
+ # lhs is for when the field is a parent of the actual operator node
74
+ # ex. { year: { gte: 2010 } } needs to be converted to (gte(year, 2010)) -- infix operators to RPN
63
75
  def hash_dispatch(key, value, lhs = false)
64
76
  if OPERATORS_TO_NODE_CLASS.include? key
65
77
  # Detect the node type, forward the lhs if it was passed in (essentially when the operator is a binary op)
66
- args = [lhs, parse(value)] if lhs
67
- args ||= [parse(value)]
78
+ case key
79
+ when :foreign
80
+ args = [hash_dispatch(:dataset, value[:dataset]), hash_dispatch(:filter, value[:filter])]
81
+
82
+ when :partial
83
+ args = [hash_dispatch(:given, value[:given]), hash_dispatch(:filter, value[:filter])]
84
+
85
+ when :dataset
86
+ args = [value]
87
+ when :filter, :given
88
+ # Explicit Filter
89
+ # ex { foreign: { dataset: "person", filter: { age: 25 } } }
90
+ # ex { partial: { given: { make: "Toyota" }, filter: { avg_age: 10 } } }
91
+ args = value.map { |k,v| hash_dispatch(k,v) }
92
+ else
93
+ # fall back to a Filter Node
94
+ args = [lhs, parse(value)] if lhs
95
+ args ||= [parse(value)]
96
+ end
68
97
  OPERATORS_TO_NODE_CLASS[key].new(*args)
69
98
  else
70
99
  # the key is a field
@@ -1,16 +1,175 @@
1
+ require 'forwardable'
1
2
  module MSFLVisitors
2
3
  class Visitor
3
- def initialize(collector, renderer)
4
- @collector = collector
5
- @renderer = renderer
4
+
5
+ attr_accessor :clauses, :current_clause
6
+ attr_writer :mode
7
+
8
+ def initialize
9
+ self.mode = :term # or :aggregations
10
+ self.clauses = Array.new
11
+
12
+ end
13
+
14
+ def visit(node)
15
+ case node
16
+ when Nodes::Partial
17
+ in_aggregation_mode do
18
+ clauses << { clause: get_visitor.visit(node), method_to_execute: :aggregations }
19
+ ""
20
+ end
21
+ else
22
+ get_visitor.visit(node)
23
+ end
24
+ end
25
+
26
+ def get_visitor
27
+ (mode == :term ? TermFilterVisitor : AggregationsVisitor).new(self)
6
28
  end
7
29
 
8
- def visit(obj)
9
- collector << renderer.render(obj)
30
+ def in_aggregation_mode
31
+ self.mode = :aggregations
32
+ result = yield if block_given?
33
+ self.mode = :term
34
+ result
35
+ end
36
+
37
+ def visit_tree(root)
38
+ [{clause: root.accept(self)}].concat(clauses).reject { |c| c[:clause] == "" }
10
39
  end
11
40
 
12
41
  private
13
42
 
14
- attr_reader :collector, :renderer
43
+ attr_reader :mode
44
+
45
+ class TermFilterVisitor
46
+ def initialize(visitor)
47
+ @visitor = visitor
48
+ end
49
+
50
+ BINARY_OPERATORS = {
51
+ Nodes::Containment => '==',
52
+ Nodes::GreaterThan => '>',
53
+ Nodes::GreaterThanEqual => '>=',
54
+ Nodes::Equal => '==',
55
+ Nodes::LessThan => '<',
56
+ Nodes::LessThanEqual => '<=',
57
+ }
58
+
59
+ def visit(node)
60
+ case node
61
+ when Nodes::Field
62
+ node.value.to_s
63
+ when Nodes::Word
64
+ "\"#{node.value}\""
65
+ when Nodes::Date, Nodes::Time
66
+ "\"#{node.value.iso8601}\""
67
+ when Nodes::Number, Nodes::Boolean
68
+ node.value
69
+ when Nodes::Containment,
70
+ Nodes::GreaterThan,
71
+ Nodes::GreaterThanEqual,
72
+ Nodes::Equal,
73
+ Nodes::LessThan,
74
+ Nodes::LessThanEqual
75
+ "#{node.left.accept(visitor)} #{BINARY_OPERATORS[node.class]} #{node.right.accept(visitor)}"
76
+ when Nodes::Set
77
+ "[ " + node.contents.map { |n| n.accept(visitor) }.join(" , ") + " ]"
78
+ when Nodes::Filter
79
+ if node.contents.count == 1
80
+ node.contents.first.accept(visitor)
81
+ else
82
+ node.contents.map { |n| "( " + n.accept(visitor) + " )" }.join(" & ")
83
+ end
84
+
85
+ when Nodes::And
86
+ if node.set.contents.count == 1
87
+ node.set.contents.first.accept(visitor)
88
+ else
89
+ node.set.contents.map { |n| "( " + n.accept(visitor) + " )" }.join(" & ")
90
+ end
91
+
92
+ when Nodes::Foreign
93
+ "#{node.left.accept visitor}.filter { #{node.right.accept visitor} }"
94
+
95
+ when Nodes::Dataset
96
+ "has_child( :#{node.value} )"
97
+
98
+ else
99
+ fail ArgumentError, "TERMFILTER cannot visit: #{node.class.name}"
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ attr_reader :visitor
106
+ end
107
+
108
+ class AggregationsVisitor
109
+ def initialize(visitor)
110
+ @visitor = visitor
111
+ end
112
+
113
+ RANGE_OPERATORS = {
114
+ Nodes::GreaterThan => :gt,
115
+ Nodes::GreaterThanEqual => :gte,
116
+ Nodes::LessThan => :lt,
117
+ Nodes::LessThanEqual => :lte,
118
+ }
119
+
120
+ def visit(node)
121
+ case node
122
+ when Nodes::Partial
123
+ { given: Hash[[node.left.accept(visitor), node.right.accept(visitor)]] }
124
+
125
+ when Nodes::Equal
126
+ { term: { node.left.accept(visitor) => node.right.accept(visitor) } }
127
+ # [{ clause: }]
128
+ when Nodes::Field
129
+ node.value.to_sym
130
+ when Nodes::Date, Nodes::Time
131
+ node.value.iso8601
132
+ when Nodes::Word,
133
+ Nodes::Number,
134
+ Nodes::Boolean,
135
+ Nodes::Dataset
136
+ node.value
137
+ when Nodes::GreaterThan,
138
+ Nodes::GreaterThanEqual,
139
+ Nodes::LessThan,
140
+ Nodes::LessThanEqual
141
+ { range: { node.left.accept(visitor) => { RANGE_OPERATORS[node.class] => node.right.accept(visitor) } } }
142
+ when Nodes::Given
143
+ [:filter, node.contents.first.accept(visitor)]
144
+ when Nodes::ExplicitFilter
145
+ [:filter, node.contents.map { |n| n.accept(visitor) }.reduce({}) { |hsh, x| hsh.merge!(x); hsh } ]
146
+ when Nodes::NamedValue
147
+ [:aggs, {node.name.accept(visitor).to_sym => Hash[[node.value.accept(visitor)]]}]
148
+ when Nodes::Containment
149
+ { terms: {node.left.accept(visitor).to_sym => node.right.accept(visitor)} }
150
+ when Nodes::Set
151
+ node.contents.map { |n| n.accept(visitor) }
152
+ when Nodes::Filter
153
+ if node.contents.count == 1
154
+ node.contents.first.accept visitor
155
+ else
156
+ { and: node.contents.map { |n| n.accept(visitor) } }
157
+ end
158
+ when Nodes::And
159
+ { and: node.set.accept(visitor) }
160
+
161
+ when Nodes::Foreign
162
+ { has_child: Hash[[[:type, node.left.accept(visitor)], node.right.accept(visitor)]] }
163
+
164
+ else
165
+ fail ArgumentError, "AGGREGATIONS cannot visit: #{node.class.name}"
166
+ end
167
+ end
168
+
169
+ private
170
+
171
+ attr_reader :visitor
172
+ end
15
173
  end
16
174
  end
175
+
data/lib/msfl_visitors.rb CHANGED
@@ -1,9 +1,7 @@
1
1
  require_relative 'msfl_visitors/ast'
2
2
  require_relative 'msfl_visitors/nodes'
3
3
  require_relative 'msfl_visitors/visitor'
4
- require_relative 'msfl_visitors/renderers/chewy/term_filter'
5
4
  require_relative 'msfl_visitors/parsers/msfl_parser'
6
- require_relative 'msfl_visitors/collectors'
7
5
 
8
6
  module MSFLVisitors
9
7
  end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'msfl_visitors'
3
- s.version = '0.1.0.rc3'
4
- s.date = '2015-05-11'
3
+ s.version = '0.3.0.dev'
4
+ s.date = '2015-05-15'
5
5
  s.summary = "Convert MSFL to other forms"
6
6
  s.description = "Visitor pattern approach to converting MSFL to other forms."
7
7
  s.authors = ["Courtland Caldwell"]
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
11
11
  s.homepage =
12
12
  'https://github.com/Referly/msfl_visitors'
13
- s.add_runtime_dependency "msfl", "~> 1.1", '>= 1.1.6'
13
+ s.add_runtime_dependency "msfl", "~> 1.2"
14
14
  s.add_development_dependency "rake", "~> 10.3"
15
15
  s.add_development_dependency "simplecov", "~> 0.10"
16
16
  s.add_development_dependency "yard", "~> 0.8"
@@ -2,15 +2,33 @@ require 'spec_helper'
2
2
 
3
3
  describe MSFLVisitors::Nodes::Iterator do
4
4
 
5
+ describe ".new" do
6
+
7
+ subject { described_class.new arg }
8
+
9
+ context "when the argument is not a MSFLVisitors::Nodes::Set instance" do
10
+
11
+ let(:arg) { double('Not a Set node') }
12
+
13
+ it "raises an ArgumentError" do
14
+ expect { subject }.to raise_error ArgumentError
15
+ end
16
+ end
17
+ end
18
+
5
19
  describe "#==" do
6
20
 
7
21
  let(:one) { MSFLVisitors::Nodes::Number.new(1) }
8
22
 
9
23
  let(:two) { MSFLVisitors::Nodes::Number.new(2) }
10
24
 
11
- let(:left) { MSFLVisitors::Nodes::Iterator.new [one, two] }
25
+ let(:left) { MSFLVisitors::Nodes::Iterator.new left_set }
26
+
27
+ let(:left_set) { MSFLVisitors::Nodes::Set.new [one, two] }
28
+
29
+ let(:right) { MSFLVisitors::Nodes::Iterator.new right_set }
12
30
 
13
- let(:right) { MSFLVisitors::Nodes::Iterator.new [one, two] }
31
+ let(:right_set) { MSFLVisitors::Nodes::Set.new [one, two] }
14
32
 
15
33
  subject { left == right }
16
34
 
@@ -23,7 +41,7 @@ describe MSFLVisitors::Nodes::Iterator do
23
41
 
24
42
  context "when lhs#items is not equal to rhs#items" do
25
43
 
26
- let(:right) { MSFLVisitors::Nodes::Iterator.new [one] }
44
+ let(:right_set) { MSFLVisitors::Nodes::Set.new [one] }
27
45
 
28
46
  it { is_expected.to be false }
29
47
  end