spree-state_machine 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +12 -0
  4. data/.yardopts +5 -0
  5. data/CHANGELOG.md +502 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +20 -0
  8. data/README.md +1246 -0
  9. data/Rakefile +20 -0
  10. data/examples/AutoShop_state.png +0 -0
  11. data/examples/Car_state.png +0 -0
  12. data/examples/Gemfile +5 -0
  13. data/examples/Gemfile.lock +14 -0
  14. data/examples/TrafficLight_state.png +0 -0
  15. data/examples/Vehicle_state.png +0 -0
  16. data/examples/auto_shop.rb +13 -0
  17. data/examples/car.rb +21 -0
  18. data/examples/doc/AutoShop.html +2856 -0
  19. data/examples/doc/AutoShop_state.png +0 -0
  20. data/examples/doc/Car.html +919 -0
  21. data/examples/doc/Car_state.png +0 -0
  22. data/examples/doc/TrafficLight.html +2230 -0
  23. data/examples/doc/TrafficLight_state.png +0 -0
  24. data/examples/doc/Vehicle.html +7921 -0
  25. data/examples/doc/Vehicle_state.png +0 -0
  26. data/examples/doc/_index.html +136 -0
  27. data/examples/doc/class_list.html +47 -0
  28. data/examples/doc/css/common.css +1 -0
  29. data/examples/doc/css/full_list.css +55 -0
  30. data/examples/doc/css/style.css +322 -0
  31. data/examples/doc/file_list.html +46 -0
  32. data/examples/doc/frames.html +13 -0
  33. data/examples/doc/index.html +136 -0
  34. data/examples/doc/js/app.js +205 -0
  35. data/examples/doc/js/full_list.js +173 -0
  36. data/examples/doc/js/jquery.js +16 -0
  37. data/examples/doc/method_list.html +734 -0
  38. data/examples/doc/top-level-namespace.html +105 -0
  39. data/examples/merb-rest/controller.rb +51 -0
  40. data/examples/merb-rest/model.rb +28 -0
  41. data/examples/merb-rest/view_edit.html.erb +24 -0
  42. data/examples/merb-rest/view_index.html.erb +23 -0
  43. data/examples/merb-rest/view_new.html.erb +13 -0
  44. data/examples/merb-rest/view_show.html.erb +17 -0
  45. data/examples/rails-rest/controller.rb +43 -0
  46. data/examples/rails-rest/migration.rb +7 -0
  47. data/examples/rails-rest/model.rb +23 -0
  48. data/examples/rails-rest/view__form.html.erb +34 -0
  49. data/examples/rails-rest/view_edit.html.erb +6 -0
  50. data/examples/rails-rest/view_index.html.erb +25 -0
  51. data/examples/rails-rest/view_new.html.erb +5 -0
  52. data/examples/rails-rest/view_show.html.erb +19 -0
  53. data/examples/traffic_light.rb +9 -0
  54. data/examples/vehicle.rb +33 -0
  55. data/lib/state_machine/assertions.rb +36 -0
  56. data/lib/state_machine/branch.rb +225 -0
  57. data/lib/state_machine/callback.rb +236 -0
  58. data/lib/state_machine/core.rb +7 -0
  59. data/lib/state_machine/core_ext/class/state_machine.rb +5 -0
  60. data/lib/state_machine/core_ext.rb +2 -0
  61. data/lib/state_machine/error.rb +13 -0
  62. data/lib/state_machine/eval_helpers.rb +87 -0
  63. data/lib/state_machine/event.rb +257 -0
  64. data/lib/state_machine/event_collection.rb +141 -0
  65. data/lib/state_machine/extensions.rb +149 -0
  66. data/lib/state_machine/graph.rb +92 -0
  67. data/lib/state_machine/helper_module.rb +17 -0
  68. data/lib/state_machine/initializers/rails.rb +25 -0
  69. data/lib/state_machine/initializers.rb +4 -0
  70. data/lib/state_machine/integrations/active_model/locale.rb +11 -0
  71. data/lib/state_machine/integrations/active_model/observer.rb +33 -0
  72. data/lib/state_machine/integrations/active_model/observer_update.rb +42 -0
  73. data/lib/state_machine/integrations/active_model/versions.rb +31 -0
  74. data/lib/state_machine/integrations/active_model.rb +585 -0
  75. data/lib/state_machine/integrations/active_record/locale.rb +20 -0
  76. data/lib/state_machine/integrations/active_record/versions.rb +123 -0
  77. data/lib/state_machine/integrations/active_record.rb +525 -0
  78. data/lib/state_machine/integrations/base.rb +100 -0
  79. data/lib/state_machine/integrations.rb +121 -0
  80. data/lib/state_machine/machine.rb +2287 -0
  81. data/lib/state_machine/machine_collection.rb +74 -0
  82. data/lib/state_machine/macro_methods.rb +522 -0
  83. data/lib/state_machine/matcher.rb +123 -0
  84. data/lib/state_machine/matcher_helpers.rb +54 -0
  85. data/lib/state_machine/node_collection.rb +222 -0
  86. data/lib/state_machine/path.rb +120 -0
  87. data/lib/state_machine/path_collection.rb +90 -0
  88. data/lib/state_machine/state.rb +297 -0
  89. data/lib/state_machine/state_collection.rb +112 -0
  90. data/lib/state_machine/state_context.rb +138 -0
  91. data/lib/state_machine/transition.rb +470 -0
  92. data/lib/state_machine/transition_collection.rb +245 -0
  93. data/lib/state_machine/version.rb +3 -0
  94. data/lib/state_machine/yard/handlers/base.rb +32 -0
  95. data/lib/state_machine/yard/handlers/event.rb +25 -0
  96. data/lib/state_machine/yard/handlers/machine.rb +344 -0
  97. data/lib/state_machine/yard/handlers/state.rb +25 -0
  98. data/lib/state_machine/yard/handlers/transition.rb +47 -0
  99. data/lib/state_machine/yard/handlers.rb +12 -0
  100. data/lib/state_machine/yard/templates/default/class/html/setup.rb +30 -0
  101. data/lib/state_machine/yard/templates/default/class/html/state_machines.erb +12 -0
  102. data/lib/state_machine/yard/templates.rb +3 -0
  103. data/lib/state_machine/yard.rb +8 -0
  104. data/lib/state_machine.rb +8 -0
  105. data/lib/yard-state_machine.rb +2 -0
  106. data/state_machine.gemspec +22 -0
  107. data/test/files/en.yml +17 -0
  108. data/test/files/switch.rb +15 -0
  109. data/test/functional/state_machine_test.rb +1066 -0
  110. data/test/test_helper.rb +7 -0
  111. data/test/unit/assertions_test.rb +40 -0
  112. data/test/unit/branch_test.rb +969 -0
  113. data/test/unit/callback_test.rb +704 -0
  114. data/test/unit/error_test.rb +43 -0
  115. data/test/unit/eval_helpers_test.rb +270 -0
  116. data/test/unit/event_collection_test.rb +398 -0
  117. data/test/unit/event_test.rb +1196 -0
  118. data/test/unit/graph_test.rb +98 -0
  119. data/test/unit/helper_module_test.rb +17 -0
  120. data/test/unit/integrations/active_model_test.rb +1245 -0
  121. data/test/unit/integrations/active_record_test.rb +2551 -0
  122. data/test/unit/integrations/base_test.rb +104 -0
  123. data/test/unit/integrations_test.rb +71 -0
  124. data/test/unit/invalid_event_test.rb +20 -0
  125. data/test/unit/invalid_parallel_transition_test.rb +18 -0
  126. data/test/unit/invalid_transition_test.rb +115 -0
  127. data/test/unit/machine_collection_test.rb +603 -0
  128. data/test/unit/machine_test.rb +3395 -0
  129. data/test/unit/matcher_helpers_test.rb +37 -0
  130. data/test/unit/matcher_test.rb +155 -0
  131. data/test/unit/node_collection_test.rb +362 -0
  132. data/test/unit/path_collection_test.rb +266 -0
  133. data/test/unit/path_test.rb +485 -0
  134. data/test/unit/state_collection_test.rb +352 -0
  135. data/test/unit/state_context_test.rb +441 -0
  136. data/test/unit/state_machine_test.rb +31 -0
  137. data/test/unit/state_test.rb +1101 -0
  138. data/test/unit/transition_collection_test.rb +2168 -0
  139. data/test/unit/transition_test.rb +1558 -0
  140. metadata +264 -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,362 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class Node < Struct.new(:name, :value, :machine)
