state_machine 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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