msfl_visitors 1.2.3 → 1.3.0.dev.f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4f7b46f12ec1e288ad1b62e983c0585a6194b5c
4
- data.tar.gz: 01bf0621c30d745039618cd6f8ce71927fe13e1d
3
+ metadata.gz: ec528af7457f8551d7febd5d497337a2b805ac8b
4
+ data.tar.gz: 5e3de6c175ad703eb72b351c30cb3e7a025d9c82
5
5
  SHA512:
6
- metadata.gz: 1be1ea7b20669e7205edf8dd164ba9799cc67995c5dff2b41706b2259a2f62ec8af4b75ad3e612fdeaf8782797ca2c43df1ceb7e207c80787b41cfd4452ccf6e
7
- data.tar.gz: 5a5c14a0c70f0bb6e6273e3450f46216bd183766ba1539d0690fb3a52b2a3ccb1a825c8d3b83984f64f4faac7b769545579533d5b55c30422abe35dde1e522e7
6
+ metadata.gz: a78faedefd14402aba98cbdcd9e4c8ff976c43fc80aa5a9370cf17d6cc1d3ddc0350e47e4d4c3ced60669253fc7840ff0fe54ece4d6a46641f8a55b1449667c8
7
+ data.tar.gz: c05b7c376734ef110bb67a02f16c2e4bc167da846e07a30b00c6197900655b85da0c3adf6b671384f3b55da9e8ca19ff8bda38ff6c53599c021752344be4d89c
@@ -19,11 +19,15 @@ module MSFLVisitors
19
19
  def composable_expr_for(regex_as_literal_string)
20
20
  regex_as_literal_string[3..-4]
21
21
  end
22
+
23
+ def coerce_value_to_unquoted(value)
24
+ return value[1..-2] if value[0] == "\""
25
+ end
22
26
  end
23
27
 
24
28
  class Visitor
25
29
 
26
- attr_accessor :clauses, :current_clause
30
+ attr_accessor :clauses, :current_clause, :arel_table
27
31
  attr_writer :mode
28
32
 
29
33
  def initialize
@@ -35,6 +39,8 @@ module MSFLVisitors
35
39
  def visit(node)
36
40
  if mode == :es_term
37
41
  get_visitor.visit(node)
42
+ elsif mode == :arel
43
+ get_visitor.visit(node)
38
44
  else
39
45
  case node
40
46
  when Nodes::Partial
@@ -54,6 +60,8 @@ module MSFLVisitors
54
60
  TermFilterVisitor.new(self)
55
61
  when :es_term
56
62
  ESTermFilterVisitor.new(self)
63
+ when :arel
64
+ ArelFilterVisitor.new(self, arel_table)
57
65
  else
58
66
  AggregationsVisitor.new(self)
59
67
  end
@@ -66,8 +74,11 @@ module MSFLVisitors
66
74
  result
67
75
  end
68
76
 
69
- def visit_tree(root)
70
- [{clause: root.accept(self)}].concat(clauses).reject { |c| c[:clause] == "" }
77
+ def visit_tree(root, arel_table: nil)
78
+ return [{clause: root.accept(self)}].concat(clauses).reject { |c| c[:clause] == "" } unless mode == :arel
79
+ raise ArgumentError unless arel_table
80
+ @arel_table = arel_table.name
81
+ "#{root.accept(self)}"
71
82
  end
72
83
 
73
84
  private
@@ -245,6 +256,87 @@ module MSFLVisitors
245
256
  attr_reader :visitor
246
257
  end
247
258
 
