state_machines 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -2
  3. data/README.md +25 -0
  4. data/Rakefile +10 -1
  5. data/lib/state_machines/branch.rb +0 -4
  6. data/lib/state_machines/core.rb +23 -5
  7. data/lib/state_machines/error.rb +81 -2
  8. data/lib/state_machines/event.rb +2 -20
  9. data/lib/state_machines/event_collection.rb +25 -27
  10. data/lib/state_machines/extensions.rb +34 -34
  11. data/lib/state_machines/integrations.rb +98 -90
  12. data/lib/state_machines/integrations/base.rb +11 -60
  13. data/lib/state_machines/matcher.rb +0 -2
  14. data/lib/state_machines/node_collection.rb +0 -2
  15. data/lib/state_machines/path_collection.rb +0 -2
  16. data/lib/state_machines/state.rb +0 -3
  17. data/lib/state_machines/state_collection.rb +17 -19
  18. data/lib/state_machines/state_context.rb +1 -6
  19. data/lib/state_machines/transition.rb +0 -56
  20. data/lib/state_machines/version.rb +1 -1
  21. data/spec/spec_helper.rb +1 -0
  22. data/spec/state_machines/assertions_spec.rb +31 -0
  23. data/spec/state_machines/branch_spec.rb +827 -0
  24. data/spec/state_machines/callbacks_spec.rb +706 -0
  25. data/spec/state_machines/errors_spec.rb +1 -0
  26. data/spec/state_machines/event_collection_spec.rb +401 -0
  27. data/spec/state_machines/event_spec.rb +1140 -0
  28. data/spec/{helpers → state_machines}/helper_spec.rb +0 -0
  29. data/spec/state_machines/integration_base_spec.rb +12 -0
  30. data/spec/state_machines/integration_spec.rb +132 -0
  31. data/spec/state_machines/invalid_event_spec.rb +19 -0
  32. data/spec/state_machines/invalid_parallel_transition_spec.rb +18 -0
  33. data/spec/state_machines/invalid_transition_spec.rb +114 -0
  34. data/spec/state_machines/machine_collection_spec.rb +606 -0
  35. data/spec/{machine_spec.rb → state_machines/machine_spec.rb} +11 -2
  36. data/spec/{matcher_helpers_spec.rb → state_machines/matcher_helpers_spec.rb} +0 -0
  37. data/spec/{matcher_spec.rb → state_machines/matcher_spec.rb} +0 -0
  38. data/spec/{node_collection_spec.rb → state_machines/node_collection_spec.rb} +0 -0
  39. data/spec/{path_collection_spec.rb → state_machines/path_collection_spec.rb} +0 -0
  40. data/spec/{path_spec.rb → state_machines/path_spec.rb} +0 -0
  41. data/spec/{state_collection_spec.rb → state_machines/state_collection_spec.rb} +0 -0
  42. data/spec/{state_context_spec.rb → state_machines/state_context_spec.rb} +0 -0
  43. data/spec/{state_machine_spec.rb → state_machines/state_machine_spec.rb} +0 -0
  44. data/spec/{state_spec.rb → state_machines/state_spec.rb} +0 -0
  45. data/spec/{transition_collection_spec.rb → state_machines/transition_collection_spec.rb} +0 -0
  46. data/spec/{transition_spec.rb → state_machines/transition_spec.rb} +0 -0
  47. data/spec/support/migration_helpers.rb +9 -0
  48. data/state_machines.gemspec +3 -1
  49. metadata +68 -45
  50. data/lib/state_machines/yard.rb +0 -8
  51. data/spec/errors/default_spec.rb +0 -14
  52. data/spec/errors/with_message_spec.rb +0 -39
