kronk 1.6.2 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/History.rdoc +29 -1
  2. data/Manifest.txt +6 -1
  3. data/README.rdoc +74 -28
  4. data/Rakefile +4 -3
  5. data/TODO.rdoc +7 -5
  6. data/bin/kronk +2 -11
  7. data/lib/kronk/async/em_ext.rb +34 -0
  8. data/lib/kronk/async/request.rb +73 -0
  9. data/lib/kronk/async/response.rb +70 -0
  10. data/lib/kronk/async.rb +118 -0
  11. data/lib/kronk/cmd.rb +111 -43
  12. data/lib/kronk/constants.rb +1 -0
  13. data/lib/kronk/core_ext.rb +1 -1
  14. data/lib/kronk/data_string.rb +251 -0
  15. data/lib/kronk/diff/output.rb +132 -100
  16. data/lib/kronk/diff.rb +20 -24
  17. data/lib/kronk/path/matcher.rb +8 -4
  18. data/lib/kronk/path/path_match.rb +48 -4
  19. data/lib/kronk/path/transaction.rb +74 -53
  20. data/lib/kronk/path.rb +11 -6
  21. data/lib/kronk/player/benchmark.rb +11 -12
  22. data/lib/kronk/player/input_reader.rb +40 -3
  23. data/lib/kronk/player/request_parser.rb +4 -1
  24. data/lib/kronk/player/stream.rb +2 -2
  25. data/lib/kronk/player/suite.rb +16 -9
  26. data/lib/kronk/player.rb +93 -143
  27. data/lib/kronk/queue_runner.rb +238 -0
  28. data/lib/kronk/request.rb +25 -20
  29. data/lib/kronk/response.rb +39 -10
  30. data/lib/kronk/test/assertions.rb +2 -2
  31. data/lib/kronk/test/helper_methods.rb +1 -1
  32. data/lib/kronk.rb +56 -24
  33. data/test/test_assertions.rb +4 -4
  34. data/test/test_cmd.rb +38 -10
  35. data/test/test_data_string.rb +242 -1
  36. data/test/test_diff.rb +8 -303
  37. data/test/test_helper.rb +1 -1
  38. data/test/test_kronk.rb +21 -28
  39. data/test/test_path.rb +29 -0
  40. data/test/test_path_match.rb +47 -2
  41. data/test/test_path_matcher.rb +42 -1
  42. data/test/test_player.rb +71 -72
  43. data/test/test_request.rb +31 -6
  44. data/test/test_request_parser.rb +7 -1
  45. data/test/test_response.rb +1 -1
  46. data/test/test_transaction.rb +78 -30
  47. metadata +64 -8
  48. data/lib/kronk/data_renderer.rb +0 -219
data/test/test_player.rb CHANGED
@@ -27,6 +27,8 @@ class TestPlayer < Test::Unit::TestCase
27
27
 
28
28
 
29
29
  def setup
30
+ Kronk::Player.async = false
31
+
30
32
  @io = MockPipe.new
31
33
  @parser = MockParser
32
34
  @output = MockOutput
@@ -87,13 +89,6 @@ class TestPlayer < Test::Unit::TestCase
87
89
  end
88
90
 
89
91
 
90
- def test_queue_req
91
- @player.queue_req :first_item
92
- @player.queue_req :second_item
93
- assert_equal [:first_item, :second_item], @player.queue
94
- end
95
-
96
-
97
92
  def test_from_io
98
93
  @player.from_io "mock"
99
94
  assert_equal "mock", @player.input.io
@@ -105,18 +100,13 @@ class TestPlayer < Test::Unit::TestCase
105
100
  end
106
101
 
107
102
 
108
- def test_output_results
109
- @player.output.expects(:completed).with().returns "FINISHED"
110
- assert_equal "FINISHED", @player.output_results
111
- end
112
-
113
-
114
103
  def test_finished_false
115
104
  @player.number = nil
116
105
 
117
106
  @player.queue.clear
118
107
  @player.count = 2
