state_machine 0.8.1 → 0.9.0

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.
Files changed (42) hide show
  1. data/CHANGELOG.rdoc +17 -0
  2. data/LICENSE +1 -1
  3. data/README.rdoc +162 -23
  4. data/Rakefile +3 -18
  5. data/lib/state_machine.rb +3 -4
  6. data/lib/state_machine/callback.rb +65 -13
  7. data/lib/state_machine/eval_helpers.rb +20 -4
  8. data/lib/state_machine/initializers.rb +4 -0
  9. data/lib/state_machine/initializers/merb.rb +1 -0
  10. data/lib/state_machine/initializers/rails.rb +7 -0
  11. data/lib/state_machine/integrations.rb +21 -6
  12. data/lib/state_machine/integrations/active_model.rb +414 -0
  13. data/lib/state_machine/integrations/active_model/locale.rb +11 -0
  14. data/lib/state_machine/integrations/{active_record → active_model}/observer.rb +7 -7
  15. data/lib/state_machine/integrations/active_record.rb +65 -129
  16. data/lib/state_machine/integrations/active_record/locale.rb +4 -11
  17. data/lib/state_machine/integrations/data_mapper.rb +24 -6
  18. data/lib/state_machine/integrations/data_mapper/observer.rb +36 -0
  19. data/lib/state_machine/integrations/mongo_mapper.rb +295 -0
  20. data/lib/state_machine/integrations/sequel.rb +33 -7
  21. data/lib/state_machine/machine.rb +121 -23
  22. data/lib/state_machine/machine_collection.rb +12 -103
  23. data/lib/state_machine/transition.rb +125 -164
  24. data/lib/state_machine/transition_collection.rb +244 -0
  25. data/lib/tasks/state_machine.rb +12 -15
  26. data/test/functional/state_machine_test.rb +11 -1
  27. data/test/unit/callback_test.rb +305 -32
  28. data/test/unit/eval_helpers_test.rb +103 -1
  29. data/test/unit/event_test.rb +2 -1
  30. data/test/unit/guard_test.rb +2 -1
  31. data/test/unit/integrations/active_model_test.rb +909 -0
  32. data/test/unit/integrations/active_record_test.rb +1542 -1292
  33. data/test/unit/integrations/data_mapper_test.rb +1369 -1041
  34. data/test/unit/integrations/mongo_mapper_test.rb +1349 -0
  35. data/test/unit/integrations/sequel_test.rb +1214 -985
  36. data/test/unit/integrations_test.rb +8 -0
  37. data/test/unit/machine_collection_test.rb +140 -513
  38. data/test/unit/machine_test.rb +212 -10
  39. data/test/unit/state_test.rb +2 -1
  40. data/test/unit/transition_collection_test.rb +2098 -0
  41. data/test/unit/transition_test.rb +704 -552
  42. metadata +16 -3
@@ -24,6 +24,10 @@ class IntegrationMatcherTest < Test::Unit::TestCase
24
24
  end
25
25
 
26
26
  class IntegrationFinderTest < Test::Unit::TestCase
27
+ def test_should_find_active_model
28
+ assert_equal StateMachine::Integrations::ActiveModel, StateMachine::Integrations.find(:active_model)
29
+ end
30
+
27
31
  def test_should_find_active_record
28
32
  assert_equal StateMachine::Integrations::ActiveRecord, StateMachine::Integrations.find(:active_record)
29
33
  end
@@ -32,6 +36,10 @@ class IntegrationFinderTest < Test::Unit::TestCase
32
36
  assert_equal StateMachine::Integrations::DataMapper, StateMachine::Integrations.find(:data_mapper)
33
37
  end
34
38
 
39
+ def test_should_find_mongo_mapper
40
+ assert_equal StateMachine::Integrations::MongoMapper, StateMachine::Integrations.find(:mongo_mapper)
41
+ end
42
+
35
43
  def test_should_find_sequel
36
44
  assert_equal StateMachine::Integrations::Sequel, StateMachine::Integrations.find(:sequel)
37
45
  end
@@ -101,9 +101,18 @@ class MachineCollectionStateInitializationTest < Test::Unit::TestCase
101
101
  assert_equal 'parked', @object.state
