taskinator 0.0.5 → 0.0.7
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +12 -12
- data/README.md +332 -4
- data/lib/taskinator/definition/builder.rb +7 -1
- data/lib/taskinator/definition.rb +6 -2
- data/lib/taskinator/version.rb +1 -1
- data/spec/support/test_flow.rb +2 -2
- data/spec/taskinator/definition/builder_spec.rb +23 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb55f92dd0ef5d48b4fb0d1f3d82093c59fdca7c
|
4
|
+
data.tar.gz: c87595e40a584e0913571dbc50176ae8236010d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71858572f752ee6a0572607fb70607e36a49df6334e83c5c1a477675b70f41f75cbefc04e23cefb802bac39adc1207d947d69d580954d51e9992804a7ef2aa95
|
7
|
+
data.tar.gz: a405c8209923653109f732d03601f2747cf35642ae452b44598ad78487c3c639a3ae91ba065c887116e7b47c7e512374104994a8b8c9a9f7b812e47530af5b96
|
data/Gemfile.lock
CHANGED
@@ -8,7 +8,7 @@ GIT
|
|
8
8
|
PATH
|
9
9
|
remote: .
|
10
10
|
specs:
|
11
|
-
taskinator (0.0.
|
11
|
+
taskinator (0.0.7)
|
12
12
|
connection_pool (>= 2.0.0)
|
13
13
|
json (>= 1.8.1)
|
14
14
|
redis (>= 3.0.6)
|
@@ -38,18 +38,18 @@ GEM
|
|
38
38
|
term-ansicolor
|
39
39
|
thor
|
40
40
|
debugger-linecache (1.2.0)
|
41
|
-
delayed_job (4.0.
|
41
|
+
delayed_job (4.0.4)
|
42
42
|
activesupport (>= 3.0, < 4.2)
|
43
43
|
diff-lcs (1.2.5)
|
44
44
|
docile (1.1.5)
|
45
45
|
i18n (0.6.11)
|
46
46
|
json (1.8.1)
|
47
47
|
method_source (0.8.2)
|
48
|
-
mime-types (2.
|
49
|
-
minitest (5.4.
|
48
|
+
mime-types (2.4.2)
|
49
|
+
minitest (5.4.2)
|
50
50
|
mono_logger (1.1.0)
|
51
51
|
multi_json (1.10.1)
|
52
|
-
netrc (0.7.
|
52
|
+
netrc (0.7.8)
|
53
53
|
pry (0.9.12.6)
|
54
54
|
coderay (~> 1.0)
|
55
55
|
method_source (~> 0.8)
|
@@ -82,23 +82,23 @@ GEM
|
|
82
82
|
rspec-core (~> 3.1.0)
|
83
83
|
rspec-expectations (~> 3.1.0)
|
84
84
|
rspec-mocks (~> 3.1.0)
|
85
|
-
rspec-core (3.1.
|
85
|
+
rspec-core (3.1.7)
|
86
86
|
rspec-support (~> 3.1.0)
|
87
|
-
rspec-expectations (3.1.
|
87
|
+
rspec-expectations (3.1.2)
|
88
88
|
diff-lcs (>= 1.2.0, < 2.0)
|
89
89
|
rspec-support (~> 3.1.0)
|
90
|
-
rspec-mocks (3.1.
|
90
|
+
rspec-mocks (3.1.3)
|
91
91
|
rspec-support (~> 3.1.0)
|
92
|
-
rspec-support (3.1.
|
92
|
+
rspec-support (3.1.2)
|
93
93
|
sidekiq (3.2.5)
|
94
94
|
celluloid (= 0.15.2)
|
95
95
|
connection_pool (>= 2.0.0)
|
96
96
|
json
|
97
97
|
redis (>= 3.0.6)
|
98
98
|
redis-namespace (>= 1.3.1)
|
99
|
-
simplecov (0.9.
|
99
|
+
simplecov (0.9.1)
|
100
100
|
docile (~> 1.1.0)
|
101
|
-
multi_json
|
101
|
+
multi_json (~> 1.0)
|
102
102
|
simplecov-html (~> 0.8.0)
|
103
103
|
simplecov-html (0.8.0)
|
104
104
|
sinatra (1.4.5)
|
@@ -112,7 +112,7 @@ GEM
|
|
112
112
|
thread_safe (0.3.4)
|
113
113
|
tilt (1.4.1)
|
114
114
|
timers (1.1.0)
|
115
|
-
tins (1.3.
|
115
|
+
tins (1.3.3)
|
116
116
|
tzinfo (1.2.2)
|
117
117
|
thread_safe (~> 0.1)
|
118
118
|
vegas (0.1.11)
|
data/README.md
CHANGED
@@ -69,8 +69,28 @@ module MyProcess
|
|
69
69
|
end
|
70
70
|
```
|
71
71
|
|
72
|
-
|
73
|
-
a
|
72
|
+
The `define_process` method optionally takes the list of expected arguments which are used to validate the
|
73
|
+
arguments supplied when creating a new process. These should be specified with symbols.
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
module MyProcess
|
77
|
+
extend Taskinator::Definition
|
78
|
+
|
79
|
+
# defines a process
|
80
|
+
define_process :date, :options do
|
81
|
+
# ...
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# when creating a process, 2 arguments are expected
|
86
|
+
process = MyProcess.create_process Date.today, :option_1 => true
|
87
|
+
```
|
88
|
+
|
89
|
+
NOTE: The current implementation performs a naive check on the count of arguments, but this will be
|
90
|
+
improved in subsequent versions.
|
91
|
+
|
92
|
+
Next, specify the tasks with their corresponding implementation methods, that make up the process,
|
93
|
+
using the `task` method and providing the `method` to execute for the task.
|
74
94
|
|
75
95
|
```ruby
|
76
96
|
module MyProcess
|
@@ -124,7 +144,35 @@ module MyProcess
|
|
124
144
|
end
|
125
145
|
```
|
126
146
|
|
127
|
-
|
147
|
+
It is likely that you have already have worker classes for one of the queueing libraries, such as resque or delayed_job, and wish to
|
148
|
+
reuse them for executing them in the sequence defined by the process definition.
|
149
|
+
|
150
|
+
You define a `job` step, providing the class of the worker, and them taskinator will execute that worker as part of the process definition.
|
151
|
+
The `job` step will be queued and executed on the configured queue for `delayed_job`, or that of the worker for `resque` and `sidekiq`.
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
# E.g. A resque worker
|
155
|
+
class DoSomeWork
|
156
|
+
queue :high_priority
|
157
|
+
|
158
|
+
def self.perform(arg1, arg2)
|
159
|
+
# code to do the work
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
module MyProcess
|
164
|
+
extend Taskinator::Definition
|
165
|
+
|
166
|
+
# when creating the process, supply the same arguments
|
167
|
+
# that the DoSomeWork worker expects
|
168
|
+
|
169
|
+
define_process do
|
170
|
+
job DoSomeWork
|
171
|
+
end
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
You can also define data driven tasks using the `for_each` method, which takes an iterator method name as an argument.
|
128
176
|
The iterator method yields the items to produce a parameterized task for that item. Notice that the task method
|
129
177
|
takes a parameter in this case, which will be the item provided by the iterator.
|
130
178
|
|
@@ -149,6 +197,67 @@ module MyProcess
|
|
149
197
|
end
|
150
198
|
```
|
151
199
|
|
200
|
+
It is possible to branch the process logic based on the options hash passed in when creating a process.
|
201
|
+
The `options?` method takes the options key as an argument and calls the supplied block if the option
|
202
|
+
is present and it's value is truthy.
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
module MyProcess
|
206
|
+
extend Taskinator::Definition
|
207
|
+
|
208
|
+
define_process do
|
209
|
+
|
210
|
+
option?(:some_setting) do
|
211
|
+
task :prerequisite_step
|
212
|
+
end
|
213
|
+
|
214
|
+
task :work_step
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
def prerequisite_step
|
219
|
+
# ...
|
220
|
+
end
|
221
|
+
|
222
|
+
def work_step
|
223
|
+
# ...
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
|
228
|
+
# now when creating the process, the `:some_setting` option can be used to branch the logic
|
229
|
+
process1 = MyProcess.create_process :some_setting => true
|
230
|
+
process1.tasks.count #=> 2
|
231
|
+
|
232
|
+
process2 = MyProcess.create_process
|
233
|
+
process2.tasks.count #=> 1
|
234
|
+
```
|
235
|
+
|
236
|
+
In addition, it is possible to transform the arguments used by a task or job, by including a `transform` step in the definition.
|
237
|
+
Similarly to the `for_each` method, `transform` takes a method name as an argument. The transformer method must yield the new arguments as required.
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
module MyProcess
|
241
|
+
extend Taskinator::Definition
|
242
|
+
|
243
|
+
# this process is created with a hash argument
|
244
|
+
|
245
|
+
define_process do
|
246
|
+
transform :convert_args do
|
247
|
+
task :work_step
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def convert_args(options)
|
252
|
+
yield *[options[:date_from], options[:date_to]]
|
253
|
+
end
|
254
|
+
|
255
|
+
def work_step(date_from, date_to)
|
256
|
+
# TODO: supply implementation
|
257
|
+
end
|
258
|
+
end
|
259
|
+
```
|
260
|
+
|
152
261
|
Processes can be composed of other processes too:
|
153
262
|
|
154
263
|
```ruby
|
@@ -207,6 +316,33 @@ In this example, the `work_step_begin` is executed, followed by the `work_step_a
|
|
207
316
|
the sub process `MySubProcess` is created and executed, followed by the `work_step_one_by_one` tasks which are executed sequentially and
|
208
317
|
finally the `work_step_end` is executed.
|
209
318
|
|
319
|
+
It is also possible to embed conditional logic within the process definition stages in order to produce steps based on the required logic.
|
320
|
+
All builder methods are available within the scope of the `define_process` block. These methods include `args` and `options`
|
321
|
+
which are passed into the `create_process` method of the definition.
|
322
|
+
|
323
|
+
E.g.
|
324
|
+
|
325
|
+
```ruby
|
326
|
+
module MyProcess
|
327
|
+
extend Taskinator::Definition
|
328
|
+
|
329
|
+
define_process do
|
330
|
+
task :task_1
|
331
|
+
task :task_2
|
332
|
+
task :task_3 if args[3] == 1
|
333
|
+
task :send_notification if options[:send_notification]
|
334
|
+
end
|
335
|
+
|
336
|
+
# "task" methods are omitted for brevity
|
337
|
+
|
338
|
+
end
|
339
|
+
|
340
|
+
# when creating this proces, you supply to option when calling `create_process`
|
341
|
+
# in this example, 'args' will be an array [1,2,3] and options will be a Hash {:send_notification => true}
|
342
|
+
MyProcess.create_process(1, 2, 3, :send_notification => true)
|
343
|
+
|
344
|
+
```
|
345
|
+
|
210
346
|
### Execution
|
211
347
|
|
212
348
|
A process is executed by calling the generated `create_process` method on your "process" module.
|
@@ -216,9 +352,201 @@ process = MyProcess.create_process
|
|
216
352
|
process.enqueue!
|
217
353
|
```
|
218
354
|
|
355
|
+
Or, to start immediately, call the `start!` method.
|
356
|
+
|
357
|
+
```ruby
|
358
|
+
process = MyProcess.create_process
|
359
|
+
process.start!
|
360
|
+
```
|
361
|
+
|
219
362
|
#### Arguments
|
220
363
|
|
221
|
-
|
364
|
+
Argument handling for defining and executing process definitions is where things can get trickey.
|
365
|
+
_This may be something that gets refactored down the line_.
|
366
|
+
|
367
|
+
To best understand how arguments are handled, you need to break it down into 3 phases. Namely:
|
368
|
+
|
369
|
+
* Definition,
|
370
|
+
* Creation and
|
371
|
+
* Execution
|
372
|
+
|
373
|
+
Firstly, a process definition is declarative in that the `define_process` and a mix of `sequential`, `concurrent`, `for_each`,
|
374
|
+
`task` and `job` directives provide the way to specify the sequencing of the steps for the process.
|
375
|
+
Taskinator will interprete this definition and execute each step in the desired sequence or concurrency.
|
376
|
+
|
377
|
+
Consider the following process definition:
|
378
|
+
|
379
|
+
```ruby
|
380
|
+
module MySimpleProcess
|
381
|
+
extend Taskinator::Definition
|
382
|
+
|
383
|
+
# definition
|
384
|
+
|
385
|
+
define_process do
|
386
|
+
task :work_step_1
|
387
|
+
task :work_step_2
|
388
|
+
|
389
|
+
for_each :additional_step do
|
390
|
+
task :work_step_3
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
# creation
|
395
|
+
|
396
|
+
def additional_step(options)
|
397
|
+
options.steps.each do |k, v|
|
398
|
+
yield k, v
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
# execution
|
403
|
+
|
404
|
+
def work_step_1(options)
|
405
|
+
# ...
|
406
|
+
end
|
407
|
+
|
408
|
+
def work_step_2(options)
|
409
|
+
# ...
|
410
|
+
end
|
411
|
+
|
412
|
+
def work_step_3(k, v)
|
413
|
+
# ...
|
414
|
+
end
|
415
|
+
|
416
|
+
end
|
417
|
+
```
|
418
|
+
|
419
|
+
There are three tasks; namely `:work_step_1`, `:work_step_2` and `:work_step_3`.
|
420
|
+
|
421
|
+
The third task, `:work_step_3`, is built up using the `for_each` iterator, which means that the number of `:work_step_3` tasks
|
422
|
+
will depend on how many times the `additional_step` iterator method yields to the definition.
|
423
|
+
|
424
|
+
This brings us to the creation part. When `create_process` is called on the given module, you provide arguments to it, which will get
|
425
|
+
passed onto the respective `task` and `for_each` iterator methods.
|
426
|
+
|
427
|
+
So, considering the `MySimpleProcess` module shown above, `work_step_1`, `work_step_2` and `work_step_3` methods each expect arguments.
|
428
|
+
These will ultimately come from the arguments passed into the `create_process` method.
|
429
|
+
|
430
|
+
E.g.
|
431
|
+
|
432
|
+
```ruby
|
433
|
+
|
434
|
+
# Given an options hash
|
435
|
+
options = {
|
436
|
+
:opt1 => true,
|
437
|
+
:opt2 => false,
|
438
|
+
:steps => {
|
439
|
+
:a => 1,
|
440
|
+
:b => 2,
|
441
|
+
:c => 3,
|
442
|
+
}
|
443
|
+
}
|
444
|
+
|
445
|
+
# You create the process, passing in the options hash
|
446
|
+
process = MySimpleProcess.create_process(options)
|
447
|
+
|
448
|
+
```
|
449
|
+
|
450
|
+
To best understand how the process is created, consider the following "procedural" code for how it could work.
|
451
|
+
|
452
|
+
```ruby
|
453
|
+
# A process, which maps the target and a list of steps
|
454
|
+
class Process
|
455
|
+
attr_reader :target
|
456
|
+
attr_reader :tasks
|
457
|
+
|
458
|
+
def initialize(target)
|
459
|
+
@target = target
|
460
|
+
@tasks = []
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
# A task, which maps the method to call and it's arguments
|
465
|
+
class Task
|
466
|
+
attr_reader :method
|
467
|
+
attr_reader :args
|
468
|
+
|
469
|
+
def initialize(method, args)
|
470
|
+
@method, @args = method, args
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
# Your module, with the methods which do the actual work
|
475
|
+
module MySimpleProcess
|
476
|
+
|
477
|
+
def self.work_step_1(options) ...
|
478
|
+
def self.work_step_2(options) ...
|
479
|
+
def self.work_step_3(k, v) ...
|
480
|
+
|
481
|
+
end
|
482
|
+
|
483
|
+
# Now, the creation phase of the definition
|
484
|
+
# create a process, providing the module
|
485
|
+
|
486
|
+
process = Process.new(MySimpleProcess)
|
487
|
+
|
488
|
+
# create the first and second tasks, providing the method
|
489
|
+
# for the task and it's arguments, which are the options defined above
|
490
|
+
|
491
|
+
process.tasks << Task.new(:work_step_1, options)
|
492
|
+
process.tasks << Task.new(:work_step_2, options)
|
493
|
+
|
494
|
+
# iterate over the steps hash in the options, and add the third step
|
495
|
+
# this time specify the key and value as the
|
496
|
+
# arguments for the work_step_3 method
|
497
|
+
|
498
|
+
options.steps.each do |k, v|
|
499
|
+
process.tasks << Task.new(:work_step_3, [k, v])
|
500
|
+
end
|
501
|
+
|
502
|
+
# we now have a process with the tasks defined
|
503
|
+
|
504
|
+
process.tasks #=> [<Task :method=>work_step_1, :args=>options, ...> ,
|
505
|
+
# <Task :method=>work_step_2, :args=>options, ...>,
|
506
|
+
# <Task :method=>work_step_3, :args=>[:a, 1], ...>,
|
507
|
+
# <Task :method=>work_step_3, :args=>[:b, 2], ...>,
|
508
|
+
# <Task :method=>work_step_3, :args=>[:c, 3], ...>]
|
509
|
+
|
510
|
+
```
|
511
|
+
|
512
|
+
Finally, for the execution phase, the process and tasks will act on the supplied module.
|
513
|
+
|
514
|
+
```ruby
|
515
|
+
# building out the "Process" class
|
516
|
+
class Process
|
517
|
+
#...
|
518
|
+
|
519
|
+
def execute
|
520
|
+
tasks.each {|task| task.execute(target) )
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
# and the "Task" class
|
525
|
+
class Task
|
526
|
+
#...
|
527
|
+
|
528
|
+
def execute(target)
|
529
|
+
puts "Calling '#{method}' on '#{target.name}' with #{args.inspect}..."
|
530
|
+
target.send(method, *args)
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
# executing the process iterates over each task and
|
535
|
+
# the target modules method is called with the arguments
|
536
|
+
|
537
|
+
process.execute
|
538
|
+
|
539
|
+
# Calling 'work_step_1' on 'MySimpleProcess' with {:opt1 => true, :opt2 => false, ...}
|
540
|
+
# Calling 'work_step_2' on 'MySimpleProcess' with {:opt1 => true, :opt2 => false, ...}
|
541
|
+
# Calling 'work_step_3' on 'MySimpleProcess' with [:a, 1]
|
542
|
+
# Calling 'work_step_3' on 'MySimpleProcess' with [:b, 2]
|
543
|
+
# Calling 'work_step_3' on 'MySimpleProcess' with [:c, 3]
|
544
|
+
|
545
|
+
```
|
546
|
+
|
547
|
+
In reality, each task is executed by a worker process, possibly on another host, so the execution process isn't as simple,
|
548
|
+
but this example should help you to understand conceptually how the process is executed, and how the arguments are propagated
|
549
|
+
through.
|
222
550
|
|
223
551
|
### Monitoring
|
224
552
|
|
@@ -5,14 +5,20 @@ module Taskinator
|
|
5
5
|
attr_reader :process
|
6
6
|
attr_reader :definition
|
7
7
|
attr_reader :args
|
8
|
+
attr_reader :options
|
8
9
|
|
9
|
-
def initialize(process, definition, args)
|
10
|
+
def initialize(process, definition, *args)
|
10
11
|
@process = process
|
11
12
|
@definition = definition
|
12
13
|
@args = args
|
14
|
+
@options = args.last.is_a?(Hash) ? args.last : {}
|
13
15
|
@executor = Taskinator::Executor.new(@definition)
|
14
16
|
end
|
15
17
|
|
18
|
+
def option?(key, &block)
|
19
|
+
yield if @options.key?(key) && @options[key]
|
20
|
+
end
|
21
|
+
|
16
22
|
# defines a sub process of tasks which are executed sequentially
|
17
23
|
def sequential(options={}, &block)
|
18
24
|
raise ArgumentError, 'block' unless block_given?
|
@@ -3,10 +3,14 @@ module Taskinator
|
|
3
3
|
class UndefinedProcessError < RuntimeError; end
|
4
4
|
|
5
5
|
# defines a process
|
6
|
-
def define_process(&block)
|
6
|
+
def define_process(*arg_list, &block)
|
7
7
|
define_singleton_method :_create_process_ do |*args|
|
8
|
+
|
9
|
+
# TODO: better validation of arguments
|
10
|
+
raise ArgumentError, "wrong number of arguments (#{args.length} for #{arg_list.length})" if args.length < arg_list.length
|
11
|
+
|
8
12
|
process = Process.define_sequential_process_for(self)
|
9
|
-
Builder.new(process, self, args).instance_eval(&block)
|
13
|
+
Builder.new(process, self, *args).instance_eval(&block)
|
10
14
|
process.save
|
11
15
|
process
|
12
16
|
end
|
data/lib/taskinator/version.rb
CHANGED
data/spec/support/test_flow.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module TestFlow
|
2
2
|
extend Taskinator::Definition
|
3
3
|
|
4
|
-
define_process do
|
4
|
+
define_process :some_arg1, :some_arg2 do
|
5
5
|
task :error_task, :continue_on_error => true
|
6
6
|
|
7
7
|
task :the_task
|
@@ -54,7 +54,7 @@ module TestFlow
|
|
54
54
|
module TestSubFlow
|
55
55
|
extend Taskinator::Definition
|
56
56
|
|
57
|
-
define_process do
|
57
|
+
define_process :some_arg1, :some_arg2 do
|
58
58
|
task :the_task
|
59
59
|
task :the_task
|
60
60
|
task :the_task
|
@@ -15,7 +15,7 @@ describe Taskinator::Definition::Builder do
|
|
15
15
|
Class.new(Taskinator::Process).new(definition)
|
16
16
|
}
|
17
17
|
|
18
|
-
let(:args) { [:arg1, :arg2] }
|
18
|
+
let(:args) { [:arg1, :arg2, {:option => 1, :another => false}] }
|
19
19
|
|
20
20
|
let(:block) { SpecSupport::Block.new() }
|
21
21
|
|
@@ -24,12 +24,30 @@ describe Taskinator::Definition::Builder do
|
|
24
24
|
Proc.new {|*args| the_block.call }
|
25
25
|
}
|
26
26
|
|
27
|
-
subject { Taskinator::Definition::Builder.new(process, definition, args) }
|
27
|
+
subject { Taskinator::Definition::Builder.new(process, definition, *args) }
|
28
28
|
|
29
29
|
it "assign attributes" do
|
30
30
|
expect(subject.process).to eq(process)
|
31
31
|
expect(subject.definition).to eq(definition)
|
32
32
|
expect(subject.args).to eq(args)
|
33
|
+
expect(subject.options).to eq({:option => 1, :another => false})
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#option?" do
|
37
|
+
it "invokes supplied block for 'option' option" do
|
38
|
+
expect(block).to receive(:call)
|
39
|
+
subject.option?(:option, &define_block)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "does not invoke supplied block for 'another' option" do
|
43
|
+
expect(block).to_not receive(:call)
|
44
|
+
subject.option?(:another, &define_block)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "does not invoke supplied block for an unspecified option" do
|
48
|
+
expect(block).to_not receive(:call)
|
49
|
+
subject.option?(:unspecified, &define_block)
|
50
|
+
end
|
33
51
|
end
|
34
52
|
|
35
53
|
describe "#sequential" do
|
@@ -154,7 +172,8 @@ describe Taskinator::Definition::Builder do
|
|
154
172
|
Module.new() do
|
155
173
|
extend Taskinator::Definition
|
156
174
|
|
157
|
-
define_process
|
175
|
+
define_process :some_arg1, :some_arg2, :some_arg3 do
|
176
|
+
end
|
158
177
|
end
|
159
178
|
end
|
160
179
|
|
@@ -164,7 +183,7 @@ describe Taskinator::Definition::Builder do
|
|
164
183
|
end
|
165
184
|
|
166
185
|
it "creates a sub process task" do
|
167
|
-
sub_process = sub_definition.create_process(:argX, :argY)
|
186
|
+
sub_process = sub_definition.create_process(:argX, :argY, :argZ)
|
168
187
|
allow(sub_definition).to receive(:create_process) { sub_process }
|
169
188
|
expect(Taskinator::Task).to receive(:define_sub_process_task).with(process, sub_process, {})
|
170
189
|
subject.sub_process(sub_definition)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: taskinator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Stefano
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|