methodical 0.0.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.
@@ -0,0 +1,217 @@
1
+ require File.expand_path("../test_helper", File.dirname(__FILE__))
2
+ require 'methodical/dsl'
3
+ require 'methodical/action_item'
4
+
5
+ class DslTest < Test::Unit::TestCase
6
+ include Methodical::DSL
7
+
8
+ context "#action" do
9
+ specify "constructs an ActionItem" do
10
+ step = action("TITLE") do
11
+ "RESULT"
12
+ end
13
+
14
+ assert_kind_of Methodical::ActionItem, step
15
+ assert_equal "TITLE", step.title
16
+ assert_equal "RESULT", step.execute!.result
17
+ end
18
+ end
19
+
20
+ context "#sufficient" do
21
+ specify "makes successful actions sufficient" do
22
+ step = action("TITLE") do "RESULT" end
23
+ sufficient_step = sufficient << step
24
+
25
+ assert_equal :sufficient, sufficient_step.execute!.status
26
+ end
27
+
28
+ specify "has no effect on unsuccessful actions" do
29
+ step = action("TITLE") do raise "FAIL" end
30
+ sufficient_step = sufficient << step
31
+
32
+ assert_equal :failed, sufficient_step.execute!.status
33
+ end
34
+ end
35
+
36
+ context "#requisite" do
37
+ specify "makes failed actions abort" do
38
+ step = action("TITLE") do raise "FAIL" end
39
+ requisite_step = requisite << step
40
+
41
+ disposition = requisite_step.execute!
42
+ assert_equal :abort, disposition.status
43
+ end
44
+ end
45
+
46
+ context "#ignore" do
47
+ specify "makes steps ignorable" do
48
+ step = action("TITLE") do raise "FAIL" end
49
+ ignored_step = ignore << step
50
+ ignored_step.execute!
51
+ assert ignored_step.ignored?
52
+ end
53
+ end
54
+
55
+ context "#skip_if" do
56
+ specify "skips step if condition is true" do
57
+ step = skip_if(""){true} << action("TITLE") do
58
+ flunk("Should not get here")
59
+ end
60
+ assert_equal :skipped, step.execute!().status
61
+ end
62
+
63
+ specify "performs step if condition is false" do
64
+ sensor = :unset
65
+ step = skip_if(""){false} << action("TITLE") do
66
+ "RESULT"
67
+ end
68
+ assert_equal "RESULT", step.execute!.result
69
+ end
70
+
71
+ specify "passes baton into condition" do
72
+ baton = stub("Baton")
73
+ sensor = :unset
74
+ step = skip_if(""){|b, s| sensor = b} << action("TITLE") do
75
+ "RESULT"
76
+ end
77
+ step.execute!(baton)
78
+ assert_same baton, sensor
79
+ end
80
+
81
+ specify "passes step into condition" do
82
+ baton = stub("Baton")
83
+ sensor = :unset
84
+ step = skip_if(""){|b, s| sensor = s} << inner = action("TITLE") do
85
+ "RESULT"
86
+ end
87
+ step.execute!(baton)
88
+ assert_same inner, sensor
89
+ end
90
+
91
+ specify "returns reason if skipped" do
92
+ step = skip_if("EXPL"){true} << action("TITLE") do
93
+ flunk("Should not get here")
94
+ end
95
+ assert_equal "EXPL", step.execute!().explanation
96
+ end
97
+
98
+ specify "updates status of step" do
99
+ step = skip_if("EXPL"){true} << action("TITLE") do
100
+ flunk("Should not get here")
101
+ end
102
+ step.execute!
103
+ assert_equal "EXPL", step.explanation
104
+ assert_equal :skipped, step.status
105
+ end
106
+ end
107
+
108
+ context "#handle_error" do
109
+ specify "rescues errors" do
110
+ step = handle_error(RuntimeError){|b,s,e| s.succeed! } <<
111
+ action("TITLE") do
112
+ raise "UH-OH"
113
+ end
114
+ assert_nothing_raised do
115
+ step.execute!(nil, true)
116
+ end
117
+ end
118
+
119
+ specify "substitutes its own disposition" do
120
+ step = handle_error(RuntimeError){|b,s,e| s.succeed! } <<
121
+ action("TITLE") do
122
+ raise "UH-OH"
123
+ end
124
+ assert_equal :succeeded, step.execute!(nil, true).status
125
+ end
126
+
127
+ end
128
+
129
+ context "#filter" do
130
+ specify "modifies step disposition" do
131
+ step = filter {|d|
132
+ d.merge(:status => :failed, :explanation => "MODIFIED")
133
+ } << action("TITLE") {
134
+ |b,s| s.succeed!("ORIGINAL")
135
+ }
136
+ result = step.execute!
137
+ assert_equal :failed, result.status
138
+ assert_equal "MODIFIED", result.explanation
139
+ assert_equal :failed, step.status
140
+ assert_equal "MODIFIED", step.explanation
141
+ end
142
+ end
143
+
144
+ context "#recover_failure" do
145
+ specify "executes block on failure" do
146
+ sensor = :unset
147
+ step = action("test") do |b,s| s.fail!("FAIL") end
148
+ wrapped_step = recover_failure do |baton, step, disposition|
149
+ sensor = :set
150
+ end << step
151
+ wrapped_step.execute!
152
+ assert_equal :set, sensor
153
+ end
154
+
155
+ specify "does not execute block on success" do
156
+ sensor = :unset
157
+ step = action("test") do |b,s| s.succeed!("OK") end
158
+ wrapped_step = recover_failure do |baton, step, disposition|
159
+ sensor = :set
160
+ end << step
161
+ wrapped_step.execute!
162
+ assert_equal :unset, sensor
163
+ end
164
+
165
+ specify "does not execute block on error" do
166
+ sensor = :unset
167
+ step = action("test") do raise StandardError, "BAD" end
168
+ wrapped_step = recover_failure do |baton, step, disposition|
169
+ sensor = :set
170
+ end << step
171
+ wrapped_step.execute!
172
+ assert_equal :unset, sensor
173
+ end
174
+ end
175
+
176
+ context "#retry_on_failure" do
177
+ specify "retries on failure" do
178
+ call_count = 0
179
+ step = action("test") do
180
+ call_count += 1
181
+ if call_count == 1
182
+ raise RuntimeError, "FAIL!"
183
+ end
184
+ end
185
+ wrapped_step = (retry_on_failure(2) << step)
186
+ wrapped_step.execute!
187
+ assert_equal 2, call_count
188
+ end
189
+
190
+ specify "will not retry more than the specified number of times" do
191
+ call_count = 0
192
+ step = action("test") do
193
+ call_count += 1
194
+ raise RuntimeError, "FAIL!"
195
+ end
196
+ wrapped_step = (retry_on_failure(2) << step)
197
+ wrapped_step.execute!
198
+ assert_equal 3, call_count
199
+ end
200
+
201
+ specify "will not retry if timeout expires" do
202
+ time = Time.mktime(1970, 1, 1)
203
+ clock = stub("Clock", :now => time)
204
+ call_count = 0
205
+ step = action("test") do
206
+ call_count += 1
207
+ time += 1
208
+ clock.stubs(:now => time)
209
+ raise RuntimeError, "FAIL!"
210
+ end
211
+ wrapped_step = (retry_on_failure(2, 1, :clock => clock) << step)
212
+ wrapped_step.execute!
213
+ assert_equal 1, call_count
214
+ end
215
+ end
216
+
217
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path("../test_helper", File.dirname(__FILE__))
2
+ require 'methodical/modifier'
3
+ require 'methodical/action_item'
4
+
5
+ class ModifierTest < Test::Unit::TestCase
6
+ context "#execute!" do
7
+ specify "executes the modifier block" do
8
+ step = stub_everything("ActionItem")
9
+ sensor = :unset
10
+ it = Methodical::Modifier.new("NAME", step) do
11
+ sensor = :set
12
+ end
13
+ it.execute!
14
+ assert_equal :set, sensor
15
+ end
16
+
17
+ specify "passes the action item to the block" do
18
+ step = stub_everything("ActionItem")
19
+ sensor = :unset
20
+ it = Methodical::Modifier.new("NAME", step) do |action_item, baton|
21
+ sensor = action_item
22
+ end
23
+ it.execute!
24
+ assert_same step, sensor
25
+ end
26
+
27
+ specify "passes a baton to the block" do
28
+ baton = stub("Baton")
29
+ step = stub_everything("ActionItem")
30
+ sensor = :unset
31
+ it = Methodical::Modifier.new("NAME", step) do |action_item, baton|
32
+ sensor = baton
33
+ end
34
+ it.execute!(baton)
35
+ assert_not_nil sensor
36
+ assert_same baton, sensor
37
+ end
38
+ end
39
+
40
+ context "#<<" do
41
+ specify "composes modifier and modified" do
42
+ step = stub_everything("ActionItem")
43
+ it = Methodical::Modifier.new("NAME")
44
+ it << step
45
+ assert_same step, it.action_item
46
+ end
47
+
48
+ specify "returns the modifier" do
49
+ step = stub_everything("ActionItem")
50
+ it = Methodical::Modifier.new("NAME")
51
+ assert_same it, (it << step)
52
+ end
53
+
54
+ specify "delegates to action_item, if set" do
55
+ mod2 = stub("Inner Modifier")
56
+ step = stub_everything("ActionItem")
57
+ it = Methodical::Modifier.new("NAME", mod2)
58
+ mod2.expects(:<<).with(step)
59
+ it << step
60
+ end
61
+ end
62
+
63
+ context "#clone" do
64
+ specify "deeply copies action item" do
65
+ step = stub_everything("ActionItem")
66
+ copy = stub_everything("Copy")
67
+ it = Methodical::Modifier.new("NAME", step)
68
+ step.expects(:clone).returns(copy).at_least_once
69
+ assert_same copy, it.clone.action_item
70
+ end
71
+ end
72
+
73
+ specify "delegates unknown methods to action item" do
74
+ step = stub_everything("ActionItem")
75
+ it = Methodical::Modifier.new("NAME", step)
76
+ step.expects(:foo).with("bar")
77
+ it.foo("bar")
78
+ end
79
+ end
@@ -0,0 +1,825 @@
1
+ require File.expand_path("../test_helper", File.dirname(__FILE__))
2
+ require 'methodical/simple_action_item'
3
+
4
+ class SimpleActionItemTest < Test::Unit::TestCase
5
+ include Methodical
6
+
7
+ specify "can be updated all at once" do
8
+ it = SimpleActionItem.new("Test") {}
9
+ it.update!(:skipped, "EXPLANATION", [1,2,3])
10
+ assert_equal :skipped, it.status
11
+ assert_equal "EXPLANATION", it.explanation
12
+ assert_equal [1,2,3], it.result
13
+ end
14
+
15
+ context "#update" do
16
+ specify "returns a disposition" do
17
+ it = SimpleActionItem.new("Test") {}
18
+ assert_equal(
19
+ Disposition.new([:skipped, "EXPLANATION", [1,2,3]]),
20
+ it.update!(:skipped, "EXPLANATION", [1,2,3]))
21
+ end
22
+ end
23
+
24
+ specify "defaults to NOT ignored" do
25
+ it = SimpleActionItem.new("Test") {}
26
+ assert !it.ignored?
27
+ end
28
+
29
+ specify "defaults to being relevant" do
30
+ it = SimpleActionItem.new("Test") {}
31
+ assert it.relevant?
32
+ end
33
+
34
+ specify "defaults to empty details" do
35
+ it = SimpleActionItem.new("Test") {}
36
+ assert_equal "", it.details
37
+ end
38
+
39
+ context "created from a block" do
40
+ specify "executes the block when called" do
41
+ sensor = :unset
42
+ it = SimpleActionItem.new("Test") do
43
+ sensor = :set
44
+ end
45
+ it.execute!
46
+ assert_equal :set, sensor
47
+ end
48
+
49
+ specify "has the given title" do
50
+ it = SimpleActionItem.new("Foo") {}
51
+ assert_equal "Foo", it.title
52
+ end
53
+
54
+ specify "knows it is undone before being called" do
55
+ it = SimpleActionItem.new("Foo") {}
56
+ assert !it.done?
57
+ end
58
+
59
+ specify "knows it is done after being called" do
60
+ it = SimpleActionItem.new("Foo") {}
61
+ it.execute!
62
+ assert it.done?
63
+ end
64
+
65
+ specify "has a status of :succeeded after being called" do
66
+ it = SimpleActionItem.new("Foo") {}
67
+ it.execute!
68
+ assert_equal :succeeded, it.status
69
+ end
70
+
71
+ specify "has a status of :not_started before being called" do
72
+ it = SimpleActionItem.new("Foo") {}
73
+ assert_equal :not_started, it.status
74
+ end
75
+
76
+ specify "knows it has neither succeeded or failed before being called" do
77
+ it = SimpleActionItem.new("Foo") {}
78
+ assert !it.succeeded?
79
+ assert !it.failed?
80
+ assert !it.bad?
81
+ end
82
+
83
+ specify "can format a status message" do
84
+ it = SimpleActionItem.new("Foo") {}
85
+ assert_equal "Foo: Not started.", it.synopsis
86
+ end
87
+
88
+ specify "passes self to block" do
89
+ sensor = :unset
90
+ it = SimpleActionItem.new("Foo") do |baton, step|
91
+ sensor = step
92
+ end
93
+ it.execute!(nil)
94
+ assert_same it, sensor
95
+ end
96
+
97
+ specify "called with a baton object, passes baton to block" do
98
+ sensor = :unset
99
+ it = SimpleActionItem.new("Foo") do |baton, step|
100
+ sensor = baton
101
+ end
102
+ test_baton = stub("Baton")
103
+ it.execute!(test_baton)
104
+ assert_same test_baton, sensor
105
+ end
106
+ end
107
+
108
+ context "created from a callable" do
109
+ specify "executes the callable when called" do
110
+ sensor = :unset
111
+ callable = lambda do |baton, step|
112
+ sensor = :set
113
+ end
114
+ it = SimpleActionItem.new("Test", callable)
115
+ it.execute!
116
+ assert_equal :set, sensor
117
+ end
118
+
119
+ specify "called with a baton object, passes baton to callable" do
120
+ sensor = :unset
121
+ callable = lambda do |baton, step|
122
+ sensor = baton
123
+ end
124
+ it = SimpleActionItem.new("Foo", callable)
125
+ test_baton = stub("Baton")
126
+ it.execute!(test_baton)
127
+ assert_same test_baton, sensor
128
+ end
129
+ end
130
+
131
+ context "with a block that throws a disposition" do
132
+ specify "should save and return the disposition" do
133
+ it = SimpleActionItem.new("Failure") do
134
+ throw(:methodical_disposition,
135
+ Methodical::Disposition(:in_progress, "Procrastinating", 42))
136
+ end
137
+ assert_equal(Methodical::Disposition(:in_progress, "Procrastinating", 42),
138
+ it.execute!)
139
+ assert_equal(Methodical::Disposition(:in_progress, "Procrastinating", 42),
140
+ it.disposition)
141
+ end
142
+ end
143
+
144
+ context "with a block that raises a runtime error" do
145
+ specify "has a status of :failed after being called" do
146
+ it = SimpleActionItem.new("Failure") do raise "Fail" end
147
+ it.execute!
148
+ assert_equal :failed, it.status
149
+ end
150
+
151
+ specify "stores the exception" do
152
+ it = SimpleActionItem.new("Failure") do raise "Fail" end
153
+ it.execute!
154
+ assert_kind_of RuntimeError, it.error
155
+ assert_equal "Fail", it.error.message
156
+ end
157
+
158
+ specify "returns a disposition from call" do
159
+ it = SimpleActionItem.new("Failure") do raise "Fail" end
160
+ assert_kind_of Methodical::Disposition, it.execute!
161
+ assert_equal "Fail", it.execute!.explanation
162
+ end
163
+
164
+ specify "details should be derived from the error backtrace" do
165
+ error = RuntimeError.new("Fail")
166
+ error.set_backtrace(['FRAME1', 'FRAME2'])
167
+ it = SimpleActionItem.new("Failure") do raise error end
168
+ assert_equal "FRAME1\nFRAME2", it.execute!.details
169
+ end
170
+
171
+ end
172
+
173
+ context "with a block that raises a StandardError" do
174
+ specify "has a status of :bad after being called" do
175
+ it = SimpleActionItem.new("Failure") do
176
+ raise StandardError, "Fail"
177
+ end
178
+ it.execute!
179
+ assert_equal :bad, it.status
180
+ end
181
+
182
+ specify "stores the exception" do
183
+ it = SimpleActionItem.new("Failure") do
184
+ raise StandardError, "Fail"
185
+ end
186
+ it.execute!
187
+ assert_kind_of StandardError, it.error
188
+ assert_equal "Fail", it.error.message
189
+ end
190
+
191
+ specify "details should be derived from the error backtrace" do
192
+ error = StandardError.new("Fail")
193
+ error.set_backtrace(['FRAME1', 'FRAME2'])
194
+ it = SimpleActionItem.new("Failure") do raise error end
195
+ assert_equal "FRAME1\nFRAME2", it.execute!.details
196
+ end
197
+ end
198
+
199
+ context "with a block that raises a Exception" do
200
+ specify "has a status of :bad after being called" do
201
+ it = SimpleActionItem.new("Failure") do
202
+ raise Exception, "Alert!"
203
+ end
204
+ begin
205
+ it.execute!
206
+ rescue Exception
207
+ end
208
+ assert_equal :bad, it.status
209
+ end
210
+
211
+ specify "stores the exception" do
212
+ it = SimpleActionItem.new("Failure") do
213
+ raise Exception, "Fail"
214
+ end
215
+ begin
216
+ it.execute!
217
+ rescue Exception
218
+ end
219
+ assert_kind_of Exception, it.error
220
+ assert_equal "Fail", it.error.message
221
+ assert_equal "Fail", it.explanation
222
+ end
223
+
224
+ specify "passes the exception on" do
225
+ it = SimpleActionItem.new("Failure") do
226
+ raise Exception, "Fail"
227
+ end
228
+ assert_raises(Exception) do
229
+ it.execute!
230
+ end
231
+ end
232
+
233
+ specify "details should be derived from the error backtrace" do
234
+ error = Exception.new("Fail")
235
+ error.set_backtrace(['FRAME1', 'FRAME2'])
236
+ it = SimpleActionItem.new("Failure") do raise error end
237
+ begin
238
+ it.execute!
239
+ rescue Exception
240
+ end
241
+ assert_equal "FRAME1\nFRAME2", it.details
242
+ end
243
+
244
+ end
245
+
246
+ context "with a block that returns no details" do
247
+ specify "has no explanation" do
248
+ it = SimpleActionItem.new("Foo") {}
249
+ it.execute!
250
+ assert it.explanation.blank?
251
+ end
252
+
253
+ specify "returns a disposition on call" do
254
+ it = SimpleActionItem.new("Foo") {}
255
+ assert_kind_of Methodical::Disposition, it.execute!
256
+ end
257
+ end
258
+
259
+ context "with a block that returns success details" do
260
+ specify "uses second element for explanation" do
261
+ it = SimpleActionItem.new("Foo") do
262
+ [:succeeded, "EXPLANATION", nil]
263
+ end
264
+ it.execute!
265
+ assert_equal "EXPLANATION", it.explanation
266
+ end
267
+
268
+ specify "uses third element for result" do
269
+ it = SimpleActionItem.new("Foo") do
270
+ [:succeeded, "EXPLANATION", {:frobozz => "magic"}]
271
+ end
272
+ it.execute!
273
+ assert_equal({:frobozz => "magic"}, it.result)
274
+ end
275
+
276
+ specify "returns a disposition on call" do
277
+ it = SimpleActionItem.new("Foo") do
278
+ [:succeeded, "EXPLANATION", {:frobozz => "magic"}]
279
+ end
280
+ assert_kind_of Methodical::Disposition, it.execute!
281
+ end
282
+ end
283
+
284
+ context "with a status of :skipped" do
285
+ specify "can format a status message" do
286
+ it = SimpleActionItem.new("Foo") {}
287
+ it.status = :skipped
288
+ assert_equal "Foo: Skipped.", it.synopsis
289
+ end
290
+ end
291
+
292
+ context "with a status of :abort" do
293
+ specify "can format a status message" do
294
+ it = SimpleActionItem.new("Foo") {}
295
+ it.status = :abort
296
+ assert_equal "Foo: Failed.", it.synopsis
297
+ end
298
+ end
299
+
300
+ context "with the ignored bit set" do
301
+ specify "knows it is ignored" do
302
+ it = SimpleActionItem.new("Foo") {}
303
+ it.ignored = true
304
+ assert it.ignored?
305
+ end
306
+
307
+ specify "does not count towards overall outcome" do
308
+ it = SimpleActionItem.new("Foo") {}
309
+ it.ignored = true
310
+ assert !it.relevant?
311
+ end
312
+
313
+ end
314
+
315
+ context "failed, with the ignored bit set" do
316
+ specify "can format a status message" do
317
+ it = SimpleActionItem.new("Foo") {}
318
+ it.status = :failed
319
+ it.explanation = "Stuff happened"
320
+ it.ignored = true
321
+ assert_equal "Foo: Failed (Stuff happened) (Ignored).", it.synopsis
322
+ end
323
+
324
+ specify "should say continuing is OK" do
325
+ it = SimpleActionItem.new("Foo") {}
326
+ it.status = :failed
327
+ it.explanation = "Stuff happened"
328
+ it.ignored = true
329
+ assert it.continue?
330
+ end
331
+
332
+ specify "is not decisive" do
333
+ it = SimpleActionItem.new("Foo") {}
334
+ it.status = :failed
335
+ it.ignored = true
336
+ assert !it.decisive?
337
+ end
338
+ end
339
+
340
+ context "aborted, with the ignored bit set" do
341
+ specify "can format a status message" do
342
+ it = SimpleActionItem.new("Foo") {}
343
+ it.status = :abort
344
+ it.explanation = "Stuff happened"
345
+ it.ignored = true
346
+ assert_equal "Foo: Failed (Stuff happened) (Ignored).", it.synopsis
347
+ end
348
+
349
+ specify "should NOT say continuing is OK" do
350
+ it = SimpleActionItem.new("Foo") {}
351
+ it.status = :abort
352
+ it.explanation = "Stuff happened"
353
+ it.ignored = true
354
+ assert !it.continue?
355
+ end
356
+
357
+ specify "is not decisive" do
358
+ it = SimpleActionItem.new("Foo") {}
359
+ it.status = :aborted
360
+ it.ignored = true
361
+ assert !it.decisive?
362
+ end
363
+ end
364
+
365
+ context "succeeded, with the ignored bit set" do
366
+ specify "can format a status message" do
367
+ it = SimpleActionItem.new("Foo") {}
368
+ it.status = :succeeded
369
+ it.explanation = "Stuff happened"
370
+ it.ignored = true
371
+ assert_equal "Foo: OK (Stuff happened).", it.synopsis
372
+ end
373
+
374
+ specify "should say continuing is OK" do
375
+ it = SimpleActionItem.new("Foo") {}
376
+ it.status = :succeeded
377
+ it.explanation = "Stuff happened"
378
+ it.ignored = true
379
+ assert it.continue?
380
+ end
381
+ end
382
+
383
+ context "with a status of :sufficient" do
384
+ specify "can format a status message" do
385
+ it = SimpleActionItem.new("Foo") {}
386
+ it.status = :sufficient
387
+ assert_equal "Foo: OK.", it.synopsis
388
+ end
389
+ end
390
+
391
+ context "with a status of :finish" do
392
+ specify "can format a status message" do
393
+ it = SimpleActionItem.new("Foo") {}
394
+ it.status = :finish
395
+ assert_equal "Foo: OK.", it.synopsis
396
+ end
397
+
398
+ specify "should NOT approve continuation" do
399
+ it = SimpleActionItem.new("Foo") {}
400
+ it.status = :finish
401
+ assert !it.continue?
402
+ end
403
+ end
404
+
405
+ context "with a block that returns a single value" do
406
+ specify "has no explanation" do
407
+ it = SimpleActionItem.new("Foo") do
408
+ "RESULT"
409
+ end
410
+ it.execute!
411
+ assert it.explanation.blank?
412
+ end
413
+
414
+ specify "uses value for result" do
415
+ it = SimpleActionItem.new("Foo") do
416
+ "RESULT"
417
+ end
418
+ it.execute!
419
+ assert_equal("RESULT", it.result)
420
+ end
421
+ end
422
+
423
+ context "which has failed" do
424
+ specify "knows it has failed" do
425
+ it = SimpleActionItem.new("Failure") do raise "Fail" end
426
+ it.execute!
427
+ assert it.failed?
428
+ end
429
+
430
+ specify "knows it has not succeeded" do
431
+ it = SimpleActionItem.new("Failure") do raise "Fail" end
432
+ it.execute!
433
+ assert !it.succeeded?
434
+ end
435
+
436
+ specify "is decisive" do
437
+ it = SimpleActionItem.new("Failure") do raise "Fail" end
438
+ it.execute!
439
+ assert it.decisive?
440
+ end
441
+
442
+ specify "knows it is not bad" do
443
+ it = SimpleActionItem.new("Fail") do raise "Fail" end
444
+ it.execute!
445
+ assert !it.bad?
446
+ end
447
+
448
+ specify "gets explanation from error" do
449
+ it = SimpleActionItem.new("Fail") do raise "Fail" end
450
+ it.execute!
451
+ assert_equal "Fail", it.explanation
452
+ end
453
+
454
+ specify "can format a status message" do
455
+ it = SimpleActionItem.new("Foo") do raise "MESSAGE" end
456
+ it.execute!
457
+ assert_equal "Foo: Failed (MESSAGE).", it.synopsis
458
+ end
459
+ end
460
+
461
+ context "which has raised a standard error" do
462
+ specify "knows it has failed" do
463
+ it = SimpleActionItem.new("Failure") do
464
+ raise StandardError, "Fail"
465
+ end
466
+ it.execute!
467
+ assert it.failed?
468
+ end
469
+
470
+ specify "knows it has not succeeded" do
471
+ it = SimpleActionItem.new("Failure") do
472
+ raise StandardError, "Fail"
473
+ end
474
+ it.execute!
475
+ assert !it.succeeded?
476
+ end
477
+
478
+ specify "knows it is bad" do
479
+ it = SimpleActionItem.new("Fail") do
480
+ raise StandardError, "Fail"
481
+ end
482
+ it.execute!
483
+ assert it.bad?
484
+ end
485
+
486
+ specify "gets explanation from error" do
487
+ it = SimpleActionItem.new("Fail") do raise StandardError, "Fail" end
488
+ it.execute!
489
+ assert_equal "Fail", it.explanation
490
+ end
491
+
492
+ specify "can format a status message" do
493
+ it = SimpleActionItem.new("Foo") do
494
+ raise StandardError, "SOME_ERROR"
495
+ end
496
+ it.execute!
497
+ assert_equal "Foo: Error (SOME_ERROR).", it.synopsis
498
+ end
499
+ end
500
+
501
+ context "which has succeeded" do
502
+ specify "knows it has not failed" do
503
+ it = SimpleActionItem.new("Success") do end
504
+ it.execute!
505
+ assert !it.failed?
506
+ end
507
+
508
+ specify "knows it has succeeded" do
509
+ it = SimpleActionItem.new("Success") do end
510
+ it.execute!
511
+ assert it.succeeded?
512
+ end
513
+
514
+ specify "knows it is not bad" do
515
+ it = SimpleActionItem.new("Success") do end
516
+ it.execute!
517
+ assert !it.bad?
518
+ end
519
+
520
+ specify "can format a status message" do
521
+ it = SimpleActionItem.new("Foo") {}
522
+ it.execute!
523
+ assert_equal "Foo: OK.", it.synopsis
524
+ end
525
+
526
+ end
527
+
528
+ context "#succeed!" do
529
+ specify "throws :methodical_disposition" do
530
+ it = SimpleActionItem.new("TEST") {}
531
+ assert_throws(:methodical_disposition) do
532
+ it.succeed!
533
+ end
534
+ end
535
+
536
+ specify "throws a disposition object" do
537
+ it = SimpleActionItem.new("TEST") {}
538
+ assert_kind_of(Methodical::Disposition,
539
+ catch(:methodical_disposition) { it.succeed! })
540
+ end
541
+
542
+ specify "throws a successful disposition" do
543
+ it = SimpleActionItem.new("TEST") {}
544
+ assert_equal(:succeeded,
545
+ catch(:methodical_disposition) { it.succeed! }.status)
546
+ end
547
+
548
+ specify "throws the given explanation" do
549
+ it = SimpleActionItem.new("TEST") {}
550
+ assert_equal("EXPL",
551
+ catch(:methodical_disposition) { it.succeed!("EXPL") }.explanation)
552
+ end
553
+
554
+ specify "throws the given result" do
555
+ it = SimpleActionItem.new("TEST") {}
556
+ assert_equal(42,
557
+ catch(:methodical_disposition) { it.succeed!("EXPL", 42) }.result)
558
+ end
559
+
560
+ specify "throws the given details" do
561
+ it = SimpleActionItem.new("TEST") {}
562
+ assert_equal("DETAILS",
563
+ catch(:methodical_disposition) {
564
+ it.succeed!("EXPL", 42, "DETAILS")
565
+ }.details)
566
+ end
567
+ end
568
+
569
+ context "#failed!" do
570
+ specify "throws :methodical_disposition" do
571
+ it = SimpleActionItem.new("TEST") {}
572
+ assert_throws(:methodical_disposition) do
573
+ it.fail!
574
+ end
575
+ end
576
+
577
+ specify "throws a disposition object" do
578
+ it = SimpleActionItem.new("TEST") {}
579
+ assert_kind_of(Methodical::Disposition,
580
+ catch(:methodical_disposition) { it.fail! })
581
+ end
582
+
583
+ specify "throws a failed disposition" do
584
+ it = SimpleActionItem.new("TEST") {}
585
+ assert_equal(:failed,
586
+ catch(:methodical_disposition) { it.fail! }.status)
587
+ end
588
+
589
+ specify "throws the given explanation" do
590
+ it = SimpleActionItem.new("TEST") {}
591
+ assert_equal("EXPL",
592
+ catch(:methodical_disposition) { it.fail!("EXPL") }.explanation)
593
+ end
594
+
595
+ specify "throws the given result" do
596
+ it = SimpleActionItem.new("TEST") {}
597
+ assert_equal(42,
598
+ catch(:methodical_disposition) { it.fail!("EXPL", 42) }.result)
599
+ end
600
+
601
+ specify "throws the given error" do
602
+ it = SimpleActionItem.new("TEST") {}
603
+ assert_equal("FOO",
604
+ catch(:methodical_disposition) {
605
+ it.fail!("EXPL", 42, RuntimeError.new("FOO"))
606
+ }.error.message)
607
+ end
608
+
609
+ specify "throws the given details" do
610
+ it = SimpleActionItem.new("TEST") {}
611
+ assert_equal("DETAILS",
612
+ catch(:methodical_disposition) {
613
+ it.fail!("EXPL", 42, nil, "DETAILS")
614
+ }.details)
615
+ end
616
+ end
617
+
618
+ context "#skip!" do
619
+ specify "throws :methodical_disposition" do
620
+ it = SimpleActionItem.new("TEST") {}
621
+ assert_throws(:methodical_disposition) do
622
+ it.skip!
623
+ end
624
+ end
625
+
626
+ specify "throws a disposition object" do
627
+ it = SimpleActionItem.new("TEST") {}
628
+ assert_kind_of(Methodical::Disposition,
629
+ catch(:methodical_disposition) { it.skip! })
630
+ end
631
+
632
+ specify "throws a skipped disposition" do
633
+ it = SimpleActionItem.new("TEST") {}
634
+ assert_equal(:skipped,
635
+ catch(:methodical_disposition) { it.skip! }.status)
636
+ end
637
+
638
+ specify "throws the given explanation" do
639
+ it = SimpleActionItem.new("TEST") {}
640
+ assert_equal("EXPL",
641
+ catch(:methodical_disposition) { it.skip!("EXPL") }.explanation)
642
+ end
643
+
644
+ specify "throws the given details" do
645
+ it = SimpleActionItem.new("TEST") {}
646
+ assert_equal("DETAILS",
647
+ catch(:methodical_disposition) {
648
+ it.skip!("EXPL", "DETAILS")
649
+ }.details)
650
+ end
651
+ end
652
+
653
+ context "#checkpoint!" do
654
+ specify "throws :methodical_disposition" do
655
+ it = SimpleActionItem.new("TEST") {}
656
+ assert_throws(:methodical_disposition) do
657
+ it.checkpoint!
658
+ end
659
+ end
660
+
661
+ specify "throws a disposition object" do
662
+ it = SimpleActionItem.new("TEST") {}
663
+ assert_kind_of(Methodical::Disposition,
664
+ catch(:methodical_disposition) { it.checkpoint! })
665
+ end
666
+
667
+ specify "throws an in_progress disposition" do
668
+ it = SimpleActionItem.new("TEST") {}
669
+ assert_equal(:in_progress,
670
+ catch(:methodical_disposition) { it.checkpoint! }.status)
671
+ end
672
+
673
+ specify "throws the given explanation" do
674
+ it = SimpleActionItem.new("TEST") {}
675
+ assert_equal("EXPL",
676
+ catch(:methodical_disposition) { it.checkpoint!("EXPL") }.explanation)
677
+ end
678
+
679
+ specify "throws the given memento" do
680
+ it = SimpleActionItem.new("TEST") {}
681
+ assert_equal(42,
682
+ catch(:methodical_disposition) { it.checkpoint!("EXPL", 42) }.memento)
683
+ end
684
+
685
+ specify "throws the given details" do
686
+ it = SimpleActionItem.new("TEST") {}
687
+ assert_equal("DETAILS",
688
+ catch(:methodical_disposition) {
689
+ it.checkpoint!("EXPL", 42, "DETAILS")
690
+ }.details)
691
+ end
692
+ end
693
+
694
+
695
+ context "#sufficient!" do
696
+ specify "throws :methodical_disposition" do
697
+ it = SimpleActionItem.new("TEST") {}
698
+ assert_throws(:methodical_disposition) do
699
+ it.sufficient!
700
+ end
701
+ end
702
+
703
+ specify "throws a disposition object" do
704
+ it = SimpleActionItem.new("TEST") {}
705
+ assert_kind_of(Methodical::Disposition,
706
+ catch(:methodical_disposition) { it.sufficient! })
707
+ end
708
+
709
+ specify "throws a sufficient disposition" do
710
+ it = SimpleActionItem.new("TEST") {}
711
+ assert_equal(:sufficient,
712
+ catch(:methodical_disposition) { it.sufficient! }.status)
713
+ end
714
+
715
+ specify "throws the given explanation" do
716
+ it = SimpleActionItem.new("TEST") {}
717
+ assert_equal("EXPL",
718
+ catch(:methodical_disposition) { it.sufficient!("EXPL") }.explanation)
719
+ end
720
+
721
+ specify "throws the given result" do
722
+ it = SimpleActionItem.new("TEST") {}
723
+ assert_equal(42,
724
+ catch(:methodical_disposition) { it.sufficient!("EXPL", 42) }.result)
725
+ end
726
+
727
+ specify "throws the given details" do
728
+ it = SimpleActionItem.new("TEST") {}
729
+ assert_equal("DETAILS",
730
+ catch(:methodical_disposition) {
731
+ it.sufficient!("EXPL", 42, "DETAILS")
732
+ }.details)
733
+ end
734
+ end
735
+
736
+ context "#finish!" do
737
+ specify "throws :methodical_disposition" do
738
+ it = SimpleActionItem.new("TEST") {}
739
+ assert_throws(:methodical_disposition) do
740
+ it.finish!
741
+ end
742
+ end
743
+
744
+ specify "throws a disposition object" do
745
+ it = SimpleActionItem.new("TEST") {}
746
+ assert_kind_of(Methodical::Disposition,
747
+ catch(:methodical_disposition) { it.finish! })
748
+ end
749
+
750
+ specify "throws a finish disposition" do
751
+ it = SimpleActionItem.new("TEST") {}
752
+ assert_equal(:finish,
753
+ catch(:methodical_disposition) { it.finish! }.status)
754
+ end
755
+
756
+ specify "throws the given explanation" do
757
+ it = SimpleActionItem.new("TEST") {}
758
+ assert_equal("EXPL",
759
+ catch(:methodical_disposition) { it.finish!("EXPL") }.explanation)
760
+ end
761
+
762
+ specify "throws the given result" do
763
+ it = SimpleActionItem.new("TEST") {}
764
+ assert_equal(42,
765
+ catch(:methodical_disposition) { it.finish!("EXPL", 42) }.result)
766
+ end
767
+
768
+ specify "throws the given details" do
769
+ it = SimpleActionItem.new("TEST") {}
770
+ assert_equal("DETAILS",
771
+ catch(:methodical_disposition) {
772
+ it.finish!("EXPL", 42, "DETAILS")
773
+ }.details)
774
+ end
775
+ end
776
+
777
+ context "#abort!" do
778
+ specify "throws :methodical_disposition" do
779
+ it = SimpleActionItem.new("TEST") {}
780
+ assert_throws(:methodical_disposition) do
781
+ it.abort!
782
+ end
783
+ end
784
+
785
+ specify "throws a disposition object" do
786
+ it = SimpleActionItem.new("TEST") {}
787
+ assert_kind_of(Methodical::Disposition,
788
+ catch(:methodical_disposition) { it.abort! })
789
+ end
790
+
791
+ specify "throws an abort disposition" do
792
+ it = SimpleActionItem.new("TEST") {}
793
+ assert_equal(:abort,
794
+ catch(:methodical_disposition) { it.abort! }.status)
795
+ end
796
+
797
+ specify "throws the given explanation" do
798
+ it = SimpleActionItem.new("TEST") {}
799
+ assert_equal("EXPL",
800
+ catch(:methodical_disposition) { it.abort!("EXPL") }.explanation)
801
+ end
802
+
803
+ specify "throws the given result" do
804
+ it = SimpleActionItem.new("TEST") {}
805
+ assert_equal(42,
806
+ catch(:methodical_disposition) { it.abort!("EXPL", 42) }.result)
807
+ end
808
+
809
+ specify "throws the given error" do
810
+ it = SimpleActionItem.new("TEST") {}
811
+ assert_equal("FOO",
812
+ catch(:methodical_disposition) {
813
+ it.abort!("EXPL", 42, RuntimeError.new("FOO"))
814
+ }.error.message)
815
+ end
816
+
817
+ specify "throws the given details" do
818
+ it = SimpleActionItem.new("TEST") {}
819
+ assert_equal("DETAILS",
820
+ catch(:methodical_disposition) {
821
+ it.abort!("EXPL", 42, nil, "DETAILS")
822
+ }.details)
823
+ end
824
+ end
825
+ end