kronk 1.5.4 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,329 @@
1
+ require 'test/test_helper'
2
+
3
+ class TestPathMatcher < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @matcher = Kronk::Path::Matcher.new :key => "foo*", :value => "*bar*"
7
+ @data = {
8
+ :key1 => {
9
+ :key1a => [
10
+ "foo",
11
+ "bar",
12
+ "foobar",
13
+ {:findme => "thing"}
14
+ ],
15
+ 'key1b' => "findme"
16
+ },
17
+ 'findme' => [
18
+ 123,
19
+ 456,
20
+ {:findme => 123456}
21
+ ],
22
+ :key2 => "foobar",
23
+ :key3 => {
24
+ :key3a => ["val1", "val2", "val3"]
25
+ }
26
+ }
27
+ end
28
+
29
+
30
+ def test_new
31
+ assert_equal %r{\Afoo(.*)\Z}, @matcher.key
32
+ assert_equal %r{\A(.*)bar(.*)\Z}, @matcher.value
33
+ assert !@matcher.recursive?
34
+ end
35
+
36
+
37
+
38
+ def test_each_data_item_hash
39
+ hash = {
40
+ :a => 1,
41
+ :b => 2,
42
+ :c => 3
43
+ }
44
+
45
+ keys = []
46
+ values = []
47
+
48
+ @matcher.each_data_item hash do |key, val|
49
+ keys << key
50
+ values << val
51
+ end
52
+
53
+ assert_equal keys, (keys | hash.keys)
54
+ assert_equal values, (values | hash.values)
55
+ end
56
+
57
+
58
+ def test_each_data_item_array
59
+ ary = [:a, :b, :c]
60
+
61
+ keys = []
62
+ values = []
63
+
64
+ @matcher.each_data_item ary do |key, val|
65
+ keys << key
66
+ values << val
67
+ end
68
+
69
+ assert_equal [2,1,0], keys
70
+ assert_equal ary.reverse, values
71
+ end
72
+
73
+
74
+ def test_match_node
75
+ assert @matcher.match_node(:key, "key")
76
+ assert @matcher.match_node("key", :key)
77
+
78
+ assert @matcher.match_node(/key/, "foo_key")
79
+ assert !@matcher.match_node("foo_key", /key/)
80
+ assert @matcher.match_node(/key/, /key/)
81
+
82
+ assert @matcher.match_node(Kronk::Path::Matcher::ANY_VALUE, "foo_key")
83
+ assert !@matcher.match_node("foo_key", Kronk::Path::Matcher::ANY_VALUE)
84
+
85
+ assert @matcher.match_node(1..3, 1)
86
+ assert !@matcher.match_node(1, 1..3)
87
+ assert @matcher.match_node(1..3, 1..3)
88
+ end
89
+
90
+
91
+ def test_find_in
92
+ keys = []
93
+
94
+ Kronk::Path::Matcher.new(:key => /key/).find_in @data do |data, key|
95
+ keys << key.to_s
96
+ assert_equal @data, data
97
+ end
98
+
99
+ assert_equal ['key1', 'key2', 'key3'], keys.sort
100
+ end
101
+
102
+
103
+ def test_find_in_recursive
104
+ keys = []
105
+ data_points = []
106
+
107
+ matcher = Kronk::Path::Matcher.new :key => :findme,
108
+ :recursive => true
109
+
110
+ matcher.find_in @data do |data, key|
111
+ keys << key.to_s
112
+ data_points << data
113
+ end
114
+
115
+ assert_equal 3, keys.length
116
+ assert_equal 1, keys.uniq.length
117
+ assert_equal "findme", keys.first
118
+
119
+ assert_equal 3, data_points.length
120
+ assert data_points.include?(@data)
121
+ assert data_points.include?({:findme => "thing"})
122
+ assert data_points.include?({:findme => 123456})
123
+ end
124
+
125
+
126
+ def test_find_in_value
127
+ keys = []
128
+ data_points = []
129
+
130
+ matcher = Kronk::Path::Matcher.new :key => "*", :value => "findme"
131
+ matcher.find_in @data do |data, key|
132
+ keys << key.to_s
133
+ data_points << data
134
+ end
135
+
136
+ assert keys.empty?
137
+ assert data_points.empty?
138
+
139
+ matcher = Kronk::Path::Matcher.new :key => "*",
140
+ :value => "findme",
141
+ :recursive => true
142
+
143
+ paths = matcher.find_in @data do |data, key|
144
+ keys << key.to_s
145
+ data_points << data
146
+ end
147
+
148
+ assert_equal ['key1b'], keys
149
+ assert_equal [@data[:key1]], data_points
150
+ assert_equal ['key1b'], paths.first.matches
151
+ end
152
+
153
+
154
+ def test_find_in_match
155
+ matcher = Kronk::Path::Matcher.new :key => "find*",
156
+ :value => "th*g",
157
+ :recursive => true
158
+ paths = matcher.find_in @data
159
+ assert_equal [[:key1, :key1a, 3, :findme]], paths
160
+ assert_equal Kronk::Path::PathMatch, paths.first.class
161
+
162
+ assert_equal ["me", "in"], paths.first.matches
163
+ end
164
+
165
+
166
+ def test_find_in_match_one
167
+ matcher = Kronk::Path::Matcher.new :key => "findme|foo",
168
+ :recursive => true
169
+ paths = matcher.find_in @data
170
+
171
+ expected_paths = [
172
+ ["findme"],
173
+ ["findme", 2, :findme],
174
+ [:key1, :key1a, 3, :findme]
175
+ ]
176
+
177
+ assert_equal expected_paths, (expected_paths | paths)
178
+ assert_equal Kronk::Path::PathMatch, paths.first.class
179
+
180
+ assert_equal ["findme"], paths.first.matches
181
+ end
182
+
183
+
184
+ def test_find_in_match_one_value
185
+ matcher = Kronk::Path::Matcher.new :key => "findme|foo",
186
+ :value => "th*g",
187
+ :recursive => true
188
+ paths = matcher.find_in @data
189
+ assert_equal [[:key1, :key1a, 3, :findme]], paths
190
+ assert_equal Kronk::Path::PathMatch, paths.first.class
191
+
192
+ assert_equal ["findme", "in"], paths.first.matches
193
+ end
194
+
195
+
196
+ def test_find_in_match_any
197
+ matcher = Kronk::Path::Matcher.new :key => "*"
198
+ paths = matcher.find_in @data
199
+
200
+ expected_paths = [
201
+ ["findme"],
202
+ [:key1],
203
+ [:key2],
204
+ [:key3]
205
+ ]
206
+
207
+ assert_equal expected_paths, (expected_paths | paths)
208
+ assert_equal Kronk::Path::PathMatch, paths.first.class
209
+ assert_equal expected_paths, (expected_paths | paths.map{|p| p.matches})
210
+ end
211
+
212
+
213
+ def test_find_in_match_value_only
214
+ matcher = Kronk::Path::Matcher.new :value => "th*g",
215
+ :recursive => true
216
+
217
+ paths = matcher.find_in @data
218
+
219
+ assert_equal [[:key1, :key1a, 3, :findme]], paths
220
+ assert_equal ["in"], paths.first.matches
221
+ end
222
+
223
+
224
+ def test_find_in_match_value_and_nil_key
225
+ matcher = Kronk::Path::Matcher.new :key => nil,
226
+ :value => "th*g",
227
+ :recursive => true
228
+
229
+ paths = matcher.find_in @data
230
+
231
+ assert_equal [[:key1, :key1a, 3, :findme]], paths
232
+ assert_equal ["in"], paths.first.matches
233
+ end
234
+
235
+
236
+ def test_find_in_match_value_and_empty_key
237
+ matcher = Kronk::Path::Matcher.new :key => "",
238
+ :value => "th*g",
239
+ :recursive => true
240
+
241
+ paths = matcher.find_in @data
242
+
243
+ assert_equal [[:key1, :key1a, 3, :findme]], paths
244
+ assert_equal ["in"], paths.first.matches
245
+ end
246
+
247
+
248
+ def test_find_in_match_value_and_nil_value
249
+ matcher = Kronk::Path::Matcher.new :key => "*3a",
250
+ :value => nil,
251
+ :recursive => true
252
+
253
+ paths = matcher.find_in @data
254
+
255
+ assert_equal [[:key3, :key3a]], paths
256
+ assert_equal ["key"], paths.first.matches
257
+ end
258
+
259
+
260
+ def test_find_in_match_value_and_empty_value
261
+ matcher = Kronk::Path::Matcher.new :key => "*3a",
262
+ :value => "",
263
+ :recursive => true
264
+
265
+ paths = matcher.find_in @data
266
+
267
+ assert_equal [[:key3, :key3a]], paths
268
+ assert_equal ["key"], paths.first.matches
269
+ end
270
+
271
+
272
+ def test_parse_node_range
273
+ assert_equal 1..4, @matcher.parse_node("1..4")
274
+ assert_equal 1...4, @matcher.parse_node("1...4")
275
+ assert_equal "1..4", @matcher.parse_node("\\1..4")
276
+ assert_equal "1..4", @matcher.parse_node("1\\..4")
277
+ assert_equal "1..4", @matcher.parse_node("1.\\.4")
278
+ assert_equal "1..4", @matcher.parse_node("1..\\4")
279
+ assert_equal "1..4", @matcher.parse_node("1..4\\")
280
+ end
281
+
282
+
283
+ def test_parse_node_index_length
284
+ assert_equal 2...6, @matcher.parse_node("2,4")
285
+ assert_equal "2,4", @matcher.parse_node("\\2,4")
286
+ assert_equal "2,4", @matcher.parse_node("2\\,4")
287
+ assert_equal "2,4", @matcher.parse_node("2,\\4")
288
+ assert_equal "2,4", @matcher.parse_node("2,4\\")
289
+ end
290
+
291
+
292
+ def test_parse_node_anyval
293
+ assert_equal Kronk::Path::Matcher::ANY_VALUE, @matcher.parse_node("*")
294
+ assert_equal Kronk::Path::Matcher::ANY_VALUE, @matcher.parse_node("")
295
+ assert_equal Kronk::Path::Matcher::ANY_VALUE, @matcher.parse_node("**?*?*?")
296
+ assert_equal Kronk::Path::Matcher::ANY_VALUE, @matcher.parse_node(nil)
297
+ end
298
+
299
+
300
+ def test_parse_node_regex
301
+ assert_equal(/\Atest(.*)\Z/, @matcher.parse_node("test*"))
302
+ assert_equal(/\A(.?)test(.*)\Z/, @matcher.parse_node("?test*"))
303
+ assert_equal(/\A\?test(.*)\Z/, @matcher.parse_node("\\?test*"))
304
+ assert_equal(/\A(.?)test\*(.*)\Z/, @matcher.parse_node("?test\\**"))
305
+ assert_equal(/\A(.?)test(.*)\Z/, @matcher.parse_node("?test*?**??"))
306
+ assert_equal(/\A(.?)test(.?)(.?)(.*)\Z/, @matcher.parse_node("?test??**??"))
307
+ assert_equal(/\Aa|b\Z/, @matcher.parse_node("a|b"))
308
+ assert_equal(/\Aa|b(c|d)\Z/, @matcher.parse_node("a|b(c|d)"))
309
+
310
+ matcher = Kronk::Path::Matcher.new :regex_opts => Regexp::IGNORECASE
311
+ assert_equal(/\Aa|b(c|d)\Z/i, matcher.parse_node("a|b(c|d)"))
312
+ end
313
+
314
+
315
+ def test_parse_node_string
316
+ assert_equal "a|b", @matcher.parse_node("a\\|b")
317
+ assert_equal "a(b", @matcher.parse_node("a\\(b")
318
+ assert_equal "a?b", @matcher.parse_node("a\\?b")
319
+ assert_equal "a*b", @matcher.parse_node("a\\*b")
320
+ end
321
+
322
+
323
+ def test_parse_node_passthru
324
+ assert_equal Kronk::Path::PARENT,
325
+ @matcher.parse_node(Kronk::Path::PARENT)
326
+
327
+ assert_equal :thing, @matcher.parse_node(:thing)
328
+ end
329
+ end
@@ -166,11 +166,11 @@ class TestResponse < Test::Unit::TestCase
166
166
  def test_parsed_header