119
- @player.input.stubs(:eof?).returns false
108
+ @player.reader_thread = "mock thread"
109
+ @player.reader_thread.stubs(:alive?).returns true
120
110
  assert !@player.finished?
121
111
 
122
112
  @player.queue << "test"
@@ -129,13 +119,6 @@ class TestPlayer < Test::Unit::TestCase
129
119
  @player.input.stubs(:eof?).returns true
130
120
  assert !@player.finished?
131
121
 
132
- @player.count = 4
133
- @player.queue.clear
134
- @player.input.stubs(:eof?).returns true
135
- @player.reader_thread = "mock thread"
136
- @player.reader_thread.expects(:alive?).returns true
137
- assert !@player.finished?
138
-
139
122
  @player.queue << "test"
140
123
  @player.input.stubs(:eof?).returns true
141
124
  @player.reader_thread.stubs(:alive?).returns false
@@ -153,7 +136,12 @@ class TestPlayer < Test::Unit::TestCase
153
136
  @player.number = nil
154
137
  @player.count = 1
155
138
  @player.queue.clear
156
- @player.input.stubs(:eof?).returns true
139
+ @player.reader_thread = "mock thread"
140
+ @player.reader_thread.expects(:alive?).returns false
141
+ assert @player.finished?
142
+
143
+ @player.count = 4
144
+ @player.queue.clear
157
145
  @player.reader_thread = "mock thread"
158
146
  @player.reader_thread.expects(:alive?).returns false
159
147
  assert @player.finished?
@@ -161,8 +149,7 @@ class TestPlayer < Test::Unit::TestCase
161
149
  @player.number = 10
162
150
  @player.count = 1
163
151
  @player.queue.clear
164
- @player.input.stubs(:eof?).returns true
165
- @player.reader_thread.expects(:alive?).returns false
152
+ @player.reader_thread = nil
166
153
  assert @player.finished?
167
154
  end
168
155
 
@@ -177,6 +164,9 @@ class TestPlayer < Test::Unit::TestCase
177
164
 
178
165
 
179
166
  def test_compare
167
+ @player.output.expects :start
168
+ @player.output.expects :completed
169
+
180
170
  @player.concurrency = 3
181
171
  @player.input.parser = Kronk::Player::RequestParser
182
172
  @player.input.io << "/req3\n/req4\n/req5\n"
@@ -215,11 +205,14 @@ class TestPlayer < Test::Unit::TestCase
215
205
 
216
206
 
217
207
  def test_request
218
- @player.concurrency = 3
219
- @player.input.parser = Kronk::Player::RequestParser
220
- @player.input.io << "/req3\n/req4\n/req5\n"
221
- @player.input.io.rewind
222
- @player.input.io.close_write
208
+ @player.concurrency = 3
209
+
210
+ paths = %w{/req3 /req4 /req5}
211
+
212
+ @player.on :input do
213
+ @player.stop_input! if paths.empty?
214
+ {:uri_suffix => paths.shift}
215
+ end
223
216
 
224
217
  @player.queue.concat [{:uri_suffix => "/req1"}, {:uri_suffix => "/req2"}]
225
218
 
@@ -238,20 +231,26 @@ class TestPlayer < Test::Unit::TestCase
238
231
  :query => "foo=bar"
239
232
  end
240
233
 
241
- @player.request "example.com", :query => "foo=bar"
234
+ result_calls = 0
242
235
 
243
- assert_equal 5, @player.output.result_calls
236
+ @player.request "example.com", :query => "foo=bar" do |kronk, err|
237
+ result_calls += 1
238
+ end
239
+
240
+ assert_equal 5, result_calls
244
241
  end
245
242
 
246
243
 
247
- def test_process_queue_interrupted
244
+ def test_run_interrupted
248
245
  @player.concurrency = 0
249
246
 
250
247
  @player.output.expects :start
251
248
  @player.output.expects :completed
252
249
 
253
250
  thread = Thread.new do
