ruote 2.3.0.1 → 2.3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. data/CHANGELOG.txt +23 -0
  2. data/CREDITS.txt +4 -0
  3. data/LICENSE.txt +1 -1
  4. data/lib/ruote.rb +2 -0
  5. data/lib/ruote/context.rb +2 -1
  6. data/lib/ruote/dashboard.rb +169 -13
  7. data/lib/ruote/dboard/mutation.rb +282 -0
  8. data/lib/ruote/dboard/process_error.rb +1 -1
  9. data/lib/ruote/dboard/process_status.rb +61 -48
  10. data/lib/ruote/engine.rb +1 -1
  11. data/lib/ruote/exp/command.rb +1 -1
  12. data/lib/ruote/exp/commanded.rb +1 -1
  13. data/lib/ruote/exp/condition.rb +2 -1
  14. data/lib/ruote/exp/fe_add_branches.rb +1 -1
  15. data/lib/ruote/exp/fe_apply.rb +1 -1
  16. data/lib/ruote/exp/fe_await.rb +97 -48
  17. data/lib/ruote/exp/fe_cancel_process.rb +1 -1
  18. data/lib/ruote/exp/fe_command.rb +2 -3
  19. data/lib/ruote/exp/fe_concurrence.rb +162 -66
  20. data/lib/ruote/exp/fe_concurrent_iterator.rb +25 -7
  21. data/lib/ruote/exp/fe_cron.rb +1 -1
  22. data/lib/ruote/exp/fe_cursor.rb +10 -11
  23. data/lib/ruote/exp/fe_define.rb +1 -1
  24. data/lib/ruote/exp/fe_echo.rb +1 -1
  25. data/lib/ruote/exp/fe_equals.rb +1 -1
  26. data/lib/ruote/exp/fe_error.rb +1 -1
  27. data/lib/ruote/exp/fe_filter.rb +1 -1
  28. data/lib/ruote/exp/fe_forget.rb +1 -1
  29. data/lib/ruote/exp/fe_given.rb +1 -1
  30. data/lib/ruote/exp/fe_if.rb +87 -7
  31. data/lib/ruote/exp/fe_inc.rb +1 -1
  32. data/lib/ruote/exp/fe_iterator.rb +1 -1
  33. data/lib/ruote/exp/fe_listen.rb +1 -1
  34. data/lib/ruote/exp/fe_lose.rb +1 -1
  35. data/lib/ruote/exp/fe_noop.rb +1 -1
  36. data/lib/ruote/exp/fe_on_error.rb +1 -1
  37. data/lib/ruote/exp/fe_once.rb +1 -1
  38. data/lib/ruote/exp/fe_participant.rb +49 -16
  39. data/lib/ruote/exp/fe_read.rb +1 -1
  40. data/lib/ruote/exp/fe_redo.rb +1 -1
  41. data/lib/ruote/exp/fe_ref.rb +1 -1
  42. data/lib/ruote/exp/fe_registerp.rb +1 -1
  43. data/lib/ruote/exp/fe_reserve.rb +1 -1
  44. data/lib/ruote/exp/fe_restore.rb +1 -7
  45. data/lib/ruote/exp/fe_save.rb +1 -1
  46. data/lib/ruote/exp/fe_sequence.rb +1 -1
  47. data/lib/ruote/exp/fe_set.rb +1 -1
  48. data/lib/ruote/exp/fe_stall.rb +1 -1
  49. data/lib/ruote/exp/fe_subprocess.rb +1 -1
  50. data/lib/ruote/exp/fe_that.rb +1 -1
  51. data/lib/ruote/exp/fe_undo.rb +1 -1
  52. data/lib/ruote/exp/fe_unregisterp.rb +1 -1
  53. data/lib/ruote/exp/fe_wait.rb +1 -1
  54. data/lib/ruote/exp/flow_expression.rb +117 -8
  55. data/lib/ruote/exp/iterator.rb +1 -1
  56. data/lib/ruote/exp/ro_attributes.rb +1 -1
  57. data/lib/ruote/exp/ro_filters.rb +1 -1
  58. data/lib/ruote/exp/ro_on_x.rb +4 -2
  59. data/lib/ruote/exp/ro_persist.rb +1 -1
  60. data/lib/ruote/exp/ro_timers.rb +1 -1
  61. data/lib/ruote/exp/ro_variables.rb +1 -1
  62. data/lib/ruote/extract.rb +125 -0
  63. data/lib/ruote/fei.rb +10 -73
  64. data/lib/ruote/id/mnemo_wfid_generator.rb +1 -1
  65. data/lib/ruote/id/wfid_generator.rb +1 -1
  66. data/lib/ruote/log/default_history.rb +17 -3
  67. data/lib/ruote/log/fancy_printing.rb +12 -32
  68. data/lib/ruote/log/storage_history.rb +1 -1
  69. data/lib/ruote/log/wait_logger.rb +15 -7
  70. data/lib/ruote/merge.rb +123 -0
  71. data/lib/ruote/observer.rb +1 -1
  72. data/lib/ruote/part/block_participant.rb +1 -1
  73. data/lib/ruote/part/code_participant.rb +1 -1
  74. data/lib/ruote/part/engine_participant.rb +1 -1
  75. data/lib/ruote/part/local_participant.rb +9 -1
  76. data/lib/ruote/part/no_op_participant.rb +1 -1
  77. data/lib/ruote/part/null_participant.rb +1 -1
  78. data/lib/ruote/part/participant.rb +1 -1
  79. data/lib/ruote/part/rev_participant.rb +1 -1
  80. data/lib/ruote/part/smtp_participant.rb +1 -1
  81. data/lib/ruote/part/storage_participant.rb +18 -1
  82. data/lib/ruote/part/template.rb +1 -1
  83. data/lib/ruote/reader.rb +1 -1
  84. data/lib/ruote/reader/json.rb +1 -1
  85. data/lib/ruote/reader/radial.rb +4 -4
  86. data/lib/ruote/reader/ruby_dsl.rb +1 -1
  87. data/lib/ruote/reader/xml.rb +1 -1
  88. data/lib/ruote/receiver/base.rb +13 -1
  89. data/lib/ruote/storage/base.rb +8 -14
  90. data/lib/ruote/storage/composite_storage.rb +1 -1
  91. data/lib/ruote/storage/fs_storage.rb +1 -1
  92. data/lib/ruote/storage/hash_storage.rb +2 -1
  93. data/lib/ruote/svc/dispatch_pool.rb +29 -18
  94. data/lib/ruote/svc/dollar_sub.rb +5 -8
  95. data/lib/ruote/svc/error_handler.rb +1 -1
  96. data/lib/ruote/svc/expression_map.rb +1 -1
  97. data/lib/ruote/svc/participant_list.rb +8 -5
  98. data/lib/ruote/svc/tracker.rb +154 -56
  99. data/lib/ruote/svc/treechecker.rb +1 -1
  100. data/lib/ruote/tree_dot.rb +1 -1
  101. data/lib/ruote/util/deep.rb +4 -2
  102. data/lib/ruote/util/filter.rb +1 -1
  103. data/lib/ruote/util/hashdot.rb +1 -1
  104. data/lib/ruote/util/look.rb +1 -1
  105. data/lib/ruote/util/lookup.rb +1 -1
  106. data/lib/ruote/util/misc.rb +51 -1
  107. data/lib/ruote/util/mpatch.rb +1 -1
  108. data/lib/ruote/util/ometa.rb +1 -1
  109. data/lib/ruote/util/subprocess.rb +1 -1
  110. data/lib/ruote/util/time.rb +3 -3
  111. data/lib/ruote/util/tree.rb +43 -4
  112. data/lib/ruote/version.rb +2 -2
  113. data/lib/ruote/worker.rb +30 -18
  114. data/lib/ruote/workitem.rb +1 -1
  115. data/ruote.gemspec +6 -2
  116. data/test/functional/base.rb +0 -1
  117. data/test/functional/concurrent_base.rb +1 -1
  118. data/test/functional/eft_14_cursor.rb +42 -52
  119. data/test/functional/eft_16_if.rb +24 -16
  120. data/test/functional/eft_18_concurrent_iterator.rb +31 -1
  121. data/test/functional/eft_6_concurrence.rb +149 -34
  122. data/test/functional/ft_10_dollar.rb +14 -30
  123. data/test/functional/ft_12_launchitem.rb +15 -0
  124. data/test/functional/ft_1_process_status.rb +62 -13
  125. data/test/functional/ft_20_storage_participant.rb +25 -0
  126. data/test/functional/ft_38_participant_more.rb +1 -1
  127. data/test/functional/ft_42_storage_copy.rb +1 -3
  128. data/test/functional/ft_43_participant_on_reply.rb +63 -5
  129. data/test/functional/ft_66_flank.rb +41 -0
  130. data/test/functional/ft_6_on_cancel.rb +9 -18
  131. data/test/functional/ft_71_retries.rb +25 -12
  132. data/test/functional/ft_79_attach.rb +138 -0
  133. data/test/functional/ft_7_tags.rb +27 -0
  134. data/test/functional/ft_80_pause_on_apply.rb +64 -0
  135. data/test/functional/ft_81_mutation.rb +417 -0
  136. data/test/functional/ft_82_await_attribute.rb +84 -0
  137. data/test/functional/ft_83_trackers.rb +79 -0
  138. data/test/functional/storage.rb +3 -4
  139. data/test/unit/ut_12_wait_logger.rb +41 -3
  140. data/test/unit/ut_15_util.rb +30 -0
  141. data/test/unit/ut_17_merge.rb +54 -53
  142. data/test/unit/ut_1_fei.rb +2 -2
  143. data/test/unit/ut_24_radial_reader.rb +7 -0
  144. data/test/unit/ut_26_deep.rb +14 -0
  145. data/test/unit/ut_5_tree.rb +38 -28
  146. metadata +206 -169
  147. data/couch_url.txt +0 -1
  148. data/lib/ruote/exp/merge.rb +0 -134