@@ -0,0 +1,706 @@
1
+ require 'spec_helper'
2
+
3
+ describe StateMachines::Callback do
4
+
5
+ context 'Default' do
6
+ it 'should_raise_exception_if_invalid_type_specified' do
7
+ assert_raise(ArgumentError) { StateMachines::Callback.new(:invalid) {} }
8
+ end
9
+
10
+ it 'should_not_raise_exception_if_using_before_type' do
11
+ assert_nothing_raised { StateMachines::Callback.new(:before) {} }
12
+ end
13
+
14
+ it 'should_not_raise_exception_if_using_after_type' do
15
+ assert_nothing_raised { StateMachines::Callback.new(:after) {} }
16
+ end
17
+
18
+ it 'should_not_raise_exception_if_using_around_type' do
19
+ assert_nothing_raised { StateMachines::Callback.new(:around) {} }
20
+ end
21
+
22
+ it 'should_not_raise_exception_if_using_failure_type' do
23
+ assert_nothing_raised { StateMachines::Callback.new(:failure) {} }
24
+ end
25
+
26
+ it 'should_raise_exception_if_no_methods_specified' do
27
+ assert_raise(ArgumentError) { StateMachines::Callback.new(:before) }
28
+ end
29
+
30
+ it 'should_not_raise_exception_if_method_specified_in_do_option' do
31
+ assert_nothing_raised { StateMachines::Callback.new(:before, :do => :run) }
32
+ end
33
+
34
+ it 'should_not_raise_exception_if_method_specified_as_argument' do
35
+ assert_nothing_raised { StateMachines::Callback.new(:before, :run) }
36
+ end
37
+
38
+ it 'should_not_raise_exception_if_method_specified_as_block' do
39
+ assert_nothing_raised { StateMachines::Callback.new(:before, :run) {} }
40
+ end
41
+
42
+ it 'should_not_raise_exception_if_implicit_option_specified' do
43
+ assert_nothing_raised { StateMachines::Callback.new(:before, :do => :run, :invalid => :valid) }
44
+ end
45
+
46
+ it 'should_not_bind_to_objects' do
47
+ assert !StateMachines::Callback.bind_to_object
48
+ end
49
+
50
+ it 'should_not_have_a_terminator' do
51
+ assert_nil StateMachines::Callback.terminator
52
+ end
53
+ end
54
+
55
+ context 'ByDefault' do
56
+ before(:each) do
57
+ @callback = StateMachines::Callback.new(:before) {}
58
+ end
59
+
60
+ it 'should_have_type' do
61
+ assert_equal :before, @callback.type
62
+ end
63
+
64
+ it 'should_not_have_a_terminator' do
65
+ assert_nil @callback.terminator
66
+ end
67
+
68
+ it 'should_have_a_branch_with_all_matcher_requirements' do
69
+ assert_equal StateMachines::AllMatcher.instance, @callback.branch.event_requirement
70
+ assert_equal StateMachines::AllMatcher.instance, @callback.branch.state_requirements.first[:from]
71
+ assert_equal StateMachines::AllMatcher.instance, @callback.branch.state_requirements.first[:to]
72
+ end
73
+
74
+ it 'should_not_have_any_known_states' do
75
+ assert_equal [], @callback.known_states
76
+ end
77
+ end
78
+
79
+ context 'WithMethodArgument' do
80
+ before(:each) do
81
+ @callback = StateMachines::Callback.new(:before, lambda {|*args| @args = args})
82
+
83
+ @object = Object.new
84
+ @result = @callback.call(@object)
85
+ end
86
+
87
+ it 'should_be_successful' do
88
+ assert @result
89
+ end
90
+
91
+ it 'should_call_with_empty_context' do
92
+ assert_equal [@object], @args
93
+ end
94
+ end
95
+
96
+ context 'WithMultipleMethodArguments' do
97
+ before(:each) do
98
+ @callback = StateMachines::Callback.new(:before, :run_1, :run_2)
99
+
100
+ class << @object = Object.new
101
+ attr_accessor :callbacks
102
+
103
+ def run_1
104
+ (@callbacks ||= []) << :run_1
105
+ end
106
+
107
+ def run_2
108
+ (@callbacks ||= []) << :run_2
109
+ end
110
+ end
111
+
112
+ @result = @callback.call(@object)
113
+ end
114
+
115
+ it 'should_be_successful' do
116
+ assert @result
117
+ end
118
+
119
+ it 'should_call_each_callback_in_order' do
120
+ assert_equal [:run_1, :run_2], @object.callbacks
121
+ end
122
+ end
123
+
124
+ context 'WithDoMethod' do
125
+ before(:each) do
126
+ @callback = StateMachines::Callback.new(:before, :do => lambda {|*args| @args = args})
127
+
128
+ @object = Object.new
129
+ @result = @callback.call(@object)
130
+ end
131
+
132
+ it 'should_be_successful' do
133
+ assert @result
134
+ end
135
+
136
+ it 'should_call_with_empty_context' do
137
+ assert_equal [@object], @args
138
+ end
139
+ end
140
+
141
+ context 'WithMultipleDoMethods' do
142
+ before(:each) do
143
+ @callback = StateMachines::Callback.new(:before, :do => [:run_1, :run_2])
144
+
145
+ class << @object = Object.new
146
+ attr_accessor :callbacks
147
+
148
+ def run_1
149
+ (@callbacks ||= []) << :run_1
150
+ end
151
+
152
+ def run_2
153
+ (@callbacks ||= []) << :run_2
154
+ end
155
+ end
156
+
157
+ @result = @callback.call(@object)
158
+ end
159
+
160
+ it 'should_be_successful' do
161
+ assert @result
162
+ end
163
+
164
+ it 'should_call_each_callback_in_order' do
165
+ assert_equal [:run_1, :run_2], @object.callbacks
166
+ end
167
+ end
168
+
169
+ context 'WithBlock' do
170
+ before(:each) do
171
+ @callback = StateMachines::Callback.new(:before) do |*args|
172
+ @args = args
173
+ end
174
+
175
+ @object = Object.new
176
+ @result = @callback.call(@object)
177
+ end
178
+
179
+ it 'should_be_successful' do
180
+ assert @result
181
+ end
182
+
183
+ it 'should_call_with_empty_context' do
184
+ assert_equal [@object], @args
185
+ end
186
+ end
187
+
188
+ context 'WithMixedMethods' do
189
+ before(:each) do
190
+ @callback = StateMachines::Callback.new(:before, :run_argument, :do => :run_do) do |object|
191
+ object.callbacks << :block
192
+ end
193
+
194
+ class << @object = Object.new
195
+ attr_accessor :callbacks
196
+
197
+ def run_argument
198
+ (@callbacks ||= []) << :argument
199
+ end
200
+
201
+ def run_do
202
+ (@callbacks ||= []) << :do
203
+ end
204
+ end
205
+
206
+ @result = @callback.call(@object)
207
+ end
208
+
209
+ it 'should_be_successful' do
210
+ assert @result
211
+ end
212
+
213
+ it 'should_call_each_callback_in_order' do
214
+ assert_equal [:argument, :do, :block], @object.callbacks
215
+ end
216
+ end
217
+
218
+ context 'WithExplicitRequirements' do
219
+ before(:each) do
220
+ @object = Object.new
221
+ @callback = StateMachines::Callback.new(:before, :from => :parked, :to => :idling, :on => :ignite, :do => lambda {})
222
+ end
223
+
224
+ it 'should_call_with_empty_context' do
225
+ assert @callback.call(@object, {})
226
+ end
227
+
228
+ it 'should_not_call_if_from_not_included' do
229
+ assert !@callback.call(@object, :from => :idling)
230
+ end
231
+
232
+ it 'should_not_call_if_to_not_included' do
233
+ assert !@callback.call(@object, :to => :parked)
234
+ end
235
+
236
+ it 'should_not_call_if_on_not_included' do
237
+ assert !@callback.call(@object, :on => :park)
238
+ end
239
+
240
+ it 'should_call_if_all_requirements_met' do
241
+ assert @callback.call(@object, :from => :parked, :to => :idling, :on => :ignite)
242
+ end
243
+
244
+ it 'should_include_in_known_states' do
245
+ assert_equal [:parked, :idling], @callback.known_states
246
+ end
247
+ end
248
+
249
+ context 'WithImplicitRequirements' do
250
+ before(:each) do
251
+ @object = Object.new
252
+ @callback = StateMachines::Callback.new(:before, :parked => :idling, :on => :ignite, :do => lambda {})
253
+ end
254
+
255
+ it 'should_call_with_empty_context' do
256
+ assert @callback.call(@object, {})
257
+ end
258
+
259
+ it 'should_not_call_if_from_not_included' do
260
+ assert !@callback.call(@object, :from => :idling)
261
+ end
262
+
263
+ it 'should_not_call_if_to_not_included' do
264
+ assert !@callback.call(@object, :to => :parked)
265
+ end
266
+
267
+ it 'should_not_call_if_on_not_included' do
268
+ assert !@callback.call(@object, :on => :park)
269
+ end
270
+
271
+ it 'should_call_if_all_requirements_met' do
272
+ assert @callback.call(@object, :from => :parked, :to => :idling, :on => :ignite)
273
+ end
274
+
275
+ it 'should_include_in_known_states' do
276
+ assert_equal [:parked, :idling], @callback.known_states
277
+ end
278
+ end
279
+
280
+ context 'WithIfCondition' do
281
+ before(:each) do
282
+ @object = Object.new
283
+ end
284
+
285
+ it 'should_call_if_true' do
286
+ callback = StateMachines::Callback.new(:before, :if => lambda {true}, :do => lambda {})
287
+ assert callback.call(@object)
288
+ end
289
+
290
+ it 'should_not_call_if_false' do
291
+ callback = StateMachines::Callback.new(:before, :if => lambda {false}, :do => lambda {})
292
+ assert !callback.call(@object)
293
+ end
294
+ end
295
+
296
+ context 'WithUnlessCondition' do
297
+ before(:each) do
298
+ @object = Object.new
299
+ end
300
+
301
+ it 'should_call_if_false' do
302
+ callback = StateMachines::Callback.new(:before, :unless => lambda {false}, :do => lambda {})
303
+ assert callback.call(@object)
304
+ end
305
+
306
+ it 'should_not_call_if_true' do
307
+ callback = StateMachines::Callback.new(:before, :unless => lambda {true}, :do => lambda {})
308
+ assert !callback.call(@object)
309
+ end
310
+ end
311
+
312
+ context 'WithoutTerminator' do
313
+ before(:each) do
314
+ @object = Object.new
315
+ end
316
+
317
+ it 'should_not_halt_if_result_is_false' do
318
+ callback = StateMachines::Callback.new(:before, :do => lambda {false}, :terminator => nil)
319
+ assert_nothing_thrown { callback.call(@object) }
320
+ end
321
+ end
322
+
323
+ context 'WithTerminator' do
324
+ before(:each) do
325
+ @object = Object.new
326
+ end
327
+
328
+ it 'should_not_halt_if_terminator_does_not_match' do
329
+ callback = StateMachines::Callback.new(:before, :do => lambda {false}, :terminator => lambda {|result| result == true})
330
+ assert_nothing_thrown { callback.call(@object) }
331
+ end
332
+
333
+ it 'should_halt_if_terminator_matches' do
334
+ callback = StateMachines::Callback.new(:before, :do => lambda {false}, :terminator => lambda {|result| result == false})
335
+ assert_throws(:halt) { callback.call(@object) }
336
+ end
337
+
338
+ it 'should_halt_if_terminator_matches_any_method' do
339
+ callback = StateMachines::Callback.new(:before, :do => [lambda {true}, lambda {false}], :terminator => lambda {|result| result == false})
340
+ assert_throws(:halt) { callback.call(@object) }
341
+ end
342
+ end
343
+
344
+ context 'WithoutArguments' do
345
+ before(:each) do
346
+ @callback = StateMachines::Callback.new(:before, :do => lambda {|object| @arg = object})
347
+
348
+ @object = Object.new
349
+ @callback.call(@object, {}, 1, 2, 3)
350
+ end
351
+
352
+ it 'should_call_method_with_object_as_argument' do
353
+ assert_equal @object, @arg
354
+ end
355
+ end
356
+
357
+ context 'WithArguments' do
358
+ before(:each) do
359
+ @callback = StateMachines::Callback.new(:before, :do => lambda {|*args| @args = args})
360
+
361
+ @object = Object.new
362
+ @callback.call(@object, {}, 1, 2, 3)
363
+ end
364
+
365
+ it 'should_call_method_with_all_arguments' do
366
+ assert_equal [@object, 1, 2, 3], @args
367
+ end
368
+ end
369
+
370
+ context 'WithUnboundMethod' do
371
+ before(:each) do
372
+ @callback = StateMachines::Callback.new(:before, :do => lambda {|*args| @context = args.unshift(self)})
373
+
374
+ @object = Object.new
375
+ @callback.call(@object, {}, 1, 2, 3)
376
+ end
377
+
378
+ it 'should_call_method_outside_the_context_of_the_object' do
379
+ assert_equal [self, @object, 1, 2, 3], @context
380
+ end
381
+ end
382
+
383
+ context 'WithBoundMethod' do
384
+ before(:each) do
385
+ @object = Object.new
386
+ end
387
+
388
+ it 'should_call_method_within_the_context_of_the_object_for_block_methods' do
389
+ context = nil
390
+ callback = StateMachines::Callback.new(:before, :do => lambda {|*args| context = [self] + args}, :bind_to_object => true)
391
+ callback.call(@object, {}, 1, 2, 3)
392
+
393
+ assert_equal [@object, 1, 2, 3], context
394
+ end
395
+
396
+ it 'should_ignore_option_for_symbolic_methods' do
397
+ class << @object
398
+ attr_reader :context
399
+
400
+ def after_ignite(*args)
401
+ @context = args
402
+ end
403
+ end
404
+
405
+ callback = StateMachines::Callback.new(:before, :do => :after_ignite, :bind_to_object => true)
406
+ callback.call(@object)
407
+
408
+ assert_equal [], @object.context
409
+ end
410
+
411
+ it 'should_ignore_option_for_string_methods' do
412
+ callback = StateMachines::Callback.new(:before, :do => '[1, 2, 3]', :bind_to_object => true)
413
+ assert callback.call(@object)
414
+ end
415
+ end
416
+
417
+ context 'WithMultipleBoundMethods' do
418
+ before(:each) do
419
+ @object = Object.new
420
+
421
+ first_context = nil
422
+ second_context = nil
423
+
424
+ @callback = StateMachines::Callback.new(:before, :do => [lambda {first_context = self}, lambda {second_context = self}], :bind_to_object => true)
425
+ @callback.call(@object)
426
+
427
+ @first_context = first_context
428
+ @second_context = second_context
429
+ end
430
+
431
+ it 'should_call_each_method_within_the_context_of_the_object' do
432
+ assert_equal @object, @first_context
433
+ assert_equal @object, @second_context
434
+ end
435
+ end
436
+
437
+ context 'WithApplicationBoundObject' do
438
+ before(:each) do
439
+ @original_bind_to_object = StateMachines::Callback.bind_to_object
440
+ StateMachines::Callback.bind_to_object = true
441
+
442
+ context = nil
443
+ @callback = StateMachines::Callback.new(:before, :do => lambda {|*args| context = self})
444
+
445
+ @object = Object.new
446
+ @callback.call(@object)
447
+ @context = context
448
+ end
449
+
450
+ it 'should_call_method_within_the_context_of_the_object' do
451
+ assert_equal @object, @context
452
+ end
453
+
454
+ after(:each) do
455
+ StateMachines::Callback.bind_to_object = @original_bind_to_object
456
+ end
457
+ end
458
+
459
+ context 'WithBoundMethodAndArguments' do
460
+ before(:each) do
461
+ @object = Object.new
462
+ end
463
+
464
+ it 'should_include_single_argument_if_specified' do
465
+ context = nil
466
+ callback = StateMachines::Callback.new(:before, :do => lambda {|arg1| context = [arg1]}, :bind_to_object => true)
467
+ callback.call(@object, {}, 1)
468
+ assert_equal [1], context
469
+ end
470
+
471
+ it 'should_include_multiple_arguments_if_specified' do
472
+ context = nil
473
+ callback = StateMachines::Callback.new(:before, :do => lambda {|arg1, arg2, arg3| context = [arg1, arg2, arg3]}, :bind_to_object => true)
474
+ callback.call(@object, {}, 1, 2, 3)
475
+ assert_equal [1, 2, 3], context
476
+ end
477
+
478
+ it 'should_include_arguments_if_splat_used' do
479
+ context = nil
480
+ callback = StateMachines::Callback.new(:before, :do => lambda {|*args| context = args}, :bind_to_object => true)
481
+ callback.call(@object, {}, 1, 2, 3)
482
+ assert_equal [1, 2, 3], context
483
+ end
484
+ end
485
+
486
+ context 'WithApplicationTerminator' do
487
+ before(:each) do
488
+ @original_terminator = StateMachines::Callback.terminator
489
+ StateMachines::Callback.terminator = lambda {|result| result == false}
490
+
491
+ @object = Object.new
492
+ end
493
+
494
+ it 'should_not_halt_if_terminator_does_not_match' do
495
+ callback = StateMachines::Callback.new(:before, :do => lambda {true})
496
+ assert_nothing_thrown { callback.call(@object) }
497
+ end
498
+
499
+ it 'should_halt_if_terminator_matches' do
500
+ callback = StateMachines::Callback.new(:before, :do => lambda {false})
501
+ assert_throws(:halt) { callback.call(@object) }
502
+ end
503
+
504
+ def teardown
505
+ StateMachines::Callback.terminator = @original_terminator
506
+ end
507
+ end
508
+
509
+ context 'WithAroundTypeAndBlock' do
510
+ before(:each) do
511
+ @object = Object.new
512
+ @callbacks = []
513
+ end
514
+
515
+ it 'should_evaluate_before_without_after' do
516
+ callback = StateMachines::Callback.new(:around, lambda {|*args| block = args.pop; @args = args; block.call})
517
+ assert callback.call(@object)
518
+ assert_equal [@object], @args
519
+ end
520
+
521
+ it 'should_evaluate_after_without_before' do
522
+ callback = StateMachines::Callback.new(:around, lambda {|*args| block = args.pop; block.call; @args = args})
523
+ assert callback.call(@object)
524
+ assert_equal [@object], @args
525
+ end
526
+
527
+ it 'should_halt_if_not_yielded' do
528
+ callback = StateMachines::Callback.new(:around, lambda {|block|})
529
+ assert_throws(:halt) { callback.call(@object) }
530
+ end
531
+
532
+ it 'should_call_block_after_before' do
533
+ callback = StateMachines::Callback.new(:around, lambda {|block| @callbacks << :before; block.call})
534
+ assert callback.call(@object) { @callbacks << :block }
535
+ assert_equal [:before, :block], @callbacks
536
+ end
537
+
538
+ it 'should_call_block_before_after' do
539
+ @callbacks = []
540
+ callback = StateMachines::Callback.new(:around, lambda {|block| block.call; @callbacks << :after})
541
+ assert callback.call(@object) { @callbacks << :block }
542
+ assert_equal [:block, :after], @callbacks
543
+ end
544
+
545
+ it 'should_halt_if_block_halts' do
546
+ callback = StateMachines::Callback.new(:around, lambda {|block| block.call; @callbacks << :after})
547
+ assert_throws(:halt) { callback.call(@object) { throw :halt } }
548
+ assert_equal [], @callbacks
549
+ end
550
+ end
551
+
552
+ context 'WithAroundTypeAndMultipleMethods' do
553
+ before(:each) do
554
+ @callback = StateMachines::Callback.new(:around, :run_1, :run_2)
555
+
556
+ class << @object = Object.new
557
+ attr_accessor :before_callbacks
558
+ attr_accessor :after_callbacks
559
+
560
+ def run_1
561
+ (@before_callbacks ||= []) << :run_1
562
+ yield
563
+ (@after_callbacks ||= []) << :run_1
564
+ end
565
+
566
+ def run_2
567
+ (@before_callbacks ||= []) << :run_2
568
+ yield
569
+ (@after_callbacks ||= []) << :run_2
570
+ end
571
+ end
572
+ end
573
+
574
+ it 'should_succeed' do
575
+ assert @callback.call(@object)
576
+ end
577
+
578
+ it 'should_evaluate_before_callbacks_in_order' do
579
+ @callback.call(@object)
580
+ assert_equal [:run_1, :run_2], @object.before_callbacks
581
+ end
582
+
583
+ it 'should_evaluate_after_callbacks_in_reverse_order' do
584
+ @callback.call(@object)
585
+ assert_equal [:run_2, :run_1], @object.after_callbacks
586
+ end
587
+
588
+ it 'should_call_block_after_before_callbacks' do
589
+ @callback.call(@object) { (@object.before_callbacks ||= []) << :block }
590
+ assert_equal [:run_1, :run_2, :block], @object.before_callbacks
591
+ end
592
+
593
+ it 'should_call_block_before_after_callbacks' do
594
+ @callback.call(@object) { (@object.after_callbacks ||= []) << :block }
595
+ assert_equal [:block, :run_2, :run_1], @object.after_callbacks
596
+ end
597
+
598
+ it 'should_halt_if_first_doesnt_yield' do
599
+ class << @object
600
+ remove_method :run_1
601
+ def run_1
602
+ (@before_callbacks ||= []) << :run_1
603
+ end
604
+ end
605
+
606
+ catch(:halt) do
607
+ @callback.call(@object) { (@object.before_callbacks ||= []) << :block }
608
+ end
609
+
610
+ assert_equal [:run_1], @object.before_callbacks
611
+ assert_nil @object.after_callbacks
612
+ end
613
+
614
+ it 'should_halt_if_last_doesnt_yield' do
615
+ class << @object
616
+ remove_method :run_2
617
+ def run_2
618
+ (@before_callbacks ||= []) << :run_2
619
+ end
620
+ end
621
+
622
+ catch(:halt) { @callback.call(@object) }
623
+ assert_equal [:run_1, :run_2], @object.before_callbacks
624
+ assert_nil @object.after_callbacks
625
+ end
626
+
627
+ it 'should_not_evaluate_further_methods_if_after_halts' do
628
+ class << @object
629
+ remove_method :run_2
630
+ def run_2
631
+ (@before_callbacks ||= []) << :run_2
632
+ yield
633
+ (@after_callbacks ||= []) << :run_2
634
+ throw :halt
635
+ end
636
+ end
637
+
638
+ catch(:halt) { @callback.call(@object) }
639
+ assert_equal [:run_1, :run_2], @object.before_callbacks
640
+ assert_equal [:run_2], @object.after_callbacks
641
+ end
642
+ end
643
+
644
+ context 'WithAroundTypeAndArguments' do
645
+ before(:each) do
646
+ @object = Object.new
647
+ end
648
+
649
+ it 'should_include_object_if_specified' do
650
+ callback = StateMachines::Callback.new(:around, lambda {|object, block| @args = [object]; block.call})
651
+ callback.call(@object)
652
+ assert_equal [@object], @args
653
+ end
654
+
655
+ it 'should_include_arguments_if_specified' do
656
+ callback = StateMachines::Callback.new(:around, lambda {|object, arg1, arg2, arg3, block| @args = [object, arg1, arg2, arg3]; block.call})
657
+ callback.call(@object, {}, 1, 2, 3)
658
+ assert_equal [@object, 1, 2, 3], @args
659
+ end
660
+
661
+ it 'should_include_arguments_if_splat_used' do
662
+ callback = StateMachines::Callback.new(:around, lambda {|*args| block = args.pop; @args = args; block.call})
663
+ callback.call(@object, {}, 1, 2, 3)
664
+ assert_equal [@object, 1, 2, 3], @args
665
+ end
666
+ end
667
+
668
+ context 'WithAroundTypeAndTerminator' do
669
+ before(:each) do
670
+ @object = Object.new
671
+ end
672
+
673
+ it 'should_not_halt_if_terminator_does_not_match' do
674
+ callback = StateMachines::Callback.new(:around, :do => lambda {|block| block.call(false); false}, :terminator => lambda {|result| result == true})
675
+ assert_nothing_thrown { callback.call(@object) }
676
+ end
677
+
678
+ it 'should_not_halt_if_terminator_matches' do
679
+ callback = StateMachines::Callback.new(:around, :do => lambda {|block| block.call(false); false}, :terminator => lambda {|result| result == false})
680
+ assert_nothing_thrown { callback.call(@object) }
681
+ end
682
+ end
683
+
684
+ context 'WithAroundTypeAndBoundMethod' do
685
+ before(:each) do
686
+ @object = Object.new
687
+ end
688
+
689
+ it 'should_call_method_within_the_context_of_the_object' do
690
+ context = nil
691
+ callback = StateMachines::Callback.new(:around, :do => lambda {|block| context = self; block.call}, :bind_to_object => true)
692
+ callback.call(@object, {}, 1, 2, 3)
693
+
694
+ assert_equal @object, context
695
+ end
696
+
697
+ it 'should_include_arguments_if_specified' do
698
+ context = nil
699
+ callback = StateMachines::Callback.new(:around, :do => lambda {|*args| block = args.pop; context = args; block.call}, :bind_to_object => true)
700
+ callback.call(@object, {}, 1, 2, 3)
701
+
702
+ assert_equal [1, 2, 3], context
703
+ end
704
+ end
705
+
706
+ end