254
- @player.process_queue
251
+ @player.run do |item, mutex|
252
+ sleep 0.1
253
+ end
255
254
  end
256
255
 
257
256
  sleep 0.1
@@ -270,9 +269,6 @@ class TestPlayer < Test::Unit::TestCase
270
269
  @player.queue.concat requests.dup
271
270
  @player.input.io.close
272
271
 
273
- @player.output.expects :start
274
- @player.output.expects :completed
275
-
276
272
  start = Time.now
277
273
  processed = []
278
274
 
@@ -293,9 +289,6 @@ class TestPlayer < Test::Unit::TestCase
293
289
 
294
290
  def test_process_queue_from_io
295
291
  @player.concurrency = 10
296
- @player.output.expects :start
297
- @player.output.expects :completed
298
-
299
292
  @player.input.parser.stubs(:start_new?).returns true
300
293
  @player.input.parser.stubs(:start_new?).with("").returns false
301
294
 
@@ -352,13 +345,13 @@ class TestPlayer < Test::Unit::TestCase
352
345
  end
353
346
 
354
347
 
355
- def test_try_fill_queue_from_input
348
+ def test_start_input_from_input
356
349
  @player.input.stubs(:get_next).returns "mock_request"
357
350
 
358
351
  @player.concurrency = 5
359
352
  @player.number = 20
360
353
 
361
- thread = @player.try_fill_queue
354
+ thread = @player.start_input!
362
355
  assert_equal Thread, thread.class
363
356
 
364
357
  sleep 0.2
@@ -374,14 +367,14 @@ class TestPlayer < Test::Unit::TestCase
374
367
  end
375
368
 
376
369
 
377
- def test_try_fill_queue_from_last
370
+ def test_start_input_from_last
378
371
  @player.input.stubs(:get_next).returns nil
379
372
  @player.input.stubs(:eof?).returns false
380
373
 
381
374
  @player.concurrency = 5
382
375
  @player.queue << "mock_request"
383
376
 
384
- thread = @player.try_fill_queue
377
+ thread = @player.start_input!
385
378
  assert_equal Thread, thread.class
386
379
 
387
380
  sleep 0.2
@@ -397,13 +390,13 @@ class TestPlayer < Test::Unit::TestCase
397
390
  end
398
391
 
399
392
 
400
- def test_try_fill_queue_no_input
393
+ def test_start_input_no_input
401
394
  @player.input.stubs(:eof?).returns true
402
395
 
403
396
  @player.concurrency = 5
404
397
  @player.queue << "mock_request"
405
398
 
406
- thread = @player.try_fill_queue
399
+ thread = @player.start_input!
407
400
  assert_equal Thread, thread.class
408
401
 
409
402
  sleep 0.2
@@ -414,27 +407,27 @@ class TestPlayer < Test::Unit::TestCase
414
407
  end
415
408
 
416
409
 
417
- def test_next_request
410
+ def test_next_input
418
411
  @player.input.expects(:get_next).returns "NEXT ITEM"
419
- assert_equal "NEXT ITEM", @player.next_request
412
+ assert_equal "NEXT ITEM", @player.trigger(:input)
420
413
 
421
414
  @player.input.expects(:get_next).returns nil
422
415
  @player.queue.concat ["FIRST ITEM", "QUEUE REPEAT"]
423
- assert_equal "QUEUE REPEAT", @player.next_request
416
+ assert_equal "QUEUE REPEAT", @player.trigger(:input)
424
417
 
425
418
  @player.input.expects(:get_next).returns nil
426
419
  @player.queue.clear
427
420
  @player.instance_variable_set "@last_req", "LAST REQ"
428
- assert_equal "LAST REQ", @player.next_request
421
+ assert_equal "LAST REQ", @player.trigger(:input)
429
422
 
430
423
  @player.input.expects(:get_next).returns nil
431
424
  @player.queue.clear
432
425
  @player.instance_variable_set "@last_req", nil
433
- assert_equal Hash.new, @player.next_request
426
+ assert_equal Hash.new, @player.trigger(:input)
434
427
  end
