stateful.rb 2.0.0 → 2.2.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +137 -0
  3. data/Gemfile +2 -0
  4. data/README.md +309 -0
  5. data/lib/Stateful/Sequel/ClassMethods.rb +117 -0
  6. data/lib/Stateful/Sequel.rb +30 -0
  7. data/lib/Stateful/VERSION.rb +1 -1
  8. data/lib/Stateful.rb +4 -1
  9. data/stateful.rb.gemspec +42 -0
  10. data/test/ActiveRecord/WithColumnName.rb +159 -0
  11. data/test/ActiveRecord/WithExplicitDeterministicEventOrdering.rb +159 -0
  12. data/test/ActiveRecord/WithExplicitGlobalNonDeterministicEventOrdering.rb +165 -0
  13. data/test/ActiveRecord/WithExplicitGlobalNonDeterministicEventOrderingAndInitialStateBlock.rb +163 -0
  14. data/test/ActiveRecord/WithExplicitNonDeterministicEventOrdering.rb +161 -0
  15. data/test/ActiveRecord/WithInitialStateBlock.rb +157 -0
  16. data/test/ActiveRecord/WithMultipleFinalStates.rb +188 -0
  17. data/test/ActiveRecord/WithMultipleStateMachines.rb +221 -0
  18. data/test/ActiveRecord/WithMultipleStateMachinesAndStatefulBlock.rb +223 -0
  19. data/test/ActiveRecord/WithPersistenceNonSpecificExtend.rb +159 -0
  20. data/test/ActiveRecord/WithPersistenceNonSpecificExtendAndStatefulBlock.rb +161 -0
  21. data/test/ActiveRecord/WithPersistenceSpecificExtend.rb +159 -0
  22. data/test/ActiveRecord/WithPersistenceSpecificExtendAndStatefulBlock.rb +161 -0
  23. data/test/ActiveRecord/test_helper.rb +9 -0
  24. data/test/ActiveRecord.rb +5 -0
  25. data/test/Poro/WithExplicitDeterministicEventOrdering.rb +147 -0
  26. data/test/Poro/WithExplicitGlobalNonDeterministicEventOrdering.rb +153 -0
  27. data/test/Poro/WithExplicitGlobalNonDeterministicEventOrderingAndInitialStateBlock.rb +151 -0
  28. data/test/Poro/WithExplicitNonDeterministicEventOrdering.rb +149 -0
  29. data/test/Poro/WithInitialStateBlock.rb +145 -0
  30. data/test/Poro/WithMultipleFinalStates.rb +176 -0
  31. data/test/Poro/WithMultipleStateMachines.rb +192 -0
  32. data/test/Poro/WithMultipleStateMachinesAndStatefulBlock.rb +194 -0
  33. data/test/Poro/WithPersistenceNonSpecificExtend.rb +147 -0
  34. data/test/Poro/WithPersistenceNonSpecificExtendAndStatefulBlock.rb +149 -0
  35. data/test/Poro/WithPersistenceSpecificExtend.rb +147 -0
  36. data/test/Poro/WithPersistenceSpecificExtendAndStatefulBlock.rb +149 -0
  37. data/test/Poro/WithVariableName.rb +147 -0
  38. data/test/Poro.rb +5 -0
  39. data/test/Sequel/WithColumnName.rb +154 -0
  40. data/test/Sequel/WithExplicitDeterministicEventOrdering.rb +154 -0
  41. data/test/Sequel/WithExplicitGlobalNonDeterministicEventOrdering.rb +160 -0
  42. data/test/Sequel/WithExplicitGlobalNonDeterministicEventOrderingAndInitialStateBlock.rb +158 -0
  43. data/test/Sequel/WithExplicitNonDeterministicEventOrdering.rb +156 -0
  44. data/test/Sequel/WithInitialStateBlock.rb +152 -0
  45. data/test/Sequel/WithMultipleFinalStates.rb +183 -0
  46. data/test/Sequel/WithMultipleStateMachines.rb +216 -0
  47. data/test/Sequel/WithMultipleStateMachinesAndStatefulBlock.rb +218 -0
  48. data/test/Sequel/WithPersistenceNonSpecificExtend.rb +154 -0
  49. data/test/Sequel/WithPersistenceNonSpecificExtendAndStatefulBlock.rb +156 -0
  50. data/test/Sequel/WithPersistenceSpecificExtend.rb +154 -0
  51. data/test/Sequel/WithPersistenceSpecificExtendAndStatefulBlock.rb +156 -0
  52. data/test/Sequel/test_helper.rb +5 -0
  53. data/test/Sequel.rb +5 -0
  54. data/test/Stateful.rb +15 -0
  55. metadata +69 -4