102
102
  assert_equal 'active', @object.alarm_state
103
103
  end
104
+
105
+ def test_should_not_modify_ignore_option
106
+ ignore = ['state', 'alarm_state']
107
+ @machines.initialize_states(@object, :ignore => ignore)
108
+
109
+ assert_nil @object.state
110
+ assert_nil @object.alarm_state
111
+ assert_equal ['state', 'alarm_state'], ignore
112
+ end
104
113
  end
105
114
 
106
- class MachineCollectionFireExplicitTest < Test::Unit::TestCase
115
+ class MachineCollectionFireTest < Test::Unit::TestCase
107
116
  def setup
108
117
  @machines = StateMachine::MachineCollection.new
109
118
 
@@ -171,7 +180,7 @@ class MachineCollectionFireExplicitTest < Test::Unit::TestCase
171
180
  end
172
181
  end
173
182
 
174
- class MachineCollectionFireExplicitWithTransactionsTest < Test::Unit::TestCase
183
+ class MachineCollectionFireWithTransactionsTest < Test::Unit::TestCase
175
184
  def setup
176
185
  @machines = StateMachine::MachineCollection.new
177
186
 
@@ -231,7 +240,7 @@ class MachineCollectionFireExplicitWithTransactionsTest < Test::Unit::TestCase
231
240
  end
232
241
  end
233
242
 
234
- class MachineCollectionFireExplicitWithValidationsTest < Test::Unit::TestCase
243
+ class MachineCollectionFireWithValidationsTest < Test::Unit::TestCase
235
244
  def setup