435
428
 
436
429
 
437
- def test_process_compare
430
+ def test_process_compare_one
438
431
  mock_thread = "mock_thread"
439
432
  Thread.expects(:new).twice.yields.returns mock_thread
440
433
  mock_thread.expects(:join).twice
@@ -462,14 +455,14 @@ class TestPlayer < Test::Unit::TestCase
462
455
  true
463
456
  end
464
457
 
465
- @player.process_compare "example.com", "beta-example.com",
466
- :uri_suffix => "/test", :include_headers => true
458
+ opts = {:uri_suffix => "/test", :include_headers => true}
459
+ @player.process_one opts, :compare, "example.com", "beta-example.com"
467
460
 
468
461
  assert @got_results, "Expected output to get results but didn't"
469
462
  end
470
463
 
471
464
 
472
- def test_process_compare_error
465
+ def test_process_one_compare_error
473
466
  @got_results = []
474
467
 
475
468
  @player.output.expects(:error).times(3).with do |error, kronk, mutex|
@@ -481,27 +474,31 @@ class TestPlayer < Test::Unit::TestCase
481
474
 
482
475
  errs = [Kronk::Exception, Kronk::Response::MissingParser, Errno::ECONNRESET]
483
476
  errs.each do |eklass|
484
- Kronk.any_instance.expects(:compare).raises eklass
477
+ Kronk.any_instance.expects(:compare).
478
+ with("example.com", "beta-example.com").
479
+ raises eklass
485
480
 
486
- @player.process_compare "example.com", "beta-example.com",
487
- :uri_suffix => "/test", :include_headers => true
481
+ opts = {:uri_suffix => "/test", :include_headers => true}
482
+ @player.process_one opts, :compare, "example.com", "beta-example.com"
488
483
  end
489
484
 
490
485
  assert_equal errs, @got_results, "Expected output to get errors but didn't"
491
486
  end
492
487
 
493
488
 
494
- def test_process_compare_error_not_caught
495
- Kronk.any_instance.expects(:compare).raises RuntimeError
489
+ def test_process_one_compare_error_not_caught
490
+ Kronk.any_instance.expects(:compare).
491
+ with("example.com", "beta-example.com").
492
+ raises RuntimeError
496
493
 
497
494
  assert_raises RuntimeError do
498
- @player.process_compare "example.com", "beta-example.com",
499
- :uri_suffix => "/test", :include_headers => true
495
+ opts = {:uri_suffix => "/test", :include_headers => true}
496
+ @player.process_one opts, :compare, "example.com", "beta-example.com"
500
497
  end
501
498
  end
502
499
 
503
500
 
504
- def test_process_request
501
+ def test_process_one_request
505
502
  resp = Kronk::Response.new mock_resp("200_response.json")
506
503
  resp.parser = JSON
507
504
 
@@ -519,14 +516,14 @@ class TestPlayer < Test::Unit::TestCase
519
516
  true
520
517
  end
521
518
 
522
- @player.process_request "example.com",
523
- :uri_suffix => "/test", :include_headers => true
519
+ opts = {:uri_suffix => "/test", :include_headers => true}
520
+ @player.process_one opts, :request, "example.com"
524
521
 
525
522
  assert @got_results, "Expected output to get results but didn't"
526
523
  end
527
524
 
528
525
 
529
- def test_process_request_error
526
+ def test_process_one_request_error
530
527
  @got_results = []
531
528
 
532
529
  @player.output.expects(:error).times(3).with do |error, kronk, mutex|
@@ -538,22 +535,24 @@ class TestPlayer < Test::Unit::TestCase
538
535
 
539
536
  errs = [Kronk::Exception, Kronk::Response::MissingParser, Errno::ECONNRESET]
540
537
  errs.each do |eklass|
541
- Kronk.any_instance.expects(:retrieve).raises eklass
538
+ Kronk.any_instance.expects(:request).with("example.com").
539
+ raises eklass
542
540
 
