sparkql 1.2.5 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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?
|