state_machine 0.7.1 → 0.7.2

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.
@@ -1,15 +1,23 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
2
 
3
3
  class CallbackTest < Test::Unit::TestCase
4
- def test_should_raise_exception_if_do_option_not_specified
4
+ def test_should_raise_exception_if_no_methods_specified
5
5
  exception = assert_raise(ArgumentError) { StateMachine::Callback.new }
6
- assert_equal ':do callback must be specified', exception.message
6
+ assert_equal 'Method(s) for callback must be specified', exception.message
7
7
  end
8
8
 
9
- def test_should_not_raise_exception_if_do_option_specified
9
+ def test_should_not_raise_exception_if_method_specified_in_do_option
10
10
  assert_nothing_raised { StateMachine::Callback.new(:do => :run) }
11
11
  end
12
12
 
13
+ def test_should_not_raise_exception_if_method_specified_as_argument
14
+ assert_nothing_raised { StateMachine::Callback.new(:run) }
15
+ end
16
+
17
+ def test_should_not_raise_exception_if_method_specified_as_block
18
+ assert_nothing_raised { StateMachine::Callback.new(:run) {} }
19
+ end
20
+
13
21
  def test_should_not_raise_exception_if_implicit_option_specified
14
22
  assert_nothing_raised { StateMachine::Callback.new(:do => :run, :invalid => true) }
15
23
  end
@@ -25,9 +33,7 @@ end
25
33
 
26
34
  class CallbackByDefaultTest < Test::Unit::TestCase
27
35
  def setup
28
- @object = Object.new
29
- @method = lambda {|*args| args.unshift(self)}
30
- @callback = StateMachine::Callback.new(:do => @method)
36
+ @callback = StateMachine::Callback.new(:do => lambda {})
31
37
  end
32
38
 
33
39
  def test_should_not_have_a_terminator
@@ -40,30 +46,154 @@ class CallbackByDefaultTest < Test::Unit::TestCase
40
46
  assert_equal StateMachine::AllMatcher.instance, @callback.guard.state_requirements.first[:to]
41
47
  end
42
48
 
43
- def test_should_not_bind_to_the_object
44
- assert_equal [self, @object], @callback.call(@object)
45
- end
46
-
47
49
  def test_should_not_have_any_known_states
48
50
  assert_equal [], @callback.known_states
49
51
  end
50
52
  end
51
53
 
52
- class CallbackWithOnlyMethodTest < Test::Unit::TestCase
54
+ class CallbackWithMethodArgumentTest < Test::Unit::TestCase
55
+ def setup
56
+ @callback = StateMachine::Callback.new(lambda {|*args| @args = args})
57
+
58
+ @object = Object.new
59
+ @result = @callback.call(@object)
60
+ end
61
+
62
+ def test_should_be_successful
63
+ assert @result
64
+ end
65
+
66
+ def test_should_call_with_empty_context
67
+ assert_equal [@object], @args
68
+ end
69
+ end
70
+
71
+ class CallbackWithMultipleMethodArgumentsTest < Test::Unit::TestCase
72
+ def setup
73
+ @callback = StateMachine::Callback.new(:run_1, :run_2)
74
+
75
+ class << @object = Object.new
76
+ attr_accessor :callbacks
77
+
78
+ def run_1
79
+ (@callbacks ||= []) << :run_1
80
+ end
81
+
82
+ def run_2
83
+ (@callbacks ||= []) << :run_2
84
+ end
85
+ end
86
+
87
+ @result = @callback.call(@object)
88
+ end
89
+
90
+ def test_should_be_successful
91
+ assert @result
92
+ end
93
+
94
+ def test_should_call_each_callback_in_order
95
+ assert_equal [:run_1, :run_2], @object.callbacks
96
+ end
97
+ end
98
+
99
+ class CallbackWithDoMethodTest < Test::Unit::TestCase
100
+ def setup
101
+ @callback = StateMachine::Callback.new(:do => lambda {|*args| @args = args})
102
+
103
+ @object = Object.new
104
+ @result = @callback.call(@object)
105
+ end
106
+
107
+ def test_should_be_successful
108
+ assert @result
109
+ end
110
+
111
+ def test_should_call_with_empty_context
112
+ assert_equal [@object], @args
113
+ end
114
+ end
115
+
116
+ class CallbackWithMultipleDoMethodsTest < Test::Unit::TestCase
117
+ def setup
118
+ @callback = StateMachine::Callback.new(:do => [:run_1, :run_2])
119
+
120
+ class << @object = Object.new
121
+ attr_accessor :callbacks
122
+
123
+ def run_1
124
+ (@callbacks ||= []) << :run_1
125
+ end
126
+
127
+ def run_2
128
+ (@callbacks ||= []) << :run_2
129
+ end
130
+ end
131
+
132
+ @result = @callback.call(@object)
133
+ end
134
+
135
+ def test_should_be_successful
136
+ assert @result
137
+ end
138
+
139
+ def test_should_call_each_callback_in_order
140
+ assert_equal [:run_1, :run_2], @object.callbacks
141
+ end
142
+ end
143
+
144
+ class CallbackWithBlockTest < Test::Unit::TestCase
53
145
  def setup
