joelind-state_machine 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/CHANGELOG.rdoc +297 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +466 -0
  4. data/Rakefile +98 -0
  5. data/examples/AutoShop_state.png +0 -0
  6. data/examples/Car_state.png +0 -0
  7. data/examples/TrafficLight_state.png +0 -0
  8. data/examples/Vehicle_state.png +0 -0
  9. data/examples/auto_shop.rb +11 -0
  10. data/examples/car.rb +19 -0
  11. data/examples/merb-rest/controller.rb +51 -0
  12. data/examples/merb-rest/model.rb +28 -0
  13. data/examples/merb-rest/view_edit.html.erb +24 -0
  14. data/examples/merb-rest/view_index.html.erb +23 -0
  15. data/examples/merb-rest/view_new.html.erb +13 -0
  16. data/examples/merb-rest/view_show.html.erb +17 -0
  17. data/examples/rails-rest/controller.rb +43 -0
  18. data/examples/rails-rest/migration.rb +11 -0
  19. data/examples/rails-rest/model.rb +23 -0
  20. data/examples/rails-rest/view_edit.html.erb +25 -0
  21. data/examples/rails-rest/view_index.html.erb +23 -0
  22. data/examples/rails-rest/view_new.html.erb +14 -0
  23. data/examples/rails-rest/view_show.html.erb +17 -0
  24. data/examples/traffic_light.rb +7 -0
  25. data/examples/vehicle.rb +31 -0
  26. data/init.rb +1 -0
  27. data/lib/state_machine.rb +388 -0
  28. data/lib/state_machine/assertions.rb +36 -0
  29. data/lib/state_machine/callback.rb +189 -0
  30. data/lib/state_machine/condition_proxy.rb +94 -0
  31. data/lib/state_machine/eval_helpers.rb +67 -0
  32. data/lib/state_machine/event.rb +252 -0
  33. data/lib/state_machine/event_collection.rb +122 -0
  34. data/lib/state_machine/extensions.rb +149 -0
  35. data/lib/state_machine/guard.rb +230 -0
  36. data/lib/state_machine/integrations.rb +68 -0
  37. data/lib/state_machine/integrations/active_record.rb +492 -0
  38. data/lib/state_machine/integrations/active_record/locale.rb +11 -0
  39. data/lib/state_machine/integrations/active_record/observer.rb +41 -0
  40. data/lib/state_machine/integrations/data_mapper.rb +351 -0
  41. data/lib/state_machine/integrations/data_mapper/observer.rb +139 -0
  42. data/lib/state_machine/integrations/sequel.rb +322 -0
  43. data/lib/state_machine/machine.rb +1467 -0
  44. data/lib/state_machine/machine_collection.rb +155 -0
  45. data/lib/state_machine/matcher.rb +123 -0
  46. data/lib/state_machine/matcher_helpers.rb +54 -0
  47. data/lib/state_machine/node_collection.rb +152 -0
  48. data/lib/state_machine/state.rb +249 -0
  49. data/lib/state_machine/state_collection.rb +112 -0
  50. data/lib/state_machine/transition.rb +394 -0
  51. data/tasks/state_machine.rake +1 -0
  52. data/tasks/state_machine.rb +30 -0
  53. data/test/classes/switch.rb +11 -0
  54. data/test/functional/state_machine_test.rb +941 -0
  55. data/test/test_helper.rb +4 -0
  56. data/test/unit/assertions_test.rb +40 -0
  57. data/test/unit/callback_test.rb +455 -0
  58. data/test/unit/condition_proxy_test.rb +328 -0
  59. data/test/unit/eval_helpers_test.rb +120 -0
  60. data/test/unit/event_collection_test.rb +326 -0
  61. data/test/unit/event_test.rb +743 -0
  62. data/test/unit/guard_test.rb +908 -0
  63. data/test/unit/integrations/active_record_test.rb +1374 -0
  64. data/test/unit/integrations/data_mapper_test.rb +962 -0
  65. data/test/unit/integrations/sequel_test.rb +859 -0
  66. data/test/unit/integrations_test.rb +42 -0
  67. data/test/unit/invalid_event_test.rb +7 -0
  68. data/test/unit/invalid_transition_test.rb +7 -0
  69. data/test/unit/machine_collection_test.rb +938 -0
  70. data/test/unit/machine_test.rb +2004 -0
  71. data/test/unit/matcher_helpers_test.rb +37 -0
  72. data/test/unit/matcher_test.rb +155 -0
  73. data/test/unit/node_collection_test.rb +207 -0
  74. data/test/unit/state_collection_test.rb +280 -0
  75. data/test/unit/state_machine_test.rb +31 -0
  76. data/test/unit/state_test.rb +795 -0
  77. data/test/unit/transition_test.rb +1212 -0
  78. metadata +163 -0