@@ -0,0 +1,84 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Wed Dec 5 21:38:21 JST 2012
6
+ #
7
+
8
+ require File.expand_path('../base', __FILE__)
9
+
10
+
11
+ class FtAwaitAttributeTest < Test::Unit::TestCase
12
+ include FunctionalBase
13
+
14
+ def test_left_tag
15
+
16
+ pdef = Ruote.define do
17
+ concurrence do
18
+ sequence do
19
+ echo 'b', :await => 'left_tag:x'
20
+ end
21
+ sequence :tag => 'x' do
22
+ wait '1s'
23
+ echo 'a'
24
+ end
25
+ end
26
+ end
27
+
28
+ wfid = @dashboard.launch(pdef)
29
+ r = @dashboard.wait_for(wfid)
30
+
31
+ assert_equal('terminated', r['action'])
32
+ assert_equal(%w[ a b ], @tracer.to_a)
33
+
34
+ assert_equal 0, @dashboard.storage.get_trackers['trackers'].size
35
+ end
36
+
37
+ def test_left_tag__implicit_in
38
+
39
+ pdef = Ruote.define do
40
+ concurrence do
41
+ sequence do
42
+ echo 'c', :await => 'tag:x'
43
+ end
44
+ sequence do
45
+ echo 'a'
46
+ wait 0.350
47
+ echo 'b', :tag => 'x'
48
+ end
49
+ end
50
+ end
51
+
52
+ wfid = @dashboard.launch(pdef)
53
+ r = @dashboard.wait_for(wfid)
54
+
55
+ assert_equal('terminated', r['action'])
56
+ assert_equal(%w[ a b c ], @tracer.to_a)
57
+
58
+ assert_equal 0, @dashboard.storage.get_trackers['trackers'].size
59
+ end
60
+
61
+ def test_default_to_left_tag
62
+
63
+ pdef = Ruote.define do
64
+ concurrence do
65
+ sequence do
66
+ echo 'b', :await => 'x'
67
+ end
68
+ sequence :tag => 'x' do
69
+ wait '.350'
70
+ echo 'a'
71
+ end
72
+ end
73
+ end
74
+
75
+ wfid = @dashboard.launch(pdef)
76
+ r = @dashboard.wait_for(wfid)
77
+
78
+ assert_equal('terminated', r['action'])
79
+ assert_equal(%w[ a b ], @tracer.to_a)
80
+
81
+ assert_equal 0, @dashboard.storage.get_trackers['trackers'].size
82
+ end
83
+ end
84
+
@@ -0,0 +1,79 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Tue Dec 18 07:35:02 JST 2012
6
+ #
7
+
8
+ require File.expand_path('../base', __FILE__)
9
+
10
+
11
+ class FtTrackersTest < Test::Unit::TestCase
12
+ include FunctionalBase
13
+
14
+ def test_get_trackers
15
+
16
+ pdef =
17
+ Ruote.define do
18
+ await :left_tag => 'nada0' do
19
+ echo 'nada0'
20
+ end
21
+ end
22
+
23
+ wfid = @dashboard.launch(pdef)
24
+ @dashboard.wait_for('apply')
25
+
26
+ exp = @dashboard.ps(wfid).expressions.last
27
+
28
+ assert_equal Hash, @dashboard.get_trackers.class
29
+ assert_equal [ Ruote.sid(exp.fei) ], @dashboard.get_trackers.keys
30
+ end
31
+
32
+ def test_remove_fei_sid_tracker
33
+
34
+ pdef =
35
+ Ruote.define do
36
+ concurrence do
37
+ await :left_tag => 'nada0' do
38
+ echo 'nada0'
39
+ end
40
+ await :left_tag => 'nada1' do
41
+ echo 'nada1'
42
+ end
43
+ await :left_tag => 'nada2' do
44
+ echo 'nada2'
45
+ end
46
+ end
47
+ end
48
+
49
+ wfid = @dashboard.launch(pdef)
50
+ (1 + 3).times { @dashboard.wait_for('apply') }
51
+
52
+ assert_equal 3, @dashboard.storage.get_trackers['trackers'].size
53
+ assert_equal 3, @dashboard.get_trackers.size
54
+
55
+ ps = @dashboard.ps(wfid)
56
+ fei = ps.leaves[0].fei
57
+ hfei = ps.leaves[1].fei.h
58
+ sfei = ps.leaves[2].fei.sid
59
+
60
+ @dashboard.remove_tracker(fei)
61
+ @dashboard.remove_tracker(hfei)
62
+ @dashboard.remove_tracker(sfei)
63
+
64
+ assert_equal 0, @dashboard.storage.get_trackers['trackers'].size
65
+ assert_equal 0, @dashboard.get_trackers.size
66
+ end
67
+
68
+ def test_remove_string_id_tracker
69
+
70
+ @dashboard.add_tracker(nil, 'apply', 'xyz', {}, {})
71
+
72
+ assert_equal 1, @dashboard.get_trackers.size
73
+
74
+ @dashboard.remove_tracker('xyz')
75
+
76
+ assert_equal 0, @dashboard.get_trackers.size
77
+ end
78
+ end
79
+
@@ -218,19 +218,18 @@ class FtStorage < Test::Unit::TestCase
218
218
  def test_put_sequence
