bumbleworks 0.0.48 → 0.0.50
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -1
- data/lib/bumbleworks.rb +9 -8
- data/lib/bumbleworks/configuration.rb +8 -5
- data/lib/bumbleworks/entity.rb +88 -0
- data/lib/bumbleworks/participant.rb +6 -7
- data/lib/bumbleworks/participant/base.rb +11 -0
- data/lib/bumbleworks/participant/entity_interactor.rb +29 -0
- data/lib/bumbleworks/participant/error_handler.rb +14 -0
- data/lib/bumbleworks/participant/local_participant.rb +11 -0
- data/lib/bumbleworks/participant/storage_participant.rb +11 -0
- data/lib/bumbleworks/process.rb +64 -0
- data/lib/bumbleworks/ruote.rb +12 -4
- data/lib/bumbleworks/support.rb +3 -5
- data/lib/bumbleworks/task.rb +6 -4
- data/lib/bumbleworks/{tasks → task}/base.rb +1 -1
- data/lib/bumbleworks/task/finder.rb +39 -3
- data/lib/bumbleworks/version.rb +1 -1
- data/spec/fixtures/entities/furby.rb +30 -0
- data/spec/integration/entity_spec.rb +49 -0
- data/spec/integration/history_storage_spec.rb +4 -4
- data/spec/integration/sample_application_spec.rb +8 -2
- data/spec/lib/bumbleworks/entity_spec.rb +208 -0
- data/spec/lib/bumbleworks/{participant_spec.rb → participant/base_spec.rb} +3 -3
- data/spec/lib/bumbleworks/participant/entity_interactor_spec.rb +91 -0
- data/spec/lib/bumbleworks/{error_handler_participant_spec.rb → participant/error_handler_spec.rb} +1 -1
- data/spec/lib/bumbleworks/{local_participant_spec.rb → participant/local_participant_spec.rb} +1 -1
- data/spec/lib/bumbleworks/process_spec.rb +147 -0
- data/spec/lib/bumbleworks/ruote/exp/broadcast_event_expression_spec.rb +1 -1
- data/spec/lib/bumbleworks/ruote/exp/wait_for_event_expression_spec.rb +3 -3
- data/spec/lib/bumbleworks/ruote_spec.rb +28 -21
- data/spec/lib/bumbleworks/task/finder_spec.rb +9 -0
- data/spec/lib/bumbleworks/task_spec.rb +98 -3
- data/spec/lib/bumbleworks_spec.rb +14 -7
- data/spec/spec_helper.rb +0 -1
- data/spec/support/process_testing_helpers.rb +9 -0
- metadata +34 -13
- data/lib/bumbleworks/error_handler_participant.rb +0 -12
- data/lib/bumbleworks/local_participant.rb +0 -9
- data/lib/bumbleworks/storage_participant.rb +0 -9
@@ -0,0 +1,147 @@
|
|
1
|
+
describe Bumbleworks::Process do
|
2
|
+
before :each do
|
3
|
+
Bumbleworks.reset!
|
4
|
+
Bumbleworks.storage = {}
|
5
|
+
Bumbleworks::Ruote.register_participants
|
6
|
+
Bumbleworks.start_worker!
|
7
|
+
|
8
|
+
Bumbleworks.define_process 'going_to_the_dance' do
|
9
|
+
concurrence do
|
10
|
+
wait_for_event :an_invitation
|
11
|
+
await :left_tag => 'a_friend'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
Bumbleworks.define_process 'straightening_the_rocks' do
|
15
|
+
concurrence do
|
16
|
+
wait_for_event :rock_caliper_delivery
|
17
|
+
wait_for_event :speedos
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.new' do
|
23
|
+
it 'sets workflow id' do
|
24
|
+
bp = described_class.new('apples')
|
25
|
+
bp.id.should == 'apples'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#wfid' do
|
30
|
+
it 'is aliased to id' do
|
31
|
+
bp = described_class.new('smorgatoof')
|
32
|
+
bp.wfid.should == 'smorgatoof'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#tasks' do
|
37
|
+
it 'returns task query filtered for this process' do
|
38
|
+
bp = described_class.new('chumpy')
|
39
|
+
Bumbleworks::Task.stub(:for_process).with('chumpy').and_return(:my_task_query)
|
40
|
+
bp.tasks.should == :my_task_query
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#trackers' do
|
45
|
+
it 'lists all trackers this process is waiting on' do
|
46
|
+
bp1 = Bumbleworks.launch!('going_to_the_dance')
|
47
|
+
bp2 = Bumbleworks.launch!('straightening_the_rocks')
|
48
|
+
wait_until { bp1.trackers.count == 2 && bp2.trackers.count == 2 }
|
49
|
+
bp1.trackers.map { |t| t['msg']['fei']['wfid'] }.should == [bp1.wfid, bp1.wfid]
|
50
|
+
bp2.trackers.map { |t| t['msg']['fei']['wfid'] }.should == [bp2.wfid, bp2.wfid]
|
51
|
+
bp1.trackers.map { |t| t['action'] }.should == ['left_tag', 'left_tag']
|
52
|
+
bp2.trackers.map { |t| t['action'] }.should == ['left_tag', 'left_tag']
|
53
|
+
bp1.trackers.map { |t| t['conditions']['tag'] }.should == [['an_invitation'], ['a_friend']]
|
54
|
+
bp2.trackers.map { |t| t['conditions']['tag'] }.should == [['rock_caliper_delivery'], ['speedos']]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#all_subscribed_tags' do
|
59
|
+
it 'lists all tags this process is waiting on' do
|
60
|
+
bp1 = Bumbleworks.launch!('going_to_the_dance')
|
61
|
+
bp2 = Bumbleworks.launch!('straightening_the_rocks')
|
62
|
+
wait_until { bp1.trackers.count == 2 && bp2.trackers.count == 2 }
|
63
|
+
bp1.all_subscribed_tags.should == { :global => ['an_invitation'], bp1.wfid => ['a_friend'] }
|
64
|
+
bp2.all_subscribed_tags.should == { :global => ['rock_caliper_delivery', 'speedos'] }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#subscribed_events' do
|
69
|
+
it 'lists all events (global tags) this process is waiting on' do
|
70
|
+
bp1 = Bumbleworks.launch!('going_to_the_dance')
|
71
|
+
bp2 = Bumbleworks.launch!('straightening_the_rocks')
|
72
|
+
wait_until { bp1.trackers.count == 2 && bp2.trackers.count == 2 }
|
73
|
+
bp1.subscribed_events.should == ['an_invitation']
|
74
|
+
bp2.subscribed_events.should == ['rock_caliper_delivery', 'speedos']
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#is_waiting_for?' do
|
79
|
+
it 'returns true if event is in subscribed events' do
|
80
|
+
bp = described_class.new('whatever')
|
81
|
+
bp.stub(:subscribed_events => ['ghosts', 'mouses'])
|
82
|
+
bp.is_waiting_for?('mouses').should be_true
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'converts symbolized queries' do
|
86
|
+
bp = described_class.new('whatever')
|
87
|
+
bp.stub(:subscribed_events => ['ghosts', 'mouses'])
|
88
|
+
bp.is_waiting_for?(:ghosts).should be_true
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'returns false if event is not in subscribed events' do
|
92
|
+
bp = described_class.new('whatever')
|
93
|
+
bp.stub(:subscribed_events => ['ghosts', 'mouses'])
|
94
|
+
bp.is_waiting_for?('organs').should be_false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#kill!' do
|
99
|
+
it 'kills process' do
|
100
|
+
bp = described_class.new('frogheads')
|
101
|
+
Bumbleworks.should_receive(:kill_process!).with('frogheads')
|
102
|
+
bp.kill!
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '#cancel!' do
|
107
|
+
it 'cancels process' do
|
108
|
+
bp = described_class.new('frogheads')
|
109
|
+
Bumbleworks.should_receive(:cancel_process!).with('frogheads')
|
110
|
+
bp.cancel!
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#==' do
|
115
|
+
it 'returns true if other object has same wfid' do
|
116
|
+
bp1 = described_class.new('in_da_sky')
|
117
|
+
bp2 = described_class.new('in_da_sky')
|
118
|
+
bp1.should == bp2
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe '#process_status' do
|
123
|
+
it 'returns a process_status instance for the wfid' do
|
124
|
+
bp = described_class.new('frogheads')
|
125
|
+
Bumbleworks.dashboard.stub(:process).with('frogheads').and_return(:the_status)
|
126
|
+
bp.process_status.should == :the_status
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '#method_missing' do
|
131
|
+
it 'calls method on object returned by #process_status' do
|
132
|
+
ps = double('process_status')
|
133
|
+
ps.stub(:nuffle).with(:yay).and_return(:its_a_me)
|
134
|
+
bp = described_class.new('frogheads')
|
135
|
+
bp.stub(:process_status => ps)
|
136
|
+
bp.nuffle(:yay).should == :its_a_me
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'falls back to method missing if no process status method' do
|
140
|
+
bp = described_class.new('blah')
|
141
|
+
bp.stub(:process_status => double('process status'))
|
142
|
+
expect {
|
143
|
+
bp.kerplunk!(:oh_no)
|
144
|
+
}.to raise_error
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -18,7 +18,7 @@ describe Ruote::Exp::BroadcastEventExpression do
|
|
18
18
|
|
19
19
|
waiter = Bumbleworks.launch!('waiter')
|
20
20
|
sender = Bumbleworks.launch!('sender')
|
21
|
-
Bumbleworks.dashboard.wait_for(waiter)
|
21
|
+
Bumbleworks.dashboard.wait_for(waiter.wfid)
|
22
22
|
@tracer.should == ['amazing']
|
23
23
|
end
|
24
24
|
end
|
@@ -33,7 +33,7 @@ describe Ruote::Exp::WaitForEventExpression do
|
|
33
33
|
|
34
34
|
waiter = Bumbleworks.launch!('waiter')
|
35
35
|
sender = Bumbleworks.launch!('sender')
|
36
|
-
Bumbleworks.dashboard.wait_for(waiter)
|
36
|
+
Bumbleworks.dashboard.wait_for(waiter.wfid)
|
37
37
|
@tracer.should == ['get ready', 'oh my gosh almost there', 'hello', 'yay', 'yay2']
|
38
38
|
end
|
39
39
|
|
@@ -53,7 +53,7 @@ describe Ruote::Exp::WaitForEventExpression do
|
|
53
53
|
sender1 = Bumbleworks.launch!('sender', 'not_special' => 1)
|
54
54
|
sender2 = Bumbleworks.launch!('sender', 'special' => 3)
|
55
55
|
|
56
|
-
Bumbleworks.dashboard.wait_for(waiter3)
|
56
|
+
Bumbleworks.dashboard.wait_for(waiter3.wfid)
|
57
57
|
@tracer.should == ['specials! 3']
|
58
58
|
end
|
59
59
|
|
@@ -73,7 +73,7 @@ describe Ruote::Exp::WaitForEventExpression do
|
|
73
73
|
sender1 = Bumbleworks.launch!('sender', 'entity_type' => 'Pigeon', 'entity_id' => '13-6zoop')
|
74
74
|
sender2 = Bumbleworks.launch!('sender', 'entity_type' => 'Rhubarb', 'entity_id' => 'spitpickle-4boof')
|
75
75
|
|
76
|
-
Bumbleworks.dashboard.wait_for(waiter3)
|
76
|
+
Bumbleworks.dashboard.wait_for(waiter3.wfid)
|
77
77
|
@tracer.should == ['entities! Rhubarb,spitpickle-4boof']
|
78
78
|
end
|
79
79
|
end
|
@@ -13,11 +13,11 @@ describe Bumbleworks::Ruote do
|
|
13
13
|
Bumbleworks.define_process 'do_nothing' do
|
14
14
|
lazy_guy :task => 'absolutely_nothing'
|
15
15
|
end
|
16
|
-
|
16
|
+
process = Bumbleworks.launch!('do_nothing')
|
17
17
|
Bumbleworks.dashboard.wait_for(:lazy_guy)
|
18
|
-
Bumbleworks.dashboard.process(wfid).should_not be_nil
|
19
|
-
described_class.cancel_process!(wfid)
|
20
|
-
Bumbleworks.dashboard.process(wfid).should be_nil
|
18
|
+
Bumbleworks.dashboard.process(process.wfid).should_not be_nil
|
19
|
+
described_class.cancel_process!(process.wfid)
|
20
|
+
Bumbleworks.dashboard.process(process.wfid).should be_nil
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'times out if process is not cancelled in time' do
|
@@ -29,11 +29,11 @@ describe Bumbleworks::Ruote do
|
|
29
29
|
wait '1s'
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
32
|
+
process = Bumbleworks.launch!('time_hog')
|
33
33
|
Bumbleworks.dashboard.wait_for(:pigheaded)
|
34
|
-
Bumbleworks.dashboard.process(wfid).should_not be_nil
|
34
|
+
Bumbleworks.dashboard.process(process.wfid).should_not be_nil
|
35
35
|
expect {
|
36
|
-
described_class.cancel_process!(wfid, :timeout => 0.5)
|
36
|
+
described_class.cancel_process!(process.wfid, :timeout => 0.5)
|
37
37
|
}.to raise_error(Bumbleworks::Ruote::CancelTimeout)
|
38
38
|
end
|
39
39
|
end
|
@@ -52,11 +52,11 @@ describe Bumbleworks::Ruote do
|
|
52
52
|
wait '10s'
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
55
|
+
process = Bumbleworks.launch!('do_nothing')
|
56
56
|
Bumbleworks.dashboard.wait_for(:lazy_guy)
|
57
|
-
Bumbleworks.dashboard.process(wfid).should_not be_nil
|
58
|
-
described_class.kill_process!(wfid)
|
59
|
-
Bumbleworks.dashboard.process(wfid).should be_nil
|
57
|
+
Bumbleworks.dashboard.process(process.wfid).should_not be_nil
|
58
|
+
described_class.kill_process!(process.wfid)
|
59
|
+
Bumbleworks.dashboard.process(process.wfid).should be_nil
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'times out if process is not killed in time' do
|
@@ -235,7 +235,10 @@ describe Bumbleworks::Ruote do
|
|
235
235
|
described_class.register_participants
|
236
236
|
described_class.start_worker!
|
237
237
|
described_class.dashboard.participant_list.map(&:classname).should == [
|
238
|
-
'Bumbleworks::
|
238
|
+
'Bumbleworks::Participant::ErrorHandler',
|
239
|
+
'Bumbleworks::Participant::EntityInteractor',
|
240
|
+
'Bumbleworks::Participant::StorageParticipant'
|
241
|
+
]
|
239
242
|
Bumbleworks.dashboard.on_error.flatten[2].should == 'error_handler_participant'
|
240
243
|
end
|
241
244
|
end
|
@@ -279,9 +282,13 @@ describe Bumbleworks::Ruote do
|
|
279
282
|
|
280
283
|
described_class.dashboard.participant_list.should be_empty
|
281
284
|
described_class.register_participants ®istration_block
|
282
|
-
described_class.dashboard.participant_list.should have(
|
285
|
+
described_class.dashboard.participant_list.should have(6).items
|
283
286
|
described_class.dashboard.participant_list.map(&:classname).should == [
|
284
|
-
'Bumbleworks::
|
287
|
+
'Bumbleworks::Participant::ErrorHandler',
|
288
|
+
'Bumbleworks::Participant::EntityInteractor',
|
289
|
+
'BeesHoney', 'MapleSyrup', 'NewCatchall',
|
290
|
+
'Bumbleworks::Participant::StorageParticipant'
|
291
|
+
]
|
285
292
|
end
|
286
293
|
|
287
294
|
it 'does not add storage participant catchall if already exists' do
|
@@ -292,25 +299,25 @@ describe Bumbleworks::Ruote do
|
|
292
299
|
|
293
300
|
described_class.dashboard.participant_list.should be_empty
|
294
301
|
described_class.register_participants ®istration_block
|
295
|
-
described_class.dashboard.participant_list.should have(
|
302
|
+
described_class.dashboard.participant_list.should have(4).items
|
296
303
|
described_class.dashboard.participant_list.map(&:classname).should == [
|
297
|
-
'Bumbleworks::
|
304
|
+
'Bumbleworks::Participant::ErrorHandler', 'Bumbleworks::Participant::EntityInteractor', 'BeesHoney', 'Ruote::StorageParticipant'
|
298
305
|
]
|
299
306
|
end
|
300
307
|
|
301
308
|
it 'adds catchall and error_handler participants if block is nil' do
|
302
309
|
described_class.dashboard.participant_list.should be_empty
|
303
310
|
described_class.register_participants &nil
|
304
|
-
described_class.dashboard.participant_list.should have(
|
311
|
+
described_class.dashboard.participant_list.should have(3).item
|
305
312
|
described_class.dashboard.participant_list.map(&:classname).should ==
|
306
|
-
['Bumbleworks::
|
313
|
+
['Bumbleworks::Participant::ErrorHandler', 'Bumbleworks::Participant::EntityInteractor', 'Bumbleworks::Participant::StorageParticipant']
|
307
314
|
end
|
308
315
|
end
|
309
316
|
|
310
317
|
describe '.register_error_handler', dev:true do
|
311
318
|
it 'registers the error handler participant' do
|
312
319
|
described_class.register_error_handler
|
313
|
-
Bumbleworks.dashboard.participant_list.map(&:classname).should include('Bumbleworks::
|
320
|
+
Bumbleworks.dashboard.participant_list.map(&:classname).should include('Bumbleworks::Participant::ErrorHandler')
|
314
321
|
end
|
315
322
|
|
316
323
|
it 'it sets the global Ruote on_error to the error_handler_participant' do
|
@@ -324,7 +331,7 @@ describe Bumbleworks::Ruote do
|
|
324
331
|
end
|
325
332
|
described_class.register_error_handler
|
326
333
|
Bumbleworks.dashboard.participant_list.map(&:classname).should ==
|
327
|
-
['Whatever', 'Bumbleworks::StorageParticipant']
|
334
|
+
['Bumbleworks::Participant::EntityInteractor', 'Whatever', 'Bumbleworks::Participant::StorageParticipant']
|
328
335
|
|
329
336
|
end
|
330
337
|
end
|
@@ -362,7 +369,7 @@ describe Bumbleworks::Ruote do
|
|
362
369
|
described_class.dashboard.participant_list.should be_empty
|
363
370
|
described_class.launch('foo')
|
364
371
|
described_class.dashboard.participant_list.should have(1).item
|
365
|
-
described_class.dashboard.participant_list.first.classname.should == 'Bumbleworks::StorageParticipant'
|
372
|
+
described_class.dashboard.participant_list.first.classname.should == 'Bumbleworks::Participant::StorageParticipant'
|
366
373
|
end
|
367
374
|
end
|
368
375
|
|
@@ -31,4 +31,13 @@ describe Bumbleworks::Task::Finder do
|
|
31
31
|
Object.send(:remove_const, :MyOwnTask)
|
32
32
|
end
|
33
33
|
end
|
34
|
+
|
35
|
+
describe '#available' do
|
36
|
+
it 'adds both unclaimed and completable filters' do
|
37
|
+
query = Bumbleworks::Task::Finder.new
|
38
|
+
query.should_receive(:unclaimed).and_return(query)
|
39
|
+
query.should_receive(:completable).and_return(query)
|
40
|
+
query.available
|
41
|
+
end
|
42
|
+
end
|
34
43
|
end
|
@@ -131,7 +131,7 @@ describe Bumbleworks::Task do
|
|
131
131
|
it 'extends with base module and task module' do
|
132
132
|
task = described_class.new(workflow_item)
|
133
133
|
task.should_receive(:task_module).and_return(:task_module_double)
|
134
|
-
task.should_receive(:extend).with(Bumbleworks::
|
134
|
+
task.should_receive(:extend).with(Bumbleworks::Task::Base).ordered
|
135
135
|
task.should_receive(:extend).with(:task_module_double).ordered
|
136
136
|
task.extend_module
|
137
137
|
end
|
@@ -139,13 +139,13 @@ describe Bumbleworks::Task do
|
|
139
139
|
it 'extends only with base module if no nickname' do
|
140
140
|
task = described_class.new(workflow_item)
|
141
141
|
task.stub(:nickname).and_return(nil)
|
142
|
-
task.should_receive(:extend).with(Bumbleworks::
|
142
|
+
task.should_receive(:extend).with(Bumbleworks::Task::Base)
|
143
143
|
task.extend_module
|
144
144
|
end
|
145
145
|
|
146
146
|
it 'extends only with base module if task module does not exist' do
|
147
147
|
task = described_class.new(workflow_item)
|
148
|
-
task.should_receive(:extend).with(Bumbleworks::
|
148
|
+
task.should_receive(:extend).with(Bumbleworks::Task::Base)
|
149
149
|
task.extend_module
|
150
150
|
end
|
151
151
|
end
|
@@ -250,6 +250,61 @@ describe Bumbleworks::Task do
|
|
250
250
|
end
|
251
251
|
end
|
252
252
|
|
253
|
+
describe '.for_processes' do
|
254
|
+
before :each do
|
255
|
+
Bumbleworks.define_process 'spunking' do
|
256
|
+
concurrence do
|
257
|
+
spunker :task => 'spunk'
|
258
|
+
nonspunker :task => 'complain'
|
259
|
+
end
|
260
|
+
end
|
261
|
+
Bumbleworks.define_process 'rooting' do
|
262
|
+
concurrence do
|
263
|
+
rooter :task => 'get_the_rooting_on'
|
264
|
+
armchair_critic :task => 'scoff'
|
265
|
+
end
|
266
|
+
end
|
267
|
+
@spunking_process = Bumbleworks.launch!('spunking')
|
268
|
+
@rooting_process_1 = Bumbleworks.launch!('rooting')
|
269
|
+
@rooting_process_2 = Bumbleworks.launch!('rooting')
|
270
|
+
Bumbleworks.dashboard.wait_for(:armchair_critic)
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'returns tasks for given processes' do
|
274
|
+
spunking_tasks = described_class.for_processes([@spunking_process])
|
275
|
+
rooting_tasks = described_class.for_processes([@rooting_process_1])
|
276
|
+
tasks_for_both = described_class.for_processes([@spunking_process, @rooting_process_1])
|
277
|
+
|
278
|
+
spunking_tasks.map(&:nickname).should =~ ['spunk', 'complain']
|
279
|
+
rooting_tasks.map(&:nickname).should =~ ['get_the_rooting_on', 'scoff']
|
280
|
+
tasks_for_both.map(&:nickname).should =~ ['spunk', 'complain', 'get_the_rooting_on', 'scoff']
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'works with process ids as well' do
|
284
|
+
spunking_tasks = described_class.for_processes([@spunking_process.id])
|
285
|
+
spunking_tasks.map(&:nickname).should =~ ['spunk', 'complain']
|
286
|
+
end
|
287
|
+
|
288
|
+
it 'returns empty array when no tasks for given process id' do
|
289
|
+
described_class.for_processes(['boop']).should be_empty
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'returns empty array if given empty array' do
|
293
|
+
described_class.for_processes([]).should be_empty
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'returns empty array if given nil' do
|
297
|
+
described_class.for_processes(nil).should be_empty
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
describe '.for_process' do
|
302
|
+
it 'acts as shortcut to .for_processes with one process' do
|
303
|
+
described_class::Finder.any_instance.should_receive(:for_processes).with([:one_guy]).and_return(:aha)
|
304
|
+
described_class.for_process(:one_guy).should == :aha
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
253
308
|
describe '.for_role' do
|
254
309
|
it 'returns all tasks for given role' do
|
255
310
|
Bumbleworks.define_process 'chalking' do
|
@@ -315,6 +370,32 @@ describe Bumbleworks::Task do
|
|
315
370
|
end
|
316
371
|
end
|
317
372
|
|
373
|
+
describe '.completable' do
|
374
|
+
it 'returns only completable tasks' do
|
375
|
+
module WuggleHandsTask
|
376
|
+
def completable?
|
377
|
+
false
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
Bumbleworks.define_process 'hand_waggling' do
|
382
|
+
concurrence do
|
383
|
+
a_fella :task => 'waggle_hands'
|
384
|
+
a_monkey :task => 'wuggle_hands'
|
385
|
+
a_lady :task => 'wiggle_hands'
|
386
|
+
end
|
387
|
+
end
|
388
|
+
Bumbleworks.launch!('hand_waggling')
|
389
|
+
Bumbleworks.dashboard.wait_for(:a_lady)
|
390
|
+
tasks = described_class.completable
|
391
|
+
tasks.should have(2).items
|
392
|
+
tasks.map { |t| [t.role, t.nickname] }.should == [
|
393
|
+
['a_fella', 'waggle_hands'],
|
394
|
+
['a_lady', 'wiggle_hands']
|
395
|
+
]
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
318
399
|
describe '.all' do
|
319
400
|
before :each do
|
320
401
|
Bumbleworks.define_process 'dog-lifecycle' do
|
@@ -668,6 +749,12 @@ describe Bumbleworks::Task do
|
|
668
749
|
|
669
750
|
describe 'chained queries' do
|
670
751
|
it 'allows for AND-ed chained finders' do
|
752
|
+
module BeProudTask
|
753
|
+
def completable?
|
754
|
+
role == 'pink'
|
755
|
+
end
|
756
|
+
end
|
757
|
+
|
671
758
|
Bumbleworks.define_process 'the_big_kachunko' do
|
672
759
|
concurrence do
|
673
760
|
red :task => 'be_really_mad'
|
@@ -690,6 +777,14 @@ describe Bumbleworks::Task do
|
|
690
777
|
tasks.should have(2).items
|
691
778
|
tasks.map(&:nickname).should =~ ['be_proud', 'be_proud']
|
692
779
|
|
780
|
+
tasks = described_class.
|
781
|
+
for_roles(['green', 'pink', 'blue']).
|
782
|
+
completable.
|
783
|
+
by_nickname('be_proud')
|
784
|
+
tasks.should have(1).items
|
785
|
+
tasks.map(&:nickname).should =~ ['be_proud']
|
786
|
+
tasks.first.role.should == 'pink'
|
787
|
+
|
693
788
|
tasks = described_class.
|
694
789
|
for_claimant('crayon_box').
|
695
790
|
for_roles(['red', 'yellow', 'green'])
|