236
245
  StateMachine::Integrations.const_set('Custom', Module.new do
237
246
  def invalidate(object, attribute, message, values = [])
@@ -284,7 +293,7 @@ class MachineCollectionFireExplicitWithValidationsTest < Test::Unit::TestCase
284
293
  end
285
294
  end
286
295
 
287
- class MachineCollectionFireImplicitTest < Test::Unit::TestCase
296
+ class MachineCollectionTransitionsWithoutEventsTest < Test::Unit::TestCase
288
297
  def setup
289
298
  @klass = Class.new
290
299
 
@@ -294,507 +303,216 @@ class MachineCollectionFireImplicitTest < Test::Unit::TestCase
294
303
  transition :parked => :idling
295
304
  end
296
305
 
297
- @saved = false
298
306
  @object = @klass.new
299
- end
300
-
301
- def default_test
302
- end
303
- end
304
-
305
- class MachineCollectionFireImplicitWithoutEventTest < MachineCollectionFireImplicitTest
306
- def setup
307
- super
308
-
309
307
  @object.state_event = nil
310
- @result = @machines.fire_event_attributes(@object, :save) { @saved = true }
311
- end
312
-
313
- def test_should_be_successful
314
- assert_equal true, @result
315
- end
316
-
317
- def test_should_run_action
318
- assert @saved
308
+ @transitions = @machines.transitions(@object, :save)
319
309
  end
320
310
 
321
- def test_should_not_transition_state
322
- assert_equal 'parked', @object.state
311
+ def test_should_be_empty
312
+ assert @transitions.empty?
323
313
  end
324
314
 
325
- def test_should_not_change_event_attribute
326
- assert_nil @object.state_event
327
- end
328
-
329
- def test_should_not_have_event_transition
330
- assert_nil @object.send(:state_event_transition)
315
+ def test_should_perform
316
+ assert_equal true, @transitions.perform
331
317
  end
332
318
  end
333
319
 
334
- class MachineCollectionFireImplicitWithBlankEventTest < MachineCollectionFireImplicitTest
320
+ class MachineCollectionTransitionsWithBlankEventsTest < Test::Unit::TestCase
335
321
  def setup
336
- super
322
+ @klass = Class.new
337
323
 
324
+ @machines = StateMachine::MachineCollection.new
325
+ @machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
326
+ @machine.event :ignite do
327
+ transition :parked => :idling
328
+ end
329
+
330
+ @object = @klass.new
338
331
  @object.state_event = ''
339
- @result = @machines.fire_event_attributes(@object, :save) { @saved = true }
332
+ @transitions = @machines.transitions(@object, :save)
340
333
  end
341
334
 
342
- def test_should_be_successful
343
- assert_equal true, @result
335
+ def test_should_be_empty
336
+ assert @transitions.empty?
344
337
  end
345
338
 
346
- def test_should_run_action
347
- assert @saved
348
- end
349
-
350
- def test_should_not_transition_state
351
- assert_equal 'parked', @object.state
352
- end
353
-
354
- def test_should_not_change_event_attribute
355
- assert_nil @object.state_event
356
- end
357
-
358
- def test_should_not_have_event_transition
359
- assert_nil @object.send(:state_event_transition)
339
+ def test_should_perform
340
+ assert_equal true, @transitions.perform
360
341
  end
361
342
  end
362
343
 
363
- class MachineCollectionFireImplicitWithInvalidEventTest < MachineCollectionFireImplicitTest
344
+ class MachineCollectionTransitionsWithInvalidEventsTest < Test::Unit::TestCase
364
345
  def setup
365
- super
346
+ @klass = Class.new
366
347
 
367
- @object.state_event = 'invalid'
368
- @result = @machines.fire_event_attributes(@object, :save) { @saved = true }
369
- end
370
-
371
- def test_should_not_be_successful
372
- assert_equal false, @result
373
- end
374
-
375
- def test_should_not_run_action
376
- assert !@saved
377
- end
378
-
379
- def test_should_not_transition_state
380
- assert_equal 'parked', @object.state
381
- end
382
-
383
- def test_should_not_reset_event_attribute
384
- assert_equal :invalid, @object.state_event
385
- end
386
-
387
- def test_should_not_have_event_transition
388
- assert_nil @object.send(:state_event_transition)
389
- end
390
- end
391
-
392
- class MachineCollectionFireImplicitWithoutTransitionTest < MachineCollectionFireImplicitTest
393
- def setup
394
- super
348
+ @machines = StateMachine::MachineCollection.new
349
+ @machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
350
+ @machine.event :ignite do
351
+ transition :parked => :idling
352
+ end
395
353
 
396
- @object.state = 'idling'
397
- @object.state_event = 'ignite'
398
- @result = @machines.fire_event_attributes(@object, :save) { @saved = true }
399
- end
400
-
401
- def test_should_not_be_successful
402
- assert_equal false, @result
403
- end
404
-
405
- def test_should_not_run_action
406
- assert !@saved
407
- end
408
-
409
- def test_should_not_transition_state
410
- assert_equal 'idling', @object.state
354
+ @object = @klass.new
355
+ @object.state_event = 'invalid'
356
+ @transitions = @machines.transitions(@object, :save)
411
357
  end
412
358
 
413
- def test_should_not_reset_event_attribute
414
- assert_equal :ignite, @object.state_event
359
+ def test_should_be_empty
360
+ assert @transitions.empty?
415
361
  end
416
362
 
417
- def test_should_not_have_event_transition
418
- assert_nil @object.send(:state_event_transition)
363
+ def test_should_not_perform
364
+ assert_equal false, @transitions.perform
419
365
  end
420
366
  end
421
367
 
422
- class MachineCollectionFireImplicitWithTransitionTest < MachineCollectionFireImplicitTest
368
+ class MachineCollectionTransitionsWithoutTransitionTest < Test::Unit::TestCase
423
369
  def setup
424
- super
425
-
426
- @state_event = nil
370
+ @klass = Class.new
427
371
 
428
- @object.state_event = 'ignite'
429
- @result = @machines.fire_event_attributes(@object, :save) do
430
- @state_event = @object.state_event
431
- @saved = true
372
+ @machines = StateMachine::MachineCollection.new
373
+ @machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
374
+ @machine.event :ignite do
375
+ transition :parked => :idling
432
376
  end
433
- end
434
-
435
- def test_should_be_successful
436
- assert_equal true, @result
437
- end
438
-
439
- def test_should_run_action
440
- assert @saved
441
- end
442
-
443
- def test_should_not_have_event_while_running_action
444
- assert_nil @state_event
445
- end
446
-
447
- def test_should_transition_state
448
- assert_equal 'idling', @object.state
449
- end
450
-
451
- def test_should_reset_event_attribute
452
- assert_nil @object.state_event
453
- end
454
-
455
- def test_should_not_have_event_transition
456
- assert_nil @object.send(:state_event_transition)
457
- end
458
-
459
- def test_should_not_be_successful_if_fired_again
460
- @object.state_event = 'ignite'
461
- assert !@machines.fire_event_attributes(@object, :save) { true }
462
- end
463
- end
464
-
465
- class MachineCollectionFireImplicitWithNonBooleanResultTest < MachineCollectionFireImplicitTest
466
- def setup
467
- super
468
-
469
- @action_value = Object.new
470
377
 
378
+ @object = @klass.new
379
+ @object.state = 'idling'
471
380
  @object.state_event = 'ignite'
472
- @result = @machines.fire_event_attributes(@object, :save) do
473
- @saved = true
474
- @action_value
475
- end
381
+ @transitions = @machines.transitions(@object, :save)
476
382
  end
477
383
 
478
- def test_should_be_successful
479
- assert_equal @action_value, @result
384
+ def test_should_be_empty
385
+ assert @transitions.empty?
480
386
  end
481
387
 
482
- def test_should_run_action
483
- assert @saved
484
- end
485
-
486
- def test_should_transition_state
487
- assert_equal 'idling', @object.state
388
+ def test_should_not_perform
389
+ assert_equal false, @transitions.perform
488
390
  end
489
391
  end
490
392
 
491
- class MachineCollectionFireImplicitWithActionFailureTest < MachineCollectionFireImplicitTest
393
+ class MachineCollectionTransitionsWithTransitionTest < Test::Unit::TestCase
492
394
  def setup
493
- super
395
+ @klass = Class.new
494
396
 
495
- @object.state_event = 'ignite'
496
- @result = @machines.fire_event_attributes(@object, :save) { false }
497
- end
498
-
499
- def test_should_not_be_successful
500
- assert_equal false, @result
501
- end
502
-
503
- def test_should_not_transition_state
504
- assert_equal 'parked', @object.state
505
- end
506
-
507
- def test_should_not_reset_event_attribute
508
- assert_equal :ignite, @object.state_event
509
- end
510
-
511
- def test_should_not_have_event_transition
512
- assert_nil @object.send(:state_event_transition)
513
- end
514
- end
515
-
516
- class MachineCollectionFireImplicitWithActionErrorTest < MachineCollectionFireImplicitTest
517
- def setup
518
- super
397
+ @machines = StateMachine::MachineCollection.new
398
+ @machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
399
+ @machine.event :ignite do
400
+ transition :parked => :idling
401
+ end
519
402
 
403
+ @object = @klass.new
520
404
  @object.state_event = 'ignite'
521
- assert_raise(ArgumentError) { @machines.fire_event_attributes(@object, :save) { raise ArgumentError } }
405
+ @transitions = @machines.transitions(@object, :save)
522
406
  end
523
407
 
524
- def test_should_not_transition_state
525
- assert_equal 'parked', @object.state
526
- end
527
-
528
- def test_should_not_reset_event_attribute
529
- assert_equal :ignite, @object.state_event
408
+ def test_should_not_be_empty
409
+ assert_equal 1, @transitions.length
530
410
  end
531
411
 
532
- def test_should_not_have_event_transition
533
- assert_nil @object.send(:state_event_transition)
412
+ def test_should_perform
413
+ assert_equal true, @transitions.perform
534
414
  end
535
415
  end
536
416
 
537
- class MachineCollectionFireImplicitPartialTest < MachineCollectionFireImplicitTest
417
+ class MachineCollectionTransitionsWithSameActionsTest < Test::Unit::TestCase
538
418
  def setup
539
- super
540
-
541
- @state_event = nil
542
- @state_event_transition = nil
419
+ @klass = Class.new
543
420
 
544
- @object.state_event = 'ignite'
545
- @result = @machines.fire_event_attributes(@object, :save, false) do
546
- @state_event = @object.state_event
547
- @state_event_transition = @object.send(:state_event_transition)
548
- true
421
+ @machines = StateMachine::MachineCollection.new
422
+ @machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
423
+ @machine.event :ignite do
424
+ transition :parked => :idling
549
425
  end
550
- end
551
-
552
- def test_should_be_successful
553
- assert @result
554
- end
555
-
556
- def test_should_not_have_event_while_running_action
557
- assert_nil @state_event
558
- end
559
-
560
- def test_should_not_have_event_transition_while_running_action
561
- assert_nil @state_event_transition
562
- end
563
-
564
- def test_should_transition_state
565
- assert_equal 'idling', @object.state
566
- end
567
-
568
- def test_should_reset_event_attribute
569
- assert_nil @object.state_event
570
- end
571
-
572
- def test_should_have_event_transition
573
- assert_not_nil @object.send(:state_event_transition)
574
- end
575
-
576
- def test_should_reset_event_after_next_fire_on_success
577
- assert @machines.fire_event_attributes(@object, :save) { true }
578
- assert_equal 'idling', @object.state
579
- assert_nil @object.state_event
580
- end
581
-
582
- def test_should_reset_event_transition_after_next_fire_on_success
583
- assert @machines.fire_event_attributes(@object, :save) { true }
584
- assert_nil @object.send(:state_event_transition)
585
- end
586
-
587
- def test_should_guard_transition_after_next_fire_on_success
588
- @machines.fire_event_attributes(@object, :save) { true }
589
-
590
- @object.state = 'idling'
591
- @object.state_event = 'ignite'
592
- assert !@machines.fire_event_attributes(@object, :save) { true }
593
- end
594
-
595
- def test_should_rollback_all_attributes_after_next_fire_on_failure
596
- assert !@machines.fire_event_attributes(@object, :save) { false }
597
- assert_equal 'parked', @object.state
598
- assert_equal :ignite, @object.state_event
599
- assert_nil @object.send(:state_event_transition)
600
-
601
- @object.state = 'idling'
602
- assert !@machines.fire_event_attributes(@object, :save) { false }
603
- end
604
-
605
- def test_should_guard_transition_after_next_fire_on_failure
606
- @machines.fire_event_attributes(@object, :save) { false }
607
-
608
- @object.state = 'idling'
609
- assert !@machines.fire_event_attributes(@object, :save) { true }
610
- end
611
-
612
- def test_should_rollback_all_attributes_after_next_fire_on_error
613
- assert_raise(ArgumentError) { @machines.fire_event_attributes(@object, :save) { raise ArgumentError } }
614
- assert_equal 'parked', @object.state
615
- assert_equal :ignite, @object.state_event
616
- assert_nil @object.send(:state_event_transition)
617
- end
618
-
619
- def test_should_guard_transition_after_next_fire_on_error
620
- begin
621
- @machines.fire_event_attributes(@object, :save) { raise ArgumentError }
622
- rescue ArgumentError
426
+ @machines[:status] = @machine = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
427
+ @machine.event :shift_up do
428
+ transition :first_gear => :second_gear
623
429
  end
624
430
 
625
- @object.state = 'idling'
626
- assert !@machines.fire_event_attributes(@object, :save) { true }
627
- end
628
- end
629
-
630
- class MachineCollectionFireImplicitPartialWithCallbacksTest < MachineCollectionFireImplicitTest
631
- def setup
632
- super
633
-
431
+ @object = @klass.new
634
432
  @object.state_event = 'ignite'
433
+ @object.status_event = 'shift_up'
434
+ @transitions = @machines.transitions(@object, :save)
635
435
  end
636
436
 
637
- def test_should_run_before_callbacks
638
- ran_callback = false
639
- @machine.before_transition { ran_callback = true }
640
- @machines.fire_event_attributes(@object, :save, false) { true }
641
-
642
- assert ran_callback
643
- end
644
-
645
- def test_should_not_have_event_during_before_callbacks
646
- state_event = nil
647
- @machine.before_transition {|object, transition| state_event = object.state_event }
648
- @machines.fire_event_attributes(@object, :save, false) { true }
649
-
650
- assert_nil state_event
651
- end
652
-
653
- def test_should_not_have_event_transition_during_before_callbacks
654
- state_event_transition = nil
655
- @machine.before_transition {|object, transition| state_event_transition = object.send(:state_event_transition) }
656
- @machines.fire_event_attributes(@object, :save, false) { true }
657
-
658
- assert_nil state_event_transition
437
+ def test_should_not_be_empty
438
+ assert_equal 2, @transitions.length
659
439
  end
660
440
 
661
- def test_should_not_run_after_callbacks
662
- ran_callback = false
663
- @machine.after_transition { ran_callback = true }
664
- @machines.fire_event_attributes(@object, :save, false) { true }
665
-
666
- assert !ran_callback
667
- end
668
-
669
- def test_should_not_have_event_during_after_callbacks
670
- state_event = nil
671
- @machine.after_transition {|object, transition| state_event = object.state_event }
672
- @machines.fire_event_attributes(@object, :save, false) { true }
673
-
674
- assert_nil state_event
675
- end
676
-
677
- def test_should_not_have_event_transition_during_after_callbacks
678
- state_event_transition = nil
679
- @machine.after_transition {|object, transition| state_event_transition = object.send(:state_event_transition) }
680
- @machines.fire_event_attributes(@object, :save, false) { true }
681
-
682
- assert_nil state_event_transition
441
+ def test_should_perform
442
+ assert_equal true, @transitions.perform
683
443
  end
684
444
  end
685
445
 
686
- class MachineCollectionFireImplicitNestedPartialTest < MachineCollectionFireImplicitTest
446
+ class MachineCollectionTransitionsWithDifferentActionsTest < Test::Unit::TestCase
687
447
  def setup
688
- super
448
+ @klass = Class.new
689
449
 
690
- @partial_result = nil
450
+ @machines = StateMachine::MachineCollection.new
451
+ @machines[:state] = @state = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
452
+ @state.event :ignite do
453
+ transition :parked => :idling
454
+ end
455
+ @machines[:status] = @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :persist)
456
+ @status.event :shift_up do
457
+ transition :first_gear => :second_gear
458
+ end
691
459
 