146
+ @callback = StateMachine::Callback.new do |*args|
147
+ @args = args
148
+ end
149
+
54
150
  @object = Object.new
55
- @callback = StateMachine::Callback.new(lambda {true})
151
+ @result = @callback.call(@object)
152
+ end
153
+
154
+ def test_should_be_successful
155
+ assert @result
56
156
  end
57
157
 
58
158
  def test_should_call_with_empty_context
59
- assert @callback.call(@object)
159
+ assert_equal [@object], @args
160
+ end
161
+ end
162
+
163
+ class CallbackWithMixedMethodsTest < Test::Unit::TestCase
164
+ def setup
165
+ @callback = StateMachine::Callback.new(:run_argument, :do => :run_do) do |object|
166
+ object.callbacks << :block
167
+ end
168
+
169
+ class << @object = Object.new
170
+ attr_accessor :callbacks
171
+
172
+ def run_argument
173
+ (@callbacks ||= []) << :argument
174
+ end
175
+
176
+ def run_do
177
+ (@callbacks ||= []) << :do
178
+ end
179
+ end
180
+
181
+ @result = @callback.call(@object)
182
+ end
183
+
184
+ def test_should_be_successful
185
+ assert @result
186
+ end
187
+
188
+ def test_should_call_each_callback_in_order
189
+ assert_equal [:argument, :do, :block], @object.callbacks
60
190
  end
61
191
  end
62
192
 
63
193
  class CallbackWithExplicitRequirementsTest < Test::Unit::TestCase
64
194
  def setup
65
195
  @object = Object.new
66
- @callback = StateMachine::Callback.new(:from => :parked, :to => :idling, :on => :ignite, :do => lambda {true})
196
+ @callback = StateMachine::Callback.new(:from => :parked, :to => :idling, :on => :ignite, :do => lambda {})
67
197
  end
68
198
 
69
199
  def test_should_call_with_empty_context
@@ -94,7 +224,7 @@ end
94
224
  class CallbackWithImplicitRequirementsTest < Test::Unit::TestCase
95
225
  def setup
96
226
  @object = Object.new
97
- @callback = StateMachine::Callback.new(:parked => :idling, :on => :ignite, :do => lambda {true})
227
+ @callback = StateMachine::Callback.new(:parked => :idling, :on => :ignite, :do => lambda {})
98
228
  end
99
229
 
100
230
  def test_should_call_with_empty_context
@@ -128,12 +258,12 @@ class CallbackWithIfConditionTest < Test::Unit::TestCase
128
258
  end
129
259
 
130
260
  def test_should_call_if_true
131
- callback = StateMachine::Callback.new(:if => lambda {true}, :do => lambda {true})
261
+ callback = StateMachine::Callback.new(:if => lambda {true}, :do => lambda {})
132
262
  assert callback.call(@object)