219
219
 
220
220
  revs = []
221
- put_ats = []
222
221
  doc = { '_id' => 'putseq', 'type' => 'errors' }
223
222
 
224
223
  77.times do |i|
225
224
 
226
- @s.put(doc)
225
+ r = @s.put(doc)
227
226
  doc = @s.get('errors', 'putseq')
228
227
 
229
228
  revs << doc['_rev']
230
- put_ats << doc['put_at']
231
229
 
230
+ assert_nil r
231
+ assert_not_nil doc['put_at']
232
232
  assert_equal i + 1, revs.uniq.size
233
- assert_equal i + 1, put_ats.uniq.size
234
233
  end
235
234
  end
236
235
 
@@ -78,7 +78,7 @@ class UtWaitLoggerTest < Test::Unit::TestCase
78
78
  assert %w[ terminated error_intercepted ].include?(r['action'])
79
79
  end
80
80
 
81
- def test_or_error
81
+ def test_or_error_when_error
82
82
 
83
83
  @engine.register :alpha, Ruote::NullParticipant
84
84
 
@@ -91,8 +91,6 @@ class UtWaitLoggerTest < Test::Unit::TestCase
91
91
  error 'oh crap'
92
92
  end
93
93
 
94
- #@engine.noisy = true
95
-
96
94
  i0 = @engine.launch(d0)