@@ -0,0 +1,37 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class MatcherHelpersAllTest < Test::Unit::TestCase
4
+ include StateMachine::MatcherHelpers
5
+
6
+ def setup
7
+ @matcher = all
8
+ end
9
+
10
+ def test_should_build_an_all_matcher
11
+ assert_equal StateMachine::AllMatcher.instance, @matcher
12
+ end
13
+ end
14
+
15
+ class MatcherHelpersAnyTest < Test::Unit::TestCase
16
+ include StateMachine::MatcherHelpers
17
+
18
+ def setup
19
+ @matcher = any
20
+ end
21
+
22
+ def test_should_build_an_all_matcher
23
+ assert_equal StateMachine::AllMatcher.instance, @matcher
24
+ end
25
+ end
26
+
27
+ class MatcherHelpersSameTest < Test::Unit::TestCase
28
+ include StateMachine::MatcherHelpers
29
+
30
+ def setup
31
+ @matcher = same
32
+ end
33
+
34
+ def test_should_build_a_loopback_matcher
35
+ assert_equal StateMachine::LoopbackMatcher.instance, @matcher
36
+ end
37
+ end
@@ -0,0 +1,155 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class MatcherByDefaultTest < Test::Unit::TestCase
4
+ def setup
5
+ @matcher = StateMachine::Matcher.new
6
+ end
7
+
8
+ def test_should_have_no_values
9
+ assert_equal [], @matcher.values
10
+ end
11
+
12
+ def test_should_filter_all_values
13
+ assert_equal [], @matcher.filter([:parked, :idling])
14
+ end
15
+ end
16
+
17
+ class MatcherWithValueTest < Test::Unit::TestCase
18
+ def setup
19
+ @matcher = StateMachine::Matcher.new(nil)
20
+ end
21
+
22
+ def test_should_have_values
23
+ assert_equal [nil], @matcher.values
24
+ end
25
+
26
+ def test_should_filter_unknown_values
27
+ assert_equal [nil], @matcher.filter([nil, :parked])
28
+ end
29
+ end
30
+
31
+ class MatcherWithMultipleValuesTest < Test::Unit::TestCase
32
+ def setup
33
+ @matcher = StateMachine::Matcher.new([:parked, :idling])
34
+ end
35
+
36
+ def test_should_have_values
37
+ assert_equal [:parked, :idling], @matcher.values
38
+ end
39
+
40
+ def test_should_filter_unknown_values
41
+ assert_equal [:parked], @matcher.filter([:parked, :first_gear])
42
+ end
43
+ end
44
+
45
+ class AllMatcherTest < Test::Unit::TestCase
46
+ def setup
47
+ @matcher = StateMachine::AllMatcher.instance
48
+ end
49
+
50
+ def test_should_have_no_values
51
+ assert_equal [], @matcher.values
52
+ end
53
+
54
+ def test_should_always_match
55
+ [nil, :parked, :idling].each {|value| assert @matcher.matches?(value)}
56
+ end
57
+
58
+ def test_should_not_filter_any_values
59
+ assert_equal [:parked, :idling], @matcher.filter([:parked, :idling])
60
+ end
61
+
62
+ def test_should_generate_blacklist_matcher_after_subtraction
63
+ matcher = @matcher - [:parked, :idling]
64
+ assert_instance_of StateMachine::BlacklistMatcher, matcher
65
+ assert_equal [:parked, :idling], matcher.values
66
+ end
67
+
68
+ def test_should_have_a_description
69
+ assert_equal 'all', @matcher.description
70
+ end
71
+ end
72
+
73
+ class WhitelistMatcherTest < Test::Unit::TestCase
74
+ def setup
75
+ @matcher = StateMachine::WhitelistMatcher.new([:parked, :idling])
76
+ end
77
+
78
+ def test_should_have_values
79
+ assert_equal [:parked, :idling], @matcher.values
80
+ end
81
+
82
+ def test_should_filter_unknown_values
83
+ assert_equal [:parked, :idling], @matcher.filter([:parked, :idling, :first_gear])
84
+ end
85
+
86
+ def test_should_match_known_values
87
+ assert @matcher.matches?(:parked)
88
+ end
89
+
90
+ def test_should_not_match_unknown_values
91
+ assert !@matcher.matches?(:first_gear)
92
+ end
93
+
94
+ def test_should_have_a_description
95
+ assert_equal '[:parked, :idling]', @matcher.description
96
+
97
+ matcher = StateMachine::WhitelistMatcher.new([:parked])
98
+ assert_equal ':parked', matcher.description
99
+ end
100
+ end
101
+
102
+ class BlacklistMatcherTest < Test::Unit::TestCase
103
+ def setup
104
+ @matcher = StateMachine::BlacklistMatcher.new([:parked, :idling])
105
+ end
106
+
107
+ def test_should_have_values
108
+ assert_equal [:parked, :idling], @matcher.values
109
+ end
110
+
111
+ def test_should_filter_known_values
112
+ assert_equal [:first_gear], @matcher.filter([:parked, :idling, :first_gear])
113
+ end
114
+
115
+ def test_should_match_unknown_values
116
+ assert @matcher.matches?(:first_gear)
117
+ end
118
+
119
+ def test_should_not_match_known_values
120
+ assert !@matcher.matches?(:parked)
121
+ end
122
+
123
+ def test_should_have_a_description
124
+ assert_equal 'all - [:parked, :idling]', @matcher.description
125
+
126
+ matcher = StateMachine::BlacklistMatcher.new([:parked])
127
+ assert_equal 'all - :parked', matcher.description
128
+ end
129
+ end
130
+
131
+ class LoopbackMatcherTest < Test::Unit::TestCase
132
+ def setup
133
+ @matcher = StateMachine::LoopbackMatcher.instance
134
+ end
135
+
136
+ def test_should_have_no_values
137
+ assert_equal [], @matcher.values
138
+ end
139
+
140
+ def test_should_filter_all_values
141
+ assert_equal [], @matcher.filter([:parked, :idling])
142
+ end
143
+
144
+ def test_should_match_if_from_context_is_same
145
+ assert @matcher.matches?(:parked, :from => :parked)
146
+ end
147
+
148
+ def test_should_not_match_if_from_context_is_different
149
+ assert !@matcher.matches?(:parked, :from => :idling)
150
+ end
151
+
152
+ def test_should_have_a_description
153
+ assert_equal 'same', @matcher.description
154
+ end
155
+ end
@@ -0,0 +1,207 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class NodeCollectionByDefaultTest < Test::Unit::TestCase
4
+ def setup
5
+ @machine = StateMachine::Machine.new(Class.new)
6
+ @collection = StateMachine::NodeCollection.new(@machine)
7
+ end
8
+
9
+ def test_should_not_have_any_nodes
10
+ assert_equal 0, @collection.length
11
+ end
12
+
13
+ def test_should_have_a_machine
14
+ assert_equal @machine, @collection.machine
15
+ end
16
+
17
+ def test_should_index_by_name
18
+ @collection << object = Struct.new(:name).new(:parked)
19
+ assert_equal object, @collection[:parked]
20
+ end
21
+ end
22
+
23
+ class NodeCollectionTest < Test::Unit::TestCase
24
+ def setup
25
+ @machine = StateMachine::Machine.new(Class.new)
26
+ @collection = StateMachine::NodeCollection.new(@machine)
27
+ end
28
+
29
+ def test_should_raise_exception_if_invalid_option_specified
30
+ exception = assert_raise(ArgumentError) { StateMachine::NodeCollection.new(@machine, :invalid => true) }
31
+ assert_equal 'Invalid key(s): invalid', exception.message
32
+ end
33
+
34
+ def test_should_raise_exception_on_lookup_if_invalid_index_specified
35
+ exception = assert_raise(ArgumentError) { @collection[:something, :invalid] }
36
+ assert_equal 'Invalid index: :invalid', exception.message
37
+ end
38
+
39
+ def test_should_raise_exception_on_fetch_if_invalid_index_specified
40
+ exception = assert_raise(ArgumentError) { @collection.fetch(:something, :invalid) }
41
+ assert_equal 'Invalid index: :invalid', exception.message
42
+ end
43
+ end
44
+
45
+ class NodeCollectionAfterBeingCopiedTest < Test::Unit::TestCase
46
+ def setup
47
+ machine = StateMachine::Machine.new(Class.new)
48
+ @collection = StateMachine::NodeCollection.new(machine)
49
+ @collection << @parked = Struct.new(:name).new(:parked)
50
+
51
+ @copied_collection = @collection.dup
52
+ @copied_collection << @idling = Struct.new(:name).new(:idling)
53
+ end
54
+
55
+ def test_should_not_modify_the_original_list
56
+ assert_equal 1, @collection.length
57
+ assert_equal 2, @copied_collection.length
58
+ end
59
+
60
+ def test_should_not_modify_the_indices
61
+ assert_nil @collection[:idling]
62
+ assert_equal @idling, @copied_collection[:idling]
63
+ end
64
+
65
+ def test_should_copy_each_node
66
+ assert_not_same @parked, @copied_collection[:parked]
67
+ end
68
+ end
69
+
70
+ class NodeCollectionWithoutIndicesTest < Test::Unit::TestCase
71
+ def setup
72
+ machine = StateMachine::Machine.new(Class.new)
73
+ @collection = StateMachine::NodeCollection.new(machine, :index => {})
74
+ end
75
+
76
+ def test_should_allow_adding_node
77
+ @collection << Object.new
78
+ assert_equal 1, @collection.length
79
+ end
80
+
81
+ def test_should_not_allow_keys_retrieval
82
+ exception = assert_raise(ArgumentError) { @collection.keys }
83
+ assert_equal 'No indices configured', exception.message
84
+ end
85
+
86
+ def test_should_not_allow_lookup
87
+ @collection << object = Object.new
88
+ exception = assert_raise(ArgumentError) { @collection[0] }
89
+ assert_equal 'No indices configured', exception.message
90
+ end
91
+
92
+ def test_should_not_allow_fetching
93
+ @collection << object = Object.new
94
+ exception = assert_raise(ArgumentError) { @collection.fetch(0) }
95
+ assert_equal 'No indices configured', exception.message
96
+ end
97
+ end
98
+
99
+ class NodeCollectionWithIndicesTest < Test::Unit::TestCase
100
+ def setup
101
+ machine = StateMachine::Machine.new(Class.new)
102
+ @collection = StateMachine::NodeCollection.new(machine, :index => [:name, :value])
103
+
104
+ @object = Struct.new(:name, :value).new(:parked, 1)
105
+ @collection << @object
106
+ end
107
+
108
+ def test_should_use_first_index_by_default_on_key_retrieval
109
+ assert_equal [:parked], @collection.keys
110
+ end
111
+
112
+ def test_should_allow_customizing_index_for_key_retrieval
113
+ assert_equal [1], @collection.keys(:value)
114
+ end
115
+
116
+ def test_should_use_first_index_by_default_on_lookup
117
+ assert_equal @object, @collection[:parked]
118
+ assert_nil @collection[1]
119
+ end
120
+
121
+ def test_should_allow_customizing_index_on_lookup
122
+ assert_equal @object, @collection[1, :value]
123
+ assert_nil @collection[:parked, :value]
124
+ end
125
+
126
+ def test_should_use_first_index_by_default_on_fetch
127
+ assert_equal @object, @collection.fetch(:parked)
128
+ exception = assert_raise(IndexError) { @collection.fetch(1) }
129
+ assert_equal '1 is an invalid name', exception.message
130
+ end
131
+
132
+ def test_should_allow_customizing_index_on_fetch
133
+ assert_equal @object, @collection.fetch(1, :value)
134
+ exception = assert_raise(IndexError) { @collection.fetch(:parked, :value) }
135
+ assert_equal ':parked is an invalid value', exception.message
136
+ end
137
+ end
138
+
139
+ class NodeCollectionWithNodesTest < Test::Unit::TestCase
140
+ def setup
141
+ machine = StateMachine::Machine.new(Class.new)
142
+ @collection = StateMachine::NodeCollection.new(machine)
143
+
144
+ @klass = Struct.new(:name, :machine)
145
+ @parked = @klass.new(:parked, machine)
146
+ @idling = @klass.new(:idling, machine)
147
+
148
+ @collection << @parked
149
+ @collection << @idling
150
+ end
151
+
152
+ def test_should_be_able_to_enumerate
153
+ order = []
154
+ @collection.each {|object| order << object}
155
+
156
+ assert_equal [@parked, @idling], order
157
+ end
158
+
159
+ def test_should_be_able_to_access_by_index
160
+ assert_equal @parked, @collection.at(0)
161
+ assert_equal @idling, @collection.at(1)
162
+ end
163
+
164
+ def test_should_deep_copy_machine_changes
165
+ new_machine = StateMachine::Machine.new(Class.new)
166
+ @collection.machine = new_machine
167
+
168
+ assert_equal new_machine, @collection.machine
169
+ assert_equal new_machine, @parked.machine
170
+ assert_equal new_machine, @idling.machine
171
+ end
172
+ end
173
+
174
+ class NodeCollectionAfterUpdateTest < Test::Unit::TestCase
175
+ def setup
176
+ machine = StateMachine::Machine.new(Class.new)
177
+ @collection = StateMachine::NodeCollection.new(machine, :index => [:name, :value])
178
+
179
+ @klass = Struct.new(:name, :value)
180
+ @parked = @klass.new(:parked, 1)
181
+ @idling = @klass.new(:idling, 2)
182
+
183
+ @collection << @parked << @idling
184
+
185
+ @parked.name = :parking
186
+ @parked.value = 0
187
+ @collection.update(@parked)
188
+ end
189
+
190
+ def test_should_not_change_the_index
191
+ assert_equal @parked, @collection.at(0)
192
+ end
193
+
194
+ def test_should_not_duplicate_in_the_collection
195
+ assert_equal 2, @collection.length
196
+ end
197
+
198
+ def test_should_add_each_indexed_key
199
+ assert_equal @parked, @collection[:parking]
200
+ assert_equal @parked, @collection[0, :value]
201
+ end
202
+
203
+ def test_should_remove_each_old_indexed_key
204
+ assert_nil @collection[:parked]
205
+ assert_nil @collection[1, :value]
206
+ end
207
+ end
@@ -0,0 +1,280 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class StateCollectionByDefaultTest < Test::Unit::TestCase
4
+ def setup
5
+ @machine = StateMachine::Machine.new(Class.new)
6
+ @states = StateMachine::StateCollection.new(@machine)
7
+ end
8
+
9
+ def test_should_not_have_any_nodes
10
+ assert_equal 0, @states.length
11
+ end
12
+
13
+ def test_should_have_a_machine
14
+ assert_equal @machine, @states.machine
15
+ end
16
+
17
+ def test_should_be_empty_by_priority
18
+ assert_equal [], @states.by_priority
19
+ end
20
+ end
21
+
22
+ class StateCollectionTest < Test::Unit::TestCase
23
+ def setup
24
+ @klass = Class.new
25
+ @machine = StateMachine::Machine.new(@klass)
26
+ @states = StateMachine::StateCollection.new(@machine)
27
+
28
+ @states << @nil = StateMachine::State.new(@machine, nil)
29
+ @states << @parked = StateMachine::State.new(@machine, :parked)
30
+ @states << @idling = StateMachine::State.new(@machine, :idling)
31
+
32
+ @object = @klass.new
33
+ end
34
+
35
+ def test_should_index_by_name
36
+ assert_equal @parked, @states[:parked, :name]
37
+ end
38
+
39
+ def test_should_index_by_name_by_default
40
+ assert_equal @parked, @states[:parked]
41
+ end
42
+
43
+ def test_should_index_by_value
44
+ assert_equal @parked, @states['parked', :value]
45
+ end
46
+
47
+ def test_should_not_match_if_value_does_not_match
48
+ assert !@states.matches?(@object, :parked)
49
+ assert !@states.matches?(@object, :idling)
50
+ end
51
+
52
+ def test_should_match_if_value_matches
53
+ assert @states.matches?(@object, nil)
54
+ end
55
+
56
+ def test_raise_exception_if_matching_invalid_state
57
+ assert_raise(IndexError) { @states.matches?(@object, :invalid) }
58
+ end
59
+
60
+ def test_should_find_state_for_object_if_value_is_known
61
+ @object.state = 'parked'
62
+ assert_equal @parked, @states.match(@object)
63
+ end
64
+
65
+ def test_should_find_bang_state_for_object_if_value_is_known
66
+ @object.state = 'parked'
67
+ assert_equal @parked, @states.match!(@object)
68
+ end
69
+
70
+ def test_should_not_find_state_for_object_with_unknown_value
71
+ @object.state = 'invalid'
72
+ assert_nil @states.match(@object)
73
+ end
74
+
75
+ def test_should_raise_exception_if_finding_bang_state_for_object_with_unknown_value
76
+ @object.state = 'invalid'
77
+ exception = assert_raise(ArgumentError) { @states.match!(@object) }
78
+ assert_equal '"invalid" is not a known state value', exception.message
79
+ end
80
+ end
81
+
82
+ class StateCollectionWithCustomStateValuesTest < Test::Unit::TestCase
83
+ def setup
84
+ @klass = Class.new
85
+ @machine = StateMachine::Machine.new(@klass)
86
+ @states = StateMachine::StateCollection.new(@machine)
87
+
88
+ @states << @state = StateMachine::State.new(@machine, :parked, :value => 1)
89
+
90
+ @object = @klass.new
91
+ @object.state = 1
92
+ end
93
+
94
+ def test_should_match_if_value_matches
95
+ assert @states.matches?(@object, :parked)
96
+ end
97
+
98
+ def test_should_not_match_if_value_does_not_match
99
+ @object.state = 2
100
+ assert !@states.matches?(@object, :parked)
101
+ end
102
+
103
+ def test_should_find_state_for_object_if_value_is_known
104
+ assert_equal @state, @states.match(@object)
105
+ end
106
+ end
107
+
108
+ class StateCollectionWithStateMatchersTest < Test::Unit::TestCase
109
+ def setup
110
+ @klass = Class.new
111
+ @machine = StateMachine::Machine.new(@klass)
112
+ @states = StateMachine::StateCollection.new(@machine)
113
+
114
+ @states << @state = StateMachine::State.new(@machine, :parked, :if => lambda {|value| !value.nil?})
115
+
116
+ @object = @klass.new
117
+ @object.state = 1
118
+ end
119
+
120
+ def test_should_match_if_value_matches
121
+ assert @states.matches?(@object, :parked)
122
+ end
123
+
124
+ def test_should_not_match_if_value_does_not_match
125
+ @object.state = nil
126
+ assert !@states.matches?(@object, :parked)
127
+ end
128
+
129
+ def test_should_find_state_for_object_if_value_is_known
130
+ assert_equal @state, @states.match(@object)
131
+ end
132
+ end
133
+
134
+ class StateCollectionWithInitialStateTest < Test::Unit::TestCase
135
+ def setup
136
+ @machine = StateMachine::Machine.new(Class.new)
137
+ @states = StateMachine::StateCollection.new(@machine)
138
+
139
+ @states << @parked = StateMachine::State.new(@machine, :parked)
140
+ @states << @idling = StateMachine::State.new(@machine, :idling)
141
+
142
+ @parked.initial = true
143
+ end
144
+
145
+ def test_should_order_state_before_transition_states
146
+ @machine.event :ignite do
147
+ transition :to => :idling
148
+ end
149
+ assert_equal [@parked, @idling], @states.by_priority
150
+ end
151
+
152
+ def test_should_order_state_before_states_with_behaviors
153
+ @idling.context do
154
+ def speed
155
+ 0
156
+ end
157
+ end
158
+ assert_equal [@parked, @idling], @states.by_priority
159
+ end
160
+
161
+ def test_should_order_state_before_other_states
162
+ assert_equal [@parked, @idling], @states.by_priority
163
+ end
164
+
165
+ def test_should_order_state_before_callback_states
166
+ @machine.before_transition :from => :idling, :do => lambda {}
167
+ assert_equal [@parked, @idling], @states.by_priority
168
+ end
169
+ end
170
+
171
+ class StateCollectionWithStateBehaviorsTest < Test::Unit::TestCase
172
+ def setup
173
+ @machine = StateMachine::Machine.new(Class.new)
174
+ @states = StateMachine::StateCollection.new(@machine)
175
+
176
+ @states << @parked = StateMachine::State.new(@machine, :parked)
177
+ @states << @idling = StateMachine::State.new(@machine, :idling)
178
+
179
+ @idling.context do
180
+ def speed
181
+ 0
182
+ end
183
+ end
184
+ end
185
+
186
+ def test_should_order_states_after_initial_state
187
+ @parked.initial = true
188
+ assert_equal [@parked, @idling], @states.by_priority
189
+ end
190
+
191
+ def test_should_order_states_after_transition_states
192
+ @machine.event :ignite do
193
+ transition :from => :parked
194
+ end
195
+ assert_equal [@parked, @idling], @states.by_priority
196
+ end
197
+
198
+ def test_should_order_states_before_other_states
199
+ assert_equal [@idling, @parked], @states.by_priority
200
+ end
201
+
202
+ def test_should_order_state_before_callback_states
203
+ @machine.before_transition :from => :parked, :do => lambda {}
204
+ assert_equal [@idling, @parked], @states.by_priority
205
+ end
206
+ end
207
+
208
+ class StateCollectionWithEventTransitionsTest < Test::Unit::TestCase
209
+ def setup
210
+ @machine = StateMachine::Machine.new(Class.new)
211
+ @states = StateMachine::StateCollection.new(@machine)
212
+
213
+ @states << @parked = StateMachine::State.new(@machine, :parked)
214
+ @states << @idling = StateMachine::State.new(@machine, :idling)
215
+
216
+ @machine.event :ignite do
217
+ transition :to => :idling
218
+ end
219
+ end
220
+
221
+ def test_should_order_states_after_initial_state
222
+ @parked.initial = true
223
+ assert_equal [@parked, @idling], @states.by_priority
224
+ end
225
+
226
+ def test_should_order_states_before_states_with_behaviors
227
+ @parked.context do
228
+ def speed
229
+ 0
230
+ end
231
+ end
232
+ assert_equal [@idling, @parked], @states.by_priority
233
+ end
234
+
235
+ def test_should_order_states_before_other_states
236
+ assert_equal [@idling, @parked], @states.by_priority
237
+ end
238
+
239
+ def test_should_order_state_before_callback_states
240
+ @machine.before_transition :from => :parked, :do => lambda {}
241
+ assert_equal [@idling, @parked], @states.by_priority
242
+ end
243
+ end
244
+
245
+ class StateCollectionWithTransitionCallbacksTest < Test::Unit::TestCase
246
+ def setup
247
+ @machine = StateMachine::Machine.new(Class.new)
248
+ @states = StateMachine::StateCollection.new(@machine)
249
+
250
+ @states << @parked = StateMachine::State.new(@machine, :parked)
251
+ @states << @idling = StateMachine::State.new(@machine, :idling)
252
+
253
+ @machine.before_transition :to => :idling, :do => lambda {}
254
+ end
255
+
256
+ def test_should_order_states_after_initial_state
257
+ @parked.initial = true
258
+ assert_equal [@parked, @idling], @states.by_priority
259
+ end
260
+
261
+ def test_should_order_states_after_transition_states
262
+ @machine.event :ignite do
263
+ transition :from => :parked
264
+ end
265
+ assert_equal [@parked, @idling], @states.by_priority
266
+ end
267
+
268
+ def test_should_order_states_after_states_with_behaviors
269
+ @parked.context do
270
+ def speed
271
+ 0
272
+ end
273
+ end
274
+ assert_equal [@parked, @idling], @states.by_priority
275
+ end
276
+
277
+ def test_should_order_states_after_other_states
278
+ assert_equal [@parked, @idling], @states.by_priority
279
+ end
280
+ end