133
263
  end
134
264
 
135
265
  def test_should_not_call_if_false
136
- callback = StateMachine::Callback.new(:if => lambda {false}, :do => lambda {true})
266
+ callback = StateMachine::Callback.new(:if => lambda {false}, :do => lambda {})
137
267
  assert !callback.call(@object)
138
268
  end
139
269
  end
@@ -144,12 +274,12 @@ class CallbackWithUnlessConditionTest < Test::Unit::TestCase
144
274
  end
145
275
 
146
276
  def test_should_call_if_false
147
- callback = StateMachine::Callback.new(:unless => lambda {false}, :do => lambda {true})
277
+ callback = StateMachine::Callback.new(:unless => lambda {false}, :do => lambda {})
148
278
  assert callback.call(@object)
149
279
  end
150
280
 
151
281
  def test_should_not_call_if_true
152
- callback = StateMachine::Callback.new(:unless => lambda {true}, :do => lambda {true})
282
+ callback = StateMachine::Callback.new(:unless => lambda {true}, :do => lambda {})
153
283
  assert !callback.call(@object)
154
284
  end
155
285
  end
@@ -171,73 +301,111 @@ class CallbackWithTerminatorTest < Test::Unit::TestCase
171
301
  end
172
302
 
173
303
  def test_should_not_halt_if_terminator_does_not_match
174
- callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => lambda {|result| false})
304
+ callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => lambda {|result| result == true})
175
305
  assert_nothing_thrown { callback.call(@object) }
176
306
  end
177
307
 
178
308
  def test_should_halt_if_terminator_matches
179
- callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => lambda {|result| true})
309
+ callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => lambda {|result| result == false})
310
+ assert_throws(:halt) { callback.call(@object) }
311
+ end
312
+
313
+ def test_should_halt_if_terminator_matches_any_method
314
+ callback = StateMachine::Callback.new(:do => [lambda {true}, lambda {false}], :terminator => lambda {|result| result == false})
180
315
  assert_throws(:halt) { callback.call(@object) }
181
316
  end
182
317
  end
183
318
 
184
319
  class CallbackWithoutArgumentsTest < Test::Unit::TestCase
185
320
  def setup
321
+ @callback = StateMachine::Callback.new(:do => lambda {|object| @arg = object})
322
+
186
323
  @object = Object.new
187
- @callback = StateMachine::Callback.new(:do => lambda {|object| object})
324
+ @callback.call(@object, {}, 1, 2, 3)
188
325
  end
189
326
 
190
327
  def test_should_call_method_with_object_as_argument
191
- assert_equal @object, @callback.call(@object, {}, 1, 2, 3)
328
+ assert_equal @object, @arg
192
329
  end
193
330
  end
194
331
 
195
332
  class CallbackWithArgumentsTest < Test::Unit::TestCase
196
333
  def setup
334
+ @callback = StateMachine::Callback.new(:do => lambda {|*args| @args = args})
335
+
197
336
  @object = Object.new
198
- @callback = StateMachine::Callback.new(:do => lambda {|*args| args})
337
+ @callback.call(@object, {}, 1, 2, 3)
199
338
  end
200
339
 
201
340
  def test_should_call_method_with_all_arguments
202
- assert_equal [@object, 1, 2, 3], @callback.call(@object, {}, 1, 2, 3)
341
+ assert_equal [@object, 1, 2, 3], @args
203
342
  end
204
343
  end
205
344
 
206
- class CallbackWithUnboundObjectTest < Test::Unit::TestCase
345
+ class CallbackWithUnboundMethodTest < Test::Unit::TestCase
207
346
  def setup
347
+ @callback = StateMachine::Callback.new(:do => lambda {|*args| @context = args.unshift(self)})
348
+
208
349
  @object = Object.new
209
- @callback = StateMachine::Callback.new(:do => lambda {|*args| args.unshift(self)})
350
+ @callback.call(@object, {}, 1, 2, 3)
210
351
  end
211
352
 