460
+ @object = @klass.new
692
461
  @object.state_event = 'ignite'
693
- @result = @machines.fire_event_attributes(@object, :save) do
694
- @partial_result = @machines.fire_event_attributes(@object, :save, false) { true }
695
- true
696
- end
697
- end
698
-
699
- def test_should_be_successful
700
- assert @result
701
- end
702
-
703
- def test_should_have_successful_partial_fire
704
- assert @partial_result
705
- end
706
-
707
- def test_should_transition_state
708
- assert_equal 'idling', @object.state
462
+ @object.status_event = 'shift_up'
463
+ @transitions = @machines.transitions(@object, :save)
709
464
  end
710
465
 
711
- def test_should_reset_event_attribute
712
- assert_nil @object.state_event
713
- end
714
-
715
- def test_should_reset_event_transition_attribute
716
- assert_nil @object.send(:state_event_transition)
466
+ def test_should_only_select_matching_actions
467
+ assert_equal 1, @transitions.length
717
468
  end
718
469
  end
719
470
 
720
- class MachineCollectionFireImplicitWithDifferentActionsTest < MachineCollectionFireImplicitTest
471
+ class MachineCollectionTransitionsWithExisitingTransitionsTest < Test::Unit::TestCase
721
472
  def setup
722
- super
473
+ @klass = Class.new
723
474
 
