sparkql 1.2.5 → 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 +5 -13
- data/.rubocop.yml +111 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +16 -0
- data/Gemfile +1 -2
- 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 +777 -676
- 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 +98 -77
- 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 +20 -18
- 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 +445 -203
- 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 +133 -99
- metadata +36 -35
@@ -1,21 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
require 'sparkql/geo'
|
3
5
|
|
4
6
|
class FunctionResolverTest < Test::Unit::TestCase
|
5
7
|
include Sparkql
|
6
|
-
|
7
|
-
EXAMPLE_DATE = DateTime.parse("2013-07-26T10:22:15.422804")
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YEAR = 2021
|
10
|
+
MONTH = 12
|
11
|
+
DAY = 31
|
12
|
+
HOURS = 0
|
13
|
+
MINUTES = 1
|
14
|
+
SECONDS = 2
|
15
|
+
MILLI = 123_456
|
16
|
+
SECONDSF = 2.123456
|
17
|
+
|
18
|
+
EXAMPLE_DATE = Time.new(YEAR, MONTH, DAY, HOURS, MINUTES, SECONDSF)
|
19
|
+
TIME_TESTS = {
|
20
|
+
year: YEAR,
|
21
|
+
month: MONTH,
|
22
|
+
mday: DAY,
|
23
|
+
hour: HOURS,
|
24
|
+
min: MINUTES,
|
25
|
+
sec: SECONDS
|
26
|
+
}.freeze
|
27
|
+
|
28
|
+
def assert_times(call_value, expected_call_type = :datetime, overrides = {})
|
29
|
+
assert_equal call_value[:type], expected_call_type
|
30
|
+
test_time = Time.parse(call_value[:value])
|
31
|
+
tests = TIME_TESTS.merge(overrides)
|
32
|
+
tests.each do |key, value|
|
33
|
+
assert_equal value, test_time.send(key), "#{key}: #{test_time}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
test '#lookup' do
|
38
|
+
good = FunctionResolver.lookup('all')
|
39
|
+
bad = FunctionResolver.lookup('not_function')
|
40
|
+
assert !good.nil?
|
41
|
+
assert_nil bad
|
42
|
+
end
|
43
|
+
|
44
|
+
test 'all with field' do
|
45
|
+
f = FunctionResolver.new('all', [
|
46
|
+
{ type: :field, value: 'Name' }
|
47
|
+
])
|
48
|
+
|
49
|
+
f.validate
|
50
|
+
assert !f.errors?, "Errors #{f.errors.inspect}"
|
51
|
+
value = f.call
|
52
|
+
|
53
|
+
assert_equal :function, value[:type]
|
54
|
+
assert_equal 'all', value[:value]
|
55
|
+
assert_equal 'Name', value[:args].first[:value]
|
56
|
+
end
|
57
|
+
|
58
|
+
test 'function parameters and name preserved' do
|
59
|
+
f = FunctionResolver.new('radius', [{ type: :character,
|
60
|
+
value: '35.12 -68.33' }, { type: :decimal, value: 1.0 }])
|
12
61
|
value = f.call
|
13
62
|
assert_equal 'radius', value[:function_name]
|
14
|
-
assert_equal([
|
63
|
+
assert_equal(['35.12 -68.33', 1.0], value[:function_parameters])
|
15
64
|
end
|
16
65
|
|
17
|
-
test
|
18
|
-
f = FunctionResolver.new('round', [{:
|
66
|
+
test 'round(float)' do
|
67
|
+
f = FunctionResolver.new('round', [{ type: :decimal, value: 0.5 }])
|
19
68
|
f.validate
|
20
69
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
21
70
|
value = f.call
|
@@ -23,22 +72,22 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
23
72
|
assert_equal '1', value[:value]
|
24
73
|
end
|
25
74
|
|
26
|
-
test
|
27
|
-
f = FunctionResolver.new('round', [{:
|
75
|
+
test 'round(Field)' do
|
76
|
+
f = FunctionResolver.new('round', [{ type: :field, value: 'ListPrice' }])
|
28
77
|
f.validate
|
29
78
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
30
79
|
value = f.call
|
31
80
|
|
32
81
|
assert_equal :function, value[:type]
|
33
82
|
assert_equal 'round', value[:value]
|
34
|
-
assert_equal
|
83
|
+
assert_equal 'ListPrice', value[:args].first[:value]
|
35
84
|
end
|
36
85
|
|
37
|
-
test
|
86
|
+
test 'substring character one index' do
|
38
87
|
f = FunctionResolver.new('substring', [
|
39
|
-
|
40
|
-
|
41
|
-
|
88
|
+
{ type: :character, value: 'ListPrice' },
|
89
|
+
{ type: :integer, value: 1 }
|
90
|
+
])
|
42
91
|
|
43
92
|
f.validate
|
44
93
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
@@ -48,26 +97,26 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
48
97
|
assert_equal 'istPrice', value[:value]
|
49
98
|
end
|
50
99
|
|
51
|
-
test
|
100
|
+
test 'substring character two indexes' do
|
52
101
|
f = FunctionResolver.new('substring', [
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
102
|
+
{ type: :character, value: 'alfb' },
|
103
|
+
{ type: :integer, value: 1 },
|
104
|
+
{ type: :integer, value: 2 }
|
105
|
+
])
|
57
106
|
|
58
107
|
f.validate
|
59
108
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
60
109
|
value = f.call
|
61
110
|
|
62
111
|
assert_equal :character, value[:type]
|
63
|
-
assert_equal
|
112
|
+
assert_equal 'lf', value[:value]
|
64
113
|
end
|
65
114
|
|
66
|
-
test
|
115
|
+
test 'substring character large first index' do
|
67
116
|
f = FunctionResolver.new('substring', [
|
68
|
-
|
69
|
-
|
70
|
-
|
117
|
+
{ type: :character, value: 'ListPrice' },
|
118
|
+
{ type: :integer, value: 10 }
|
119
|
+
])
|
71
120
|
|
72
121
|
f.validate
|
73
122
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
@@ -77,11 +126,11 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
77
126
|
assert_equal '', value[:value]
|
78
127
|
end
|
79
128
|
|
80
|
-
test
|
129
|
+
test 'substring field one index' do
|
81
130
|
f = FunctionResolver.new('substring', [
|
82
|
-
|
83
|
-
|
84
|
-
|
131
|
+
{ type: :field, value: 'ListPrice' },
|
132
|
+
{ type: :integer, value: 1 }
|
133
|
+
])
|
85
134
|
|
86
135
|
f.validate
|
87
136
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
@@ -89,16 +138,16 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
89
138
|
|
90
139
|
assert_equal :function, value[:type]
|
91
140
|
assert_equal 'substring', value[:value]
|
92
|
-
assert_equal
|
141
|
+
assert_equal 'ListPrice', value[:args].first[:value]
|
93
142
|
assert_equal 2, value[:args].size
|
94
143
|
end
|
95
144
|
|
96
|
-
test
|
145
|
+
test 'substring field two indexes' do
|
97
146
|
f = FunctionResolver.new('substring', [
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
147
|
+
{ type: :field, value: 'ListPrice' },
|
148
|
+
{ type: :integer, value: 1 },
|
149
|
+
{ type: :integer, value: 2 }
|
150
|
+
])
|
102
151
|
|
103
152
|
f.validate
|
104
153
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
@@ -106,28 +155,28 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
106
155
|
|
107
156
|
assert_equal :function, value[:type]
|
108
157
|
assert_equal 'substring', value[:value]
|
109
|
-
assert_equal
|
158
|
+
assert_equal 'ListPrice', value[:args].first[:value]
|
110
159
|
assert_equal 2, value[:args].last[:value]
|
111
160
|
end
|
112
161
|
|
113
|
-
test
|
162
|
+
test 'substring with negative M is a parse error' do
|
114
163
|
f = FunctionResolver.new('substring', [
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
164
|
+
{ type: :field, value: 'ListPrice' },
|
165
|
+
{ type: :integer, value: 1 },
|
166
|
+
{ type: :integer, value: -5 }
|
167
|
+
])
|
119
168
|
|
120
169
|
f.validate
|
121
170
|
f.call
|
122
171
|
assert f.errors?
|
123
172
|
end
|
124
173
|
|
125
|
-
test
|
174
|
+
test 'character substring with negative M is a parse error' do
|
126
175
|
f = FunctionResolver.new('substring', [
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
176
|
+
{ type: :character, value: 'ListPrice' },
|
177
|
+
{ type: :integer, value: 1 },
|
178
|
+
{ type: :integer, value: -5 }
|
179
|
+
])
|
131
180
|
|
132
181
|
f.validate
|
133
182
|
f.call
|
@@ -136,8 +185,8 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
136
185
|
|
137
186
|
test 'trim with field' do
|
138
187
|
f = FunctionResolver.new('trim', [
|
139
|
-
|
140
|
-
|
188
|
+
{ type: :field, value: 'Name' }
|
189
|
+
])
|
141
190
|
|
142
191
|
f.validate
|
143
192
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
@@ -145,13 +194,13 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
145
194
|
|
146
195
|
assert_equal :function, value[:type]
|
147
196
|
assert_equal 'trim', value[:value]
|
148
|
-
assert_equal
|
197
|
+
assert_equal 'Name', value[:args].first[:value]
|
149
198
|
end
|
150
199
|
|
151
200
|
test 'trim with character' do
|
152
201
|
f = FunctionResolver.new('trim', [
|
153
|
-
|
154
|
-
|
202
|
+
{ type: :character, value: ' val ' }
|
203
|
+
])
|
155
204
|
|
156
205
|
f.validate
|
157
206
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
@@ -162,7 +211,7 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
162
211
|
end
|
163
212
|
|
164
213
|
test "tolower('string')" do
|
165
|
-
f = FunctionResolver.new('tolower', [{:
|
214
|
+
f = FunctionResolver.new('tolower', [{ type: :character, value: 'STRING' }])
|
166
215
|
f.validate
|
167
216
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
168
217
|
value = f.call
|
@@ -170,18 +219,18 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
170
219
|
assert_equal "'string'", value[:value]
|
171
220
|
end
|
172
221
|
|
173
|
-
test
|
174
|
-
f = FunctionResolver.new('toupper', [{:
|
222
|
+
test 'toupper(SomeField)' do
|
223
|
+
f = FunctionResolver.new('toupper', [{ type: :field, value: 'City' }])
|
175
224
|
f.validate
|
176
225
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
177
226
|
value = f.call
|
178
227
|
assert_equal :function, value[:type]
|
179
228
|
assert_equal 'toupper', value[:value]
|
180
|
-
assert_equal
|
229
|
+
assert_equal 'City', value[:args].first[:value]
|
181
230
|
end
|
182
231
|
|
183
232
|
test "toupper('string')" do
|
184
|
-
f = FunctionResolver.new('toupper', [{:
|
233
|
+
f = FunctionResolver.new('toupper', [{ type: :character, value: 'string' }])
|
185
234
|
f.validate
|
186
235
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
187
236
|
value = f.call
|
@@ -189,18 +238,18 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
189
238
|
assert_equal "'STRING'", value[:value]
|
190
239
|
end
|
191
240
|
|
192
|
-
test
|
193
|
-
f = FunctionResolver.new('length', [{:
|
241
|
+
test 'length(SomeField)' do
|
242
|
+
f = FunctionResolver.new('length', [{ type: :field, value: 'City' }])
|
194
243
|
f.validate
|
195
244
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
196
245
|
value = f.call
|
197
246
|
assert_equal :function, value[:type]
|
198
247
|
assert_equal 'length', value[:value]
|
199
|
-
assert_equal
|
248
|
+
assert_equal 'City', value[:args].first[:value]
|
200
249
|
end
|
201
250
|
|
202
251
|
test "length('string')" do
|
203
|
-
f = FunctionResolver.new('length', [{:
|
252
|
+
f = FunctionResolver.new('length', [{ type: :character, value: 'string' }])
|
204
253
|
f.validate
|
205
254
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
206
255
|
value = f.call
|
@@ -208,7 +257,7 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
208
257
|
assert_equal '6', value[:value]
|
209
258
|
end
|
210
259
|
|
211
|
-
test
|
260
|
+
test 'now()' do
|
212
261
|
start = Time.now
|
213
262
|
f = FunctionResolver.new('now', [])
|
214
263
|
f.validate
|
@@ -216,10 +265,11 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
216
265
|
value = f.call
|
217
266
|
assert_equal :datetime, value[:type]
|
218
267
|
test_time = Time.parse(value[:value])
|
219
|
-
assert (
|
268
|
+
assert (test_time - start > -5 && test_time - start < 5),
|
269
|
+
"Time range off by more than five seconds #{test_time - start} '#{test_time} - #{start}'"
|
220
270
|
end
|
221
271
|
|
222
|
-
test
|
272
|
+
test 'mindatetime()' do
|
223
273
|
f = FunctionResolver.new('mindatetime', [])
|
224
274
|
f.validate
|
225
275
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
@@ -229,7 +279,7 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
229
279
|
assert_equal '1970-01-01T00:00:00+00:00', value[:value]
|
230
280
|
end
|
231
281
|
|
232
|
-
test
|
282
|
+
test 'maxdatetime()' do
|
233
283
|
f = FunctionResolver.new('maxdatetime', [])
|
234
284
|
f.validate
|
235
285
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
@@ -239,8 +289,8 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
239
289
|
assert_equal '9999-12-31T23:59:59+00:00', value[:value]
|
240
290
|
end
|
241
291
|
|
242
|
-
test
|
243
|
-
f = FunctionResolver.new('floor', [{:
|
292
|
+
test 'floor(float)' do
|
293
|
+
f = FunctionResolver.new('floor', [{ type: :decimal, value: 0.5 }])
|
244
294
|
f.validate
|
245
295
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
246
296
|
value = f.call
|
@@ -248,19 +298,19 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
248
298
|
assert_equal '0', value[:value]
|
249
299
|
end
|
250
300
|
|
251
|
-
test
|
252
|
-
f = FunctionResolver.new('floor', [{:
|
301
|
+
test 'floor(Field)' do
|
302
|
+
f = FunctionResolver.new('floor', [{ type: :field, value: 'ListPrice' }])
|
253
303
|
f.validate
|
254
304
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
255
305
|
value = f.call
|
256
306
|
|
257
307
|
assert_equal :function, value[:type]
|
258
308
|
assert_equal 'floor', value[:value]
|
259
|
-
assert_equal
|
309
|
+
assert_equal 'ListPrice', value[:args].first[:value]
|
260
310
|
end
|
261
311
|
|
262
|
-
test
|
263
|
-
f = FunctionResolver.new('ceiling', [{:
|
312
|
+
test 'ceiling(float)' do
|
313
|
+
f = FunctionResolver.new('ceiling', [{ type: :decimal, value: 0.5 }])
|
264
314
|
f.validate
|
265
315
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
266
316
|
value = f.call
|
@@ -268,93 +318,275 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
268
318
|
assert_equal '1', value[:value]
|
269
319
|
end
|
270
320
|
|
271
|
-
test
|
272
|
-
f = FunctionResolver.new('ceiling', [{:
|
321
|
+
test 'ceiling(Field)' do
|
322
|
+
f = FunctionResolver.new('ceiling', [{ type: :field, value: 'ListPrice' }])
|
273
323
|
f.validate
|
274
324
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
275
325
|
value = f.call
|
276
326
|
|
277
327
|
assert_equal :function, value[:type]
|
278
328
|
assert_equal 'ceiling', value[:value]
|
279
|
-
assert_equal
|
329
|
+
assert_equal 'ListPrice', value[:args].first[:value]
|
280
330
|
end
|
281
331
|
|
282
|
-
test
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
start = Time.parse(dt.to_s)
|
287
|
-
f = FunctionResolver.new('days', [{:type=>:integer, :value =>7}])
|
332
|
+
test 'seconds()' do
|
333
|
+
f = FunctionResolver.new('seconds',
|
334
|
+
[{ type: :integer, value: 7 }],
|
335
|
+
current_timestamp: EXAMPLE_DATE)
|
288
336
|
f.validate
|
289
|
-
assert !f.errors
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
337
|
+
assert !f.errors?
|
338
|
+
assert_times f.call, :datetime, sec: SECONDS + 7
|
339
|
+
|
340
|
+
f = FunctionResolver.new('seconds',
|
341
|
+
[{ type: :integer, value: -3 }],
|
342
|
+
current_timestamp: EXAMPLE_DATE)
|
343
|
+
f.validate
|
344
|
+
assert !f.errors?
|
345
|
+
assert_times f.call, :datetime, sec: 59, min: MINUTES - 1
|
346
|
+
|
347
|
+
f = FunctionResolver.new('seconds',
|
348
|
+
[{ type: :integer, value: Sparkql::FunctionResolver::SECONDS_IN_DAY }],
|
349
|
+
current_timestamp: EXAMPLE_DATE)
|
350
|
+
f.validate
|
351
|
+
assert !f.errors?
|
352
|
+
|
353
|
+
assert_times f.call, :datetime, year: 2022, mday: 1, month: 1
|
294
354
|
end
|
295
355
|
|
296
|
-
test
|
297
|
-
|
298
|
-
|
356
|
+
test 'minutes()' do
|
357
|
+
f = FunctionResolver.new('minutes',
|
358
|
+
[{ type: :integer, value: 7 }],
|
359
|
+
current_timestamp: EXAMPLE_DATE)
|
360
|
+
f.validate
|
361
|
+
assert !f.errors?
|
362
|
+
assert_times f.call, :datetime, min: MINUTES + 7
|
363
|
+
|
364
|
+
f = FunctionResolver.new('minutes',
|
365
|
+
[{ type: :integer, value: -2 }],
|
366
|
+
current_timestamp: EXAMPLE_DATE)
|
367
|
+
f.validate
|
368
|
+
assert !f.errors?
|
369
|
+
assert_times f.call, :datetime, min: 59, hour: 23, mday: DAY - 1
|
299
370
|
|
300
|
-
f = FunctionResolver.new('
|
371
|
+
f = FunctionResolver.new('minutes',
|
372
|
+
[{ type: :integer, value: -1440 }],
|
373
|
+
current_timestamp: EXAMPLE_DATE)
|
301
374
|
f.validate
|
302
|
-
assert !f.errors
|
375
|
+
assert !f.errors?
|
376
|
+
assert_times f.call, :datetime, mday: DAY - 1
|
377
|
+
end
|
378
|
+
|
379
|
+
test 'hours(), same day' do
|
380
|
+
tests = [1, 5, 12, 23, 0]
|
381
|
+
tests.each do |offset|
|
382
|
+
f = FunctionResolver.new('hours',
|
383
|
+
[{ type: :integer, value: offset }],
|
384
|
+
current_timestamp: EXAMPLE_DATE)
|
385
|
+
f.validate
|
386
|
+
assert !f.errors?
|
387
|
+
assert_times f.call, :datetime, hour: HOURS + offset
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
test 'hours(), previous day' do
|
392
|
+
tests = [-1, -5, -12]
|
393
|
+
tests.each do |offset|
|
394
|
+
f = FunctionResolver.new('hours',
|
395
|
+
[{ type: :integer, value: offset }],
|
396
|
+
current_timestamp: EXAMPLE_DATE)
|
397
|
+
f.validate
|
398
|
+
assert !f.errors?
|
399
|
+
assert_times f.call, :datetime, hour: 24 + offset, mday: DAY - 1
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
test 'hours(), wrap day' do
|
404
|
+
# Jump forward a few days, and a few hours.
|
405
|
+
f = FunctionResolver.new('hours',
|
406
|
+
[{ type: :integer, value: 52 }],
|
407
|
+
current_timestamp: EXAMPLE_DATE)
|
408
|
+
f.validate
|
409
|
+
assert !f.errors?
|
410
|
+
assert_times f.call, :datetime, hour: HOURS + 4, mday: 2, month: 1, year: 2022
|
411
|
+
|
412
|
+
# Drop back to the previous day, which'll also hit the previous month
|
413
|
+
f = FunctionResolver.new('hours',
|
414
|
+
[{ type: :integer, value: -24 }],
|
415
|
+
current_timestamp: EXAMPLE_DATE)
|
416
|
+
f.validate
|
417
|
+
assert !f.errors?
|
418
|
+
assert_times f.call, :datetime, mday: DAY - 1
|
419
|
+
|
420
|
+
# Drop back one full year's worth of hours.
|
421
|
+
f = FunctionResolver.new('hours',
|
422
|
+
[{ type: :integer, value: -8760 }],
|
423
|
+
current_timestamp: EXAMPLE_DATE)
|
424
|
+
f.validate
|
425
|
+
assert !f.errors?
|
426
|
+
assert_times f.call, :datetime, year: 2020
|
427
|
+
end
|
428
|
+
|
429
|
+
test 'days()' do
|
430
|
+
[
|
431
|
+
[-1, '2021-12-30', EXAMPLE_DATE],
|
432
|
+
[0, '2021-12-31', EXAMPLE_DATE],
|
433
|
+
[1, '2022-01-01', EXAMPLE_DATE],
|
434
|
+
[7, '2022-01-07', EXAMPLE_DATE],
|
435
|
+
[0, '2022-01-01', Time.parse('2022-01-01T00:00:00-0500')]
|
436
|
+
].each do |val, result, current_timestamp|
|
437
|
+
f = FunctionResolver.new('days',
|
438
|
+
[{ type: :integer, value: val }],
|
439
|
+
current_timestamp: current_timestamp)
|
440
|
+
f.validate
|
441
|
+
assert !f.errors?
|
442
|
+
value = f.call
|
443
|
+
assert_equal :date, value[:type]
|
444
|
+
assert_equal result, value[:value], val
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
test 'weekdays()' do
|
449
|
+
friday = Date.new(2012, 10, 19)
|
450
|
+
saturday = Date.new(2012, 10, 20)
|
451
|
+
sunday = Date.new(2012, 10, 21)
|
452
|
+
monday = Date.new(2012, 10, 22)
|
453
|
+
{
|
454
|
+
friday => [
|
455
|
+
[-5, '2012-10-12'],
|
456
|
+
[-4, '2012-10-15'],
|
457
|
+
[-1, '2012-10-18'],
|
458
|
+
[0, '2012-10-19'],
|
459
|
+
[1, '2012-10-22'],
|
460
|
+
[2, '2012-10-23'],
|
461
|
+
[5, '2012-10-26'],
|
462
|
+
[6, '2012-10-29'],
|
463
|
+
[7, '2012-10-30'],
|
464
|
+
[31, '2012-12-03']
|
465
|
+
],
|
466
|
+
saturday => [
|
467
|
+
[-6, '2012-10-12'],
|
468
|
+
[-5, '2012-10-15'],
|
469
|
+
[-1, '2012-10-19'],
|
470
|
+
[0, '2012-10-22'],
|
471
|
+
[1, '2012-10-22'],
|
472
|
+
[2, '2012-10-23'],
|
473
|
+
[3, '2012-10-24'],
|
474
|
+
[4, '2012-10-25'],
|
475
|
+
[5, '2012-10-26'],
|
476
|
+
[6, '2012-10-29'],
|
477
|
+
[7, '2012-10-30'],
|
478
|
+
[31, '2012-12-03']
|
479
|
+
],
|
480
|
+
sunday => [
|
481
|
+
[-6, '2012-10-12'],
|
482
|
+
[-5, '2012-10-15'],
|
483
|
+
[-1, '2012-10-19'],
|
484
|
+
[0, '2012-10-22'],
|
485
|
+
[1, '2012-10-22'],
|
486
|
+
[2, '2012-10-23'],
|
487
|
+
[5, '2012-10-26'],
|
488
|
+
[6, '2012-10-29'],
|
489
|
+
[7, '2012-10-30'],
|
490
|
+
[31, '2012-12-03']
|
491
|
+
],
|
492
|
+
monday => [
|
493
|
+
[-6, '2012-10-12'],
|
494
|
+
[-5, '2012-10-15'],
|
495
|
+
[-1, '2012-10-19'],
|
496
|
+
[0, '2012-10-22'],
|
497
|
+
[1, '2012-10-23'],
|
498
|
+
[2, '2012-10-24'],
|
499
|
+
[5, '2012-10-29'],
|
500
|
+
[6, '2012-10-30'],
|
501
|
+
[7, '2012-10-31'],
|
502
|
+
[31, '2012-12-04']
|
503
|
+
]
|
504
|
+
}.each do |test_date, weekday_tests|
|
505
|
+
weekday_tests.each do |days, expected_value|
|
506
|
+
f = FunctionResolver.new('weekdays', [{ type: :integer, value: days }])
|
507
|
+
f.expects(:current_date).returns(test_date)
|
508
|
+
f.validate
|
509
|
+
assert !f.errors?, "#{test_date}: #{days} = #{expected_value}"
|
510
|
+
value = f.call
|
511
|
+
assert_equal :date, value[:type]
|
512
|
+
assert_equal expected_value, value[:value], "#{test_date}: #{days} = #{expected_value}"
|
513
|
+
end
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
test 'months()' do
|
518
|
+
f = FunctionResolver.new('months',
|
519
|
+
[{ type: :integer, value: 3 }],
|
520
|
+
current_timestamp: EXAMPLE_DATE)
|
521
|
+
f.validate
|
522
|
+
assert !f.errors?
|
303
523
|
value = f.call
|
304
524
|
assert_equal :date, value[:type]
|
305
|
-
|
306
|
-
assert_equal "2014-04-06", value[:value]
|
525
|
+
assert_equal '2022-03-31', value[:value]
|
307
526
|
end
|
308
|
-
|
309
|
-
test
|
310
|
-
|
311
|
-
|
312
|
-
|
527
|
+
|
528
|
+
test 'years()' do
|
529
|
+
f = FunctionResolver.new('years',
|
530
|
+
[{ type: :integer, value: -4 }],
|
531
|
+
current_timestamp: EXAMPLE_DATE)
|
313
532
|
f.validate
|
314
|
-
assert !f.errors
|
533
|
+
assert !f.errors?
|
315
534
|
value = f.call
|
316
535
|
assert_equal :date, value[:type]
|
317
|
-
assert_equal '
|
536
|
+
assert_equal '2017-12-31', value[:value]
|
318
537
|
end
|
319
538
|
|
320
|
-
test
|
321
|
-
[
|
322
|
-
f = FunctionResolver.new(function, [{:
|
539
|
+
test 'year(), month(), and day()' do
|
540
|
+
%w[year month day].each do |function|
|
541
|
+
f = FunctionResolver.new(function, [{ type: :field, value: 'OriginalEntryTimestamp' }])
|
323
542
|
f.validate
|
324
543
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
325
544
|
value = f.call
|
326
545
|
assert_equal :function, value[:type]
|
327
546
|
assert_equal function, value[:value]
|
328
|
-
assert_equal
|
547
|
+
assert_equal 'OriginalEntryTimestamp', value[:args].first[:value]
|
329
548
|
end
|
330
549
|
end
|
331
550
|
|
332
|
-
test
|
333
|
-
[
|
334
|
-
f = FunctionResolver.new(function, [{:
|
551
|
+
test 'hour(), minute(), and second()' do
|
552
|
+
%w[year month day].each do |function|
|
553
|
+
f = FunctionResolver.new(function, [{ type: :field, value: 'OriginalEntryTimestamp' }])
|
335
554
|
f.validate
|
336
555
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
337
556
|
value = f.call
|
338
557
|
assert_equal :function, value[:type]
|
339
558
|
assert_equal function, value[:value]
|
340
|
-
assert_equal
|
559
|
+
assert_equal 'OriginalEntryTimestamp', value[:args].first[:value]
|
341
560
|
end
|
342
561
|
end
|
343
562
|
|
344
|
-
test
|
345
|
-
|
563
|
+
test 'day of week and day of year parse' do
|
564
|
+
%w[dayofyear dayofweek].each do |function|
|
565
|
+
f = FunctionResolver.new(function, [{ type: :field, value: 'OriginalEntryTimestamp' }])
|
566
|
+
f.validate
|
567
|
+
assert !f.errors?, "Errors #{f.errors.inspect}"
|
568
|
+
value = f.call
|
569
|
+
assert_equal :function, value[:type]
|
570
|
+
assert_equal function, value[:value]
|
571
|
+
assert_equal 'OriginalEntryTimestamp', value[:args].first[:value]
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
test 'fractionalseconds()' do
|
576
|
+
f = FunctionResolver.new('fractionalseconds', [{ type: :field, value: 'OriginalEntryTimestamp' }])
|
346
577
|
f.validate
|
347
578
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
348
579
|
value = f.call
|
349
580
|
assert_equal :function, value[:type]
|
350
581
|
assert_equal 'fractionalseconds', value[:value]
|
351
|
-
assert_equal
|
582
|
+
assert_equal 'OriginalEntryTimestamp', value[:args].first[:value]
|
352
583
|
end
|
353
584
|
|
354
585
|
# Polygon searches
|
355
|
-
|
356
|
-
test
|
357
|
-
f = FunctionResolver.new('radius',
|
586
|
+
|
587
|
+
test 'radius()' do
|
588
|
+
f = FunctionResolver.new('radius',
|
589
|
+
[{ type: :character, value: '35.12 -68.33' }, { type: :decimal, value: 1.0 }])
|
358
590
|
f.validate
|
359
591
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
360
592
|
value = f.call
|
@@ -364,38 +596,41 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
364
596
|
assert_equal 1.0, value[:value].radius, "#{value[:value].inspect} "
|
365
597
|
end
|
366
598
|
|
367
|
-
test
|
368
|
-
f = FunctionResolver.new('radius', [{:
|
369
|
-
|
599
|
+
test 'radius() can be overloaded with a ListingKey' do
|
600
|
+
f = FunctionResolver.new('radius', [{ type: :character, value: '20100000000000000000000000' },
|
601
|
+
{ type: :decimal, value: 1.0 }])
|
370
602
|
f.validate
|
371
603
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
372
604
|
value = f.call
|
373
605
|
assert_equal :shape, value[:type]
|
374
606
|
assert_equal Sparkql::Geo::RecordRadius, value[:value].class
|
375
|
-
assert_equal
|
607
|
+
assert_equal '20100000000000000000000000', value[:value].record_id, "#{value[:value].inspect} "
|
376
608
|
assert_equal 1.0, value[:value].radius, "#{value[:value].inspect} "
|
377
609
|
end
|
378
610
|
|
379
|
-
test
|
380
|
-
f = FunctionResolver.new('radius', [{:
|
381
|
-
|
611
|
+
test 'radius() fails if not given coords or a flex ID' do
|
612
|
+
f = FunctionResolver.new('radius', [{ type: :character, value: '35.12,-68.33' },
|
613
|
+
{ type: :decimal, value: 1.0 }])
|
382
614
|
f.validate
|
383
615
|
f.call
|
384
616
|
assert f.errors?
|
385
617
|
end
|
386
618
|
|
387
|
-
test
|
388
|
-
f = FunctionResolver.new('polygon',
|
619
|
+
test 'polygon()' do
|
620
|
+
f = FunctionResolver.new('polygon',
|
621
|
+
[{ type: :character,
|
622
|
+
value: '35.12 -68.33,35.12 -68.32, 35.13 -68.32,35.13 -68.33' }])
|
389
623
|
f.validate
|
390
624
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
391
625
|
value = f.call
|
392
626
|
assert_equal :shape, value[:type]
|
393
627
|
assert_equal GeoRuby::SimpleFeatures::Polygon, value[:value].class
|
394
|
-
assert_equal [[-68.33, 35.12], [-68.32, 35.12], [-68.32, 35.13], [-68.33, 35.13], [-68.33, 35.12]],
|
628
|
+
assert_equal [[-68.33, 35.12], [-68.32, 35.12], [-68.32, 35.13], [-68.33, 35.13], [-68.33, 35.12]],
|
629
|
+
value[:value].to_coordinates.first, "#{value[:value].inspect} "
|
395
630
|
end
|
396
|
-
|
397
|
-
test
|
398
|
-
f = FunctionResolver.new('linestring', [{:
|
631
|
+
|
632
|
+
test 'linestring()' do
|
633
|
+
f = FunctionResolver.new('linestring', [{ type: :character, value: '35.12 -68.33,35.12 -68.32' }])
|
399
634
|
f.validate
|
400
635
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
401
636
|
value = f.call
|
@@ -404,70 +639,72 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
404
639
|
assert_equal [[-68.33, 35.12], [-68.32, 35.12]], value[:value].to_coordinates, "#{value[:value].inspect} "
|
405
640
|
end
|
406
641
|
|
407
|
-
test
|
408
|
-
f = FunctionResolver.new('rectangle', [{:
|
642
|
+
test 'rectangle()' do
|
643
|
+
f = FunctionResolver.new('rectangle', [{ type: :character, value: '35.12 -68.33, 35.13 -68.32' }])
|
409
644
|
f.validate
|
410
645
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
411
646
|
value = f.call
|
412
647
|
assert_equal :shape, value[:type]
|
413
648
|
assert_equal GeoRuby::SimpleFeatures::Polygon, value[:value].class
|
414
|
-
assert_equal [[-68.33,35.12], [-68.32,35.12], [-68.32,35.13], [-68.33,35.13], [-68.33,35.12]],
|
649
|
+
assert_equal [[-68.33, 35.12], [-68.32, 35.12], [-68.32, 35.13], [-68.33, 35.13], [-68.33, 35.12]],
|
650
|
+
value[:value].to_coordinates.first, "#{value[:value].inspect} "
|
415
651
|
end
|
416
652
|
|
417
|
-
test
|
418
|
-
f = FunctionResolver.new('range', [{:
|
419
|
-
|
653
|
+
test 'range()' do
|
654
|
+
f = FunctionResolver.new('range', [{ type: :character, value: 'M01' },
|
655
|
+
{ type: :character, value: 'M05' }])
|
420
656
|
f.validate
|
421
657
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
422
658
|
value = f.call
|
423
659
|
assert_equal :character, value[:type]
|
424
|
-
assert_equal [
|
660
|
+
assert_equal %w[M01 M05], value[:value]
|
425
661
|
end
|
426
|
-
|
427
|
-
test
|
428
|
-
f = FunctionResolver.new('now', [{:
|
662
|
+
|
663
|
+
test 'invalid params' do
|
664
|
+
f = FunctionResolver.new('now', [{ type: :character, value: 'bad value' }])
|
429
665
|
f.validate
|
430
666
|
assert f.errors?, "'now' function does not support parameters"
|
431
|
-
|
667
|
+
|
432
668
|
f = FunctionResolver.new('days', [])
|
433
669
|
f.validate
|
434
670
|
assert f.errors?, "'days' function requires one parameter"
|
435
|
-
|
436
|
-
f = FunctionResolver.new('days', [{:
|
671
|
+
|
672
|
+
f = FunctionResolver.new('days', [{ type: :character, value: 'bad value' }])
|
437
673
|
f.validate
|
438
674
|
assert f.errors?, "'days' function needs integer parameter"
|
439
675
|
end
|
440
676
|
|
441
|
-
test
|
442
|
-
f = FunctionResolver.new('radius', [{:
|
443
|
-
|
444
|
-
|
677
|
+
test 'assert nil returned when function called with errors' do
|
678
|
+
f = FunctionResolver.new('radius', [{ type: :character,
|
679
|
+
value: '35.12 -68.33, 35.13 -68.34' }, { type: :decimal,
|
680
|
+
value: 1.0 }])
|
445
681
|
assert_nil f.call
|
446
682
|
end
|
447
|
-
|
448
|
-
test
|
449
|
-
f = FunctionResolver.new('radius', [{:
|
450
|
-
|
451
|
-
|
683
|
+
|
684
|
+
test 'return_type' do
|
685
|
+
f = FunctionResolver.new('radius', [{ type: :character,
|
686
|
+
value: '35.12 -68.33, 35.13 -68.34' }, { type: :decimal,
|
687
|
+
value: 1.0 }])
|
452
688
|
assert_equal :shape, f.return_type
|
453
689
|
end
|
454
690
|
|
455
691
|
test 'return_type for cast()' do
|
456
|
-
f = FunctionResolver.new('cast', [{:
|
457
|
-
|
458
|
-
|
692
|
+
f = FunctionResolver.new('cast', [{ type: :character,
|
693
|
+
value: '1' }, { type: :character,
|
694
|
+
value: 'decimal' }])
|
459
695
|
|
460
696
|
assert_equal :decimal, f.return_type
|
461
697
|
|
462
|
-
f = FunctionResolver.new('cast', [{:
|
463
|
-
|
464
|
-
|
698
|
+
f = FunctionResolver.new('cast', [{ type: :character,
|
699
|
+
value: '1' }, { type: :character,
|
700
|
+
value: 'integer' }])
|
465
701
|
|
466
702
|
assert_equal :integer, f.return_type
|
467
703
|
end
|
468
704
|
|
469
|
-
test
|
470
|
-
f = FunctionResolver.new('cast',
|
705
|
+
test 'cast() decimal to integer' do
|
706
|
+
f = FunctionResolver.new('cast',
|
707
|
+
[{ type: :decimal, value: '1.2' }, { type: :character, value: 'integer' }])
|
471
708
|
f.validate
|
472
709
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
473
710
|
value = f.call
|
@@ -476,8 +713,8 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
476
713
|
assert_equal '1', value[:value]
|
477
714
|
end
|
478
715
|
|
479
|
-
test
|
480
|
-
f = FunctionResolver.new('cast', [{:
|
716
|
+
test 'cast() integer to decimal' do
|
717
|
+
f = FunctionResolver.new('cast', [{ type: :decimal, value: '1' }, { type: :character, value: 'decimal' }])
|
481
718
|
f.validate
|
482
719
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
483
720
|
value = f.call
|
@@ -486,8 +723,8 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
486
723
|
assert_equal '1.0', value[:value]
|
487
724
|
end
|
488
725
|
|
489
|
-
test
|
490
|
-
f = FunctionResolver.new('cast', [{:
|
726
|
+
test 'cast() nil to integer' do
|
727
|
+
f = FunctionResolver.new('cast', [{ type: :null, value: 'NULL' }, { type: :character, value: 'integer' }])
|
491
728
|
f.validate
|
492
729
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
493
730
|
value = f.call
|
@@ -496,8 +733,8 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
496
733
|
assert_equal '0', value[:value]
|
497
734
|
end
|
498
735
|
|
499
|
-
test
|
500
|
-
f = FunctionResolver.new('cast', [{:
|
736
|
+
test 'cast() nil to decimal' do
|
737
|
+
f = FunctionResolver.new('cast', [{ type: :null, value: 'NULL' }, { type: :character, value: 'decimal' }])
|
501
738
|
f.validate
|
502
739
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
503
740
|
value = f.call
|
@@ -506,8 +743,9 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
506
743
|
assert_equal '0.0', value[:value]
|
507
744
|
end
|
508
745
|
|
509
|
-
test
|
510
|
-
f = FunctionResolver.new('cast',
|
746
|
+
test 'cast() nil to character' do
|
747
|
+
f = FunctionResolver.new('cast',
|
748
|
+
[{ type: :null, value: 'NULL' }, { type: :character, value: 'character' }])
|
511
749
|
f.validate
|
512
750
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
513
751
|
value = f.call
|
@@ -516,39 +754,43 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
516
754
|
assert_equal "''", value[:value]
|
517
755
|
end
|
518
756
|
|
519
|
-
test
|
520
|
-
f = FunctionResolver.new('cast',
|
757
|
+
test 'cast() character to decimal' do
|
758
|
+
f = FunctionResolver.new('cast',
|
759
|
+
[{ type: :character, value: '1.1' }, { type: :character, value: 'decimal' }])
|
521
760
|
f.validate
|
522
761
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
523
762
|
value = f.call
|
524
763
|
|
525
764
|
assert_equal :decimal, value[:type]
|
526
|
-
assert_equal
|
765
|
+
assert_equal '1.1', value[:value]
|
527
766
|
end
|
528
767
|
|
529
|
-
test
|
530
|
-
f = FunctionResolver.new('cast',
|
768
|
+
test 'cast() character to integer' do
|
769
|
+
f = FunctionResolver.new('cast',
|
770
|
+
[{ type: :character, value: '1' }, { type: :character, value: 'integer' }])
|
531
771
|
f.validate
|
532
772
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
533
773
|
value = f.call
|
534
774
|
|
535
775
|
assert_equal :integer, value[:type]
|
536
|
-
assert_equal
|
776
|
+
assert_equal '1', value[:value]
|
537
777
|
end
|
538
778
|
|
539
|
-
test
|
540
|
-
f = FunctionResolver.new('cast',
|
779
|
+
test 'cast() Field' do
|
780
|
+
f = FunctionResolver.new('cast',
|
781
|
+
[{ type: :field, value: 'Bedrooms' }, { type: :character, value: 'character' }])
|
541
782
|
f.validate
|
542
783
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
543
784
|
value = f.call
|
544
785
|
|
545
786
|
assert_equal :function, value[:type]
|
546
787
|
assert_equal 'cast', value[:value]
|
547
|
-
assert_equal
|
788
|
+
assert_equal(%w[Bedrooms character], value[:args].map { |v| v[:value] })
|
548
789
|
end
|
549
790
|
|
550
|
-
test
|
551
|
-
f = FunctionResolver.new('cast',
|
791
|
+
test 'invalid cast returns null' do
|
792
|
+
f = FunctionResolver.new('cast',
|
793
|
+
[{ type: :character, value: '1.1.1' }, { type: :character, value: 'integer' }])
|
552
794
|
f.validate
|
553
795
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
554
796
|
value = f.call
|
@@ -557,63 +799,63 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
557
799
|
assert_equal 'NULL', value[:value]
|
558
800
|
end
|
559
801
|
|
560
|
-
test
|
802
|
+
test 'invalid function' do
|
561
803
|
f = FunctionResolver.new('then', [])
|
562
804
|
f.validate
|
563
805
|
assert f.errors?, "'then' is not a function"
|
564
806
|
end
|
565
807
|
|
566
|
-
test
|
567
|
-
f = FunctionResolver.new('time', [{:
|
808
|
+
test 'time(datetime)' do
|
809
|
+
f = FunctionResolver.new('time', [{ type: :datetime, value: EXAMPLE_DATE }])
|
568
810
|
f.validate
|
569
811
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
570
812
|
value = f.call
|
571
813
|
assert_equal :time, value[:type]
|
572
|
-
assert_equal '
|
814
|
+
assert_equal '00:01:02.123456000', value[:value]
|
573
815
|
end
|
574
816
|
|
575
|
-
test
|
576
|
-
f = FunctionResolver.new('date', [{:
|
817
|
+
test 'date(datetime)' do
|
818
|
+
f = FunctionResolver.new('date', [{ type: :datetime, value: EXAMPLE_DATE }])
|
577
819
|
f.validate
|
578
820
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
579
821
|
value = f.call
|
580
822
|
assert_equal :date, value[:type]
|
581
|
-
assert_equal '
|
823
|
+
assert_equal '2021-12-31', value[:value]
|
582
824
|
end
|
583
825
|
|
584
|
-
###
|
585
|
-
# Delayed functions. These functions don't get run immediately and require
|
586
|
-
# resolution by the backing system
|
587
|
-
###
|
588
|
-
|
589
|
-
test
|
590
|
-
f = FunctionResolver.new('time', [{:
|
826
|
+
###
|
827
|
+
# Delayed functions. These functions don't get run immediately and require
|
828
|
+
# resolution by the backing system
|
829
|
+
###
|
830
|
+
|
831
|
+
test 'time(field)' do
|
832
|
+
f = FunctionResolver.new('time', [{ type: :field, value: 'OriginalEntryTimestamp' }])
|
591
833
|
f.validate
|
592
834
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
593
835
|
value = f.call
|
594
836
|
assert_equal :function, value[:type]
|
595
837
|
assert_equal 'time', value[:value]
|
596
|
-
assert_equal
|
838
|
+
assert_equal 'OriginalEntryTimestamp', value[:args].first[:value]
|
597
839
|
end
|
598
|
-
|
599
|
-
test
|
600
|
-
f = FunctionResolver.new('date', [{:
|
840
|
+
|
841
|
+
test 'date(field)' do
|
842
|
+
f = FunctionResolver.new('date', [{ type: :field, value: 'OriginalEntryTimestamp' }])
|
601
843
|
f.validate
|
602
844
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
603
845
|
value = f.call
|
604
846
|
assert_equal :function, value[:type]
|
605
847
|
assert_equal 'date', value[:value]
|
606
|
-
assert_equal
|
848
|
+
assert_equal 'OriginalEntryTimestamp', value[:args].first[:value]
|
607
849
|
end
|
608
850
|
|
609
|
-
test
|
610
|
-
[{'startswith' =>
|
611
|
-
{'endswith' =>
|
612
|
-
{'contains' =>
|
851
|
+
test 'startswith(), endswith() and contains()' do
|
852
|
+
[{ 'startswith' => '^far' },
|
853
|
+
{ 'endswith' => 'far$' },
|
854
|
+
{ 'contains' => 'far' }].each do |test_case|
|
613
855
|
function = test_case.keys.first
|
614
856
|
expected_value = test_case[function]
|
615
857
|
|
616
|
-
f = FunctionResolver.new(function, [{:
|
858
|
+
f = FunctionResolver.new(function, [{ type: :character, value: 'far' }])
|
617
859
|
f.validate
|
618
860
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
619
861
|
value = f.call
|
@@ -626,8 +868,8 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
626
868
|
|
627
869
|
test 'wkt()' do
|
628
870
|
f = FunctionResolver.new('wkt',
|
629
|
-
[{:
|
630
|
-
|
871
|
+
[{ type: :character,
|
872
|
+
value: 'SRID=12345;POLYGON((-127.89734578345 45.234534534,-127.89734578345 45.234534534,-127.89734578345 45.234534534,-127.89734578345 45.234534534))' }])
|
631
873
|
f.validate
|
632
874
|
assert !f.errors?, "Errors #{f.errors.inspect}"
|
633
875
|
value = f.call
|
@@ -636,8 +878,8 @@ class FunctionResolverTest < Test::Unit::TestCase
|
|
636
878
|
|
637
879
|
test 'wkt() invalid params' do
|
638
880
|
f = FunctionResolver.new('wkt',
|
639
|
-
[{:
|
640
|
-
|
881
|
+
[{ type: :character,
|
882
|
+
value: 'POLYGON((45.234534534))' }])
|
641
883
|
f.validate
|
642
884
|
f.call
|
643
885
|
assert f.errors?
|