212
353
  def test_should_call_method_outside_the_context_of_the_object
213
- assert_equal [self, @object, 1, 2, 3], @callback.call(@object, {}, 1, 2, 3)
354
+ assert_equal [self, @object, 1, 2, 3], @context
214
355
  end
215
356
  end
216
357
 
217
- class CallbackWithBoundObjectTest < Test::Unit::TestCase
358
+ class CallbackWithBoundMethodTest < Test::Unit::TestCase
218
359
  def setup
219
360
  @object = Object.new
220
- @callback = StateMachine::Callback.new(:do => lambda {|*args| args.unshift(self)}, :bind_to_object => true)
221
361
  end
222
362
 
223
- def test_should_call_method_within_the_context_of_the_object
224
- assert_equal [@object, 1, 2, 3], @callback.call(@object, {}, 1, 2, 3)
363
+ def test_should_call_method_within_the_context_of_the_object_for_block_methods
364
+ context = nil
365
+ callback = StateMachine::Callback.new(:do => lambda {|*args| context = [self] + args}, :bind_to_object => true)
366
+ callback.call(@object, {}, 1, 2, 3)
367
+
368
+ assert_equal [@object, 1, 2, 3], context
225
369
  end
226
370
 
227
- def test_should_ignore_option_for_symbolic_callbacks
371
+ def test_should_ignore_option_for_symbolic_methods
228
372
  class << @object
373
+ attr_reader :context
374
+
229
375
  def after_ignite(*args)
230
- args
376
+ @context = args
231
377
  end
232
378
  end
233
379
 
234
- @callback = StateMachine::Callback.new(:do => :after_ignite, :bind_to_object => true)
235
- assert_equal [], @callback.call(@object)
380
+ callback = StateMachine::Callback.new(:do => :after_ignite, :bind_to_object => true)
381
+ callback.call(@object)
382
+
383
+ assert_equal [], @object.context
236
384
  end
237
385
 
238
- def test_should_ignore_option_for_string_callbacks
239
- @callback = StateMachine::Callback.new(:do => '[1, 2, 3]', :bind_to_object => true)
240
- assert_equal [1, 2, 3], @callback.call(@object)
386
+ def test_should_ignore_option_for_string_methods
387
+ callback = StateMachine::Callback.new(:do => '[1, 2, 3]', :bind_to_object => true)
388
+ assert callback.call(@object)
389
+ end
390
+ end
391
+
392
+ class CallbackWithMultipleBoundMethodsTest < Test::Unit::TestCase
393
+ def setup
394
+ @object = Object.new
395
+
396
+ first_context = nil
397
+ second_context = nil
398
+
399
+ @callback = StateMachine::Callback.new(:do => [lambda {first_context = self}, lambda {second_context = self}], :bind_to_object => true)
400
+ @callback.call(@object)
401
+
402
+ @first_context = first_context
403
+ @second_context = second_context
404
+ end
405
+
406
+ def test_should_call_each_method_within_the_context_of_the_object
407
+ assert_equal @object, @first_context
408
+ assert_equal @object, @second_context
241
409
  end
242
410
  end
243
411
 
@@ -246,12 +414,16 @@ class CallbackWithApplicationBoundObjectTest < Test::Unit::TestCase
246
414
  @original_bind_to_object = StateMachine::Callback.bind_to_object
247
415
  StateMachine::Callback.bind_to_object = true
248
416
 
417
+ context = nil
418
+ @callback = StateMachine::Callback.new(:do => lambda {|*args| context = self})
419
+
249
420
  @object = Object.new
250
- @callback = StateMachine::Callback.new(:do => lambda {|*args| self})
421
+ @callback.call(@object)
422
+ @context = context
251
423
  end
252
424
 
253
425
  def test_should_call_method_within_the_context_of_the_object
254
- assert_equal @object, @callback.call(@object)
426
+ assert_equal @object, @context
255
427
  end
256
428
 
257
429
  def teardown