724
- @machines[:alarm_state] = @alarm_machine = StateMachine::Machine.new(@klass, :alarm_state, :initial => :active, :action => :save_alarm)
725
- @alarm_machine.event :disable do
726
- transition :active => :off
475
+ @machines = StateMachine::MachineCollection.new
476
+ @machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
477
+ @machine.event :ignite do
478
+ transition :parked => :idling
727
479
  end
728
480
 
729
- @saved = false
730
481
  @object = @klass.new
731
- @object.state_event = 'ignite'
732
- @object.alarm_state_event = 'disable'
733
-
734
- @machines.fire_event_attributes(@object, :save) { true }
735
- end
736
-
737
- def test_should_transition_states_for_action
738
- assert_equal 'idling', @object.state
482
+ @object.send(:state_event_transition=, StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling))
483
+ @transitions = @machines.transitions(@object, :save)
739
484
  end
740
485
 
741
- def test_should_reset_event_attribute_for_action
742
- assert_nil @object.state_event
743
- end
744
-
745
- def test_should_reset_event_transition_attribute_for_action
746
- assert_nil @object.send(:state_event_transition)
747
- end
748
-
749
- def test_should_not_transition_states_for_other_actions
750
- assert_equal 'active', @object.alarm_state
486
+ def test_should_not_be_empty
487
+ assert_equal 1, @transitions.length
751
488
  end