@@ -0,0 +1,153 @@
1
+ # test/Poro/WithExplicitGlobalNonDeterministicEventOrdering.rb
2
+
3
+ gem 'minitest'
4
+ gem 'minitest-spec-context'
5
+
6
+ require 'minitest/autorun'
7
+ require 'minitest-spec-context'
8
+
9
+ lib_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', 'lib'))
10
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
11
+
12
+ require 'Stateful'
13
+
14
+ class PoroMachine9
15
+ extend Stateful
16
+
17
+ stateful global_non_deterministic_event_ordering: true do
18
+ initial_state :initial_state
19
+
20
+ state :initial_state do
21
+ on :an_event => :next_state
22
+ on :another_event => :final_state
23
+ end
24
+
25
+ state :next_state do
26
+ on :yet_another_event => :final_state
27
+ end
28
+
29
+ final_state :final_state
30
+ end
31
+ end
32
+
33
+ describe Stateful::Poro do
34
+ let(:machine){PoroMachine9.new}
35
+
36
+ it "must have an initial state" do
37
+ _(machine.initial_state).wont_be_nil
38
+ end
39
+
40
+ it "must have a final state (if one has been specified)" do
41
+ if PoroMachine9.final_state?
42
+ _(machine.final_state).wont_be_nil
43
+ end
44
+ end
45
+
46
+ context "initial_state" do
47
+ it "must have an initial state before any events occur" do
48
+ _(machine.initial_state?).must_equal true
49
+ end
50
+
51
+ it "must have an initial state consistent with what is given" do
52
+ _(machine.initial_state).must_equal PoroMachine9.stateful_state_machine.initial_state
53
+ end
54
+
55
+ it "must have an initial state with name as per the name given" do
56
+ _(machine.initial_state.name).must_equal :initial_state
57
+ end
58
+
59
+ it "must not be in the final state (assuming that initial and final are different states)" do
60
+ _(machine.final_state?).must_equal false
61
+ end
62
+
63
+ it "must know what it's next state is given an event name" do
64
+ _(machine.next_state(:an_event)).must_equal PoroMachine9.stateful_state_machine.find(:next_state)
65
+ _(machine.next_state(:another_event)).must_equal PoroMachine9.stateful_state_machine.find(:final_state)
66
+ end
67
+
68
+ it "must have an intial state which has a collection of transitions to other states" do
69
+ _(machine.transitions.class).must_equal Array
70
+ _(machine.transitions.all?{|transition| transition.is_a?(Stateful::Transition)}).must_equal true
71
+ end
72
+
73
+ it "must have two transitions to other states" do
74
+ _(machine.transitions.size).must_equal 2
75
+ end
76
+
77
+ it "must know what transitions are available" do
78
+ transition_pairs = machine.transitions.collect{|t| [t.event_name, t.next_state_name]}
79
+ _(transition_pairs).must_include [:an_event, :next_state]
80
+ _(transition_pairs).must_include [:another_event, :final_state]
81
+ end
82
+
83
+ it "must be active" do
84
+ _(machine.active?).must_equal true
85
+ end
86
+ end
87
+
88
+ context "next_state" do
89
+ before do
90
+ machine.an_event
91
+ end
92
+
93
+ it "must not be in the initial state" do
94
+ _(machine.initial_state?).must_equal false
95
+ end
96
+
97
+ it "must not be in the final state" do
98
+ _(machine.final_state?).must_equal false
99
+ end
100
+
101
+ it "must be in the next_state state" do
102
+ _(machine.current_state.name).must_equal :next_state
103
+ _(machine.next_state?).must_equal true
104
+ end
105
+
106
+ it "must have a collection of transitions to other states" do
107
+ _(machine.transitions.class).must_equal Array
108
+ _(machine.transitions.all?{|transition| transition.is_a?(Stateful::Transition)}).must_equal true
109
+ end
110
+
111
+ it "must have one transition to other states" do
112
+ _(machine.transitions.size).must_equal 1
113
+ end
114
+
115
+ it "must know what transitions are available" do
116
+ _(machine.transitions.collect{|t| [t.event_name, t.next_state_name]}).must_equal [[:yet_another_event, :final_state]]
117
+ end
118
+
119
+ it "must be active" do
120
+ _(machine.active?).must_equal true
121
+ end
122
+ end
123
+
124
+ context "final_state" do
125
+ before do
126
+ machine.another_event
127
+ end
128
+
129
+ it "must have a final state" do
130
+ _(machine.final_state?).must_equal true
131
+ end
132
+
133
+ it "must have a final state consistent with what is given" do
134
+ _(machine.final_state).must_equal PoroMachine9.stateful_state_machine.final_state
135
+ end
136
+
137
+ it "must have a state with name as per the name given" do
138
+ _(machine.current_state.name).must_equal :final_state
139
+ end
140
+
141
+ it "must not be in the initial state (assuming that initial and final are different states)" do
142
+ _(machine.initial_state?).must_equal false
143
+ end
144
+
145
+ it "must have no transitions" do
146
+ _(machine.transitions.empty?).must_equal true
147
+ end
148
+
149
+ it "must not be active" do
150
+ _(machine.active?).must_equal false
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,151 @@
1
+ # test/Poro/WithExplicitGlobalNonDeterministicEventOrderingAndInitialStateBlock.rb
2
+
3
+ gem 'minitest'
4
+ gem 'minitest-spec-context'
5
+
6
+ require 'minitest/autorun'
7
+ require 'minitest-spec-context'
8
+
9
+ lib_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', 'lib'))
10
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
11
+
12
+ require 'Stateful'
13
+
14
+ class PoroMachine10
15
+ extend Stateful
16
+
17
+ stateful global_non_deterministic_event_ordering: true do
18
+ initial_state :initial_state do
19
+ on :an_event => :next_state
20
+ on :another_event => :final_state
21
+ end
22
+
23
+ state :next_state do
24
+ on :yet_another_event => :final_state
25
+ end
26
+
27
+ final_state :final_state
28
+ end
29
+ end
30
+
31
+ describe Stateful::Poro do
32
+ let(:machine){PoroMachine10.new}
33
+
34
+ it "must have an initial state" do
35
+ _(machine.initial_state).wont_be_nil
36
+ end
37
+
38
+ it "must have a final state (if one has been specified)" do
39
+ if PoroMachine10.final_state?
40
+ _(machine.final_state).wont_be_nil
41
+ end
42
+ end
43
+
44
+ context "initial_state" do
45
+ it "must have an initial state before any events occur" do
46
+ _(machine.initial_state?).must_equal true
47
+ end
48
+
49
+ it "must have an initial state consistent with what is given" do
50
+ _(machine.initial_state).must_equal PoroMachine10.stateful_state_machine.initial_state
51
+ end
52
+
53
+ it "must have an initial state with name as per the name given" do
54
+ _(machine.initial_state.name).must_equal :initial_state
55
+ end
56
+
57
+ it "must not be in the final state (assuming that initial and final are different states)" do
58
+ _(machine.final_state?).must_equal false
59
+ end
60
+
61
+ it "must know what it's next state is given an event name" do
62
+ _(machine.next_state(:an_event)).must_equal PoroMachine10.stateful_state_machine.find(:next_state)
63
+ _(machine.next_state(:another_event)).must_equal PoroMachine10.stateful_state_machine.find(:final_state)
64
+ end
65
+
66
+ it "must have an intial state which has a collection of transitions to other states" do
67
+ _(machine.transitions.class).must_equal Array
68
+ _(machine.transitions.all?{|transition| transition.is_a?(Stateful::Transition)}).must_equal true
69
+ end
70
+
71
+ it "must have two transitions to other states" do
72
+ _(machine.transitions.size).must_equal 2
73
+ end
74
+
75
+ it "must know what transitions are available" do
76
+ transition_pairs = machine.transitions.collect{|t| [t.event_name, t.next_state_name]}
77
+ _(transition_pairs).must_include [:an_event, :next_state]
78
+ _(transition_pairs).must_include [:another_event, :final_state]
79
+ end
80
+
81
+ it "must be active" do
82
+ _(machine.active?).must_equal true
83
+ end
84
+ end
85
+
86
+ context "next_state" do
87
+ before do
88
+ machine.an_event
89
+ end
90
+
91
+ it "must not be in the initial state" do
92
+ _(machine.initial_state?).must_equal false
93
+ end
94
+
95
+ it "must not be in the final state" do
96
+ _(machine.final_state?).must_equal false
97
+ end
98
+
99
+ it "must be in the next_state state" do
100
+ _(machine.current_state.name).must_equal :next_state
101
+ _(machine.next_state?).must_equal true
102
+ end
103
+
104
+ it "must have a collection of transitions to other states" do
105
+ _(machine.transitions.class).must_equal Array
106
+ _(machine.transitions.all?{|transition| transition.is_a?(Stateful::Transition)}).must_equal true
107
+ end
108
+
109
+ it "must have one transition to other states" do
110
+ _(machine.transitions.size).must_equal 1
111
+ end
112
+
113
+ it "must know what transitions are available" do
114
+ _(machine.transitions.collect{|t| [t.event_name, t.next_state_name]}).must_equal [[:yet_another_event, :final_state]]
115
+ end
116
+
117
+ it "must be active" do
118
+ _(machine.active?).must_equal true
119
+ end
120
+ end
121
+
122
+ context "final_state" do
123
+ before do
124
+ machine.another_event
125
+ end
126
+
127
+ it "must have a final state" do
128
+ _(machine.final_state?).must_equal true
129
+ end
130
+
131
+ it "must have a final state consistent with what is given" do
132
+ _(machine.final_state).must_equal PoroMachine10.stateful_state_machine.final_state
133
+ end
134
+
135
+ it "must have a state with name as per the name given" do
136
+ _(machine.current_state.name).must_equal :final_state
137
+ end
138
+
139
+ it "must not be in the initial state (assuming that initial and final are different states)" do
140
+ _(machine.initial_state?).must_equal false
141
+ end
142
+
143
+ it "must have no transitions" do
144
+ _(machine.transitions.empty?).must_equal true
145
+ end
146
+
147
+ it "must not be active" do
148
+ _(machine.active?).must_equal false
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,149 @@
1
+ # test/Poro/WithExplicitNonDeterministicEventOrdering.rb
2
+
3
+ gem 'minitest'
4
+ gem 'minitest-spec-context'
5
+
6
+ require 'minitest/autorun'
7
+ require 'minitest-spec-context'
8
+
9
+ lib_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', 'lib'))
10
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
11
+
12
+ require 'Stateful'
13
+
14
+ class PoroMachine6
15
+ extend Stateful
16
+
17
+ initial_state :initial_state, non_deterministic: true do
18
+ on :an_event => :next_state
19
+ on :another_event => :final_state
20
+ end
21
+
22
+ state :next_state do
23
+ on :yet_another_event => :final_state
24
+ end
25
+
26
+ final_state :final_state
27
+ end
28
+
29
+ describe Stateful::Poro do
30
+ let(:machine){PoroMachine6.new}
31
+
32
+ it "must have an initial state" do
33
+ _(machine.initial_state).wont_be_nil
34
+ end
35
+
36
+ it "must have a final state (if one has been specified)" do
37
+ if PoroMachine6.final_state?
38
+ _(machine.final_state).wont_be_nil
39
+ end
40
+ end
41
+
42
+ context "initial_state" do
43
+ it "must have an initial state before any events occur" do
44
+ _(machine.initial_state?).must_equal true
45
+ end
46
+
47
+ it "must have an initial state consistent with what is given" do
48
+ _(machine.initial_state).must_equal PoroMachine6.stateful_state_machine.initial_state
49
+ end
50
+
51
+ it "must have an initial state with name as per the name given" do
52
+ _(machine.initial_state.name).must_equal :initial_state
53
+ end
54
+
55
+ it "must not be in the final state (assuming that initial and final are different states)" do
56
+ _(machine.final_state?).must_equal false
57
+ end
58
+
59
+ it "must know what it's next state is given an event name" do
60
+ _(machine.next_state(:an_event)).must_equal PoroMachine6.stateful_state_machine.find(:next_state)
61
+ _(machine.next_state(:another_event)).must_equal PoroMachine6.stateful_state_machine.find(:final_state)
62
+ end
63
+
64
+ it "must have an intial state which has a collection of transitions to other states" do
65
+ _(machine.transitions.class).must_equal Array
66
+ _(machine.transitions.all?{|transition| transition.is_a?(Stateful::Transition)}).must_equal true
67
+ end
68
+
69
+ it "must have two transitions to other states" do
70
+ _(machine.transitions.size).must_equal 2
71
+ end
72
+
73
+ it "must know what transitions are available" do
74
+ transition_pairs = machine.transitions.collect{|t| [t.event_name, t.next_state_name]}
75
+ _(transition_pairs).must_include [:an_event, :next_state]
76
+ _(transition_pairs).must_include [:another_event, :final_state]
77
+ end
78
+
79
+ it "must be active" do
80
+ _(machine.active?).must_equal true
81
+ end
82
+ end
83
+
84
+ context "next_state" do
85
+ before do
86
+ machine.an_event
87
+ end
88
+
89
+ it "must not be in the initial state" do
90
+ _(machine.initial_state?).must_equal false
91
+ end
92
+
93
+ it "must not be in the final state" do
94
+ _(machine.final_state?).must_equal false
95
+ end
96
+
97
+ it "must be in the next_state state" do
98
+ _(machine.current_state.name).must_equal :next_state
99
+ _(machine.next_state?).must_equal true
100
+ end
101
+
102
+ it "must have a collection of transitions to other states" do
103
+ _(machine.transitions.class).must_equal Array
104
+ _(machine.transitions.all?{|transition| transition.is_a?(Stateful::Transition)}).must_equal true
105
+ end
106
+
107
+ it "must have one transition to other states" do
108
+ _(machine.transitions.size).must_equal 1
109
+ end
110
+
111
+ it "must know what transitions are available" do
112
+ _(machine.transitions.collect{|t| [t.event_name, t.next_state_name]}).must_equal [[:yet_another_event, :final_state]]
113
+ end
114
+
115
+ it "must be active" do
116
+ _(machine.active?).must_equal true
117
+ end
118
+ end
119
+
120
+ context "final_state" do
121
+ before do
122
+ machine.another_event
123
+ end
124
+
125
+ it "must have a final state" do
126
+ _(machine.final_state?).must_equal true
127
+ end
128
+
129
+ it "must have a final state consistent with what is given" do
130
+ _(machine.final_state).must_equal PoroMachine6.stateful_state_machine.final_state
131
+ end
132
+
133
+ it "must have a state with name as per the name given" do
134
+ _(machine.current_state.name).must_equal :final_state
135
+ end
136
+
137
+ it "must not be in the initial state (assuming that initial and final are different states)" do
138
+ _(machine.initial_state?).must_equal false
139
+ end
140
+
141
+ it "must have no transitions" do
142
+ _(machine.transitions.empty?).must_equal true
143
+ end
144
+
145
+ it "must not be active" do
146
+ _(machine.active?).must_equal false
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,145 @@
1
+ # test/Poro/WithInitialStateBlock.rb
2
+
3
+ gem 'minitest'
4
+ gem 'minitest-spec-context'
5
+
6
+ require 'minitest/autorun'
7
+ require 'minitest-spec-context'
8
+
9
+ lib_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', 'lib'))
10
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
11
+
12
+ require 'Stateful'
13
+
14
+ class PoroMachine4
15
+ extend Stateful
16
+
17
+ initial_state :initial_state do
18
+ on :an_event => :next_state
19
+ on :another_event => :final_state
20
+ end
21
+
22
+ state :next_state do
23
+ on :yet_another_event => :final_state
24
+ end
25
+
26
+ final_state :final_state
27
+ end
28
+
29
+ describe Stateful::Poro do
30
+ let(:machine){PoroMachine4.new}
31
+
32
+ it "must have an initial state" do
33
+ _(machine.initial_state).wont_be_nil
34
+ end
35
+
36
+ it "must have a final state (if one has been specified)" do
37
+ if PoroMachine4.final_state?
38
+ _(machine.final_state).wont_be_nil
39
+ end
40
+ end
41
+
42
+ context "initial_state" do
43
+ it "must have an initial state before any events occur" do
44
+ _(machine.initial_state?).must_equal true
45
+ end
46
+
47
+ it "must have an initial state consistent with what is given" do
48
+ _(machine.initial_state).must_equal PoroMachine4.stateful_state_machine.initial_state
49
+ end
50
+
51
+ it "must have an initial state with name as per the name given" do
52
+ _(machine.initial_state.name).must_equal :initial_state
53
+ end
54
+
55
+ it "must not be in the final state (assuming that initial and final are different states)" do
56
+ _(machine.final_state?).must_equal false
57
+ end
58
+
59
+ it "must know what it's next state is given an event name" do
60
+ _(machine.next_state(:an_event)).must_equal PoroMachine4.stateful_state_machine.find(:next_state)
61
+ _(machine.next_state(:another_event)).must_equal PoroMachine4.stateful_state_machine.find(:final_state)
62
+ end
63
+
64
+ it "must have an intial state which has as set of transitions to other states" do
65
+ _(machine.transitions.class).must_equal Array
66
+ end
67
+
68
+ it "must have two transitions to other states" do
69
+ _(machine.transitions.size).must_equal 2
70
+ end
71
+
72
+ it "must know what transitions are available" do
73
+ _(machine.transitions.collect{|t| [t.event_name, t.next_state_name]}).must_equal [[:an_event, :next_state], [:another_event, :final_state]]
74
+ end
75
+
76
+ it "must be active" do
77
+ _(machine.active?).must_equal true
78
+ end
79
+ end
80
+
81
+ context "next_state" do
82
+ before do
83
+ machine.an_event
84
+ end
85
+
86
+ it "must not be in the initial state" do
87
+ _(machine.initial_state?).must_equal false
88
+ end
89
+
90
+ it "must not be in the final state" do
91
+ _(machine.final_state?).must_equal false
92
+ end
93
+
94
+ it "must be in the next_state state" do
95
+ _(machine.current_state.name).must_equal :next_state
96
+ _(machine.next_state?).must_equal true
97
+ end
98
+
99
+ it "must have a set of transitions to other states" do
100
+ _(machine.transitions.class).must_equal Array
101
+ end
102
+
103
+ it "must have one transition to other states" do
104
+ _(machine.transitions.size).must_equal 1
105
+ end
106
+
107
+ it "must know what transitions are available" do
108
+ _(machine.transitions.collect{|t| [t.event_name, t.next_state_name]}).must_equal [[:yet_another_event, :final_state]]
109
+ end
110
+
111
+ it "must be active" do
112
+ _(machine.active?).must_equal true
113
+ end
114
+ end
115
+
116
+ context "final_state" do
117
+ before do
118
+ machine.another_event
119
+ end
120
+
121
+ it "must have a final state" do
122
+ _(machine.final_state?).must_equal true
123
+ end
124
+
125
+ it "must have a final state consistent with what is given" do
126
+ _(machine.final_state).must_equal PoroMachine4.stateful_state_machine.final_state
127
+ end
128
+
129
+ it "must have a state with name as per the name given" do
130
+ _(machine.current_state.name).must_equal :final_state
131
+ end
132
+
133
+ it "must not be in the initial state (assuming that initial and final are different states)" do
134
+ _(machine.initial_state?).must_equal false
135
+ end
136
+
137
+ it "must have no transitions" do
138
+ _(machine.transitions.empty?).must_equal true
139
+ end
140
+
141
+ it "must not be active" do
142
+ _(machine.active?).must_equal false
143
+ end
144
+ end
145
+ end