@@ -319,10 +319,6 @@ class MachineCollectionFireImplicitWithInvalidEventTest < MachineCollectionFireI
319
319
  def test_should_not_reset_event_attribute
320
320
  assert_equal :invalid, @object.state_event
321
321
  end
322
-
323
- def test_should_not_have_event_transition
324
- assert_nil @object.state_event_transition
325
- end
326
322
  end
327
323
 
328
324
  class MachineCollectionFireImplicitWithoutTransitionTest < MachineCollectionFireImplicitTest
@@ -349,10 +345,6 @@ class MachineCollectionFireImplicitWithoutTransitionTest < MachineCollectionFire
349
345
  def test_should_not_reset_event_attribute
350
346
  assert_equal :ignite, @object.state_event
351
347
  end
352
-
353
- def test_should_not_have_event_transition
354
- assert_nil @object.state_event_transition
355
- end
356
348
  end
357
349
 
358
350
  class MachineCollectionFireImplicitWithTransitionTest < MachineCollectionFireImplicitTest
@@ -360,12 +352,10 @@ class MachineCollectionFireImplicitWithTransitionTest < MachineCollectionFireImp
360
352
  super
361
353
 
362
354
  @state_event = nil
363
- @state_event_transition = nil
364
355
 
365
356
  @object.state_event = 'ignite'
366
357
  @result = @machines.fire_attribute_events(@object, :save) do
367
358
  @state_event = @object.state_event
368
- @state_event_transition = @object.state_event_transition
369
359
  @saved = true
370
360
  end
371
361
  end
@@ -382,10 +372,6 @@ class MachineCollectionFireImplicitWithTransitionTest < MachineCollectionFireImp
382
372
  assert_nil @state_event
383
373
  end
384
374
 
385
- def test_should_not_have_event_transition_while_running_action
386
- assert_nil @state_event_transition
387
- end
388
-
389
375
  def test_should_transition_state
390
376
  assert_equal 'idling', @object.state
391
377
  end
@@ -394,8 +380,9 @@ class MachineCollectionFireImplicitWithTransitionTest < MachineCollectionFireImp
394
380
  assert_nil @object.state_event
395
381
  end
396
382
 
397
- def test_should_reset_event_transition
398
- assert_nil @object.state_event_transition
383
+ def test_should_not_be_successful_if_fired_again
384
+ @object.state_event = 'ignite'
385
+ assert !@machines.fire_attribute_events(@object, :save) { true }
399
386
  end
400
387
  end
401
388
 
@@ -418,10 +405,6 @@ class MachineCollectionFireImplicitWithActionFailureTest < MachineCollectionFire
418
405
  def test_should_not_reset_event_attribute
419
406
  assert_equal :ignite, @object.state_event
420
407
  end
421
-
422
- def test_should_not_have_event_transition
423
- assert_nil @object.state_event_transition
424
- end
425
408
  end
426
409
 
427
410
  class MachineCollectionFireImplicitWithActionErrorTest < MachineCollectionFireImplicitTest
@@ -439,10 +422,6 @@ class MachineCollectionFireImplicitWithActionErrorTest < MachineCollectionFireIm
439
422
  def test_should_not_reset_event_attribute
440
423
  assert_equal :ignite, @object.state_event
441
424
  end
442
-
443
- def test_should_not_have_event_transition
444
- assert_nil @object.state_event_transition
445
- end
446
425
  end
447
426
 
448
427
  class MachineCollectionFireImplicitPartialTest < MachineCollectionFireImplicitTest
@@ -455,12 +434,10 @@ class MachineCollectionFireImplicitPartialTest < MachineCollectionFireImplicitTe
455
434
  @machine.after_transition { @ran_after_callback = true }
456
435
 
457
436
  @state_event = nil
458
- @state_event_transition = nil
459
437
 
460
438
  @object.state_event = 'ignite'
461
439
  @result = @machines.fire_attribute_events(@object, :save, false) do
462
440
  @state_event = @object.state_event
463
- @state_event_transition = @object.state_event_transition
464
441
  true
465
442
  end
466
443
  end
