state_machine 0.5.2 → 0.6.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.
- data/CHANGELOG.rdoc +9 -0
- data/README.rdoc +34 -26
- data/Rakefile +1 -1
- data/examples/auto_shop.rb +2 -2
- data/examples/car.rb +4 -4
- data/examples/traffic_light.rb +1 -3
- data/examples/vehicle.rb +7 -11
- data/lib/state_machine.rb +5 -5
- data/lib/state_machine/callback.rb +1 -1
- data/lib/state_machine/condition_proxy.rb +94 -0
- data/lib/state_machine/event.rb +92 -23
- data/lib/state_machine/guard.rb +90 -57
- data/lib/state_machine/integrations/active_record.rb +3 -3
- data/lib/state_machine/integrations/data_mapper.rb +3 -3
- data/lib/state_machine/integrations/data_mapper/observer.rb +8 -6
- data/lib/state_machine/integrations/sequel.rb +3 -3
- data/lib/state_machine/machine.rb +136 -130
- data/lib/state_machine/matcher_helpers.rb +53 -0
- data/lib/state_machine/state.rb +3 -3
- data/test/active_record.log +23221 -0
- data/test/classes/switch.rb +2 -2
- data/test/functional/state_machine_test.rb +25 -29
- data/test/sequel.log +10610 -0
- data/test/unit/callback_test.rb +36 -6
- data/test/unit/condition_proxy_test.rb +301 -0
- data/test/unit/event_test.rb +31 -17
- data/test/unit/guard_test.rb +246 -13
- data/test/unit/integrations/active_record_test.rb +29 -0
- data/test/unit/integrations/data_mapper_test.rb +45 -0
- data/test/unit/integrations/sequel_test.rb +29 -0
- data/test/unit/machine_test.rb +25 -3
- data/test/unit/matcher_helpers_test.rb +37 -0
- data/test/unit/node_collection_test.rb +0 -4
- data/test/unit/state_collection_test.rb +0 -4
- metadata +8 -2
data/test/unit/guard_test.rb
CHANGED
@@ -2,12 +2,11 @@ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
|
2
2
|
|
3
3
|
class GuardTest < Test::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
@guard = StateMachine::Guard.new(:
|
5
|
+
@guard = StateMachine::Guard.new(:from => :parked, :to => :idling)
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
9
|
-
|
10
|
-
assert_equal 'Invalid key(s): invalid', exception.message
|
8
|
+
def test_should_not_raise_exception_if_implicit_option_specified
|
9
|
+
assert_nothing_raised { StateMachine::Guard.new(:invalid => true) }
|
11
10
|
end
|
12
11
|
|
13
12
|
def test_should_not_have_an_if_condition
|
@@ -17,6 +16,10 @@ class GuardTest < Test::Unit::TestCase
|
|
17
16
|
def test_should_not_have_an_unless_condition
|
18
17
|
assert_nil @guard.unless_condition
|
19
18
|
end
|
19
|
+
|
20
|
+
def test_should_have_a_state_requirement
|
21
|
+
assert_equal 1, @guard.state_requirements.length
|
22
|
+
end
|
20
23
|
end
|
21
24
|
|
22
25
|
class GuardWithNoRequirementsTest < Test::Unit::TestCase
|
@@ -30,11 +33,11 @@ class GuardWithNoRequirementsTest < Test::Unit::TestCase
|
|
30
33
|
end
|
31
34
|
|
32
35
|
def test_should_use_all_matcher_for_from_state_requirement
|
33
|
-
assert_equal StateMachine::AllMatcher.instance, @guard.
|
36
|
+
assert_equal StateMachine::AllMatcher.instance, @guard.state_requirements.first[:from]
|
34
37
|
end
|
35
38
|
|
36
39
|
def test_should_use_all_matcher_for_to_state_requirement
|
37
|
-
assert_equal StateMachine::AllMatcher.instance, @guard.
|
40
|
+
assert_equal StateMachine::AllMatcher.instance, @guard.state_requirements.first[:to]
|
38
41
|
end
|
39
42
|
|
40
43
|
def test_should_match_nil_query
|
@@ -48,6 +51,14 @@ class GuardWithNoRequirementsTest < Test::Unit::TestCase
|
|
48
51
|
def test_should_match_non_empty_query
|
49
52
|
assert @guard.matches?(@object, :to => :idling, :from => :parked, :on => :ignite)
|
50
53
|
end
|
54
|
+
|
55
|
+
def test_should_include_all_requirements_in_match
|
56
|
+
match = @guard.match(@object, nil)
|
57
|
+
|
58
|
+
assert_equal @guard.state_requirements.first[:from], match[:from]
|
59
|
+
assert_equal @guard.state_requirements.first[:to], match[:to]
|
60
|
+
assert_equal @guard.event_requirement, match[:on]
|
61
|
+
end
|
51
62
|
end
|
52
63
|
|
53
64
|
class GuardWithFromRequirementTest < Test::Unit::TestCase
|
@@ -57,7 +68,7 @@ class GuardWithFromRequirementTest < Test::Unit::TestCase
|
|
57
68
|
end
|
58
69
|
|
59
70
|
def test_should_use_a_whitelist_matcher
|
60
|
-
assert_instance_of StateMachine::WhitelistMatcher, @guard.
|
71
|
+
assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:from]
|
61
72
|
end
|
62
73
|
|
63
74
|
def test_should_match_if_not_specified
|
@@ -87,6 +98,11 @@ class GuardWithFromRequirementTest < Test::Unit::TestCase
|
|
87
98
|
def test_should_be_included_in_known_states
|
88
99
|
assert_equal [:parked], @guard.known_states
|
89
100
|
end
|
101
|
+
|
102
|
+
def test_should_include_requirement_in_match
|
103
|
+
match = @guard.match(@object, :from => :parked)
|
104
|
+
assert_equal @guard.state_requirements.first[:from], match[:from]
|
105
|
+
end
|
90
106
|
end
|
91
107
|
|
92
108
|
class GuardWithMultipleFromRequirementsTest < Test::Unit::TestCase
|
@@ -115,7 +131,7 @@ class GuardWithToRequirementTest < Test::Unit::TestCase
|
|
115
131
|
end
|
116
132
|
|
117
133
|
def test_should_use_a_whitelist_matcher
|
118
|
-
assert_instance_of StateMachine::WhitelistMatcher, @guard.
|
134
|
+
assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:to]
|
119
135
|
end
|
120
136
|
|
121
137
|
def test_should_match_if_not_specified
|
@@ -145,6 +161,11 @@ class GuardWithToRequirementTest < Test::Unit::TestCase
|
|
145
161
|
def test_should_be_included_in_known_states
|
146
162
|
assert_equal [:idling], @guard.known_states
|
147
163
|
end
|
164
|
+
|
165
|
+
def test_should_include_requirement_in_match
|
166
|
+
match = @guard.match(@object, :to => :idling)
|
167
|
+
assert_equal @guard.state_requirements.first[:to], match[:to]
|
168
|
+
end
|
148
169
|
end
|
149
170
|
|
150
171
|
class GuardWithMultipleToRequirementsTest < Test::Unit::TestCase
|
@@ -203,6 +224,11 @@ class GuardWithOnRequirementTest < Test::Unit::TestCase
|
|
203
224
|
def test_should_not_be_included_in_known_states
|
204
225
|
assert_equal [], @guard.known_states
|
205
226
|
end
|
227
|
+
|
228
|
+
def test_should_include_requirement_in_match
|
229
|
+
match = @guard.match(@object, :on => :ignite)
|
230
|
+
assert_equal @guard.event_requirement, match[:on]
|
231
|
+
end
|
206
232
|
end
|
207
233
|
|
208
234
|
class GuardWithMultipleOnRequirementsTest < Test::Unit::TestCase
|
@@ -227,7 +253,7 @@ class GuardWithExceptFromRequirementTest < Test::Unit::TestCase
|
|
227
253
|
end
|
228
254
|
|
229
255
|
def test_should_use_a_blacklist_matcher
|
230
|
-
assert_instance_of StateMachine::BlacklistMatcher, @guard.
|
256
|
+
assert_instance_of StateMachine::BlacklistMatcher, @guard.state_requirements.first[:from]
|
231
257
|
end
|
232
258
|
|
233
259
|
def test_should_match_if_not_included
|
@@ -281,7 +307,7 @@ class GuardWithExceptToRequirementTest < Test::Unit::TestCase
|
|
281
307
|
end
|
282
308
|
|
283
309
|
def test_should_use_a_blacklist_matcher
|
284
|
-
assert_instance_of StateMachine::BlacklistMatcher, @guard.
|
310
|
+
assert_instance_of StateMachine::BlacklistMatcher, @guard.state_requirements.first[:to]
|
285
311
|
end
|
286
312
|
|
287
313
|
def test_should_match_if_not_included
|
@@ -425,6 +451,10 @@ class GuardWithDifferentRequirementsTest < Test::Unit::TestCase
|
|
425
451
|
assert !@guard.matches?(@object, :on => :park)
|
426
452
|
end
|
427
453
|
|
454
|
+
def test_should_be_nil_if_unmatched
|
455
|
+
assert_nil @guard.match(@object, :from => :parked, :to => :idling, :on => :park)
|
456
|
+
end
|
457
|
+
|
428
458
|
def test_should_include_all_known_states
|
429
459
|
assert_equal [:parked, :idling], @guard.known_states
|
430
460
|
end
|
@@ -462,6 +492,129 @@ class GuardWithNilRequirementsTest < Test::Unit::TestCase
|
|
462
492
|
end
|
463
493
|
end
|
464
494
|
|
495
|
+
class GuardWithImplicitRequirementTest < Test::Unit::TestCase
|
496
|
+
def setup
|
497
|
+
@guard = StateMachine::Guard.new(:parked => :idling, :on => :ignite)
|
498
|
+
end
|
499
|
+
|
500
|
+
def test_should_create_an_event_requirement
|
501
|
+
assert_instance_of StateMachine::WhitelistMatcher, @guard.event_requirement
|
502
|
+
assert_equal [:ignite], @guard.event_requirement.values
|
503
|
+
end
|
504
|
+
|
505
|
+
def test_should_use_a_whitelist_from_matcher
|
506
|
+
assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:from]
|
507
|
+
end
|
508
|
+
|
509
|
+
def test_should_use_a_whitelist_to_matcher
|
510
|
+
assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:to]
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
class GuardWithMultipleImplicitRequirementsTest < Test::Unit::TestCase
|
515
|
+
def setup
|
516
|
+
@object = Object.new
|
517
|
+
@guard = StateMachine::Guard.new(:parked => :idling, :idling => :first_gear, :on => :ignite)
|
518
|
+
end
|
519
|
+
|
520
|
+
def test_should_create_multiple_state_requirements
|
521
|
+
assert_equal 2, @guard.state_requirements.length
|
522
|
+
end
|
523
|
+
|
524
|
+
def test_should_not_match_event_as_state_requirement
|
525
|
+
assert !@guard.matches?(@object, :from => :on, :to => :ignite)
|
526
|
+
end
|
527
|
+
|
528
|
+
def test_should_match_if_from_included_in_any
|
529
|
+
assert @guard.matches?(@object, :from => :parked)
|
530
|
+
assert @guard.matches?(@object, :from => :idling)
|
531
|
+
end
|
532
|
+
|
533
|
+
def test_should_not_match_if_from_not_included_in_any
|
534
|
+
assert !@guard.matches?(@object, :from => :first_gear)
|
535
|
+
end
|
536
|
+
|
537
|
+
def test_should_match_if_to_included_in_any
|
538
|
+
assert @guard.matches?(@object, :to => :idling)
|
539
|
+
assert @guard.matches?(@object, :to => :first_gear)
|
540
|
+
end
|
541
|
+
|
542
|
+
def test_should_not_match_if_to_not_included_in_any
|
543
|
+
assert !@guard.matches?(@object, :to => :parked)
|
544
|
+
end
|
545
|
+
|
546
|
+
def test_should_match_if_all_options_match
|
547
|
+
assert @guard.matches?(@object, :from => :parked, :to => :idling, :on => :ignite)
|
548
|
+
assert @guard.matches?(@object, :from => :idling, :to => :first_gear, :on => :ignite)
|
549
|
+
end
|
550
|
+
|
551
|
+
def test_should_not_match_if_any_options_do_not_match
|
552
|
+
assert !@guard.matches?(@object, :from => :parked, :to => :idling, :on => :park)
|
553
|
+
assert !@guard.matches?(@object, :from => :parked, :to => :first_gear, :on => :park)
|
554
|
+
end
|
555
|
+
|
556
|
+
def test_should_include_all_known_states
|
557
|
+
assert_equal [:first_gear, :idling, :parked], @guard.known_states.sort_by {|state| state.to_s}
|
558
|
+
end
|
559
|
+
|
560
|
+
def test_should_not_duplicate_known_statse
|
561
|
+
guard = StateMachine::Guard.new(:parked => :idling, :first_gear => :idling)
|
562
|
+
assert_equal [:first_gear, :idling, :parked], guard.known_states.sort_by {|state| state.to_s}
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
class GuardWithImplicitFromRequirementMatcherTest < Test::Unit::TestCase
|
567
|
+
def setup
|
568
|
+
@matcher = StateMachine::BlacklistMatcher.new(:parked)
|
569
|
+
@guard = StateMachine::Guard.new(@matcher => :idling)
|
570
|
+
end
|
571
|
+
|
572
|
+
def test_should_not_convert_from_to_whitelist_matcher
|
573
|
+
assert_equal @matcher, @guard.state_requirements.first[:from]
|
574
|
+
end
|
575
|
+
|
576
|
+
def test_should_convert_to_to_whitelist_matcher
|
577
|
+
assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:to]
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
class GuardWithImplicitToRequirementMatcherTest < Test::Unit::TestCase
|
582
|
+
def setup
|
583
|
+
@matcher = StateMachine::BlacklistMatcher.new(:idling)
|
584
|
+
@guard = StateMachine::Guard.new(:parked => @matcher)
|
585
|
+
end
|
586
|
+
|
587
|
+
def test_should_convert_from_to_whitelist_matcher
|
588
|
+
assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:from]
|
589
|
+
end
|
590
|
+
|
591
|
+
def test_should_not_convert_to_to_whitelist_matcher
|
592
|
+
assert_equal @matcher, @guard.state_requirements.first[:to]
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
class GuardWithImplicitAndExplicitRequirementsTest < Test::Unit::TestCase
|
597
|
+
def setup
|
598
|
+
@guard = StateMachine::Guard.new(:parked => :idling, :from => :parked)
|
599
|
+
end
|
600
|
+
|
601
|
+
def test_should_create_multiple_requirements
|
602
|
+
assert_equal 2, @guard.state_requirements.length
|
603
|
+
end
|
604
|
+
|
605
|
+
def test_should_create_implicit_requirements_for_implicit_options
|
606
|
+
assert(@guard.state_requirements.any? do |state_requirement|
|
607
|
+
state_requirement[:from].values == [:parked] && state_requirement[:to].values == [:idling]
|
608
|
+
end)
|
609
|
+
end
|
610
|
+
|
611
|
+
def test_should_create_implicit_requirements_for_explicit_options
|
612
|
+
assert(@guard.state_requirements.any? do |state_requirement|
|
613
|
+
state_requirement[:from].values == [:from] && state_requirement[:to].values == [:parked]
|
614
|
+
end)
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
465
618
|
class GuardWithIfConditionalTest < Test::Unit::TestCase
|
466
619
|
def setup
|
467
620
|
@object = Object.new
|
@@ -481,6 +634,30 @@ class GuardWithIfConditionalTest < Test::Unit::TestCase
|
|
481
634
|
guard = StateMachine::Guard.new(:if => lambda {false})
|
482
635
|
assert !guard.matches?(@object)
|
483
636
|
end
|
637
|
+
|
638
|
+
def test_should_be_nil_if_unmatched
|
639
|
+
guard = StateMachine::Guard.new(:if => lambda {false})
|
640
|
+
assert_nil guard.match(@object)
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
class GuardWithMultipleIfConditionalsTest < Test::Unit::TestCase
|
645
|
+
def setup
|
646
|
+
@object = Object.new
|
647
|
+
end
|
648
|
+
|
649
|
+
def test_should_match_if_all_are_true
|
650
|
+
guard = StateMachine::Guard.new(:if => [lambda {true}, lambda {true}])
|
651
|
+
assert guard.match(@object)
|
652
|
+
end
|
653
|
+
|
654
|
+
def test_should_not_match_if_any_are_false
|
655
|
+
guard = StateMachine::Guard.new(:if => [lambda {true}, lambda {false}])
|
656
|
+
assert !guard.match(@object)
|
657
|
+
|
658
|
+
guard = StateMachine::Guard.new(:if => [lambda {false}, lambda {true}])
|
659
|
+
assert !guard.match(@object)
|
660
|
+
end
|
484
661
|
end
|
485
662
|
|
486
663
|
class GuardWithUnlessConditionalTest < Test::Unit::TestCase
|
@@ -502,12 +679,51 @@ class GuardWithUnlessConditionalTest < Test::Unit::TestCase
|
|
502
679
|
guard = StateMachine::Guard.new(:unless => lambda {true})
|
503
680
|
assert !guard.matches?(@object)
|
504
681
|
end
|
682
|
+
|
683
|
+
def test_should_be_nil_if_unmatched
|
684
|
+
guard = StateMachine::Guard.new(:unless => lambda {true})
|
685
|
+
assert_nil guard.match(@object)
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
class GuardWithMultipleUnlessConditionalsTest < Test::Unit::TestCase
|
690
|
+
def setup
|
691
|
+
@object = Object.new
|
692
|
+
end
|
693
|
+
|
694
|
+
def test_should_match_if_all_are_false
|
695
|
+
guard = StateMachine::Guard.new(:unless => [lambda {false}, lambda {false}])
|
696
|
+
assert guard.match(@object)
|
697
|
+
end
|
698
|
+
|
699
|
+
def test_should_not_match_if_any_are_true
|
700
|
+
guard = StateMachine::Guard.new(:unless => [lambda {true}, lambda {false}])
|
701
|
+
assert !guard.match(@object)
|
702
|
+
|
703
|
+
guard = StateMachine::Guard.new(:unless => [lambda {false}, lambda {true}])
|
704
|
+
assert !guard.match(@object)
|
705
|
+
end
|
505
706
|
end
|
506
707
|
|
507
708
|
class GuardWithConflictingConditionalsTest < Test::Unit::TestCase
|
508
|
-
def
|
509
|
-
|
510
|
-
|
709
|
+
def test_should_match_if_if_is_true_and_unless_is_false
|
710
|
+
guard = StateMachine::Guard.new(:if => lambda {true}, :unless => lambda {false})
|
711
|
+
assert guard.match(@object)
|
712
|
+
end
|
713
|
+
|
714
|
+
def test_should_not_match_if_if_is_false_and_unless_is_true
|
715
|
+
guard = StateMachine::Guard.new(:if => lambda {false}, :unless => lambda {true})
|
716
|
+
assert !guard.match(@object)
|
717
|
+
end
|
718
|
+
|
719
|
+
def test_should_not_match_if_if_is_false_and_unless_is_false
|
720
|
+
guard = StateMachine::Guard.new(:if => lambda {false}, :unless => lambda {false})
|
721
|
+
assert !guard.match(@object)
|
722
|
+
end
|
723
|
+
|
724
|
+
def test_should_not_match_if_if_is_true_and_unless_is_true
|
725
|
+
guard = StateMachine::Guard.new(:if => lambda {true}, :unless => lambda {true})
|
726
|
+
assert !guard.match(@object)
|
511
727
|
end
|
512
728
|
end
|
513
729
|
|
@@ -624,6 +840,23 @@ begin
|
|
624
840
|
assert_equal 'parked', @edges.first.instance_variable_get('@xNodeTwo')
|
625
841
|
end
|
626
842
|
end
|
843
|
+
|
844
|
+
class GuardDrawingWithNilStateTest < Test::Unit::TestCase
|
845
|
+
def setup
|
846
|
+
@machine = StateMachine::Machine.new(Class.new)
|
847
|
+
|
848
|
+
graph = GraphViz.new('G')
|
849
|
+
graph.add_node('parked')
|
850
|
+
|
851
|
+
@guard = StateMachine::Guard.new(:from => :idling, :to => nil)
|
852
|
+
@edges = @guard.draw(graph, :park, [nil, :idling])
|
853
|
+
end
|
854
|
+
|
855
|
+
def test_should_generate_edges_for_each_valid_from_state
|
856
|
+
assert_equal 'idling', @edges.first.instance_variable_get('@xNodeOne')
|
857
|
+
assert_equal 'nil', @edges.first.instance_variable_get('@xNodeTwo')
|
858
|
+
end
|
859
|
+
end
|
627
860
|
rescue LoadError
|
628
861
|
$stderr.puts 'Skipping GraphViz StateMachine::Guard tests. `gem install ruby-graphviz` and try again.'
|
629
862
|
end
|
@@ -486,6 +486,35 @@ begin
|
|
486
486
|
end
|
487
487
|
end
|
488
488
|
|
489
|
+
class MachineWithStateDrivenValidationsTest < ActiveRecord::TestCase
|
490
|
+
def setup
|
491
|
+
@model = new_model do
|
492
|
+
attr_accessor :seatbelt
|
493
|
+
end
|
494
|
+
|
495
|
+
@machine = StateMachine::Machine.new(@model)
|
496
|
+
@machine.state :first_gear, :second_gear do
|
497
|
+
validates_presence_of :seatbelt
|
498
|
+
end
|
499
|
+
@machine.other_states :parked
|
500
|
+
end
|
501
|
+
|
502
|
+
def test_should_be_valid_if_validation_fails_outside_state_scope
|
503
|
+
record = @model.new(:state => 'parked', :seatbelt => nil)
|
504
|
+
assert record.valid?
|
505
|
+
end
|
506
|
+
|
507
|
+
def test_should_be_invalid_if_validation_fails_within_state_scope
|
508
|
+
record = @model.new(:state => 'first_gear', :seatbelt => nil)
|
509
|
+
assert !record.valid?
|
510
|
+
end
|
511
|
+
|
512
|
+
def test_should_be_valid_if_validation_succeeds_within_state_scope
|
513
|
+
record = @model.new(:state => 'second_gear', :seatbelt => true)
|
514
|
+
assert record.valid?
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
489
518
|
class MachineWithFailedAfterCallbacksTest < ActiveRecord::TestCase
|
490
519
|
def setup
|
491
520
|
@after_count = 0
|
@@ -334,6 +334,16 @@ begin
|
|
334
334
|
@transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
|
335
335
|
end
|
336
336
|
|
337
|
+
def test_should_provide_matcher_helpers
|
338
|
+
matchers = []
|
339
|
+
|
340
|
+
new_observer(@resource) do
|
341
|
+
matchers = [all, any, same]
|
342
|
+
end
|
343
|
+
|
344
|
+
assert_equal [StateMachine::AllMatcher.instance, StateMachine::AllMatcher.instance, StateMachine::LoopbackMatcher.instance], matchers
|
345
|
+
end
|
346
|
+
|
337
347
|
def test_should_call_before_transition_callback_if_requirements_match
|
338
348
|
called = false
|
339
349
|
|
@@ -476,6 +486,41 @@ begin
|
|
476
486
|
rescue LoadError
|
477
487
|
$stderr.puts 'Skipping DataMapper Observer tests. `gem install dm-observer` and try again.'
|
478
488
|
end
|
489
|
+
|
490
|
+
begin
|
491
|
+
require 'dm-validations'
|
492
|
+
|
493
|
+
class MachineWithStateDrivenValidationsTest < BaseTestCase
|
494
|
+
def setup
|
495
|
+
@resource = new_resource do
|
496
|
+
attr_accessor :seatbelt
|
497
|
+
end
|
498
|
+
|
499
|
+
@machine = StateMachine::Machine.new(@resource)
|
500
|
+
@machine.state :first_gear, :second_gear do
|
501
|
+
validates_present :seatbelt
|
502
|
+
end
|
503
|
+
@machine.other_states :parked
|
504
|
+
end
|
505
|
+
|
506
|
+
def test_should_be_valid_if_validation_fails_outside_state_scope
|
507
|
+
record = @resource.new(:state => 'parked', :seatbelt => nil)
|
508
|
+
assert record.valid?
|
509
|
+
end
|
510
|
+
|
511
|
+
def test_should_be_invalid_if_validation_fails_within_state_scope
|
512
|
+
record = @resource.new(:state => 'first_gear', :seatbelt => nil)
|
513
|
+
assert !record.valid?
|
514
|
+
end
|
515
|
+
|
516
|
+
def test_should_be_valid_if_validation_succeeds_within_state_scope
|
517
|
+
record = @resource.new(:state => 'second_gear', :seatbelt => true)
|
518
|
+
assert record.valid?
|
519
|
+
end
|
520
|
+
end
|
521
|
+
rescue LoadError
|
522
|
+
$stderr.puts 'Skipping DataMapper Validation tests. `gem install dm-validations` and try again.'
|
523
|
+
end
|
479
524
|
end
|
480
525
|
rescue LoadError
|
481
526
|
$stderr.puts 'Skipping DataMapper tests. `gem install dm-core cucumber rspec hoe launchy do_sqlite3` and try again.'
|