97
95
  i1 = @engine.launch(d1)
98
96
 
@@ -102,6 +100,46 @@ class UtWaitLoggerTest < Test::Unit::TestCase
102
100
  assert_equal 'error_intercepted', r['action']
103
101
  end
104
102
 
103
+ def test_or_error_when_alpha
104
+
105
+ @engine.register :alpha, Ruote::NullParticipant
106
+
107
+ d0 = Ruote.define do
108
+ alpha
109
+ end
110
+
111
+ i0 = @engine.launch(d0)
112
+
113
+ r = @engine.wait_for(:alpha, :or_error)
114
+
115
+ assert_equal 'dispatch', r['action']
116
+ assert_equal 'alpha', r['participant_name']
117
+ end
118
+
119
+ # this test will *sometimes* fail with WaitLogger#check_waiting
120
+ # in revision 92adc70950087637ec76fa394f9bb149fd8a61f4 and earlier
121
+ # due to an elusive race condition that is not possible to replicate
122
+ # in this test.
123
+ # with the current code (as of this writing) it will never fail
124
+ def test_or_error_when_alpha_multiple_interests
125
+
126
+ @engine.register :alpha, Ruote::NoOpParticipant
127
+ @engine.register :bravo, Ruote::NullParticipant
128
+
129
+ d0 = Ruote.define do
130
+ alpha
131
+ bravo
132
+ end
133
+
134
+ i0 = @engine.launch(d0)
135
+
136
+ r0 = @engine.wait_for(:alpha, :or_error)
137
+ r1 = @engine.wait_for(:bravo)
138
+
139
+ assert_equal 'dispatch', r1['action']
140
+ assert_equal 'bravo', r1['participant_name']
141
+ end
142
+
105
143
  def test_wait_for_hash