4
+ def context
5
+ yield
6
+ end
7
+ end
8
+
9
+ class NodeCollectionByDefaultTest < Test::Unit::TestCase
10
+ def setup
11
+ @machine = StateMachine::Machine.new(Class.new)
12
+ @collection = StateMachine::NodeCollection.new(@machine)
13
+ end
14
+
15
+ def test_should_not_have_any_nodes
16
+ assert_equal 0, @collection.length
17
+ end
18
+
19
+ def test_should_have_a_machine
20
+ assert_equal @machine, @collection.machine
21
+ end
22
+
23
+ def test_should_index_by_name
24
+ @collection << object = Node.new(:parked)
25
+ assert_equal object, @collection[:parked]
26
+ end
27
+ end
28
+
29
+ class NodeCollectionTest < Test::Unit::TestCase
30
+ def setup
31
+ @machine = StateMachine::Machine.new(Class.new)
32
+ @collection = StateMachine::NodeCollection.new(@machine)
33
+ end
34
+
35
+ def test_should_raise_exception_if_invalid_option_specified
36
+ exception = assert_raise(ArgumentError) { StateMachine::NodeCollection.new(@machine, :invalid => true) }
37
+ assert_equal 'Invalid key(s): invalid', exception.message
38
+ end
39
+
40
+ def test_should_raise_exception_on_lookup_if_invalid_index_specified
41
+ exception = assert_raise(ArgumentError) { @collection[:something, :invalid] }
42
+ assert_equal 'Invalid index: :invalid', exception.message
43
+ end
44
+
45
+ def test_should_raise_exception_on_fetch_if_invalid_index_specified
46
+ exception = assert_raise(ArgumentError) { @collection.fetch(:something, :invalid) }
47
+ assert_equal 'Invalid index: :invalid', exception.message
48
+ end
49
+ end
50
+
51
+ class NodeCollectionAfterBeingCopiedTest < Test::Unit::TestCase
52
+ def setup
53
+ machine = StateMachine::Machine.new(Class.new)
54
+ @collection = StateMachine::NodeCollection.new(machine)
55
+ @collection << @parked = Node.new(:parked)
56
+
57
+ @contexts_run = contexts_run = []
58
+ @collection.context([:parked]) {contexts_run << :parked}
59
+ @contexts_run.clear
60
+
61
+ @copied_collection = @collection.dup
62
+ @copied_collection << @idling = Node.new(:idling)
63
+ @copied_collection.context([:first_gear]) {contexts_run << :first_gear}
64
+ end
65
+
66
+ def test_should_not_modify_the_original_list
67
+ assert_equal 1, @collection.length
68
+ assert_equal 2, @copied_collection.length
69
+ end
70
+
71
+ def test_should_not_modify_the_indices
72
+ assert_nil @collection[:idling]
73
+ assert_equal @idling, @copied_collection[:idling]
74
+ end
75
+
76
+ def test_should_copy_each_node
77
+ assert_not_same @parked, @copied_collection[:parked]
78
+ end
79
+
80
+ def test_should_not_run_contexts
81
+ assert_equal [], @contexts_run
82
+ end
83
+
84
+ def test_should_not_modify_contexts
85
+ @collection << Node.new(:first_gear)
86
+ assert_equal [], @contexts_run
87
+ end
88
+
89
+ def test_should_copy_contexts
90
+ @copied_collection << Node.new(:parked)
91
+ assert !@contexts_run.empty?
92
+ end
93
+ end
94
+
95
+ class NodeCollectionWithoutIndicesTest < Test::Unit::TestCase
96
+ def setup
97
+ machine = StateMachine::Machine.new(Class.new)
98
+ @collection = StateMachine::NodeCollection.new(machine, :index => {})
99
+ end
100
+
101
+ def test_should_allow_adding_node
102
+ @collection << Object.new
103
+ assert_equal 1, @collection.length
104
+ end
105
+
106
+ def test_should_not_allow_keys_retrieval
107
+ exception = assert_raise(ArgumentError) { @collection.keys }
108
+ assert_equal 'No indices configured', exception.message
109
+ end
110
+
111
+ def test_should_not_allow_lookup
112
+ @collection << Object.new
113
+ exception = assert_raise(ArgumentError) { @collection[0] }
114
+ assert_equal 'No indices configured', exception.message
115
+ end
116
+
117
+ def test_should_not_allow_fetching
118
+ @collection << Object.new
119
+ exception = assert_raise(ArgumentError) { @collection.fetch(0) }
120
+ assert_equal 'No indices configured', exception.message
121
+ end
122
+ end
123
+
124
+ class NodeCollectionWithIndicesTest < Test::Unit::TestCase
125
+ def setup
126
+ machine = StateMachine::Machine.new(Class.new)
127
+ @collection = StateMachine::NodeCollection.new(machine, :index => [:name, :value])
128
+
129
+ @object = Node.new(:parked, 1)
130
+ @collection << @object
131
+ end
132
+
133
+ def test_should_use_first_index_by_default_on_key_retrieval
134
+ assert_equal [:parked], @collection.keys
135
+ end
136
+
137
+ def test_should_allow_customizing_index_for_key_retrieval
138
+ assert_equal [1], @collection.keys(:value)
139
+ end
140
+
141
+ def test_should_use_first_index_by_default_on_lookup
142
+ assert_equal @object, @collection[:parked]
143
+ assert_nil @collection[1]
144
+ end
145
+
146
+ def test_should_allow_customizing_index_on_lookup
147
+ assert_equal @object, @collection[1, :value]
148
+ assert_nil @collection[:parked, :value]
149
+ end
150
+
151
+ def test_should_use_first_index_by_default_on_fetch
152
+ assert_equal @object, @collection.fetch(:parked)
153
+ exception = assert_raise(IndexError) { @collection.fetch(1) }
154
+ assert_equal '1 is an invalid name', exception.message
155
+ end
156
+
157
+ def test_should_allow_customizing_index_on_fetch
158
+ assert_equal @object, @collection.fetch(1, :value)
159
+ exception = assert_raise(IndexError) { @collection.fetch(:parked, :value) }
160
+ assert_equal ':parked is an invalid value', exception.message
161
+ end
162
+ end
163
+
164
+ class NodeCollectionWithNodesTest < Test::Unit::TestCase
165
+ def setup
166
+ @machine = StateMachine::Machine.new(Class.new)
167
+ @collection = StateMachine::NodeCollection.new(@machine)
168
+
169
+ @parked = Node.new(:parked, nil, @machine)
170
+ @idling = Node.new(:idling, nil, @machine)
171
+
172
+ @collection << @parked
173
+ @collection << @idling
174
+ end
175
+
176
+ def test_should_be_able_to_enumerate
177
+ order = []
178
+ @collection.each {|object| order << object}
179
+
180
+ assert_equal [@parked, @idling], order
181
+ end
182
+
183
+ def test_should_be_able_to_concatenate_multiple_nodes
184
+ @first_gear = Node.new(:first_gear, nil, @machine)
185
+ @second_gear = Node.new(:second_gear, nil, @machine)
186
+ @collection.concat([@first_gear, @second_gear])
187
+
188
+ order = []
189
+ @collection.each {|object| order << object}
190
+ assert_equal [@parked, @idling, @first_gear, @second_gear], order
191
+ end
192
+
193
+ def test_should_be_able_to_access_by_index
194
+ assert_equal @parked, @collection.at(0)
195
+ assert_equal @idling, @collection.at(1)
196
+ end
197
+
198
+ def test_should_deep_copy_machine_changes
199
+ new_machine = StateMachine::Machine.new(Class.new)
200
+ @collection.machine = new_machine
201
+
202
+ assert_equal new_machine, @collection.machine
203
+ assert_equal new_machine, @parked.machine
204
+ assert_equal new_machine, @idling.machine
205
+ end
206
+ end
207
+
208
+ class NodeCollectionAfterUpdateTest < Test::Unit::TestCase
209
+ def setup
210
+ machine = StateMachine::Machine.new(Class.new)
211
+ @collection = StateMachine::NodeCollection.new(machine, :index => [:name, :value])
212
+
213
+ @parked = Node.new(:parked, 1)
214
+ @idling = Node.new(:idling, 2)
215
+
216
+ @collection << @parked << @idling
217
+
218
+ @parked.name = :parking
219
+ @parked.value = 0
220
+ @collection.update(@parked)
221
+ end
222
+
223
+ def test_should_not_change_the_index
224
+ assert_equal @parked, @collection.at(0)
225
+ end
226
+
227
+ def test_should_not_duplicate_in_the_collection
228
+ assert_equal 2, @collection.length
229
+ end
230
+
231
+ def test_should_add_each_indexed_key
232
+ assert_equal @parked, @collection[:parking]
233
+ assert_equal @parked, @collection[0, :value]
234
+ end
235
+
236
+ def test_should_remove_each_old_indexed_key
237
+ assert_nil @collection[:parked]
238
+ assert_nil @collection[1, :value]
239
+ end
240
+ end
241
+
242
+ class NodeCollectionWithStringIndexTest < Test::Unit::TestCase
243
+ def setup
244
+ machine = StateMachine::Machine.new(Class.new)
245
+ @collection = StateMachine::NodeCollection.new(machine, :index => [:name, :value])
246
+
247
+ @parked = Node.new(:parked, 1)
248
+ @collection << @parked
249
+ end
250
+
251
+ def test_should_index_by_name
252
+ assert_equal @parked, @collection[:parked]
253
+ end
254
+
255
+ def test_should_index_by_string_name
256
+ assert_equal @parked, @collection['parked']
257
+ end
258
+ end
259
+
260
+ class NodeCollectionWithSymbolIndexTest < Test::Unit::TestCase
261
+ def setup
262
+ machine = StateMachine::Machine.new(Class.new)
263
+ @collection = StateMachine::NodeCollection.new(machine, :index => [:name, :value])
264
+
265
+ @parked = Node.new('parked', 1)
266
+ @collection << @parked
267
+ end
268
+
269
+ def test_should_index_by_name
270
+ assert_equal @parked, @collection['parked']
271
+ end
272
+
273
+ def test_should_index_by_symbol_name
274
+ assert_equal @parked, @collection[:parked]
275
+ end
276
+ end
277
+
278
+ class NodeCollectionWithNumericIndexTest < Test::Unit::TestCase
279
+ def setup
280
+ machine = StateMachine::Machine.new(Class.new)
281
+ @collection = StateMachine::NodeCollection.new(machine, :index => [:name, :value])
282
+
283
+ @parked = Node.new(10, 1)
284
+ @collection << @parked
285
+ end
286
+
287
+ def test_should_index_by_name
288
+ assert_equal @parked, @collection[10]
289
+ end
290
+
291
+ def test_should_index_by_string_name
292
+ assert_equal @parked, @collection['10']
293
+ end
294
+
295
+ def test_should_index_by_symbol_name
296
+ assert_equal @parked, @collection[:'10']
297
+ end
298
+ end
299
+
300
+ class NodeCollectionWithPredefinedContextsTest < Test::Unit::TestCase
301
+ def setup
302
+ machine = StateMachine::Machine.new(Class.new)
303
+ @collection = StateMachine::NodeCollection.new(machine)
304
+
305
+ @contexts_run = contexts_run = []
306
+ @collection.context([:parked]) { contexts_run << :parked }
307
+ @collection.context([:parked]) { contexts_run << :second_parked }
308
+ end
309
+
310
+ def test_should_run_contexts_in_the_order_defined
311
+ @collection << Node.new(:parked)
312
+ assert_equal [:parked, :second_parked], @contexts_run
313
+ end
314
+
315
+ def test_should_not_run_contexts_if_not_matched
316
+ @collection << Node.new(:idling)
317
+ assert_equal [], @contexts_run
318
+ end
319
+ end
320
+
321
+ class NodeCollectionWithPostdefinedContextsTest < Test::Unit::TestCase
322
+ def setup
323
+ machine = StateMachine::Machine.new(Class.new)
324
+ @collection = StateMachine::NodeCollection.new(machine)
325
+ @collection << Node.new(:parked)
326
+ end
327
+
328
+ def test_should_run_context_if_matched
329
+ contexts_run = []
330
+ @collection.context([:parked]) { contexts_run << :parked }
331
+ assert_equal [:parked], contexts_run
332
+ end
333
+
334
+ def test_should_not_run_contexts_if_not_matched
335
+ contexts_run = []
336
+ @collection.context([:idling]) { contexts_run << :idling }
337
+ assert_equal [], contexts_run
338
+ end
339
+ end
340
+
341
+ class NodeCollectionWithMatcherContextsTest < Test::Unit::TestCase
342
+ def setup
343
+ machine = StateMachine::Machine.new(Class.new)
344
+ @collection = StateMachine::NodeCollection.new(machine)
345
+ @collection << Node.new(:parked)
346
+ end
347
+
348
+ def test_should_always_run_all_matcher_context
349
+ contexts_run = []
350
+ @collection.context([StateMachine::AllMatcher.instance]) { contexts_run << :all }
351
+ assert_equal [:all], contexts_run
352
+ end
353
+
354
+ def test_should_only_run_blacklist_matcher_if_not_matched
355
+ contexts_run = []
356
+ @collection.context([StateMachine::BlacklistMatcher.new([:parked])]) { contexts_run << :blacklist }
357
+ assert_equal [], contexts_run
358
+
359
+ @collection << Node.new(:idling)
360
+ assert_equal [:blacklist], contexts_run
361
+ end
362
+ end