543
- @player.process_request "example.com",
544
- :uri_suffix => "/test", :include_headers => true
541
+ opts = {:uri_suffix => "/test", :include_headers => true}
542
+ @player.process_one opts, :request, "example.com"
545
543
  end
546
544
 
547
545
  assert_equal errs, @got_results, "Expected output to get errors but didn't"
548
546
  end
549
547
 
550
548
 
551
- def test_process_request_error_not_caught
552
- Kronk.any_instance.expects(:retrieve).raises RuntimeError
549
+ def test_process_one_request_error_not_caught
550
+ Kronk.any_instance.expects(:request).with("example.com").
551
+ raises RuntimeError
553
552
 
554
553
  assert_raises RuntimeError do
555
- @player.process_request "example.com",
556
- :uri_suffix => "/test", :include_headers => true
554
+ opts = {:uri_suffix => "/test", :include_headers => true}
555
+ @player.process_one opts, :request, "example.com"
557
556
  end
558
557
  end
559
558
 
data/test/test_request.rb CHANGED
@@ -13,6 +13,24 @@ class TestRequest < Test::Unit::TestCase
13
13
  end
14
14
 
15
15
 
16
+ def test_parse_url
17
+ raw = "https://example.com/foobar?foo=bar"
18
+ req = Kronk::Request.parse(raw)
19
+
20
+ assert_equal Kronk::Request, req.class
21
+ assert_equal URI.parse("https://example.com/foobar?foo=bar"), req.uri
22
+ end
23
+
24
+
25
+ def test_parse_url_path
26
+ raw = "/foobar?foo=bar"
27
+ req = Kronk::Request.parse(raw)
28
+
29
+ assert_equal Kronk::Request, req.class
30
+ assert_equal URI.parse("http://localhost:3000/foobar?foo=bar"), req.uri
31
+ end
32
+
33
+
16
34
  def test_parse_invalid
17
35
  assert_raises Kronk::Request::ParseError do
18
36
  Kronk::Request.parse "thing\nfoo\n"
@@ -43,6 +61,13 @@ class TestRequest < Test::Unit::TestCase
43
61
  end
44
62
 
45
63
 
64
+ def test_parse_to_hash_url
65
+ expected = {:host => "http://example.com", :uri_suffix => "/foobar?foo=bar"}
66
+ assert_equal expected,
67
+ Kronk::Request.parse_to_hash("http://example.com/foobar?foo=bar")
68
+ end
69
+
70
+
46
71
  def test_parse_to_hash_invalid
47
72
  assert_nil Kronk::Request.parse_to_hash("thing\nfoo\n")
48
73
  assert_nil Kronk::Request.parse_to_hash("")
@@ -351,7 +376,7 @@ class TestRequest < Test::Unit::TestCase
351
376
 
352
377
  def test_retrieve_proxy
353
378
  proxy = {
354
- :address => "proxy.com",
379
+ :host => "proxy.com",
355
380
  :username => "john",
356
381
  :password => "smith"
357
382
  }
@@ -378,12 +403,12 @@ class TestRequest < Test::Unit::TestCase
378
403
 
379
404
 
380
405
  def test_proxy_nil
381
- assert_equal Net::HTTP, Kronk::Request.new("host.com").use_proxy(nil)
406
+ assert_equal Net::HTTP, Kronk::Request.new("host.com").http_proxy(nil)
382
407
  end
383
408
 
384
409
 
385
410
  def test_proxy_string
386
- proxy_class = Kronk::Request.new("host.com").use_proxy("myproxy.com:80")
411
+ proxy_class = Kronk::Request.new("host.com").http_proxy("myproxy.com:80")
387
412
 
388
413
  assert_equal "myproxy.com",
389
414
  proxy_class.instance_variable_get("@proxy_address")
@@ -396,7 +421,7 @@ class TestRequest < Test::Unit::TestCase
396
421
 
397
422
 
398
423
  def test_proxy_no_port
399
- proxy_class = Kronk::Request.new("host.com").use_proxy("myproxy.com")
424
+ proxy_class = Kronk::Request.new("host.com").http_proxy("myproxy.com")
400
425
 