106
144
 
107
145
  #@engine.noisy = true
@@ -53,5 +53,35 @@ class UtMiscTest < Test::Unit::TestCase
53
53
  assert_not_equal a.object_id, b.object_id
54
54
  assert_equal 'hello', b.instance_variable_get(:@s)
55
55
  end
56
+
57
+ def test_camelize
58
+
59
+ assert_equal(
60
+ 'alphaBravoCharly', Ruote.camelize('alpha_bravo_charly'))
61
+ assert_equal(
62
+ 'AlphaBravoCharly', Ruote.camelize('alpha_bravo_charly', true))
63
+ end
64
+
65
+ def test_decamelize
66
+
67
+ assert_equal(
68
+ 'alpha_bravo_charly', Ruote.decamelize('alphaBravoCharly'))
69
+ assert_equal(
70
+ 'alpha_bravo_charly', Ruote.decamelize('AlphaBravoCharly'))
71
+ end
72
+
73
+ def test_insp
74
+
75
+ assert_equal(
76
+ '{a: [a, b], c: 3, d: true}',
77
+ Ruote.insp({ 'a' => %w[ a b ], 'c' => 3, 'd' => true }))
78
+ end
79
+
80
+ def test_pps
81
+
82
+ assert_equal(
83
+ "{\"a\"=>[\"a\", \"b\"], \"c\"=>3, \"d\"=>true}\n",
84
+ Ruote.pps({ 'a' => %w[ a b ], 'c' => 3, 'd' => true }))
85
+ end
56
86
  end
57
87
 
@@ -7,149 +7,150 @@
7
7
 
8
8
  require File.expand_path('../../test_helper', __FILE__)
9
9
 
10
- module Ruote; end
10
+ require 'ruote/fei'
11
+ require 'ruote/merge'
12
+ require 'ruote/extract'
11
13
  require 'ruote/exp/flow_expression'
12
- require 'ruote/exp/merge'
14
+ require 'ruote/exp/fe_concurrence'
13
15
 
14
16
 
15
17
  class MergeTest < Test::Unit::TestCase
16
18
 
17
- class Merger < Ruote::Exp::FlowExpression
18
- include Ruote::Exp::MergeMixin
19
+ class Merger < Ruote::Exp::ConcurrenceExpression
19
20
  def initialize
20
21
  end
21
22
  def tree
22
23
  [ 'nada', {}, [] ]
23
24
  end
25
+ public :merge_workitems
24
26
  end
25
27
 