@@ -481,10 +458,6 @@ class MachineCollectionFireImplicitPartialTest < MachineCollectionFireImplicitTe
481
458
  assert_nil @state_event
482
459
  end
483
460
 
484
- def test_should_not_have_event_transition_while_running_action
485
- assert_nil @state_event_transition
486
- end
487
-
488
461
  def test_should_transition_state
489
462
  assert_equal 'idling', @object.state
490
463
  end
@@ -493,29 +466,50 @@ class MachineCollectionFireImplicitPartialTest < MachineCollectionFireImplicitTe
493
466
  assert_equal :ignite, @object.state_event
494
467
  end
495
468
 
496
- def test_should_have_event_transition
497
- assert_not_nil @object.state_event_transition
498
- end
499
-
500
469
  def test_should_reset_event_attributes_after_next_fire_on_success
501
470
  assert @machines.fire_attribute_events(@object, :save) { true }
502
471
  assert_equal 'idling', @object.state
503
472
  assert_nil @object.state_event
504
- assert_nil @object.state_event_transition
473
+ end
474
+
475
+ def test_should_guard_transition_after_next_fire_on_success
476
+ @machines.fire_attribute_events(@object, :save) { true }
477
+
478
+ @object.state = 'idling'
479
+ @object.state_event = 'ignite'
480
+ assert !@machines.fire_attribute_events(@object, :save) { true }
505
481
  end
506
482
 
507
483
  def test_should_rollback_all_attributes_after_next_fire_on_failure
508
484
  assert !@machines.fire_attribute_events(@object, :save) { false }
509
485
  assert_equal 'parked', @object.state
510
486
  assert_equal :ignite, @object.state_event
511
- assert_nil @object.state_event_transition
487
+
488
+ @object.state = 'idling'
489
+ assert !@machines.fire_attribute_events(@object, :save) { false }
490
+ end
491
+
492
+ def test_should_guard_transition_after_next_fire_on_failure
493
+ @machines.fire_attribute_events(@object, :save) { false }
494
+
495
+ @object.state = 'idling'
496
+ assert !@machines.fire_attribute_events(@object, :save) { true }
512
497
  end
513
498
 
514
499
  def test_should_rollback_all_attributes_after_next_fire_on_error
515
500
  assert_raise(ArgumentError) { @machines.fire_attribute_events(@object, :save) { raise ArgumentError } }
516
501
  assert_equal 'parked', @object.state
517
502
  assert_equal :ignite, @object.state_event
518
- assert_nil @object.state_event_transition
503
+ end
504
+
505
+ def test_should_guard_transition_after_next_fire_on_error
506
+ begin
507
+ @machines.fire_attribute_events(@object, :save) { raise ArgumentError }
508
+ rescue ArgumentError
509
+ end
510
+
511
+ @object.state = 'idling'
512
+ assert !@machines.fire_attribute_events(@object, :save) { true }
519
513
  end
520
514
  end
521
515
 
@@ -547,10 +541,6 @@ class MachineCollectionFireImplicitNestedPartialTest < MachineCollectionFireImpl
547
541
  def test_should_reset_event_attribute
548
542
  assert_nil @object.state_event
549
543
  end
550
-
551
- def test_should_not_have_event_transition
552
- assert_nil @object.state_event_transition
553
- end
554
544
  end
555
545
 
556
546
  class MachineCollectionFireImplicitWithDifferentActionsTest < MachineCollectionFireImplicitTest
@@ -613,11 +603,6 @@ class MachineCollectionFireImplicitWithSameActionsTest < MachineCollectionFireIm
613
603
  assert_nil @object.state_event
614
604
  assert_nil @object.alarm_state_event
615
605
  end
616
-
617
- def test_should_reset_all_event_transitions_for_action
618
- assert_nil @object.state_event_transition
619
- assert_nil @object.alarm_state_event_transition
620
- end
621
606
  end
622
607
 
623
608
  class MachineCollectionFireImplicitWithValidationsTest < Test::Unit::TestCase