401
426
  assert_equal "myproxy.com",
402
427
  proxy_class.instance_variable_get("@proxy_address")
@@ -410,12 +435,12 @@ class TestRequest < Test::Unit::TestCase
410
435
 
411
436
  def test_proxy_hash
412
437
  req = Kronk::Request.new "http://example.com",
413
- :proxy => { :address => "myproxy.com",
438
+ :proxy => { :host => "myproxy.com",
414
439
  :port => 8080,
415
440
  :username => "john",
416
441
  :password => "smith" }
417
442
 
418
- proxy_class = req.instance_variable_get "@HTTP"
443
+ proxy_class = req.http_proxy req.proxy[:host], req.proxy
419
444
 
420
445
  assert_equal "myproxy.com",
421
446
  proxy_class.instance_variable_get("@proxy_address")
@@ -5,7 +5,13 @@ class TestRequestParser < Test::Unit::TestCase
5
5
  def test_start_new
6
6
  assert Kronk::Player::RequestParser.start_new?("/foobar\r\n")
7
7
  assert Kronk::Player::RequestParser.start_new?("GET /foobar\r\n")
8
- assert !Kronk::Player::RequestParser.start_new?("http://example.com\r\n")
8
+ assert Kronk::Player::RequestParser.start_new?("http://example.com\r\n")
9
+ assert Kronk::Player::RequestParser.start_new?("https://example.com\r\n")
10
+ assert Kronk::Player::RequestParser.start_new?("https://foo.com/\r\n")
11
+ assert Kronk::Player::RequestParser.start_new?("/\r\n")
12
+ assert Kronk::Player::RequestParser.start_new?("https://foo.com/bar\r\n")
13
+ assert Kronk::Player::RequestParser.start_new?(
14
+ "10.1.8.10 - - [20/Sep/2011:20:57:54 +0000] \"GET /users/d7399ed0-c5f1-012e-cf4d-00163e2aabff.json HTTP/1.1\" 200 550 \"-\" \"Ruby\" \"-\" 0.009\n")
9
15
  assert !Kronk::Player::RequestParser.start_new?("foobar\r\n")
10
16
  end
11
17
 
@@ -454,7 +454,7 @@ STR
454
454
  expected = JSON.parse \
455
455
  File.read("test/mocks/200_response.json").split("\r\n\r\n")[1]
456
456
 
457
- expected = Kronk::Diff.ordered_data_string expected, true
457
+ expected = Kronk::DataString.new expected, :struct => true
458
458
 
459
459
  assert_equal expected, str
460
460
  end
@@ -30,19 +30,35 @@ class TestTransaction < Test::Unit::TestCase
30
30
 
31
31
  def test_many_transactions
32
32
  data = @trans.run do |t|
33
- t.map "key?" => "thing%1",
34
- "key3/*/0" => "key_value"
35
- t.select "findme/0..1"
33
+ t.select "findme/0..1", "key(1|3)"
34
+ t.move [["key3/*/0", "key_value"], ["key?", "thing%1"]]
36
35
  t.delete "findme/0"
37
- t.move "findme/2" => "last_thing"
36
+ t.move "findme/1" => "last_thing"
38
37
  end
39
38
 
40
39
  expected = {
41
- "last_thing"=>{}, "key_value"=>"val1",
40
+ "last_thing"=>456 , "key_value"=>"val1", "findme" => [],
42
41
  "thing1"=>{:key1a=>["foo", "bar", "foobar", {:findme=>"thing"}],
43
42
  "key1b"=>"findme"},
44
- "thing2"=>"foobar",
45
- "thing3"=>{:key3a=>["val1", "val2", "val3"]}, "findme"=>[456]}
43
+ "thing3"=>{:key3a=>["val2", "val3"]}}
44
+
45
+ assert_equal expected, data
46
+ end
47
+
48
+
49
+ def test_many_transactions_with_map
50
+ data = @trans.run do |t|
51
+ t.select "findme/0..1", "key(1|3)"
52
+ t.map [["key3/*/0", "key_value"], ["key?", "thing%1"]]
53
+ t.delete "findme/0"
54
+ t.move "findme/1" => "last_thing"
55
+ end
56
+
57
+ expected = {
58
+ "key_value"=>"val1",
59
+ "thing1"=>{:key1a=>["foo", "bar", "foobar", {:findme=>"thing"}],
60
+ "key1b"=>"findme"},
61
+ "thing3"=>{:key3a=>["val2", "val3"]}}
46
62
 