167
167
  assert_equal @json_resp.to_hash, @json_resp.parsed_header
168
168
 
169
- assert_equal({'content-type' => ["application/json; charset=utf-8"]},
169
+ assert_equal({'content-type' => "application/json; charset=utf-8"},
170
170
  @json_resp.parsed_header('Content-Type'))
171
171
 
172
- assert_equal({'date' => ["Fri, 03 Dec 2010 21:49:00 GMT"],
173
- 'content-type' => ["application/json; charset=utf-8"]},
172
+ assert_equal({'date' => "Fri, 03 Dec 2010 21:49:00 GMT",
173
+ 'content-type' => "application/json; charset=utf-8"},
174
174
  @json_resp.parsed_header(['Content-Type', 'Date']))
175
175
 
176
176
  assert_nil @json_resp.parsed_header(false)
@@ -262,7 +262,7 @@ class TestResponse < Test::Unit::TestCase
262
262
  def test_selective_data_single_header
263
263
  body = JSON.parse @json_resp.body
264
264
  expected =
265
- [{'content-type' => ['application/json; charset=utf-8']}, body]
265
+ [{'content-type' => 'application/json; charset=utf-8'}, body]
266
266
 
267
267
  assert_equal expected,
268
268
  @json_resp.selective_data(:with_headers => "Content-Type")
@@ -272,8 +272,8 @@ class TestResponse < Test::Unit::TestCase
272
272
  def test_selective_data_multiple_headers
273
273
  body = JSON.parse @json_resp.body
274
274
  expected =
275
- [{'content-type' => ['application/json; charset=utf-8'],
276
- 'date' => ["Fri, 03 Dec 2010 21:49:00 GMT"]
275
+ [{'content-type' => 'application/json; charset=utf-8',
276
+ 'date' => "Fri, 03 Dec 2010 21:49:00 GMT"
277
277
  }, body]
278
278
 
279
279
  assert_equal expected,
@@ -284,10 +284,10 @@ class TestResponse < Test::Unit::TestCase
284
284
 
285
285
  def test_selective_data_no_body
286
286
  body = JSON.parse @json_resp.body
287
- expected =
288
- [{'content-type' => ['application/json; charset=utf-8'],
289
- 'date' => ["Fri, 03 Dec 2010 21:49:00 GMT"]
290
- }]
287
+ expected = {
288
+ 'content-type' => 'application/json; charset=utf-8',
289
+ 'date' => "Fri, 03 Dec 2010 21:49:00 GMT"
290
+ }
291
291
 
292
292
  assert_equal expected,
293
293
  @json_resp.selective_data(:no_body => true,
@@ -28,6 +28,26 @@ class TestTransaction < Test::Unit::TestCase
28
28
  end
29
29
 
30
30
 
31
+ def test_many_transactions
32
+ data = @trans.run do |t|
33
+ t.map "key?" => "thing%1",
34
+ "key3/*/0" => "key_value"
35
+ t.select "findme/0..1"
36
+ t.delete "findme/0"
37
+ t.move "findme/2" => "last_thing"
38
+ end
39
+
40
+ expected = {
41
+ "last_thing"=>{}, "key_value"=>"val1",
42
+ "thing1"=>{:key1a=>["foo", "bar", "foobar", {:findme=>"thing"}],
43
+ "key1b"=>"findme"},
44
+ "thing2"=>"foobar",
45
+ "thing3"=>{:key3a=>["val1", "val2", "val3"]}, "findme"=>[456]}
46
+
47
+ assert_equal expected, data
48
+ end
49
+
50
+
31
51
  def test_class_run
32
52
  block = lambda do |t|
33
53
  t.delete "key3/key*/2", "**=thing"
@@ -296,6 +316,114 @@ class TestTransaction < Test::Unit::TestCase
296
316
  end
297
317
 
298
318
 
319
+ def test_transaction_move
320
+ expected = {:key1=>{}, :key2=>"foobar",
321
+ "mapped"=>{
322
+ "1-a"=>["foo", "bar", "foobar", {}],
323
+ "1-b"=>"findme", "3-a"=>["val1", "val2", "val3"]},
324
+ :key3=>{}, "findme"=>[123, 456, {}],
325
+ "more"=>{"one-findme"=>"thing", "two-findme"=>123456}}
326
+
327
+ data = @trans.transaction_move @data, "key*/key??" => "mapped/%1-%3",
328
+ "mapped" => "remapped",
329
+ "**=thing" => "more/one-%1",
330
+ "**=123456" => "more/two-%1"
331
+ data = @trans.remake_arrays data
332
+
333
+ assert_equal expected, data
334
+ assert_not_equal @data, data
335
+ end
336
+
337
+
338
+ def test_transaction_map
339
+ expected = {
340
+ "mapped"=>{
341
+ "1-a"=>["foo", "bar", "foobar", {:findme=>"thing"}],
342
+ "1-b"=>"findme", "3-a"=>["val1", "val2", "val3"]},
343
+ "more"=>{:findme=>"thing"}
344
+ }
345
+
346
+ data = @trans.transaction_map @data, "key*/key??" => "mapped/%1-%3",
347
+ "mapped" => "remapped",
348
+ "**=thing" => "more/%1"
349
+
350
+ assert_equal expected, data
351
+ assert_not_equal @data, data
352
+ end
353
+
354
+
355
+ def test_transaction_move_array_conflicting
356
+ expected = {:key1=>{:key1a=>[], "key1b"=>"findme"},:key2=>"foobar",
357
+ :key3=>{:key3a=>[]}, "findme"=>[123, 456, {:findme=>123456}]}
358
+
359
+ data = @trans.transaction_move @data, "key*/key??/*" => "mapped/%4"
360
+ data = @trans.remake_arrays data
361
+
362
+ mapped = data.delete "mapped"
363
+
364
+ assert_equal expected, data
365
+ assert_not_equal @data, data
366
+
367
+ assert_equal({:findme=>"thing"}, mapped.last)
368
+
369
+ # Due to unordered hashes, this could be
370
+ # %w{val1 val2 val3} OR %w{foo bar foobar}
371
+ assert_equal [String], mapped[0..2].map{|v| v.class}.uniq
372
+ end
373
+
374
+
375
+ def test_force_assign_paths
376
+ data = {'foo' => 'bar'}
377
+
378
+ new_data = @trans.force_assign_paths data,
379
+ %w{sub thing one} => 'val1',
380
+ %w{sub thing two} => 'val2',
381
+ ['sub', 'other', 3] => 'val3',
382
+ ['sub', 'other', 1] => 'val4',
383
+ ['sub', 'other', 5, 6] => 'val5'
384
+
385
+ assert_equal({'foo' => 'bar'}, data)
386
+
387
+ expected = {
388
+ 'foo' => 'bar',
389
+ 'sub' => {
390
+ 'thing' => {'one' => 'val1', 'two' => 'val2'},
391
+ 'other' => {3 => 'val3', 1 => 'val4', 5 => {6 => 'val5'}}
392
+ }
393
+ }
394
+ assert_equal expected, new_data
395
+
396
+ expected['sub']['other'] = ['val4', 'val3', ['val5']]
397
+ new_data = @trans.remake_arrays new_data
398
+ assert_equal expected, new_data
399
+ end
400
+
401
+
402
+ def test_force_assign_paths_root_array
403
+ data = ['foo', 'bar']
404
+
405
+ new_data = @trans.force_assign_paths data,
406
+ [1, 'thing', 'one'] => 'val1',
407
+ [1, 'thing', 'two'] => 'val2',
408
+ [3, 'other', 3] => 'val3',
409
+ [3, 'other', 1] => 'val4',
410
+ [3, 'other', 5, 6] => 'val5'
411
+
412
+ assert_equal(['foo', 'bar'], data)
413
+
414
+ expected = {
415
+ 0 => 'foo',
416
+ 1 => {'thing' => {'one' => 'val1', 'two' => 'val2'}},
417
+ 3 => {'other' => {3 => 'val3', 1 => 'val4', 5 => {6 => 'val5'}}}
418
+ }
419
+ assert_equal expected, new_data
420
+
421
+ expected[3]['other'] = ['val4', 'val3', ['val5']]
422
+ new_data = @trans.remake_arrays new_data
423
+ assert_equal expected, new_data
424
+ end
425
+
426
+
299
427
  def test_ary_to_hash
300
428
  expected = {1 => :a, 0 => :foo, 2 => :b}
301
429
  assert_equal expected, @trans.ary_to_hash([:foo, :a, :b])
@@ -308,12 +436,13 @@ class TestTransaction < Test::Unit::TestCase
308
436
 
309
437
 
310
438
  def test_clear
311
- @trans.instance_variable_get(:@actions)[:foo] = :bar
312
- @trans.instance_variable_get(:@make_array) << :foobar
439
+ @trans.delete "foo"
440
+ @trans.select "bar"
313
441
 
314
442
  @trans.clear
315
443
 
316
- assert @trans.instance_variable_get(:@actions).empty?
444
+ assert @trans.instance_variable_get(:@actions)[:delete].empty?
445
+ assert @trans.instance_variable_get(:@actions)[:select].empty?
317
446
  assert @trans.instance_variable_get(:@make_array).empty?
318
447
  end
319
448