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,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