spree-state_machine 2.0.0.beta1

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 (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,352 @@
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
+ @machine.states.concat(@states)
32
+
33
+ @object = @klass.new
34
+ end
35
+
36
+ def test_should_index_by_name
37
+ assert_equal @parked, @states[:parked, :name]
38
+ end
39
+
40
+ def test_should_index_by_name_by_default
41
+ assert_equal @parked, @states[:parked]
42
+ end
43
+
44
+ def test_should_index_by_string_name
45
+ assert_equal @parked, @states['parked']
46
+ end
47
+
48
+ def test_should_index_by_qualified_name
49
+ assert_equal @parked, @states[:parked, :qualified_name]
50
+ end
51
+
52
+ def test_should_index_by_string_qualified_name
53
+ assert_equal @parked, @states['parked', :qualified_name]
54
+ end
55
+
56
+ def test_should_index_by_value
57
+ assert_equal @parked, @states['parked', :value]
58
+ end
59
+
60
+ def test_should_not_match_if_value_does_not_match
61
+ assert !@states.matches?(@object, :parked)
62
+ assert !@states.matches?(@object, :idling)
63
+ end
64
+
65
+ def test_should_match_if_value_matches
66
+ assert @states.matches?(@object, nil)
67
+ end
68
+
69
+ def test_raise_exception_if_matching_invalid_state
70
+ assert_raise(IndexError) { @states.matches?(@object, :invalid) }
71
+ end
72
+
73
+ def test_should_find_state_for_object_if_value_is_known
74
+ @object.state = 'parked'
75
+ assert_equal @parked, @states.match(@object)
76
+ end
77
+
78
+ def test_should_find_bang_state_for_object_if_value_is_known
79
+ @object.state = 'parked'
80
+ assert_equal @parked, @states.match!(@object)
81
+ end
82
+
83
+ def test_should_not_find_state_for_object_with_unknown_value
84
+ @object.state = 'invalid'
85
+ assert_nil @states.match(@object)
86
+ end
87
+
88
+ def test_should_raise_exception_if_finding_bang_state_for_object_with_unknown_value
89
+ @object.state = 'invalid'
90
+ exception = assert_raise(ArgumentError) { @states.match!(@object) }
91
+ assert_equal '"invalid" is not a known state value', exception.message
92
+ end
93
+ end
94
+
95
+ class StateCollectionStringTest < Test::Unit::TestCase
96
+ def setup
97
+ @klass = Class.new
98
+ @machine = StateMachine::Machine.new(@klass)
99
+ @states = StateMachine::StateCollection.new(@machine)
100
+
101
+ @states << @nil = StateMachine::State.new(@machine, nil)
102
+ @states << @parked = StateMachine::State.new(@machine, 'parked')
103
+ @machine.states.concat(@states)
104
+
105
+ @object = @klass.new
106
+ end
107
+
108
+ def test_should_index_by_name
109
+ assert_equal @parked, @states['parked', :name]
110
+ end
111
+
112
+ def test_should_index_by_name_by_default
113
+ assert_equal @parked, @states['parked']
114
+ end
115
+
116
+ def test_should_index_by_symbol_name
117
+ assert_equal @parked, @states[:parked]
118
+ end
119
+
120
+ def test_should_index_by_qualified_name
121
+ assert_equal @parked, @states['parked', :qualified_name]
122
+ end
123
+
124
+ def test_should_index_by_symbol_qualified_name
125
+ assert_equal @parked, @states[:parked, :qualified_name]
126
+ end
127
+ end
128
+
129
+ class StateCollectionWithNamespaceTest < Test::Unit::TestCase
130
+ def setup
131
+ @klass = Class.new
132
+ @machine = StateMachine::Machine.new(@klass, :namespace => 'vehicle')
133
+ @states = StateMachine::StateCollection.new(@machine)
134
+
135
+ @states << @state = StateMachine::State.new(@machine, :parked)
136
+ @machine.states.concat(@states)
137
+ end
138
+
139
+ def test_should_index_by_name
140
+ assert_equal @state, @states[:parked, :name]
141
+ end
142
+
143
+ def test_should_index_by_qualified_name
144
+ assert_equal @state, @states[:vehicle_parked, :qualified_name]
145
+ end
146
+ end
147
+
148
+ class StateCollectionWithCustomStateValuesTest < Test::Unit::TestCase
149
+ def setup
150
+ @klass = Class.new
151
+ @machine = StateMachine::Machine.new(@klass)
152
+ @states = StateMachine::StateCollection.new(@machine)
153
+
154
+ @states << @state = StateMachine::State.new(@machine, :parked, :value => 1)
155
+ @machine.states.concat(@states)
156
+
157
+ @object = @klass.new
158
+ @object.state = 1
159
+ end
160
+
161
+ def test_should_match_if_value_matches
162
+ assert @states.matches?(@object, :parked)
163
+ end
164
+
165
+ def test_should_not_match_if_value_does_not_match
166
+ @object.state = 2
167
+ assert !@states.matches?(@object, :parked)
168
+ end
169
+
170
+ def test_should_find_state_for_object_if_value_is_known
171
+ assert_equal @state, @states.match(@object)
172
+ end
173
+ end
174
+
175
+ class StateCollectionWithStateMatchersTest < Test::Unit::TestCase
176
+ def setup
177
+ @klass = Class.new
178
+ @machine = StateMachine::Machine.new(@klass)
179
+ @states = StateMachine::StateCollection.new(@machine)
180
+
181
+ @states << @state = StateMachine::State.new(@machine, :parked, :if => lambda {|value| !value.nil?})
182
+ @machine.states.concat(@states)
183
+
184
+ @object = @klass.new
185
+ @object.state = 1
186
+ end
187
+
188
+ def test_should_match_if_value_matches
189
+ assert @states.matches?(@object, :parked)
190
+ end
191
+
192
+ def test_should_not_match_if_value_does_not_match
193
+ @object.state = nil
194
+ assert !@states.matches?(@object, :parked)
195
+ end
196
+
197
+ def test_should_find_state_for_object_if_value_is_known
198
+ assert_equal @state, @states.match(@object)
199
+ end
200
+ end
201
+
202
+ class StateCollectionWithInitialStateTest < Test::Unit::TestCase
203
+ def setup
204
+ @machine = StateMachine::Machine.new(Class.new)
205
+ @states = StateMachine::StateCollection.new(@machine)
206
+
207
+ @states << @parked = StateMachine::State.new(@machine, :parked)
208
+ @states << @idling = StateMachine::State.new(@machine, :idling)
209
+ @machine.states.concat(@states)
210
+
211
+ @parked.initial = true
212
+ end
213
+
214
+ def test_should_order_state_before_transition_states
215
+ @machine.event :ignite do
216
+ transition :to => :idling
217
+ end
218
+ assert_equal [@parked, @idling], @states.by_priority
219
+ end
220
+
221
+ def test_should_order_state_before_states_with_behaviors
222
+ @idling.context do
223
+ def speed
224
+ 0
225
+ end
226
+ end
227
+ assert_equal [@parked, @idling], @states.by_priority
228
+ end
229
+
230
+ def test_should_order_state_before_other_states
231
+ assert_equal [@parked, @idling], @states.by_priority
232
+ end
233
+
234
+ def test_should_order_state_before_callback_states
235
+ @machine.before_transition :from => :idling, :do => lambda {}
236
+ assert_equal [@parked, @idling], @states.by_priority
237
+ end
238
+ end
239
+
240
+ class StateCollectionWithStateBehaviorsTest < Test::Unit::TestCase
241
+ def setup
242
+ @machine = StateMachine::Machine.new(Class.new)
243
+ @states = StateMachine::StateCollection.new(@machine)
244
+
245
+ @states << @parked = StateMachine::State.new(@machine, :parked)
246
+ @states << @idling = StateMachine::State.new(@machine, :idling)
247
+ @machine.states.concat(@states)
248
+
249
+ @idling.context do
250
+ def speed
251
+ 0
252
+ end
253
+ end
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_before_other_states
269
+ assert_equal [@idling, @parked], @states.by_priority
270
+ end
271
+
272
+ def test_should_order_state_before_callback_states
273
+ @machine.before_transition :from => :parked, :do => lambda {}
274
+ assert_equal [@idling, @parked], @states.by_priority
275
+ end
276
+ end
277
+
278
+ class StateCollectionWithEventTransitionsTest < Test::Unit::TestCase
279
+ def setup
280
+ @machine = StateMachine::Machine.new(Class.new)
281
+ @states = StateMachine::StateCollection.new(@machine)
282
+
283
+ @states << @parked = StateMachine::State.new(@machine, :parked)
284
+ @states << @idling = StateMachine::State.new(@machine, :idling)
285
+ @machine.states.concat(@states)
286
+
287
+ @machine.event :ignite do
288
+ transition :to => :idling
289
+ end
290
+ end
291
+
292
+ def test_should_order_states_after_initial_state
293
+ @parked.initial = true
294
+ assert_equal [@parked, @idling], @states.by_priority
295
+ end
296
+
297
+ def test_should_order_states_before_states_with_behaviors
298
+ @parked.context do
299
+ def speed
300
+ 0
301
+ end
302
+ end
303
+ assert_equal [@idling, @parked], @states.by_priority
304
+ end
305
+
306
+ def test_should_order_states_before_other_states
307
+ assert_equal [@idling, @parked], @states.by_priority
308
+ end
309
+
310
+ def test_should_order_state_before_callback_states
311
+ @machine.before_transition :from => :parked, :do => lambda {}
312
+ assert_equal [@idling, @parked], @states.by_priority
313
+ end
314
+ end
315
+
316
+ class StateCollectionWithTransitionCallbacksTest < Test::Unit::TestCase
317
+ def setup
318
+ @machine = StateMachine::Machine.new(Class.new)
319
+ @states = StateMachine::StateCollection.new(@machine)
320
+
321
+ @states << @parked = StateMachine::State.new(@machine, :parked)
322
+ @states << @idling = StateMachine::State.new(@machine, :idling)
323
+ @machine.states.concat(@states)
324
+
325
+ @machine.before_transition :to => :idling, :do => lambda {}
326
+ end
327
+
328
+ def test_should_order_states_after_initial_state
329
+ @parked.initial = true
330
+ assert_equal [@parked, @idling], @states.by_priority
331
+ end
332
+
333
+ def test_should_order_states_after_transition_states
334
+ @machine.event :ignite do
335
+ transition :from => :parked
336
+ end
337
+ assert_equal [@parked, @idling], @states.by_priority
338
+ end
339
+
340
+ def test_should_order_states_after_states_with_behaviors
341
+ @parked.context do
342
+ def speed
343
+ 0
344
+ end
345
+ end
346
+ assert_equal [@parked, @idling], @states.by_priority
347
+ end
348
+
349
+ def test_should_order_states_after_other_states
350
+ assert_equal [@parked, @idling], @states.by_priority
351
+ end
352
+ end