752
489
 
753
- def test_should_not_reset_event_attributes_for_other_actions
754
- assert_equal :disable, @object.alarm_state_event
490
+ def test_should_perform
491
+ assert_equal true, @transitions.perform
755
492
  end
756
493
  end
757
494
 
758
- class MachineCollectionFireImplicitWithSameActionsTest < MachineCollectionFireImplicitTest
495
+ class MachineCollectionTransitionsWithCustomOptionsTest < Test::Unit::TestCase
759
496
  def setup
760
- super
497
+ @klass = Class.new
761
498
 
762
- @machines[:alarm_state] = @alarm_machine = StateMachine::Machine.new(@klass, :alarm_state, :initial => :active, :action => :save)
763
- @alarm_machine.event :disable do
764
- transition :active => :off
499
+ @machines = StateMachine::MachineCollection.new
500
+ @machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
501
+ @machine.event :ignite do
502
+ transition :parked => :idling
765
503
  end
766
504
 
767
- @saved = false
768
505
  @object = @klass.new
769
- @object.state_event = 'ignite'
770
- @object.alarm_state_event = 'disable'
771
-
772
- @machines.fire_event_attributes(@object, :save) { true }
506
+ @transitions = @machines.transitions(@object, :save, :after => false)
773
507
  end
774
508
 