47
63
  assert_equal expected, data
48
64
  end
@@ -64,7 +80,7 @@ class TestTransaction < Test::Unit::TestCase
64
80
 
65
81
  def test_run
66
82
  expected = {
67
- :key1=>{:key1a=>["foo", "foobar", {}]},
83
+ :key1=>{:key1a=>["foo", "foobar"]},
68
84
  :key2=>"foobar",
69
85
  "findme"=>[123, 456, {:findme=>123456}]
70
86
  }
@@ -93,7 +109,7 @@ class TestTransaction < Test::Unit::TestCase
93
109
  result = @trans.results
94
110
 
95
111
  expected = {
96
- :key1=>{:key1a=>["foo", "foobar", {}]},
112
+ :key1=>{:key1a=>["foo", "foobar"]},
97
113
  :key2=>"foobar",
98
114
  "findme"=>[123, 456, {:findme=>123456}]
99
115
  }
@@ -109,7 +125,7 @@ class TestTransaction < Test::Unit::TestCase
109
125
  result = @trans.results :keep_indicies => true
110
126
 
111
127
  expected = {
112
- :key1=>{:key1a=>{2=>"foobar", 0=>"foo", 3=>{}}},
128
+ :key1=>{:key1a=>{2=>"foobar", 0=>"foo"}},
113
129
  :key2=>"foobar",
114
130
  "findme"=>[123, 456, {:findme=>123456}]
115
131
  }
@@ -324,10 +340,11 @@ class TestTransaction < Test::Unit::TestCase
324
340
  :key3=>{}, "findme"=>[123, 456, {}],
325
341
  "more"=>{"one-findme"=>"thing", "two-findme"=>123456}}
326
342
 
327
- data = @trans.transaction_move @data, "key*/key??" => "mapped/%1-%3",
328
- "mapped" => "remapped",
329
- "**=thing" => "more/one-%1",
330
- "**=123456" => "more/two-%1"
343
+ data = @trans.transaction_move @data,
344
+ ["**=thing", "more/one-%1"],
345
+ ["key*/key??", "mapped/%1-%3"],
346
+ ["mapped", "remapped"],
347
+ ["**=123456", "more/two-%1"]
331
348
  data = @trans.remake_arrays data
332
349
 
333
350
  assert_equal expected, data
@@ -338,14 +355,37 @@ class TestTransaction < Test::Unit::TestCase
338
355
  def test_transaction_map
339
356
  expected = {
340
357
  "mapped"=>{
341
- "1-a"=>["foo", "bar", "foobar", {:findme=>"thing"}],
358
+ "1-a"=>["foo", "bar", "foobar", {}],
359
+ "1-b"=>"findme", "3-a"=>["val1", "val2", "val3"]},
360
+ "more"=>[{:findme=>"thing"}]
361
+ }
362
+
363
+ data = @trans.transaction_map @data,
364
+ ["**=thing", "more/12/%1"],
365
+ ["key*/key??", "mapped/%1-%3"],
366
+ ["mapped", "remapped"]
367
+
368
+ data = @trans.remake_arrays data
369
+
370
+ assert_equal expected, data
371
+ assert_not_equal @data, data
372
+ end
373
+
374
+
375
+ def test_transaction_map_no_target
376
+ expected = {
377
+ "mapped"=>{
378
+ "1-a"=>["foo", "bar", "foobar", {}],
342
379
  "1-b"=>"findme", "3-a"=>["val1", "val2", "val3"]},
343
- "more"=>{:findme=>"thing"}
380
+ :key1=>{:key1a => [{:findme=>"thing"}]}
344
381
  }