259
+ class ArelFilterVisitor
260
+ include VisitorHelpers
261
+
262
+ attr_accessor :arel_table
263
+
264
+ def initialize(visitor, arel_table)
265
+ @visitor = visitor
266
+ @arel_table = arel_table
267
+ end
268
+
269
+ BINARY_OPERATORS = {
270
+ Nodes::Containment => 'in',
271
+ Nodes::GreaterThan => 'gt',
272
+ Nodes::GreaterThanEqual => 'gte',
273
+ Nodes::Equal => 'eq',
274
+ Nodes::LessThan => 'lt',
275
+ Nodes::LessThanEqual => 'lte',
276
+ Nodes::Match => '=~',
277
+ }
278
+
279
+
280
+
281
+ def visit(node)
282
+ case node
283
+ when Nodes::Field
284
+ "#{node.value.to_sym}"
285
+ when Nodes::Regex
286
+ regex_escape node.value.to_s
287
+ when Nodes::Word
288
+ "\"#{node.value}\""
289
+ when Nodes::Date, Nodes::Time
290
+ "\"#{node.value.iso8601}\""
291
+ when Nodes::Number, Nodes::Boolean
292
+ node.value
293
+
294
+ when Nodes::QueryString
295
+ %(#{node.left.accept(visitor)} LIKE '%#{coerce_value_to_unquoted node.right.accept(visitor)}%')
296
+
297
+ when Nodes::Match
298
+ if node.right.is_a? Nodes::Set
299
+ escaped_str_frags = node.right.contents.map { |right_child| composable_expr_for(MSFLVisitors::Nodes::Regex.new(right_child.value.to_s).accept(visitor).inspect) }
300
+ escaped_str = "(" + escaped_str_frags.join('|') + ")"
301
+ "#{node.left.accept(visitor)} #{BINARY_OPERATORS[node.class]} " + %r[.*#{escaped_str}.*].inspect
302
+ else
303
+ "#{node.left.accept(visitor)} #{BINARY_OPERATORS[node.class]} " + MSFLVisitors::Nodes::Regex.new(node.right.value.to_s).accept(visitor).inspect
304
+ end
305
+ when Nodes::Containment,
306
+ Nodes::GreaterThan,
307
+ Nodes::GreaterThanEqual,
308
+ Nodes::Equal,
309
+ Nodes::LessThan,
310
+ Nodes::LessThanEqual
311
+ %(#{arel_table}[:#{node.left.accept(visitor)}].#{BINARY_OPERATORS[node.class]}(#{node.right.accept(visitor)}))
312
+ when Nodes::Set
313
+ "[" + node.contents.map { |n| n.accept(visitor) }.join(", ") + "]"
314
+ when Nodes::Filter
315
+ node.contents.reduce("") { |res, n|
316
+ next(n.accept(visitor)) unless res.length > 0
317
+ res + ".and(#{n.accept(visitor)})"
318
+ }
319
+ when Nodes::And
320
+ node.set.contents.reduce("") { |res, n|
321
+ next(n.accept(visitor)) unless res.length > 0
322
+ res + ".and(#{n.accept(visitor)})"
323
+ }
324
+ when Nodes::Foreign
325
+ "#{node.left.accept visitor}.filter { #{node.right.accept visitor} }"
326
+
327
+ when Nodes::Dataset
328
+ "has_child( :#{node.value} )"
329
+
330
+ else
331
+ fail ArgumentError, "ArelFilter cannot visit: #{node.class.name}"
332
+ end
333
+ end
334
+
335
+ private
336
+
337
+ attr_reader :visitor
338
+ end
339
+
248
340
  # ESTermFilterVisitor is not currently used and so not all node types are implemented
249
341
  class ESTermFilterVisitor
250
342
  def initialize(visitor)
data/lib/msfl_visitors.rb CHANGED
@@ -15,5 +15,17 @@ module MSFLVisitors
15
15
  ast = parser.parse nmsfl
16
16
  visitor.visit_tree ast
17
17
  end
18
+
19
+ def get_arel(dataset, msfl, visitor = MSFLVisitors::Visitor.new)
20
+ visitor.mode = :arel
21
+ unless dataset.is_a? MSFL::Datasets::Base
22
+ raise ArgumentError, "The first argument to MSFLVisitors.get_arel must be a descendant of MSFL::Datasets::Base."
23
+ end
24
+ parser = MSFLVisitors::Parsers::MSFLParser.new dataset
25
+ converter = MSFL::Converters::Operator.new
26
+ nmsfl = converter.run_conversions msfl
27
+ ast = parser.parse nmsfl
28
+ visitor.visit_tree ast, arel_table: dataset.arel_table
29
+ end
18
30
  end
19
31
  end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'msfl_visitors'
3
- s.version = '1.2.3'
4
- s.date = '2015-07-09'
3
+ s.version = '1.3.0.dev.f'
4
+ s.date = '2016-09-30'
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"]
@@ -0,0 +1,451 @@
1
+ require 'spec_helper'
2
+
3
+ describe MSFLVisitors::Visitor do
4
+
5
+ let(:node) { fail ArgumentError, "You must define the node variable in each scope." }
6
+
7
+ let(:visitor) { described_class.new }
8
+
9
+ let(:left) { MSFLVisitors::Nodes::Field.new "lhs" }
10
+
11
+ let(:right) { MSFLVisitors::Nodes::Word.new "rhs" }
12
+
13
+ subject(:result) { node.accept visitor }
14
+
15
+ context "when using the ArelFilter visitor" do
16
+
17
+ before {
18
+ visitor.mode = :arel
19
+ visitor.arel_table = :cars
20
+ }
21
+
22
+ context "when visiting" do
23
+
24
+ describe "an unsupported node" do
25
+
26
+ class UnsupportedNode
27
+
28
+ def accept(visitor)
29
+ visitor.visit self
30
+ end
31
+ end
32
+
33
+ let(:node) { UnsupportedNode.new }
34
+
35
+ it "raises an ArgumentError" do
36
+ expect { subject }.to raise_error ArgumentError
37
+ end
38
+ end
39
+
40
+ # describe "a Partial node" do
41
+ #
42
+ # let(:node) { MSFLVisitors::Nodes::Partial.new given_node, named_value }
43
+ #
44
+ # let(:given_node) { MSFLVisitors::Nodes::Given.new [given_equal_node] }
45
+ #
46
+ # let(:given_equal_node) { MSFLVisitors::Nodes::Equal.new given_field_node, given_value_node }
47
+ #
48
+ # let(:given_field_node) { MSFLVisitors::Nodes::Field.new :make }
49
+ #
50
+ # let(:given_value_node) { MSFLVisitors::Nodes::Word.new "Toyota" }
51
+ #
52
+ #
53
+ # let(:named_value) { MSFLVisitors::Nodes::NamedValue.new MSFLVisitors::Nodes::Word.new("partial"), explicit_filter_node }
54
+ #
55
+ # let(:explicit_filter_node) { MSFLVisitors::Nodes::ExplicitFilter.new [greater_than_node] }
56
+ #
57
+ # let(:greater_than_node) { MSFLVisitors::Nodes::GreaterThan.new field_node, value_node }
58
+ #
59
+ # let(:field_node) { MSFLVisitors::Nodes::Field.new :age }
60
+ #
61
+ # let(:value_node) { MSFLVisitors::Nodes::Number.new 10 }
62
+ #
63
+ #
64
+ # subject { visitor.visit_tree node }
65
+ #
66
+ # it "results in the appropriate clause" do
67
+ # exp = [{
68
+ # clause: {
69
+ # given: {
70
+ # filter: {
71
+ # term: { make: "Toyota" }
72
+ # },
73
+ # aggs: {
74
+ # partial: {
75
+ # filter: { range: { age: { gt: 10 }}}
76
+ # }
77
+ # }
78
+ # }
79
+ # }
80
+ # }]
81
+ # expect(subject).to eq exp
82
+ # end
83
+ # end
84
+ #
85
+ # describe "a Given node" do
86
+ #
87
+ # let(:node) { MSFLVisitors::Nodes::Given.new [given_equal_node] }
88
+ #
89
+ # let(:given_equal_node) { MSFLVisitors::Nodes::Equal.new given_field_node, given_value_node }
90
+ #
91
+ # let(:given_field_node) { MSFLVisitors::Nodes::Field.new :make }
92
+ #
93
+ # let(:given_value_node) { MSFLVisitors::Nodes::Word.new "Toyota" }
94
+ #
95
+ #
96
+ # it "results in: [:filter, { term: { make: \"Toyota\" } }]" do
97
+ # expect(subject).to eq([:filter, { term: { make: "Toyota" } }])
98
+ # end
99
+ # end
100
+ #
101
+ # describe "a Foreign node" do
102
+ #
103
+ # let(:node) { MSFLVisitors::Nodes::Foreign.new dataset_node, filter_node }
104
+ #
105
+ # let(:dataset_node) { MSFLVisitors::Nodes::Dataset.new "person" }
106
+ #
107
+ # let(:filter_node) { MSFLVisitors::Nodes::ExplicitFilter.new [equal_node] }
108
+ #
109
+ # let(:equal_node) { MSFLVisitors::Nodes::Equal.new left, right }
110
+ #
111
+ # let(:left) { MSFLVisitors::Nodes::Field.new :age }
112
+ #
113
+ # let(:right) { MSFLVisitors::Nodes::Number.new 25 }
114
+ #
115
+ # it "results in: { has_child: { type: \"person\", filter: { term: { age: 25 } } } }" do
116
+ # expect(subject).to eq({ has_child: { type: "person", filter: { term: { age: 25 } } } })
117
+ # end
118
+ # end
119
+
120
+ describe "a Containment node" do
121
+
122
+ let(:node) { MSFLVisitors::Nodes::Containment.new field, values }
123
+
124
+ let(:values) { MSFLVisitors::Nodes::Set.new(MSFL::Types::Set.new([item_one, item_two, item_three])) }
125
+
126
+ let(:item_one) { MSFLVisitors::Nodes::Word.new "item_one" }
127
+
128
+ let(:item_two) { MSFLVisitors::Nodes::Word.new "item_two" }
129
+
130
+ let(:item_three) { MSFLVisitors::Nodes::Word.new "item_three" }
131
+
132
+ let(:field) { left }
133
+
134
+ it %(results in: 'cars[:lhs].in(["item_one", "item_two", "item_three"])') do
135
+ expect(subject).to eq(%(cars[:lhs].in(["item_one", "item_two", "item_three"])))
136
+ end
137
+ end
138
+
139
+ describe "a Set node" do
140
+
141
+ let(:node) { MSFLVisitors::Nodes::Set.new values }
142
+
143
+ let(:values) { MSFL::Types::Set.new([item_one, item_two]) }
144
+
145
+ let(:item_one) { MSFLVisitors::Nodes::Word.new "item_one" }
146
+
147
+ let(:item_two) { MSFLVisitors::Nodes::Word.new "item_two" }
148
+
149
+ it %(results in: '["item_one", "item_two"]') do
150
+ expect(result).to eq %(["item_one", "item_two"])
151
+ end
152
+ end
153
+
154
+ describe "an Equal node" do
155
+
156
+ let(:node) { MSFLVisitors::Nodes::Equal.new left, right }
157
+
158
+ it %(results in: 'cars[:lhs].eq("rhs")') do
159
+ expect(result).to eq(%(cars[:lhs].eq("rhs")))
160
+ end
161
+ end
162
+
163
+ #
164
+ # Models::Investor.arel_table.project(Arel.sql('*')).where(send MSFLVisitors.get_arel(MSFL::Datasets::Investor.new, { linkedin_id: { gt: 200 } })).to_a
165
+ #
166
+ describe "a GreaterThan node" do
167
+
168
+ let(:node) { MSFLVisitors::Nodes::GreaterThan.new left, right }
169
+
170
+ let(:right) { MSFLVisitors::Nodes::Number.new 1000 }
171
+
172
+ it %(results in: 'cars[:lhs].gt(1000)') do
173
+ expect(result).to eq(%(cars[:lhs].gt(1000)))
174
+ end
175
+ end
176
+
177
+ describe "a GreaterThanEqual node" do
178
+
179
+ let(:node) { MSFLVisitors::Nodes::GreaterThanEqual.new left, right }
180
+
181
+ let(:right) { MSFLVisitors::Nodes::Number.new 10.52 }
182
+
183
+ it %(results in: 'cars[:lhs].gte(10.52)') do
184
+ expect(result).to eq(%(cars[:lhs].gte(10.52)))
185
+ end
186
+ end
187
+
188
+ describe "a LessThan node" do
189
+
190
+ let(:node) { MSFLVisitors::Nodes::LessThan.new left, right }
191
+
192
+ let(:right) { MSFLVisitors::Nodes::Number.new 133.7 }
193
+
194
+ it %(returns: 'cars[:lhs].lt(133.7)') do
195
+ expect(result).to eq(%(cars[:lhs].lt(133.7)))
196
+ end
197
+ end
198
+
199
+ describe "a LessThanEqual node" do
200
+
201
+ let(:node) { MSFLVisitors::Nodes::LessThanEqual.new left, right }
202
+
203
+ let(:right) { MSFLVisitors::Nodes::Date.new Date.today }
204
+
205
+ it %(returns: 'cars[:lhs].lte(#{Date.today})') do
206
+ expect(result).to eq(%(cars[:lhs].lte("#{Date.today}")))
207
+ end
208
+ end
209
+
210
+ describe "a QueryString node" do
211
+
212
+ let(:node) { MSFLVisitors::Nodes::QueryString.new left, right }
213
+
214
+ let(:right) { MSFLVisitors::Nodes::Word.new "happy" }
215
+
216
+ it %(returns: "lhs LIKE '%happy%'") do
217
+ expect(result).to eq(%(lhs LIKE '%happy%'))
218
+ end
219
+ end
220
+
221
+ describe "a Filter node" do
222
+
223
+ let(:node) { MSFLVisitors::Nodes::Filter.new filtered_nodes }
224
+
225
+ let(:filtered_nodes) do
226
+ [
227
+ MSFLVisitors::Nodes::GreaterThanEqual.new(
228
+ MSFLVisitors::Nodes::Field.new(:value),
229
+ MSFLVisitors::Nodes::Number.new(1000))
230
+ ]
231
+ end
232
+
233
+ it %(returns: 'cars[:value].gte(1000)') do
234
+ expect(result).to eq(%(cars[:value].gte(1000)))
235
+ end
236
+
237
+ context "when the filter has multiple children" do
238
+
239
+ let(:filtered_nodes) do
240
+ [
241
+ MSFLVisitors::Nodes::Equal.new(
242
+ MSFLVisitors::Nodes::Field.new(:make),
243
+ MSFLVisitors::Nodes::Word.new("Chevy")
244
+ ),
245
+ MSFLVisitors::Nodes::GreaterThanEqual.new(
246
+ MSFLVisitors::Nodes::Field.new(:value),
247
+ MSFLVisitors::Nodes::Number.new(1000))
248
+ ]
249
+ end
250
+
251
+ it %(returns: 'cars[:make].eq("Chevy").and(cars[:value].gte(1000))') do
252
+ expect(result).to eq(%(cars[:make].eq("Chevy").and(cars[:value].gte(1000))))
253
+ end
254
+ end
255
+ end
256
+
257
+ describe "an And node" do
258
+
259
+ let(:first_field) { MSFLVisitors::Nodes::Field.new "first_field" }
260
+
261
+ let(:first_value) { MSFLVisitors::Nodes::Word.new "first_word" }
262
+
263
+ let(:first) { MSFLVisitors::Nodes::Equal.new(first_field, first_value) }
264
+
265
+ let(:second_field) { MSFLVisitors::Nodes::Field.new "second_field" }
266
+
267
+ let(:second_value) { MSFLVisitors::Nodes::Word.new "second_word" }
268
+
269
+ let(:second) { MSFLVisitors::Nodes::Equal.new(second_field, second_value) }
270
+
271
+ let(:third_field) { MSFLVisitors::Nodes::Field.new "third_field" }
272
+
273
+ let(:third_value) { MSFLVisitors::Nodes::Word.new "third_word" }
274
+
275
+ let(:third) { MSFLVisitors::Nodes::Equal.new(third_field, third_value) }
276
+
277
+ let(:node) { MSFLVisitors::Nodes::And.new(set_node) }
278
+
279
+ context "when the And node has zero items" do
280
+
281
+ let(:set_node) { MSFLVisitors::Nodes::Set.new [] }
282
+
283
+ it %(returns: '') do
284
+ expect(result).to eq('')
285
+ end
286
+ end
287
+
288
+ context "when the node has one item" do
289
+
290
+ let(:set_node) { MSFLVisitors::Nodes::Set.new [first] }
291
+
292
+ it %(returns: 'cars[:first_field].eq("first_word")') do
293
+ expect(result).to eq(%(cars[:first_field].eq("first_word")))
294
+ end
295
+ end
296
+
297
+ context "when the node has two items" do
298
+
299
+ let(:set_node) { MSFLVisitors::Nodes::Set.new [first, second] }
300
+
301
+ it %(returns: 'cars[:first_field].eq("first_word").and(cars[:second_field].eq("second_word"))') do
302
+ expect(result).to eq(%(cars[:first_field].eq("first_word").and(cars[:second_field].eq("second_word"))))
303
+ end
304
+ end
305
+
306
+ context "when the node has three items" do
307
+
308
+ let(:set_node) { MSFLVisitors::Nodes::Set.new [first, second, third] }
309
+
310
+ it %(returns: 'cars[:first_field].eq("first_word").and(cars[:second_field].eq("second_word")).and(cars[:third_field].eq("third_word"))') do
311
+ expect(result).to eq(%(cars[:first_field].eq("first_word").and(cars[:second_field].eq("second_word")).and(cars[:third_field].eq("third_word"))))
312
+ end
313
+ end
314
+
315
+ context "when one of the node's items is a containment node" do
316
+
317
+ let(:node) do
318
+ MSFLVisitors::Nodes::And.new(
319
+ MSFLVisitors::Nodes::Set.new(
320
+ [
321
+ MSFLVisitors::Nodes::Filter.new(
322
+ [
323
+ MSFLVisitors::Nodes::Containment.new(
324
+ MSFLVisitors::Nodes::Field.new(:make),
325
+ MSFLVisitors::Nodes::Set.new(
326
+ [
327
+ MSFLVisitors::Nodes::Word.new("Honda"),
328
+ MSFLVisitors::Nodes::Word.new("Chevy"),
329
+ MSFLVisitors::Nodes::Word.new("Volvo")
330
+ ]
331
+ )
332
+ )
333
+ ]
334
+ ),
335
+ MSFLVisitors::Nodes::Filter.new(
336
+ [
337
+ MSFLVisitors::Nodes::GreaterThanEqual.new(
338
+ MSFLVisitors::Nodes::Field.new(:value),
339
+ MSFLVisitors::Nodes::Number.new(1000)
340
+ )
341
+ ]
342
+ )
343
+ ]
344
+ )
345
+ )
346
+ end
347
+ it %(returns: 'cars[:make].in(["Honda", "Chevy", "Volvo"]).and(cars[:value].gte(1000))') do
348
+ expected = %(cars[:make].in(["Honda", "Chevy", "Volvo"]).and(cars[:value].gte(1000)))
349
+ expect(result).to eq expected
350
+ end
351
+ end
352
+ end
353
+
354
+ describe "value nodes" do
355
+ describe "a Boolean node" do
356
+
357
+ let(:node) { MSFLVisitors::Nodes::Boolean.new value }
358
+
359
+ subject(:result) { node.accept visitor }
360
+
361
+ context "with a value of true" do
362
+
363
+ let(:value) { true }
364
+
365
+ it "returns: true" do
366
+ expect(result).to eq true
367
+ end
368
+ end
369
+
370
+ context "with a value of false" do
371
+
372
+ let(:value) { false }
373
+
374
+ it "returns: false" do
375
+ expect(result).to eq false
376
+ end
377
+ end
378
+ end
379
+
380
+ describe "a Word node" do
381
+
382
+ let(:word) { "node_content" }
383
+
384
+ let(:node) { MSFLVisitors::Nodes::Word.new word }
385
+
386
+ it "returns: the literal string" do
387
+ expect(result).to eq "\"#{word}\""
388
+ end
389
+ end
390
+ end
391
+
392
+ describe "range value nodes" do
393
+
394
+ subject(:result) { node.accept visitor }
395
+
396
+ describe "a Date node" do
397
+
398
+ let(:today) { Date.today }
399
+
400
+ let(:node) { MSFLVisitors::Nodes::Date.new today }
401
+
402
+ it "returns: the date using iso8601 formatting" do
403
+ expect(result).to eq "\"#{today.iso8601}\""
404
+ end
405
+ end
406
+
407
+ describe "a Time node" do
408
+
409
+ let(:now) { Time.now }
410
+
411
+ let(:node) { MSFLVisitors::Nodes::Time.new now }
412
+
413
+ it "returns: the date using iso8601 formatting" do
414
+ expect(result).to eq "\"#{now.iso8601}\""
415
+ end
416
+ end
417
+
418
+ describe "a DateTime node" do
419
+
420
+ let(:now) { DateTime.now }
421
+
422
+ let(:node) { MSFLVisitors::Nodes::DateTime.new now }
423
+
424
+ it "returns: the date and time using iso8601 formatting" do
425
+ expect(result).to eq "\"#{now.iso8601}\""
426
+ end
427
+ end
428
+
429
+ describe "a Number node" do
430
+
431
+ let(:number) { 123 }
432
+
433
+ let(:node) { MSFLVisitors::Nodes::Number.new number }
434
+
435
+ it "returns: 123" do
436
+ expect(result).to eq number
437
+ end
438
+
439
+ context "when the number is a float" do
440
+
441
+ let(:number) { 123.456 }
442
+
443
+ it "returns: the number with the same precision" do
444
+ expect(result).to eq number
445
+ end
446
+ end
447
+ end
448
+ end
449
+ end
450
+ end
451
+ end
metadata CHANGED
@@ -1,103 +1,103 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msfl_visitors
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.3.0.dev.f
5
5
  platform: ruby
6
6
  authors:
7
7
  - Courtland Caldwell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-09 00:00:00.000000000 Z
11
+ date: 2016-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msfl
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.2'
20
- - - '>='
20
+ - - ">="
21
21
  - !ruby/object:Gem::Version
22
22
  version: 1.2.1
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ~>
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
29
  version: '1.2'
30
- - - '>='
30
+ - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 1.2.1
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rake
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - ~>
37
+ - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: '10.3'
40
40
  type: :development
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - ~>
44
+ - - "~>"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '10.3'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: simplecov
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - ~>
51
+ - - "~>"
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0.10'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - ~>
58
+ - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0.10'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: yard
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - ~>
65
+ - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: '0.8'
68
68
  type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - ~>
72
+ - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0.8'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: rspec
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ~>
79
+ - - "~>"
80
80
  - !ruby/object:Gem::Version
81
81
  version: '3.2'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - ~>
86
+ - - "~>"
87
87
  - !ruby/object:Gem::Version
88
88
  version: '3.2'
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: byebug
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
- - - ~>
93
+ - - "~>"
94
94
  - !ruby/object:Gem::Version
95
95
  version: '4.0'
96
96
  type: :development
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
- - - ~>
100
+ - - "~>"
101
101
  - !ruby/object:Gem::Version
102
102
  version: '4.0'
103
103
  description: Visitor pattern approach to converting MSFL to other forms.
@@ -106,7 +106,7 @@ executables: []
106
106
  extensions: []
107
107
  extra_rdoc_files: []
108
108
  files:
109
- - .gitignore
109
+ - ".gitignore"
110
110
  - Gemfile
111
111
  - Gemfile.lock
112
112
  - LICENSE
@@ -154,6 +154,7 @@ files:
154
154
  - spec/msfl_visitors/nodes/iterator_spec.rb
155
155
  - spec/msfl_visitors/parsers/msfl_parser_spec.rb
156
156
  - spec/msfl_visitors/visitor_spec.rb
157
+ - spec/msfl_visitors/visitors/arel_filter_spec.rb
157
158
  - spec/msfl_visitors/visitors/chewy_term_filter_spec.rb
158
159
  - spec/msfl_visitors/visitors/es_term_filter_spec.rb
159
160
  - spec/msfl_visitors_spec.rb
@@ -168,17 +169,17 @@ require_paths:
168
169
  - lib
169
170
  required_ruby_version: !ruby/object:Gem::Requirement
170
171
  requirements:
171
- - - '>='
172
+ - - ">="
172
173
  - !ruby/object:Gem::Version
173
174
  version: '0'
174
175
  required_rubygems_version: !ruby/object:Gem::Requirement
175
176
  requirements:
176
- - - '>='
177
+ - - ">"
177
178
  - !ruby/object:Gem::Version
178
- version: '0'
179
+ version: 1.3.1
179
180
  requirements: []
180
181
  rubyforge_project:
181
- rubygems_version: 2.4.2
182
+ rubygems_version: 2.4.3
182
183
  signing_key:
183
184
  specification_version: 4
184
185
  summary: Convert MSFL to other forms
@@ -187,6 +188,7 @@ test_files:
187
188
  - spec/msfl_visitors/nodes/iterator_spec.rb
188
189
  - spec/msfl_visitors/parsers/msfl_parser_spec.rb
189
190
  - spec/msfl_visitors/visitor_spec.rb
191
+ - spec/msfl_visitors/visitors/arel_filter_spec.rb
190
192
  - spec/msfl_visitors/visitors/chewy_term_filter_spec.rb
191
193
  - spec/msfl_visitors/visitors/es_term_filter_spec.rb
192
194
  - spec/msfl_visitors_spec.rb