775
- def test_should_transition_all_states_for_action
776
- assert_equal 'idling', @object.state
777
- assert_equal 'off', @object.alarm_state
778
- end
779
-
780
- def test_should_reset_all_event_attributes_for_action
781
- assert_nil @object.state_event
782
- assert_nil @object.alarm_state_event
509
+ def test_should_use_custom_options
510
+ assert @transitions.skip_after
783
511
  end
784
512
  end
785
513
 
786
- class MachineCollectionFireImplicitWithValidationsTest < Test::Unit::TestCase
514
+ class MachineCollectionFireAttributesWithValidationsTest < Test::Unit::TestCase
787
515
  def setup
788
- StateMachine::Integrations.const_set('Custom', Module.new do
789
- def invalidate(object, attribute, message, values = [])
790
- (object.errors ||= []) << generate_message(message, values)
791
- end
792
-
793
- def reset(object)
794
- object.errors = []
795
- end
796
- end)
797
-
798
516
  @klass = Class.new do
799
517
  attr_accessor :errors
800
518
 
@@ -805,17 +523,27 @@ class MachineCollectionFireImplicitWithValidationsTest < Test::Unit::TestCase
805
523
  end
806
524
 
807
525
  @machines = StateMachine::MachineCollection.new
808
- @machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save, :integration => :custom)
526
+ @machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
809
527
  @machine.event :ignite do
810
528
  transition :parked => :idling
811
529
  end
812
530
 
531
+ class << @machine
532
+ def invalidate(object, attribute, message, values = [])
533
+ (object.errors ||= []) << generate_message(message, values)
534
+ end
535
+
536
+ def reset(object)
537
+ object.errors = []
538
+ end
539
+ end
540
+
813
541
  @object = @klass.new
814
542
  end
815
543
 
816
544
  def test_should_invalidate_if_event_is_invalid
817
545
  @object.state_event = 'invalid'
818
- @machines.fire_event_attributes(@object, :save) { true }
546
+ @machines.transitions(@object, :save)
819
547
 
820
548
  assert !@object.errors.empty?
821
549
  end
