sparkql 1.2.8 → 1.3.0
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 +4 -4
- data/.rubocop.yml +111 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +4 -0
- data/Rakefile +2 -3
- data/VERSION +1 -1
- data/lib/sparkql/errors.rb +68 -71
- data/lib/sparkql/evaluator.rb +13 -9
- data/lib/sparkql/expression_resolver.rb +2 -3
- data/lib/sparkql/expression_state.rb +7 -9
- data/lib/sparkql/function_resolver.rb +15 -10
- data/lib/sparkql/geo/record_circle.rb +1 -1
- data/lib/sparkql/lexer.rb +54 -56
- data/lib/sparkql/parser.rb +35 -35
- data/lib/sparkql/parser_compatibility.rb +97 -76
- data/lib/sparkql/parser_tools.rb +159 -139
- data/lib/sparkql/token.rb +25 -25
- data/lib/sparkql/version.rb +1 -1
- data/sparkql.gemspec +1 -1
- data/test/unit/errors_test.rb +4 -5
- data/test/unit/evaluator_test.rb +15 -16
- data/test/unit/expression_state_test.rb +14 -15
- data/test/unit/function_resolver_test.rb +125 -161
- data/test/unit/geo/record_circle_test.rb +2 -2
- data/test/unit/lexer_test.rb +15 -16
- data/test/unit/parser_compatability_test.rb +177 -151
- data/test/unit/parser_test.rb +90 -90
- metadata +8 -6
data/test/unit/parser_test.rb
CHANGED
@@ -5,10 +5,10 @@ class ParserTest < Test::Unit::TestCase
|
|
5
5
|
|
6
6
|
def test_simple
|
7
7
|
@parser = Parser.new
|
8
|
-
parse 'Test Eq 10',10.to_s
|
9
|
-
parse 'Test Eq 10.0',10.0.to_s
|
10
|
-
parse 'Test Eq true',true.to_s
|
11
|
-
parse "Test Eq 'false'","'false'"
|
8
|
+
parse 'Test Eq 10', 10.to_s
|
9
|
+
parse 'Test Eq 10.0', 10.0.to_s
|
10
|
+
parse 'Test Eq true', true.to_s
|
11
|
+
parse "Test Eq 'false'", "'false'"
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_conjunction
|
@@ -26,7 +26,7 @@ class ParserTest < Test::Unit::TestCase
|
|
26
26
|
assert_equal 11.to_s, expression.last[:value]
|
27
27
|
assert_equal 'Not', expression.last[:conjunction]
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def test_tough_conjunction
|
31
31
|
@parser = Parser.new
|
32
32
|
expression = @parser.parse('Test Eq 10 Or Test Ne 11 And Test Ne 9')
|
@@ -52,50 +52,50 @@ class ParserTest < Test::Unit::TestCase
|
|
52
52
|
def test_multiples
|
53
53
|
@parser = Parser.new
|
54
54
|
expression = @parser.parse('(Test Eq 10,11,12)').first
|
55
|
-
assert_equal [10.to_s,11.to_s,12.to_s], expression[:value]
|
55
|
+
assert_equal [10.to_s, 11.to_s, 12.to_s], expression[:value]
|
56
56
|
assert_equal '10,11,12', expression[:condition]
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
def test_invalid_syntax
|
60
60
|
@parser = Parser.new
|
61
61
|
expression = @parser.parse('Test Eq DERP')
|
62
62
|
assert @parser.errors?, "Should be nil: #{expression}"
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
def test_nesting
|
66
66
|
assert_nesting(
|
67
67
|
"City Eq 'Fargo' Or (BathsFull Eq 1 Or BathsFull Eq 2) Or City Eq 'Moorhead' Or City Eq 'Dilworth'",
|
68
|
-
[0,1,1,0,0]
|
68
|
+
[0, 1, 1, 0, 0]
|
69
69
|
)
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
def test_nesting_and_functions
|
73
73
|
# Nesting with a function thrown in. Yes, this was a problem.
|
74
74
|
assert_nesting(
|
75
75
|
"City Eq 'Fargo' Or (BathsFull Eq 1 And Location Eq rectangle('35.12 -68.33, 35.13 -68.32')) Or Location Eq radius('35.12 -68.33',10.0) Or City Eq 'Dilworth'",
|
76
|
-
[0,1,1,0,0]
|
76
|
+
[0, 1, 1, 0, 0]
|
77
77
|
)
|
78
78
|
end
|
79
79
|
|
80
80
|
def test_multilevel_nesting
|
81
81
|
assert_nesting(
|
82
82
|
"(City Eq 'Fargo' And (BathsFull Eq 1 Or BathsFull Eq 2)) Or City Eq 'Moorhead' Or City Eq 'Dilworth'",
|
83
|
-
[1,2,2,0,0]
|
83
|
+
[1, 2, 2, 0, 0]
|
84
84
|
)
|
85
|
-
|
85
|
+
|
86
86
|
# API-629
|
87
87
|
assert_nesting(
|
88
88
|
"((MlsStatus Eq 'A') Or (MlsStatus Eq 'D' And CloseDate Ge 2011-05-17)) And ListPrice Ge 150000.0 And PropertyType Eq 'A'",
|
89
|
-
[2,2,2,0,0],
|
90
|
-
[2,3,3,0,0]
|
89
|
+
[2, 2, 2, 0, 0],
|
90
|
+
[2, 3, 3, 0, 0]
|
91
91
|
)
|
92
92
|
assert_nesting(
|
93
93
|
"ListPrice Ge 150000.0 And PropertyType Eq 'A' And ((MlsStatus Eq 'A') Or (MlsStatus Eq 'D' And CloseDate Ge 2011-05-17))",
|
94
|
-
[0,0,2,2,2],
|
95
|
-
[0,0,2,3,3]
|
94
|
+
[0, 0, 2, 2, 2],
|
95
|
+
[0, 0, 2, 3, 3]
|
96
96
|
)
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
def test_bad_queries
|
100
100
|
filter = "City IsLikeA 'Town'"
|
101
101
|
@parser = Parser.new
|
@@ -105,8 +105,8 @@ class ParserTest < Test::Unit::TestCase
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def test_function_months
|
108
|
-
|
109
|
-
|
108
|
+
t = Time.new(2014, 1, 5, 0, 0, 0, 0)
|
109
|
+
Time.expects(:now).returns(t)
|
110
110
|
@parser = Parser.new
|
111
111
|
expressions = @parser.parse "ExpirationDate Gt months(-3)"
|
112
112
|
assert !@parser.errors?, "errors :( #{@parser.errors.inspect}"
|
@@ -115,8 +115,8 @@ class ParserTest < Test::Unit::TestCase
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def test_function_years
|
118
|
-
|
119
|
-
|
118
|
+
t = Time.new(2014, 1, 5, 0, 0, 0, 0)
|
119
|
+
Time.expects(:now).returns(t)
|
120
120
|
@parser = Parser.new
|
121
121
|
expressions = @parser.parse "SoldDate Lt years(2)"
|
122
122
|
assert !@parser.errors?, "errors :( #{@parser.errors.inspect}"
|
@@ -125,8 +125,8 @@ class ParserTest < Test::Unit::TestCase
|
|
125
125
|
end
|
126
126
|
|
127
127
|
def test_function_days
|
128
|
-
|
129
|
-
|
128
|
+
t = Time.new(2021, 2, 22, 0, 0, 0, 0)
|
129
|
+
Time.expects(:now).returns(t)
|
130
130
|
@parser = Parser.new
|
131
131
|
expressions = @parser.parse "ExpirationDate Gt days(10)"
|
132
132
|
assert !@parser.errors?
|
@@ -135,8 +135,8 @@ class ParserTest < Test::Unit::TestCase
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def test_function_weekdays
|
138
|
-
|
139
|
-
|
138
|
+
t = Time.new(2021, 2, 22, 0, 0, 0, 0)
|
139
|
+
Time.expects(:now).returns(t)
|
140
140
|
@parser = Parser.new
|
141
141
|
expressions = @parser.parse "ExpirationDate Gt weekdays(10)"
|
142
142
|
assert !@parser.errors?
|
@@ -152,8 +152,8 @@ class ParserTest < Test::Unit::TestCase
|
|
152
152
|
assert !@parser.errors?, "errors #{@parser.errors.inspect}"
|
153
153
|
assert_equal 'now()', expressions.first[:condition]
|
154
154
|
test_time = Time.parse(expressions.first[:value])
|
155
|
-
assert
|
156
|
-
assert -
|
155
|
+
assert test_time - start < 5, "Time range off by more than five seconds #{test_time - start}"
|
156
|
+
assert(test_time - start > -5, "Time range off by more than five seconds #{test_time - start}")
|
157
157
|
end
|
158
158
|
|
159
159
|
def test_function_range
|
@@ -178,7 +178,8 @@ class ParserTest < Test::Unit::TestCase
|
|
178
178
|
assert_equal 'indexof', expression[:field_manipulations][:function_name]
|
179
179
|
assert_equal :function, expression[:field_manipulations][:type]
|
180
180
|
assert_equal :integer, expression[:field_manipulations][:return_type]
|
181
|
-
assert_equal
|
181
|
+
assert_equal(%w[City 4131800000000],
|
182
|
+
expression[:field_manipulations][:args].map { |v| v[:value] })
|
182
183
|
end
|
183
184
|
|
184
185
|
test 'add' do
|
@@ -311,7 +312,7 @@ class ParserTest < Test::Unit::TestCase
|
|
311
312
|
assert_equal 'days(-7)', expressions.first[:condition]
|
312
313
|
assert_equal([-7], expressions.first[:function_parameters])
|
313
314
|
end
|
314
|
-
|
315
|
+
|
315
316
|
test "function rangeable " do
|
316
317
|
filter = "OriginalEntryTimestamp Bt days(-7),days(-1)"
|
317
318
|
@parser = Parser.new
|
@@ -460,7 +461,7 @@ class ParserTest < Test::Unit::TestCase
|
|
460
461
|
assert !@parser.errors?, "errors #{@parser.errors.inspect}"
|
461
462
|
assert_equal "polygon('35.12 -68.33, 35.13 -68.33, 35.13 -68.32, 35.12 -68.32')", expressions.first[:condition]
|
462
463
|
assert_equal :shape, expressions.first[:type]
|
463
|
-
assert_equal [[-68.33, 35.12], [-68.33, 35.13], [-68.32,35.13], [-68.32,35.12],[-68.33, 35.12]], expressions.first[:value].to_coordinates.first, "#{expressions.first[:value].inspect} "
|
464
|
+
assert_equal [[-68.33, 35.12], [-68.33, 35.13], [-68.32, 35.13], [-68.32, 35.12], [-68.33, 35.12]], expressions.first[:value].to_coordinates.first, "#{expressions.first[:value].inspect} "
|
464
465
|
end
|
465
466
|
|
466
467
|
test "Location Eq linestring()" do
|
@@ -471,7 +472,6 @@ class ParserTest < Test::Unit::TestCase
|
|
471
472
|
assert_equal "linestring('35.12 -68.33, 35.13 -68.33')", expressions.first[:condition]
|
472
473
|
assert_equal :shape, expressions.first[:type]
|
473
474
|
assert_equal [[-68.33, 35.12], [-68.33, 35.13]], expressions.first[:value].to_coordinates, "#{expressions.first[:value].inspect} "
|
474
|
-
|
475
475
|
end
|
476
476
|
|
477
477
|
test "Location Eq rectangle()" do
|
@@ -480,7 +480,7 @@ class ParserTest < Test::Unit::TestCase
|
|
480
480
|
expressions = @parser.parse(filter)
|
481
481
|
assert !@parser.errors?, "errors #{@parser.errors.inspect}"
|
482
482
|
assert_equal :shape, expressions.first[:type]
|
483
|
-
assert_equal [[-68.33,35.12], [-68.32,35.12], [-68.32,35.13], [-68.33,35.13], [-68.33,35.12]], expressions.first[:value].to_coordinates.first, "#{expressions.first[:value].inspect} "
|
483
|
+
assert_equal [[-68.33, 35.12], [-68.32, 35.12], [-68.32, 35.13], [-68.33, 35.13], [-68.33, 35.12]], expressions.first[:value].to_coordinates.first, "#{expressions.first[:value].inspect} "
|
484
484
|
end
|
485
485
|
|
486
486
|
test "Location Eq radius()" do
|
@@ -507,26 +507,26 @@ class ParserTest < Test::Unit::TestCase
|
|
507
507
|
test "Location eq radius() error on invalid syntax" do
|
508
508
|
filter = "Location Eq radius('35.12,-68.33',1.0)"
|
509
509
|
@parser = Parser.new
|
510
|
-
|
510
|
+
@parser.parse(filter)
|
511
511
|
assert @parser.errors?, "Parser error expected due to comma between radius points"
|
512
512
|
end
|
513
|
-
|
513
|
+
|
514
514
|
test "Location ALL TOGETHER NOW" do
|
515
515
|
filter = "Location Eq linestring('35.12 -68.33, 35.13 -68.33') And Location Eq radius('35.12 -68.33',1.0) And Location Eq rectangle('35.12 -68.33, 35.13 -68.32') And Location Eq polygon('35.12 -68.33, 35.13 -68.33, 35.13 -68.32, 35.12 -68.32')"
|
516
516
|
@parser = Parser.new
|
517
517
|
expressions = @parser.parse(filter)
|
518
518
|
assert !@parser.errors?, "errors #{@parser.errors.inspect}"
|
519
|
-
assert_equal
|
519
|
+
assert_equal(%i[shape shape shape shape], expressions.map { |e| e[:type] })
|
520
520
|
end
|
521
|
-
|
521
|
+
|
522
522
|
def test_for_reserved_words_first_literals_second
|
523
523
|
["OrOrOr Eq true", "Equador Eq true", "Oregon Ge 10"].each do |filter|
|
524
524
|
@parser = Parser.new
|
525
|
-
|
525
|
+
@parser.parse(filter)
|
526
526
|
assert !@parser.errors?, "Filter '#{filter}' errors: #{@parser.errors.inspect}"
|
527
527
|
end
|
528
528
|
end
|
529
|
-
|
529
|
+
|
530
530
|
def test_custom_fields
|
531
531
|
filter = '"General Property Description"."Taxes" Lt 500.0'
|
532
532
|
@parser = Parser.new
|
@@ -536,48 +536,46 @@ class ParserTest < Test::Unit::TestCase
|
|
536
536
|
assert expressions.first[:custom_field], "Custom field expression #{expressions.inspect}"
|
537
537
|
assert_equal '500.0', expressions.first[:value], "Custom field expression #{expressions.inspect}"
|
538
538
|
end
|
539
|
-
|
539
|
+
|
540
540
|
def test_valid_custom_field_filters
|
541
541
|
['"General Property Description"."Taxes$" Lt 500.0',
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
].each do |filter|
|
542
|
+
'"General Property Desc\'"."Taxes" Lt 500.0',
|
543
|
+
'"General Property Description"."Taxes" Lt 500.0',
|
544
|
+
'"General \'Property\' Description"."Taxes" Lt 500.0',
|
545
|
+
'"General Property Description"."Taxes #" Lt 500.0',
|
546
|
+
'"General$Description"."Taxes" Lt 500.0',
|
547
|
+
'"Garage Type"."1" Eq true',
|
548
|
+
'" a "." b " Lt 500.0'].each do |filter|
|
550
549
|
@parser = Parser.new
|
551
|
-
|
550
|
+
@parser.parse(filter)
|
552
551
|
assert !@parser.errors?, "errors '#{filter}'\n#{@parser.errors.inspect}"
|
553
552
|
end
|
554
553
|
end
|
555
|
-
|
554
|
+
|
556
555
|
def test_invalid_custom_field_filters
|
557
556
|
['"$General Property Description"."Taxes" Lt 500.0',
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
].each do |filter|
|
557
|
+
'"General Property Description"."$Taxes" Lt 500.0',
|
558
|
+
'"General Property Description"."Tax.es" Lt 500.0',
|
559
|
+
'"General Property Description".".Taxes" Lt 500.0',
|
560
|
+
'"General Property Description".".Taxes"."SUB" Lt 500.0',
|
561
|
+
'"General.Description"."Taxes" Lt 500.0',
|
562
|
+
'""."" Lt 500.0'].each do |filter|
|
565
563
|
@parser = Parser.new
|
566
|
-
|
564
|
+
@parser.parse(filter)
|
567
565
|
assert @parser.errors?, "No errors? '#{filter}'\n#{@parser.inspect}"
|
568
566
|
end
|
569
567
|
end
|
570
568
|
|
571
569
|
def test_case_insensitve_ops_and_conjunctions
|
572
570
|
@parser = Parser.new
|
573
|
-
parse 'Test EQ 10',10.to_s
|
574
|
-
parse 'Test eq 10.0',10.0.to_s
|
575
|
-
parse 'Test eQ true',true.to_s
|
571
|
+
parse 'Test EQ 10', 10.to_s
|
572
|
+
parse 'Test eq 10.0', 10.0.to_s
|
573
|
+
parse 'Test eQ true', true.to_s
|
576
574
|
parse 'Test EQ 10 AND Test NE 11', 10.to_s
|
577
575
|
parse 'Test eq 10 or Test ne 11', 10.to_s
|
578
576
|
parse 'Test eq 10 NOT Test ne 11', 10.to_s
|
579
577
|
end
|
580
|
-
|
578
|
+
|
581
579
|
def test_null
|
582
580
|
@parser = Parser.new
|
583
581
|
parse 'Test Eq NULL', "NULL"
|
@@ -591,7 +589,7 @@ class ParserTest < Test::Unit::TestCase
|
|
591
589
|
end
|
592
590
|
end
|
593
591
|
end
|
594
|
-
|
592
|
+
|
595
593
|
def test_not_expression
|
596
594
|
@parser = Parser.new
|
597
595
|
expressions = @parser.parse('Test Lt 10 Not Test Eq 2')
|
@@ -612,7 +610,7 @@ class ParserTest < Test::Unit::TestCase
|
|
612
610
|
assert_equal "And", expression[:conjunction]
|
613
611
|
assert_equal expression[:level], expression[:unary_level]
|
614
612
|
end
|
615
|
-
|
613
|
+
|
616
614
|
def test_not_expression_group
|
617
615
|
@parser = Parser.new
|
618
616
|
expressions = @parser.parse('Not (Test Eq 10 Or Test Eq 11)')
|
@@ -637,7 +635,7 @@ class ParserTest < Test::Unit::TestCase
|
|
637
635
|
|
638
636
|
def test_not_not_expression
|
639
637
|
@parser = Parser.new
|
640
|
-
filter = "Not (Not ListPrice Eq 1) Not (Not BathsTotal Eq 2) And "
|
638
|
+
filter = "Not (Not ListPrice Eq 1) Not (Not BathsTotal Eq 2) And " \
|
641
639
|
"(Not TotalRooms Eq 3) Or (HasPool Eq true)"
|
642
640
|
|
643
641
|
expressions = @parser.parse(filter)
|
@@ -706,7 +704,6 @@ class ParserTest < Test::Unit::TestCase
|
|
706
704
|
assert_equal 1, e2[:level]
|
707
705
|
assert_equal "Not", e2[:conjunction]
|
708
706
|
assert_equal 1, e2[:conjunction_level]
|
709
|
-
|
710
707
|
end
|
711
708
|
|
712
709
|
def test_expression_conditions_attribute
|
@@ -738,7 +735,7 @@ class ParserTest < Test::Unit::TestCase
|
|
738
735
|
]
|
739
736
|
conditions.each do |condition|
|
740
737
|
@parser = Parser.new
|
741
|
-
|
738
|
+
@parser.parse("Test Eq #{condition}")
|
742
739
|
assert @parser.errors?, @parser.inspect
|
743
740
|
end
|
744
741
|
end
|
@@ -748,12 +745,12 @@ class ParserTest < Test::Unit::TestCase
|
|
748
745
|
"DateTimeField Bt 2013-07-26T10:22:15,2013-07-26T10:22:16",
|
749
746
|
"DateTimeField Bt 2013-07-26T10:22:15.422804-0300,2013-07-26T10:22:15.422805-0300",
|
750
747
|
"DateTimeField Bt 2013-07-26T10:22:15+0400,2013-07-26T10:22:16+0400"].each do |filter|
|
751
|
-
|
752
|
-
|
753
|
-
|
748
|
+
@parser = Parser.new
|
749
|
+
@parser.parse filter
|
750
|
+
assert !@parser.errors?, "Filter '#{filter}' failed: #{@parser.errors.first.inspect}"
|
754
751
|
end
|
755
752
|
end
|
756
|
-
|
753
|
+
|
757
754
|
def test_coercible_types
|
758
755
|
@parser = Parser.new
|
759
756
|
assert_equal :datetime, @parser.coercible_types(:date, :datetime)
|
@@ -814,7 +811,6 @@ class ParserTest < Test::Unit::TestCase
|
|
814
811
|
parser_errors("Field Eq -'Stringval'")
|
815
812
|
end
|
816
813
|
|
817
|
-
|
818
814
|
test "field negation" do
|
819
815
|
@parser = Parser.new
|
820
816
|
expressions = @parser.parse('-Test Eq 10')
|
@@ -861,7 +857,8 @@ class ParserTest < Test::Unit::TestCase
|
|
861
857
|
|
862
858
|
assert_equal 'round', expression[:field_manipulations][:function_name]
|
863
859
|
assert_equal :function, expression[:field_manipulations][:type]
|
864
|
-
assert_equal
|
860
|
+
assert_equal(['ListPrice'],
|
861
|
+
expression[:field_manipulations][:args].map { |v| v[:value] })
|
865
862
|
end
|
866
863
|
|
867
864
|
def test_ceiling_with_literal
|
@@ -921,7 +918,8 @@ class ParserTest < Test::Unit::TestCase
|
|
921
918
|
|
922
919
|
assert_equal 'floor', expression[:field_manipulations][:function_name]
|
923
920
|
assert_equal :function, expression[:field_manipulations][:type]
|
924
|
-
assert_equal
|
921
|
+
assert_equal(['ListPrice'],
|
922
|
+
expression[:field_manipulations][:args].map { |v| v[:value] })
|
925
923
|
end
|
926
924
|
|
927
925
|
def test_concat_with_field
|
@@ -932,12 +930,13 @@ class ParserTest < Test::Unit::TestCase
|
|
932
930
|
|
933
931
|
assert_equal :character, expression[:type]
|
934
932
|
assert_equal 'concat', expression[:field_function]
|
935
|
-
assert_equal([
|
933
|
+
assert_equal(%w[City b], expression[:args])
|
936
934
|
assert_equal("City", expression[:field])
|
937
935
|
|
938
936
|
assert_equal 'concat', expression[:field_manipulations][:function_name]
|
939
937
|
assert_equal :function, expression[:field_manipulations][:type]
|
940
|
-
assert_equal
|
938
|
+
assert_equal(%w[City b],
|
939
|
+
expression[:field_manipulations][:args].map { |v| v[:value] })
|
941
940
|
end
|
942
941
|
|
943
942
|
def test_concat_with_literal
|
@@ -949,7 +948,7 @@ class ParserTest < Test::Unit::TestCase
|
|
949
948
|
assert_equal 'concat', expression[:function_name]
|
950
949
|
assert_equal :character, expression[:type]
|
951
950
|
assert_equal "'ab'", expression[:value]
|
952
|
-
assert_equal [
|
951
|
+
assert_equal %w[a b], expression[:function_parameters]
|
953
952
|
end
|
954
953
|
|
955
954
|
def test_cast_with_field
|
@@ -964,7 +963,8 @@ class ParserTest < Test::Unit::TestCase
|
|
964
963
|
|
965
964
|
assert_equal 'cast', expression[:field_manipulations][:function_name]
|
966
965
|
assert_equal :function, expression[:field_manipulations][:type]
|
967
|
-
assert_equal
|
966
|
+
assert_equal(%w[ListPrice character],
|
967
|
+
expression[:field_manipulations][:args].map { |v| v[:value] })
|
968
968
|
end
|
969
969
|
|
970
970
|
def test_cast_with_invalid_type
|
@@ -1165,7 +1165,7 @@ class ParserTest < Test::Unit::TestCase
|
|
1165
1165
|
function2 = function1[:args].first
|
1166
1166
|
assert_equal :function, function2[:type]
|
1167
1167
|
assert_equal 'toupper', function2[:function_name]
|
1168
|
-
assert_equal({:
|
1168
|
+
assert_equal({ type: :field, value: "City" }, function2[:args].first)
|
1169
1169
|
end
|
1170
1170
|
|
1171
1171
|
test 'nested functions with multiple params' do
|
@@ -1176,12 +1176,12 @@ class ParserTest < Test::Unit::TestCase
|
|
1176
1176
|
function1 = expression[:field_manipulations]
|
1177
1177
|
assert_equal :function, function1[:type]
|
1178
1178
|
assert_equal 'concat', function1[:function_name]
|
1179
|
-
assert_equal({type: :character, value: 'b'}, function1[:args].last)
|
1179
|
+
assert_equal({ type: :character, value: 'b' }, function1[:args].last)
|
1180
1180
|
|
1181
1181
|
function2 = function1[:args].first
|
1182
1182
|
assert_equal :function, function2[:type]
|
1183
1183
|
assert_equal 'tolower', function2[:function_name]
|
1184
|
-
assert_equal({:
|
1184
|
+
assert_equal({ type: :field, value: "City" }, function2[:args].first)
|
1185
1185
|
end
|
1186
1186
|
|
1187
1187
|
test 'parse error with no field' do
|
@@ -1234,30 +1234,30 @@ class ParserTest < Test::Unit::TestCase
|
|
1234
1234
|
|
1235
1235
|
private
|
1236
1236
|
|
1237
|
-
def parser_errors(filter)
|
1237
|
+
def parser_errors(filter)
|
1238
1238
|
@parser = Parser.new
|
1239
1239
|
expression = @parser.parse(filter)
|
1240
1240
|
assert @parser.errors?, "Should find errors for '#{filter}': #{expression}"
|
1241
1241
|
end
|
1242
1242
|
|
1243
|
-
def parse(
|
1244
|
-
expressions = @parser.parse(
|
1245
|
-
assert !@parser.errors?, "Unexpected error parsing #{
|
1246
|
-
assert_equal
|
1243
|
+
def parse(query, value)
|
1244
|
+
expressions = @parser.parse(query)
|
1245
|
+
assert !@parser.errors?, "Unexpected error parsing #{query} #{@parser.errors.inspect}"
|
1246
|
+
assert_equal value, expressions.first[:value], "Expression #{expressions.inspect}"
|
1247
1247
|
assert !expressions.first[:custom_field], "Unexepected custom field #{expressions.inspect}"
|
1248
1248
|
end
|
1249
1249
|
|
1250
1250
|
# verify each expression in the query is at the right nesting level and group
|
1251
|
-
def assert_nesting(sparkql, levels=[], block_groups=nil)
|
1251
|
+
def assert_nesting(sparkql, levels = [], block_groups = nil)
|
1252
1252
|
block_groups = levels.clone if block_groups.nil?
|
1253
1253
|
parser = Parser.new
|
1254
1254
|
expressions = parser.parse(sparkql)
|
1255
1255
|
assert !parser.errors?, "Unexpected error parsing #{sparkql}: #{parser.errors.inspect}"
|
1256
1256
|
count = 0
|
1257
1257
|
expressions.each do |ex|
|
1258
|
-
assert_equal levels[count],
|
1259
|
-
assert_equal(block_groups[count],
|
1260
|
-
count +=1
|
1258
|
+
assert_equal levels[count], ex[:level], "Nesting level wrong for #{ex.inspect}"
|
1259
|
+
assert_equal(block_groups[count], ex[:block_group], "Nesting block group wrong for #{ex.inspect}")
|
1260
|
+
count += 1
|
1261
1261
|
end
|
1262
1262
|
end
|
1263
1263
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sparkql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wade McEwen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: georuby
|
@@ -70,16 +70,16 @@ dependencies:
|
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 12.3.3
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 12.3.3
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: test-unit
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,6 +102,8 @@ extensions: []
|
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
104
|
- ".gitignore"
|
105
|
+
- ".rubocop.yml"
|
106
|
+
- ".ruby-version"
|
105
107
|
- CHANGELOG.md
|
106
108
|
- GRAMMAR.md
|
107
109
|
- Gemfile
|