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