@@ -823,116 +551,15 @@ class MachineCollectionFireImplicitWithValidationsTest < Test::Unit::TestCase
823
551
  def test_should_invalidate_if_no_transition_exists
824
552
  @object.state = 'idling'
825
553
  @object.state_event = 'ignite'
826
- @machines.fire_event_attributes(@object, :save) { true }
554
+ @machines.transitions(@object, :save)
827
555
 
828
556
  assert !@object.errors.empty?
829
557
  end
830
558
 
831
559
  def test_should_not_invalidate_if_transition_exists
832
560
  @object.state_event = 'ignite'
833
- @machines.fire_event_attributes(@object, :save) { true }
561
+ @machines.transitions(@object, :save)
834
562
 
835
563
  assert @object.errors.empty?
836
564
  end
837
-
838
- def teardown
839
- StateMachine::Integrations.send(:remove_const, 'Custom')
840
- end
841
- end
842
-
843
- class MachineCollectionFireImplicitWithCustomMachineNameTest < MachineCollectionFireImplicitTest
844
- def setup
845
- super
846
-
847
- @object.state_event = 'ignite'
848
- end
849
-
850
- def test_should_be_successful_on_complete_file
851
- assert @machines.fire_event_attributes(@object, :save) { true }
852
- assert_equal 'idling', @object.state
853
- assert_nil @object.state_event
854
- assert_nil @object.send(:state_event_transition)
855
- end
856
-
857
- def test_should_be_successful_on_partial_fire
858
- @machines.fire_event_attributes(@object, :save, false) { true }
859
- assert_equal 'idling', @object.state
860
- assert_nil @object.state_event
861
- assert_not_nil @object.send(:state_event_transition)
862
- end
863
- end
864
-
865
- class MachineFireImplicitWithMarshallingTest < MachineCollectionFireImplicitTest
866
- def setup
867
- super
868
- self.class.const_set('Example', @klass)
869
-
870
- @object.state_event = 'ignite'
871
- end
872
-
873
- def test_should_marshal_during_before_callbacks
874
- @machine.before_transition {|object, transition| Marshal.dump(object)}
875
- assert_nothing_raised { @machines.fire_event_attributes(@object, :save) { true } }
876
- end
877
-
878
- def test_should_marshal_during_action
879
- assert_nothing_raised do
880
- @machines.fire_event_attributes(@object, :save) do
881
- Marshal.dump(@object)
882
- true
883
- end
884
- end
885
- end
886
-
887
- def test_should_marshal_during_after_callbacks
888
- @machine.after_transition {|object, transition| Marshal.dump(object)}
889
- assert_nothing_raised { @machines.fire_event_attributes(@object, :save) { true } }
890
- end
891
-
892
- def teardown
893
- self.class.send(:remove_const, 'Example')
894
- end
895
- end
896
-
897
- class MachineFireImplicitPartialWithMarshallingTest < MachineCollectionFireImplicitTest
898
- def setup
899
- super
900
- self.class.const_set('Example', @klass)
901
-
902
- @object.state_event = 'ignite'
903
- end
904
-
905
- def test_should_marshal_during_before_callbacks
906
- @machine.before_transition {|object, transition| Marshal.dump(object)}
907
- assert_nothing_raised do
908
- @machines.fire_event_attributes(@object, :save, false) { true }
909
- @machines.fire_event_attributes(@object, :save) { true }
910
- end
911
- end
912
-
913
- def test_should_marshal_during_action
914
- assert_nothing_raised do
915
- @machines.fire_event_attributes(@object, :save, false) do
916
- Marshal.dump(@object)
917
- true
918
- end
919
-
920
- @machines.fire_event_attributes(@object, :save) do
921
- Marshal.dump(@object)
922
- true
923
- end
924
- end
925
- end
926
-
927
- def test_should_marshal_during_after_callbacks
928
- @machine.after_transition {|object, transition| Marshal.dump(object)}
929
- assert_nothing_raised do
930
- @machines.fire_event_attributes(@object, :save, false) { true }
931
- @machines.fire_event_attributes(@object, :save) { true }
932
- end
933
- end
934
-
935
- def teardown
936
- self.class.send(:remove_const, 'Example')
937
- end
938
565
  end