26
- def new_workitem(fields)
28
+ def new_workitem(expid, fields)
27
29
 
28
- { 'fields' => fields }
30
+ {
31
+ 'fei' => {
32
+ 'engine' => 'e', 'wfid' => '12', 'subid' => '34', 'expid' => expid
33
+ },
34
+ 'fields' => fields
35
+ }
29
36
  end
30
37
 
31
38
  def new_workitems
32
39
 
33
40
  [
34
- new_workitem('a' => 0, 'b' => -1),
35
- new_workitem('a' => 1)
41
+ new_workitem('0_0', 'a' => 0, 'b' => -1),
42
+ new_workitem('0_1', 'a' => 1)
36
43
  ]
37
44
  end
38
45
 
39
46
  def test_override
40
47
 
41
48
  assert_equal(
42
- { 'fields' => { 'a' => 1 } },
43
- Merger.new.merge_workitems(new_workitems, 'override'))
49
+ { 'a' => 1 },
50
+ Merger.new.merge_workitems(new_workitems, 'override')['fields'])
44
51
  assert_equal(
45
- { 'fields' => { 'a' => 0, 'b' => -1 } },
46
- Merger.new.merge_workitems(new_workitems.reverse, 'override'))
52
+ { 'a' => 0, 'b' => -1 },
53
+ Merger.new.merge_workitems(new_workitems.reverse, 'override')['fields'])
47
54
  end
48
55
 
49
56
  def test_mix
50
57
 
51
58
  assert_equal(
52
- { 'fields' => { 'a' => 1, 'b' => -1 } },
53
- Merger.new.merge_workitems(new_workitems, 'mix'))
59
+ { 'a' => 1, 'b' => -1 },
60
+ Merger.new.merge_workitems(new_workitems, 'mix')['fields'])
54
61
  assert_equal(
55
- { 'fields' => { 'a' => 0, 'b' => -1 } },
56
- Merger.new.merge_workitems(new_workitems.reverse, 'mix'))
62
+ { 'a' => 0, 'b' => -1 },
63
+ Merger.new.merge_workitems(new_workitems.reverse, 'mix')['fields'])
57
64
  end
58
65
 
59
66
  def test_isolate
60
67
 
61
68
  assert_equal(
62
- { 'fields' => {
63
- '0' => { 'a' => 0, 'b' => -1 },
64
- '1' => { 'a' => 1 }
65
- } },
66
- Merger.new.merge_workitems(new_workitems, 'isolate'))
69
+ { '0' => { 'a' => 0, 'b' => -1 }, '1' => { 'a' => 1 } },
70
+ Merger.new.merge_workitems(new_workitems, 'isolate')['fields'])
67
71
  assert_equal(
68
- { 'fields' => {
69
- '0' => { 'a' => 1 },
70
- '1' => { 'a' => 0, 'b' => -1 }
71
- } },
72
- Merger.new.merge_workitems(new_workitems.reverse, 'isolate'))
72
+ { '1' => { 'a' => 1 }, '0' => { 'a' => 0, 'b' => -1 } },
73
+ Merger.new.merge_workitems(new_workitems.reverse, 'isolate')['fields'])
73
74
  end
74
75
 
75
76
  def test_stack
76
77
 
77
78
  assert_equal(
78
- { 'fields' => {
79
- 'stack' => [ { 'a' => 0, 'b' => -1 }, { 'a' => 1 } ],
80
- 'stack_attributes' => {}
81
- } },
82
- Merger.new.merge_workitems(new_workitems, 'stack'))
79
+ { 'stack' => [ { 'a' => 0, 'b' => -1 }, { 'a' => 1 } ] },
80
+ Merger.new.merge_workitems(new_workitems, 'stack')['fields'])
83
81
  assert_equal(
84
- { 'fields' => {
85
- 'stack' => [ { 'a' => 1 }, { 'a' => 0, 'b' => -1 } ],
86
- 'stack_attributes' => {}
87
- } },
88
- Merger.new.merge_workitems(new_workitems.reverse, 'stack'))
82
+ { 'stack' => [ { 'a' => 1 }, { 'a' => 0, 'b' => -1 } ] },
83
+ Merger.new.merge_workitems(new_workitems.reverse, 'stack')['fields'])
89
84
  end
