taskinator 0.4.7 → 0.5.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/{taskinator.yml → build.yml} +2 -15
  3. data/.github/workflows/release.yml +18 -0
  4. data/CHANGELOG.md +33 -1
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +64 -69
  7. data/README.md +50 -42
  8. data/lib/taskinator/builder.rb +129 -0
  9. data/lib/taskinator/definition.rb +2 -2
  10. data/lib/taskinator/instrumentation.rb +1 -0
  11. data/lib/taskinator/persistence.rb +51 -5
  12. data/lib/taskinator/process.rb +18 -9
  13. data/lib/taskinator/queues/active_job.rb +0 -12
  14. data/lib/taskinator/queues/delayed_job.rb +0 -11
  15. data/lib/taskinator/queues/resque.rb +0 -15
  16. data/lib/taskinator/queues/sidekiq.rb +0 -13
  17. data/lib/taskinator/queues.rb +0 -5
  18. data/lib/taskinator/task.rb +9 -11
  19. data/lib/taskinator/version.rb +1 -1
  20. data/lib/taskinator.rb +0 -14
  21. data/spec/support/test_job.rb +30 -0
  22. data/spec/support/test_job_task.rb +2 -0
  23. data/spec/support/test_queue.rb +21 -15
  24. data/spec/support/test_step_task.rb +2 -0
  25. data/spec/support/test_subprocess_task.rb +2 -0
  26. data/spec/taskinator/{definition/builder_spec.rb → builder_spec.rb} +2 -2
  27. data/spec/taskinator/definition_spec.rb +32 -1
  28. data/spec/taskinator/instrumentation_spec.rb +3 -2
  29. data/spec/taskinator/persistence_spec.rb +131 -5
  30. data/spec/taskinator/process_spec.rb +11 -3
  31. data/spec/taskinator/queues/active_job_spec.rb +0 -21
  32. data/spec/taskinator/queues/delayed_job_spec.rb +0 -18
  33. data/spec/taskinator/queues/resque_spec.rb +0 -21
  34. data/spec/taskinator/queues/sidekiq_spec.rb +0 -19
  35. data/spec/taskinator/queues/test_queue_adapter_spec.rb +9 -0
  36. data/spec/taskinator/task_spec.rb +43 -25
  37. data/spec/taskinator/taskinator_spec.rb +16 -0
  38. data/spec/taskinator/test_flows_spec.rb +16 -8
  39. data/taskinator.gemspec +2 -3
  40. metadata +21 -31
  41. data/lib/taskinator/definition/builder.rb +0 -129
  42. data/lib/taskinator/log_stats.rb +0 -49
  43. data/lib/taskinator/process_worker.rb +0 -13
  44. data/lib/taskinator/xml_visitor.rb +0 -109
  45. data/spec/taskinator/process_worker_spec.rb +0 -5
  46. data/spec/taskinator/xml_visitor_spec.rb +0 -5
@@ -106,6 +106,37 @@ describe Taskinator::Definition do
106
106
  expect(subject.create_process).to be_a(Taskinator::Process)
107
107
  end
108
108
 
109
+ it "handles error" do
110
+ subject.define_process do
111
+ raise ArgumentError
112
+ end
113
+
114
+ expect {
115
+ subject.create_process
116
+ }.to raise_error(ArgumentError)
117
+ end
118
+
119
+ it "checks defined arguments provided" do
120
+ subject.define_process :arg1, :arg2 do
121
+ end
122
+
123
+ expect {
124
+ subject.create_process
125
+ }.to raise_error(ArgumentError)
126
+
127
+ expect {
128
+ subject.create_process :foo
129
+ }.to raise_error(ArgumentError)
130
+
131
+ expect {
132
+ subject.create_process :foo, :bar
133
+ }.not_to raise_error
134
+
135
+ expect {
136
+ subject.create_process :foo, :bar, :baz
137
+ }.not_to raise_error
138
+ end
139
+
109
140
  it "defaults the scope to :shared" do
110
141
  block = SpecSupport::Block.new
111
142
  allow(block).to receive(:to_proc) {
@@ -156,7 +187,7 @@ describe Taskinator::Definition do
156
187
  # if an error is raised, then the context was incorrect
157
188
  expect {
158
189
  subject.create_process
159
- }.to_not raise_error(StandardError)
190
+ }.not_to raise_error
160
191
  end
161
192
 
162
193
  context "is instrumented" do
