ruote 2.3.0.1 → 2.3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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