90
85
 
91
86
  def test_unknown
92
87
 
93
88
  assert_equal(
94
- { 'fields' => { 'a' => 0, 'b' => -1 } },
95
- Merger.new.merge_workitems(new_workitems, '???'))
89
+ { 'a' => 0, 'b' => -1 },
90
+ Merger.new.merge_workitems(new_workitems, '???')['fields'])
96
91
  assert_equal(
97
- { 'fields' => { 'a' => 1 } },
98
- Merger.new.merge_workitems(new_workitems.reverse, '???'))
92
+ { 'a' => 1 },
93
+ Merger.new.merge_workitems(new_workitems.reverse, '???')['fields'])
99
94
  end
100
95
 
101
96
  def test_union
102
97
 
103
98
  workitems = [
104
- new_workitem('a' => 0, 'b' => [ 'x', 'y' ], 'c' => { 'aa' => 'bb' }),
105
- new_workitem('a' => 1, 'b' => [ 'y', 'z' ], 'c' => { 'cc' => 'dd' })
99
+ new_workitem(
100
+ '0_0', 'a' => 0, 'b' => [ 'x', 'y' ], 'c' => { 'aa' => 'bb' }),
101
+ new_workitem(
102
+ '0_1', 'a' => 1, 'b' => [ 'y', 'z' ], 'c' => { 'cc' => 'dd' })
106
103
  ]
107
104
 
108
105
  assert_equal(
109
- { 'fields' => {
106
+ {
110
107
  'a' => 1,
111
108
  'b' => [ 'x', 'y', 'z' ],
112
109
  'c' => { 'aa' => 'bb', 'cc' => 'dd' }
113
- } },
114
- Merger.new.merge_workitems(workitems, 'union'))
110
+ },
111
+ Merger.new.merge_workitems(workitems, 'union')['fields'])
115
112
  end
116
113
 
117
114
  def test_concat
118
115
 
119
116
  workitems = [
120
- new_workitem('a' => 0, 'b' => [ 'x', 'y' ], 'c' => { 'aa' => 'bb' }),
121
- new_workitem('a' => 1, 'b' => [ 'y', 'z' ], 'c' => { 'cc' => 'dd' })
117
+ new_workitem(
118
+ '0_0', 'a' => 0, 'b' => [ 'x', 'y' ], 'c' => { 'aa' => 'bb' }),
119
+ new_workitem(
120
+ '0_1', 'a' => 1, 'b' => [ 'y', 'z' ], 'c' => { 'cc' => 'dd' })
122
121
  ]
123
122
 
124
123
  assert_equal(
125
- { 'fields' => {
124
+ {
126
125
  'a' => 1,
127
126
  'b' => [ 'x', 'y', 'y', 'z' ],
128
127
  'c' => { 'aa' => 'bb', 'cc' => 'dd' }
129
- } },
130
- Merger.new.merge_workitems(workitems, 'concat'))
128
+ },
129
+ Merger.new.merge_workitems(workitems, 'concat')['fields'])
131
130
  end
132
131
 
133
132
  def test_deep
134
133
 
135
134
  workitems = [
136
135
  new_workitem(
136
+ '0_0',
137
137
  'a' => 0,
138
138
  'b' => [ 'x', 'y' ],
139
139
  'c' => { 'aa' => 'bb', 'cc' => { 'a' => 'b' } }),
140
140
  new_workitem(
141
+ '0_1',
141
142
  'a' => 1,
142
143
  'b' => [ 'y', 'z' ],
143
144
  'c' => { 'dd' => 'ee', 'cc' => { 'c' => 'd' } })
144
145
  ]
145
146
 
146
147
  assert_equal(
147
- { 'fields' => {
148
+ {
148
149
  'a' => 1,
149
150
  'b' => [ 'x', 'y', 'y', 'z' ],
150
151
  'c' => { 'aa' => 'bb', 'cc' => { 'a' => 'b', 'c' => 'd' }, 'dd' => 'ee' }
151
- } },
152
- Merger.new.merge_workitems(workitems, 'deep'))
152
+ },
153
+ Merger.new.merge_workitems(workitems, 'deep')['fields'])
153
154
  end
154
155
  end
155
156