@@ -2,8 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe Taskinator::Instrumentation, :redis => true do
4
4
 
5
- let(:definition) { TestDefinition }
6
-
7
5
  subject do
8
6
  klass = Class.new do
9
7
  include Taskinator::Persistence
@@ -15,10 +13,12 @@ describe Taskinator::Instrumentation, :redis => true do
15
13
 
16
14
  attr_reader :uuid
17
15
  attr_reader :options
16
+ attr_reader :definition
18
17
 
19
18
  def initialize
20
19
  @uuid = Taskinator.generate_uuid
21
20
  @options = { :bar => :baz }
21
+ @definition = TestDefinition
22
22
  end
23
23
  end
24
24
 
@@ -75,6 +75,7 @@ describe Taskinator::Instrumentation, :redis => true do
75
75
  expect(subject.completed_payload(:baz => :qux)).to eq(
76
76
  OpenStruct.new({
77
77
  :type => subject.class.name,
78
+ :definition => subject.definition.name,
78
79
  :process_uuid => subject.uuid,
79
80
  :process_options => {:foo => :bar},
80
81
  :uuid => subject.uuid,
@@ -46,6 +46,15 @@ describe Taskinator::Persistence, :redis => true do
46
46
  expect(subject.fetch('uuid', cache)).to eq(item)
47
47
  end
48
48
 
49
+ it "yields UnknownType" do
50
+ Taskinator.redis do |conn|
51
+ conn.hmset(*[subject.key_for("foo"), [:type, 'UnknownFoo']])
52
+ end
53
+ instance = subject.fetch("foo")
54
+ expect(instance).to be_a(Taskinator::Persistence::UnknownType)
55
+ expect(instance.type).to eq("UnknownFoo")
56
+ end
57
+
49
58
  describe "for processes" do
50
59
  let(:process) { TestProcess.new(definition) }
51
60
 
@@ -53,6 +62,19 @@ describe Taskinator::Persistence, :redis => true do
53
62
  process.save
54
63
  expect(TestProcess.fetch(process.uuid)).to eq(process)
55
64
  }
65
+
66
+ describe "unknown definition" do
67
+ it "yields UnknownType" do
68
+ Taskinator.redis do |conn|
69
+ conn.hmset(*[process.key, [:type, TestProcess.name], [:uuid, process.uuid], [:definition, 'UnknownFoo']])
70
+ end
71
+
72
+ instance = TestProcess.fetch(process.uuid)
73
+ expect(instance.uuid).to eq(process.uuid)
74
+ expect(instance.definition).to be_a(Taskinator::Persistence::UnknownType)
75
+ expect(instance.definition.type).to eq("UnknownFoo")
76
+ end
77
+ end
56
78
  end
57
79
 
58
80
  describe "for tasks" do
@@ -62,9 +84,45 @@ describe Taskinator::Persistence, :redis => true do
62
84
  it {
63
85
  process.tasks << task
64
86
  process.save
65
- expect(TestTask.fetch(task.uuid)).to eq(task)
66
- expect(TestTask.fetch(task.uuid).process).to eq(process)
87
+
88
+ instance = TestTask.fetch(task.uuid)
89
+ expect(instance).to eq(task)
90
+ expect(instance.process).to eq(process)
67
91
  }
92
+
93
+ describe "unknown job" do
94
+ let(:task) { TestJobTask.new(process, TestJob, []) }
95
+
96
+ it "yields UnknownType" do
97
+ Taskinator.redis do |conn|
98
+ conn.hmset(*[task.key, [:type, task.class.name], [:uuid, task.uuid], [:job, 'UnknownBar']])
99
+ end
100
+
101
+ instance = TestJobTask.fetch(task.uuid)
102
+ expect(instance.uuid).to eq(task.uuid)
103
+ expect(instance.job).to be_a(Taskinator::Persistence::UnknownType)
104
+ expect(instance.job.type).to eq("UnknownBar")
105
+ end
106
+ end
107
+
108
+ describe "unknown subprocess" do
109
+ let(:sub_process) { TestProcess.new(definition) }
110
+ let(:task) { TestSubProcessTask.new(process, sub_process) }
111
+
112
+ it "yields UnknownType" do
113
+ Taskinator.redis do |conn|
114
+ conn.multi do |transaction|
115
+ transaction.hmset(*[task.key, [:type, task.class.name], [:uuid, task.uuid], [:sub_process, sub_process.uuid]])
116
+ transaction.hmset(*[sub_process.key, [:type, sub_process.class.name], [:uuid, sub_process.uuid], [:definition, 'UnknownBaz']])
117
+ end
118
+ end
119
+
120
+ instance = TestSubProcessTask.fetch(task.uuid)
121
+ expect(instance.uuid).to eq(task.uuid)
122
+ expect(instance.sub_process.definition).to be_a(Taskinator::Persistence::UnknownType)
123
+ expect(instance.sub_process.definition.type).to eq("UnknownBaz")
124
+ end
125
+ end
68
126
  end
69
127
  end
70
128
  end
@@ -188,6 +246,72 @@ describe Taskinator::Persistence, :redis => true do
188
246
  end
189
247
  end
190
248
 
249
+ describe "unknown type helpers" do
250
+ subject { Taskinator::Persistence::UnknownType }
251
+
252
+ describe "#new" do
253
+ it "instantiates new module instance" do
254
+ instance = subject.new("foo")
255
+ expect(instance).to_not be_nil
256
+ expect(instance).to be_a(::Module)
257
+ end
258
+
259
+ it "yields same instance for same type" do
260
+ instance1 = subject.new("foo")
261
+ instance2 = subject.new("foo")
262
+ expect(instance1).to eq(instance2)
263
+ end
264
+ end
265
+
266
+ describe ".type" do
267
+ it {
268
+ instance = subject.new("foo")
269
+ expect(instance.type).to eq("foo")
270
+ }
271
+ end
272
+
273
+ describe ".to_s" do
274
+ it {
275
+ instance = subject.new("foo")
276
+ expect(instance.to_s).to eq("Unknown type 'foo'.")
277
+ }
278
+ end
279
+
280
+ describe ".allocate" do
281
+ it "emulates Object#allocate" do
282
+ instance = subject.new("foo")
283
+ expect(instance.allocate).to eq(instance)
284
+ end
285
+ end
286
+
287
+ describe ".accept" do
288
+ it {
289
+ instance = subject.new("foo")
290
+ expect(instance).to respond_to(:accept)
291
+ }
292
+ end
293
+
294
+ describe ".perform" do
295
+ it "raises UnknownTypeError" do
296
+ instance = subject.new("foo")
297
+ expect {
298
+ instance.perform(:foo, 1, false)
299
+ }.to raise_error(Taskinator::Persistence::UnknownTypeError)
300
+ end
301
+ end
302
+
303
+ describe "via executor" do
304
+ it "raises UnknownTypeError" do
305
+ instance = subject.new("foo")
306
+ executor = Taskinator::Executor.new(instance)
307
+
308
+ expect {
309
+ executor.foo
310
+ }.to raise_error(Taskinator::Persistence::UnknownTypeError)
311
+ end
312
+ end
313
+ end
314
+
191
315
  describe "instance methods" do
192
316
  subject {
193
317
  klass = Class.new do
@@ -207,11 +331,14 @@ describe Taskinator::Persistence, :redis => true do
207
331
  }
208
332
 
209
333
  describe "#save" do
210
- pending __FILE__
334
+ pending
211
335
  end
212
336
 
213
337
  describe "#to_xml" do
214
- pending __FILE__
338
+ it {
339
+ process = TestFlows::Task.create_process(1)
340
+ expect(process.to_xml).to match(/xml/)
341
+ }
215
342
  end
216
343
 
217
344
  describe "#key" do
@@ -426,6 +553,5 @@ describe Taskinator::Persistence, :redis => true do
426
553
  end
427
554
 
428
555
  end
429
-
430
556
  end
431
557
  end
@@ -35,6 +35,14 @@ describe Taskinator::Process do
35
35
  it { expect(subject.tasks).to be_a(Taskinator::Tasks) }
36
36
  end
37
37
 
38
+ describe "#no_tasks_defined?" do
39
+ it { expect(subject.no_tasks_defined?).to be }
40
+ it {
41
+ subject.tasks << :mock
42
+ expect(subject.no_tasks_defined?).to_not be
43
+ }
44
+ end
45
+
38
46
  describe "#to_s" do
39
47
  it { expect(subject.to_s).to match(/#{subject.uuid}/) }
40
48
  end
@@ -288,7 +296,7 @@ describe Taskinator::Process do
288
296
  subject.task_completed(task1)
289
297
  end
290
298
 
291
- it "deincrements the pending task count" do
299
+ it "decrements the pending task count" do
292
300
  tasks.each {|t| subject.tasks << t }
293
301
  task1 = tasks[0]
294
302
  task2 = tasks[1]
@@ -367,7 +375,7 @@ describe Taskinator::Process do
367
375
  subject.task_failed(tasks.first, error)
368
376
  end
369
377
 
370
- it "doesn't deincement pending task count" do
378
+ it "doesn't decrement pending task count" do
371
379
  tasks.each {|t| subject.tasks << t }
372
380
 
373
381
  expect(subject).to_not receive(:deincr_pending_tasks)
@@ -515,7 +523,7 @@ describe Taskinator::Process do
515
523
  end
516
524
  end
517
525
 
518
- it "deincrements the pending task count" do
526
+ it "decrements the pending task count" do
519
527
  tasks.each {|t| subject.tasks << t }
520
528
  task1 = tasks[0]
521
529
  task2 = tasks[1]
@@ -35,27 +35,6 @@ describe Taskinator::Queues::ActiveJobAdapter, :active_job do
35
35
  end
36
36
  end
37
37
 
38
- describe "ProcessWorker" do
39
- it "enqueues processes" do
40
- worker = adapter::ProcessWorker
41
- subject.enqueue_process(double('process', :uuid => uuid, :queue => nil))
42
-
43
- expect(worker).to have_been_enqueued.with(uuid)
44
- end
45
-
46
- it "enqueues process to specified queue" do
47
- worker = adapter::ProcessWorker
48
- subject.enqueue_process(double('process', :uuid => uuid, :queue => :other))
49
-
50
- expect(worker).to have_been_enqueued.with(uuid).on_queue(:other)
51
- end
52
-
53
- it "calls process worker" do
54
- expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
55
- adapter::ProcessWorker.new.perform(uuid)
56
- end
57
- end
58
-
59
38
  describe "TaskWorker" do
60
39
  it "enqueues tasks" do
61
40
  worker = adapter::TaskWorker
@@ -30,24 +30,6 @@ describe Taskinator::Queues::DelayedJobAdapter, :delayed_job do
30
30
  end
31
31
  end
32
32
 
33
- describe "ProcessWorker" do
34
- it "enqueues processes" do
35
- expect {
36
- subject.enqueue_process(double('process', :uuid => uuid, :queue => nil))
37
- }.to change(Delayed::Job.queue, :size).by(1)
38
- end
39
-
40
- it "enqueues process to specified queue" do
41
- subject.enqueue_process(double('process', :uuid => uuid, :queue => :other))
42
- expect(Delayed::Job.contains?(adapter::ProcessWorker, uuid, :other)).to be
43
- end
44
-
45
- it "calls process worker" do
46
- expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
47
- adapter::ProcessWorker.new(uuid).perform
48
- end
49
- end
50
-
51
33
  describe "TaskWorker" do
52
34
  it "enqueues tasks" do
53
35
  expect {
@@ -34,27 +34,6 @@ describe Taskinator::Queues::ResqueAdapter, :resque do
34
34
  end
35
35
  end
36
36
 
37
- describe "ProcessWorker" do
38
- it "enqueues processes" do
39
- worker = adapter::ProcessWorker
40
- subject.enqueue_process(double('process', :uuid => uuid, :queue => nil))
41
-
42
- expect(worker).to have_queued(uuid)
43
- end
44
-
45
- it "enqueues process to specified queue" do
46
- worker = adapter::ProcessWorker
47
- subject.enqueue_process(double('process', :uuid => uuid, :queue => :other))
48
-
49
- expect(worker).to have_queued(uuid).in(:other)
50
- end
51
-
52
- it "calls process worker" do
53
- expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
54
- adapter::ProcessWorker.perform(uuid)
55
- end
56
- end
57
-
58
37
  describe "TaskWorker" do
59
38
  it "enqueues tasks" do
60
39
  worker = adapter::TaskWorker
@@ -33,25 +33,6 @@ describe Taskinator::Queues::SidekiqAdapter, :sidekiq do
33
33
  end
34
34
  end
35
35
 
36
- describe "ProcessWorker" do
37
- it "enqueues processes" do
38
- worker = adapter::ProcessWorker
39
- process = double('process', :uuid => uuid, :queue => nil)
40
- subject.enqueue_process(process)
41
- expect(worker).to have_enqueued_sidekiq_job(process.uuid)
42
- end
43
-
44
- it "enqueues process to specified queue" do
45
- subject.enqueue_process(double('process', :uuid => uuid, :queue => :other))
46
- expect(adapter::ProcessWorker).to be_processed_in_x(:other)
47
- end
48
-
49
- it "calls process worker" do
50
- expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
51
- adapter::ProcessWorker.new.perform(uuid)
52
- end
53
- end
54
-
55
36
  describe "TaskWorker" do
56
37
  it "enqueues tasks" do
57
38
  worker = adapter::TaskWorker
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Taskinator::Queues::TestQueueAdapter do
4
+
5
+ # sanity check for the test adapter
6
+
7
+ it_should_behave_like "a queue adapter", :test_queue, Taskinator::Queues::TestQueueAdapter
8
+
9
+ end
@@ -93,6 +93,16 @@ describe Taskinator::Task do
93
93
  }
94
94
  end
95
95
 
96
+ describe "#cancel!" do
97
+ it { expect(subject).to respond_to(:cancel!) }
98
+ it {
99
+ expect(subject).to receive(:cancel)
100
+ subject.start!
101
+ subject.cancel!
102
+ expect(subject.current_state).to eq(:cancelled)
103
+ }
104
+ end
105
+
96
106
  describe "#fail!" do
97
107
  it { expect(subject).to respond_to(:fail!) }
98
108
  it {
@@ -144,6 +154,7 @@ describe Taskinator::Task do
144
154
  visitor = double('visitor')
145
155
  expect(visitor).to receive(:visit_attribute).with(:uuid)
146
156
  expect(visitor).to receive(:visit_process_reference).with(:process)
157
+ expect(visitor).to receive(:visit_type).with(:definition)
147
158
  expect(visitor).to receive(:visit_task_reference).with(:next)
148
159
  expect(visitor).to receive(:visit_args).with(:options)
149
160
  expect(visitor).to receive(:visit_attribute).with(:queue)
@@ -250,6 +261,18 @@ describe Taskinator::Task do
250
261
  expect(exec_context.options).to eq(subject.options)
251
262
  end
252
263
 
264
+ it "throws an exception for unknown definition type" do
265
+ executor = Taskinator::Executor.new(Taskinator::Persistence::UnknownType.new("Foo"), subject)
266
+
267
+ # replace the internal executor instance for the task
268
+ # with this one, so we can hook into the methods
269
+ subject.instance_eval { @executor = executor }
270
+
271
+ expect {
272
+ subject.start!
273
+ }.to raise_error(Taskinator::Persistence::UnknownTypeError)
274
+ end
275
+
253
276
  it "is instrumented" do
254
277
  instrumentation_block = SpecSupport::Block.new
255
278
 
@@ -314,36 +337,12 @@ describe Taskinator::Task do
314
337
 
315
338
  describe "#inspect" do
316
339
  it { expect(subject.inspect).to_not be_nil }
340
+ it { expect(subject.inspect).to include(definition.name) }
317
341
  end
318
342
  end
319
343
 
320
344
  describe Taskinator::Task::Job do
321
345
 
322
- module TestJob
323
- def self.perform(*args)
324
- end
325
- end
326
-
327
- class TestJobClass
328
- def perform(*args)
329
- end
330
- end
331
-
332
- module TestJobModule
333
- def self.perform(*args)
334
- end
335
- end
336
-
337
- class TestJobClassNoArgs
338
- def perform
339
- end
340
- end
341
-
342
- module TestJobModuleNoArgs
343
- def self.perform
344
- end
345
- end
346
-
347
346
  subject { Taskinator::Task.define_job_task(process, TestJob, [1, {:a => 1, :b => 2}]) }
348
347
 
349
348
  it_should_behave_like "a task", Taskinator::Task::Job
@@ -404,6 +403,22 @@ describe Taskinator::Task do
404
403
  task.start!
405
404
  }
406
405
 
406
+ it "throws an exception when unknown job type" do
407
+ task = Taskinator::Task.define_job_task(process, Taskinator::Persistence::UnknownType.new("Foo"), nil)
408
+
409
+ expect {
410
+ task.start!
411
+ }.to raise_error(Taskinator::Persistence::UnknownTypeError)
412
+ end
413
+
414
+ it "handles failure" do
415
+ task = Taskinator::Task.define_job_task(process, TestJobError, nil)
416
+
417
+ expect {
418
+ task.start!
419
+ }.to raise_error(ArgumentError)
420
+ end
421
+
407
422
  it "is instrumented" do
408
423
  allow(process).to receive(:task_completed).with(subject)
409
424
 
@@ -473,6 +488,7 @@ describe Taskinator::Task do
473
488
 
474
489
  describe "#inspect" do
475
490
  it { expect(subject.inspect).to_not be_nil }
491
+ it { expect(subject.inspect).to include(definition.name) }
476
492
  end
477
493
  end
478
494
 
@@ -582,6 +598,7 @@ describe Taskinator::Task do
582
598
  visitor = double('visitor')
583
599
  expect(visitor).to receive(:visit_attribute).with(:uuid)
584
600
  expect(visitor).to receive(:visit_process_reference).with(:process)
601
+ expect(visitor).to receive(:visit_type).with(:definition)
585
602
  expect(visitor).to receive(:visit_task_reference).with(:next)
586
603
  expect(visitor).to receive(:visit_args).with(:options)
587
604
  expect(visitor).to receive(:visit_process).with(:sub_process)
@@ -595,6 +612,7 @@ describe Taskinator::Task do
595
612
 
596
613
  describe "#inspect" do
597
614
  it { expect(subject.inspect).to_not be_nil }
615
+ it { expect(subject.inspect).to include(definition.name) }
598
616
  end
599
617
  end
600
618
 
@@ -86,6 +86,22 @@ describe Taskinator do
86
86
  end
87
87
  end
88
88
  end
89
+ end
90
+
91
+ [
92
+ Taskinator::NoOpInstrumenter,
93
+ Taskinator::ConsoleInstrumenter
94
+ ].each do |instrumenter|
95
+ describe instrumenter do
96
+ it "yields to given block" do
97
+ instance = instrumenter.new
98
+
99
+ block = SpecSupport::Block.new
100
+ expect(block).to receive(:call)
89
101
 
102
+ instance.instrument(:foo, :bar => :baz, &block)
103
+ end
104
+ end
90
105
  end
106
+
91
107
  end
@@ -98,10 +98,14 @@ describe TestFlows do
98
98
  let(:definition) { TestFlows::EmptySequentialProcessTest }
99
99
  subject { definition.create_process }
100
100
 
101
+ it "contains 3 tasks" do
102
+ expect(subject.tasks.length).to eq(3)
103
+ end
104
+
101
105
  it "invokes each task" do
102
- # this doesn't work...
103
- # expect_any_instance_of(Taskinator::Executor).to receive(:do_task_x).exactly(3).times
104
- # subject.start!
106
+ expect_any_instance_of(definition).to receive(:task_0)
107
+ expect_any_instance_of(definition).to receive(:task_1)
108
+ expect_any_instance_of(definition).to receive(:task_2)
105
109
 
106
110
  expect {
107
111
  subject.enqueue!
@@ -113,10 +117,14 @@ describe TestFlows do
113
117
  let(:definition) { TestFlows::EmptyConcurrentProcessTest }
114
118
  subject { definition.create_process }
115
119
 
120
+ it "contains 3 tasks" do
121
+ expect(subject.tasks.length).to eq(3)
122
+ end
123
+
116
124
  it "invokes each task" do
117
- # this doesn't work...
118
- # expect_any_instance_of(Taskinator::Executor).to receive(:do_task_x).exactly(3).times
119
- # subject.start!
125
+ expect_any_instance_of(definition).to receive(:task_0)
126
+ expect_any_instance_of(definition).to receive(:task_1)
127
+ expect_any_instance_of(definition).to receive(:task_2)
120
128
 
121
129
  expect {
122
130
  subject.enqueue!
@@ -173,11 +181,11 @@ describe TestFlows do
173
181
  end
174
182
 
175
183
  describe "job" do
176
-
184
+ pending
177
185
  end
178
186
 
179
187
  describe "subprocess" do
180
-
188
+ pending
181
189
  end
182
190
  end
183
191
 
data/taskinator.gemspec CHANGED
@@ -26,8 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency 'connection_pool' , '>= 2.2.0'
27
27
  spec.add_dependency 'json' , '>= 1.8.2'
28
28
  spec.add_dependency 'builder' , '>= 3.2.2'
29
- spec.add_dependency 'globalid' , '~> 0.3'
30
- spec.add_dependency 'statsd-ruby' , '~> 1.4.0'
31
- spec.add_dependency 'thwait' , '~> 0.2'
29
+ spec.add_dependency 'globalid' , '>= 0.3'
30
+ spec.add_dependency 'thwait' , '>= 0.2'
32
31
 
33
32
  end