345
382
 
346
- data = @trans.transaction_map @data, "key*/key??" => "mapped/%1-%3",
347
- "mapped" => "remapped",
348
- "**=thing" => "more/%1"
383
+ data = @trans.transaction_map @data,
384
+ "**=thing",
385
+ ["key*/key??", "mapped/%1-%3"],
386
+ ["mapped", "remapped"]
387
+
388
+ data = @trans.remake_arrays data
349
389
 
350
390
  assert_equal expected, data
351
391
  assert_not_equal @data, data
@@ -356,7 +396,7 @@ class TestTransaction < Test::Unit::TestCase
356
396
  expected = {:key1=>{:key1a=>[], "key1b"=>"findme"},:key2=>"foobar",
357
397
  :key3=>{:key3a=>[]}, "findme"=>[123, 456, {:findme=>123456}]}
358
398
 
359
- data = @trans.transaction_move @data, "key*/key??/*" => "mapped/%4"
399
+ data = @trans.transaction_move @data, ["key*/key??/*", "mapped/%4"]
360
400
  data = @trans.remake_arrays data
361
401
 
362
402
  mapped = data.delete "mapped"
@@ -424,6 +464,14 @@ class TestTransaction < Test::Unit::TestCase
424
464
  end
425
465
 
426
466
 
467
+ def test_is_integer
468
+ assert @trans.is_integer?("123")
469
+ assert @trans.is_integer?(:"123")
470
+ assert !@trans.is_integer?("foo123")
471
+ assert !@trans.is_integer?(:foo123)
472
+ end
473
+
474
+
427
475
  def test_ary_to_hash
428
476
  expected = {1 => :a, 0 => :foo, 2 => :b}
429
477
  assert_equal expected, @trans.ary_to_hash([:foo, :a, :b])
@@ -441,30 +489,30 @@ class TestTransaction < Test::Unit::TestCase
441
489
 
442
490
  @trans.clear
443
491
 
444
- assert @trans.instance_variable_get(:@actions)[:delete].empty?
445
- assert @trans.instance_variable_get(:@actions)[:select].empty?
492
+ assert @trans.instance_variable_get(:@actions).empty?
446
493
  assert @trans.instance_variable_get(:@make_array).empty?
447
494
  end
448
495
 
449
496
 
450
497
  def test_select
451
498
  @trans.select "path1", "path2", "path3"
452
- assert_equal ["path1", "path2", "path3"],
453
- @trans.instance_variable_get(:@actions)[:select]
499
+ assert_equal [[:select, ["path1", "path2", "path3"]]],
500
+ @trans.instance_variable_get(:@actions)
454
501
 
455
502
  @trans.select "path4", "path5"
456
- assert_equal ["path1", "path2", "path3", "path4", "path5"],
457
- @trans.instance_variable_get(:@actions)[:select]
503
+ assert_equal [[:select, ["path1", "path2", "path3", "path4", "path5"]]],
504
+ @trans.instance_variable_get(:@actions)
458
505
  end
459
506
 
460
507
 
461
508
  def test_delete
462
509
  @trans.delete "path1", "path2", "path3"
463
- assert_equal ["path1", "path2", "path3"],
464
- @trans.instance_variable_get(:@actions)[:delete]
510
+ assert_equal [[:delete, ["path1", "path2", "path3"]]],
511
+ @trans.instance_variable_get(:@actions)
465
512
 
466
513
  @trans.delete "path4", "path5"
467
- assert_equal ["path1", "path2", "path3", "path4", "path5"],
468
- @trans.instance_variable_get(:@actions)[:delete]
514
+ assert_equal [[:delete, ["path1", "path2", "path3"]],
515
+ [:delete, ["path4", "path5"]]],
516
+ @trans.instance_variable_get(:@actions)
469
517
  end
470
518
  end