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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +12 -0
- data/.yardopts +5 -0
- data/CHANGELOG.md +502 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +1246 -0
- data/Rakefile +20 -0
- data/examples/AutoShop_state.png +0 -0
- data/examples/Car_state.png +0 -0
- data/examples/Gemfile +5 -0
- data/examples/Gemfile.lock +14 -0
- data/examples/TrafficLight_state.png +0 -0
- data/examples/Vehicle_state.png +0 -0
- data/examples/auto_shop.rb +13 -0
- data/examples/car.rb +21 -0
- data/examples/doc/AutoShop.html +2856 -0
- data/examples/doc/AutoShop_state.png +0 -0
- data/examples/doc/Car.html +919 -0
- data/examples/doc/Car_state.png +0 -0
- data/examples/doc/TrafficLight.html +2230 -0
- data/examples/doc/TrafficLight_state.png +0 -0
- data/examples/doc/Vehicle.html +7921 -0
- data/examples/doc/Vehicle_state.png +0 -0
- data/examples/doc/_index.html +136 -0
- data/examples/doc/class_list.html +47 -0
- data/examples/doc/css/common.css +1 -0
- data/examples/doc/css/full_list.css +55 -0
- data/examples/doc/css/style.css +322 -0
- data/examples/doc/file_list.html +46 -0
- data/examples/doc/frames.html +13 -0
- data/examples/doc/index.html +136 -0
- data/examples/doc/js/app.js +205 -0
- data/examples/doc/js/full_list.js +173 -0
- data/examples/doc/js/jquery.js +16 -0
- data/examples/doc/method_list.html +734 -0
- data/examples/doc/top-level-namespace.html +105 -0
- data/examples/merb-rest/controller.rb +51 -0
- data/examples/merb-rest/model.rb +28 -0
- data/examples/merb-rest/view_edit.html.erb +24 -0
- data/examples/merb-rest/view_index.html.erb +23 -0
- data/examples/merb-rest/view_new.html.erb +13 -0
- data/examples/merb-rest/view_show.html.erb +17 -0
- data/examples/rails-rest/controller.rb +43 -0
- data/examples/rails-rest/migration.rb +7 -0
- data/examples/rails-rest/model.rb +23 -0
- data/examples/rails-rest/view__form.html.erb +34 -0
- data/examples/rails-rest/view_edit.html.erb +6 -0
- data/examples/rails-rest/view_index.html.erb +25 -0
- data/examples/rails-rest/view_new.html.erb +5 -0
- data/examples/rails-rest/view_show.html.erb +19 -0
- data/examples/traffic_light.rb +9 -0
- data/examples/vehicle.rb +33 -0
- data/lib/state_machine/assertions.rb +36 -0
- data/lib/state_machine/branch.rb +225 -0
- data/lib/state_machine/callback.rb +236 -0
- data/lib/state_machine/core.rb +7 -0
- data/lib/state_machine/core_ext/class/state_machine.rb +5 -0
- data/lib/state_machine/core_ext.rb +2 -0
- data/lib/state_machine/error.rb +13 -0
- data/lib/state_machine/eval_helpers.rb +87 -0
- data/lib/state_machine/event.rb +257 -0
- data/lib/state_machine/event_collection.rb +141 -0
- data/lib/state_machine/extensions.rb +149 -0
- data/lib/state_machine/graph.rb +92 -0
- data/lib/state_machine/helper_module.rb +17 -0
- data/lib/state_machine/initializers/rails.rb +25 -0
- data/lib/state_machine/initializers.rb +4 -0
- data/lib/state_machine/integrations/active_model/locale.rb +11 -0
- data/lib/state_machine/integrations/active_model/observer.rb +33 -0
- data/lib/state_machine/integrations/active_model/observer_update.rb +42 -0
- data/lib/state_machine/integrations/active_model/versions.rb +31 -0
- data/lib/state_machine/integrations/active_model.rb +585 -0
- data/lib/state_machine/integrations/active_record/locale.rb +20 -0
- data/lib/state_machine/integrations/active_record/versions.rb +123 -0
- data/lib/state_machine/integrations/active_record.rb +525 -0
- data/lib/state_machine/integrations/base.rb +100 -0
- data/lib/state_machine/integrations.rb +121 -0
- data/lib/state_machine/machine.rb +2287 -0
- data/lib/state_machine/machine_collection.rb +74 -0
- data/lib/state_machine/macro_methods.rb +522 -0
- data/lib/state_machine/matcher.rb +123 -0
- data/lib/state_machine/matcher_helpers.rb +54 -0
- data/lib/state_machine/node_collection.rb +222 -0
- data/lib/state_machine/path.rb +120 -0
- data/lib/state_machine/path_collection.rb +90 -0
- data/lib/state_machine/state.rb +297 -0
- data/lib/state_machine/state_collection.rb +112 -0
- data/lib/state_machine/state_context.rb +138 -0
- data/lib/state_machine/transition.rb +470 -0
- data/lib/state_machine/transition_collection.rb +245 -0
- data/lib/state_machine/version.rb +3 -0
- data/lib/state_machine/yard/handlers/base.rb +32 -0
- data/lib/state_machine/yard/handlers/event.rb +25 -0
- data/lib/state_machine/yard/handlers/machine.rb +344 -0
- data/lib/state_machine/yard/handlers/state.rb +25 -0
- data/lib/state_machine/yard/handlers/transition.rb +47 -0
- data/lib/state_machine/yard/handlers.rb +12 -0
- data/lib/state_machine/yard/templates/default/class/html/setup.rb +30 -0
- data/lib/state_machine/yard/templates/default/class/html/state_machines.erb +12 -0
- data/lib/state_machine/yard/templates.rb +3 -0
- data/lib/state_machine/yard.rb +8 -0
- data/lib/state_machine.rb +8 -0
- data/lib/yard-state_machine.rb +2 -0
- data/state_machine.gemspec +22 -0
- data/test/files/en.yml +17 -0
- data/test/files/switch.rb +15 -0
- data/test/functional/state_machine_test.rb +1066 -0
- data/test/test_helper.rb +7 -0
- data/test/unit/assertions_test.rb +40 -0
- data/test/unit/branch_test.rb +969 -0
- data/test/unit/callback_test.rb +704 -0
- data/test/unit/error_test.rb +43 -0
- data/test/unit/eval_helpers_test.rb +270 -0
- data/test/unit/event_collection_test.rb +398 -0
- data/test/unit/event_test.rb +1196 -0
- data/test/unit/graph_test.rb +98 -0
- data/test/unit/helper_module_test.rb +17 -0
- data/test/unit/integrations/active_model_test.rb +1245 -0
- data/test/unit/integrations/active_record_test.rb +2551 -0
- data/test/unit/integrations/base_test.rb +104 -0
- data/test/unit/integrations_test.rb +71 -0
- data/test/unit/invalid_event_test.rb +20 -0
- data/test/unit/invalid_parallel_transition_test.rb +18 -0
- data/test/unit/invalid_transition_test.rb +115 -0
- data/test/unit/machine_collection_test.rb +603 -0
- data/test/unit/machine_test.rb +3395 -0
- data/test/unit/matcher_helpers_test.rb +37 -0
- data/test/unit/matcher_test.rb +155 -0
- data/test/unit/node_collection_test.rb +362 -0
- data/test/unit/path_collection_test.rb +266 -0
- data/test/unit/path_test.rb +485 -0
- data/test/unit/state_collection_test.rb +352 -0
- data/test/unit/state_context_test.rb +441 -0
- data/test/unit/state_machine_test.rb +31 -0
- data/test/unit/state_test.rb +1101 -0
- data/test/unit/transition_collection_test.rb +2168 -0
- data/test/unit/transition_test.rb +1558 -0
- metadata +264 -0
@@ -0,0 +1,1558 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class TransitionTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@klass = Class.new
|
6
|
+
@machine = StateMachine::Machine.new(@klass)
|
7
|
+
@machine.state :parked, :idling
|
8
|
+
@machine.event :ignite
|
9
|
+
|
10
|
+
@object = @klass.new
|
11
|
+
@object.state = 'parked'
|
12
|
+
|
13
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_should_have_an_object
|
17
|
+
assert_equal @object, @transition.object
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_should_have_a_machine
|
21
|
+
assert_equal @machine, @transition.machine
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_should_have_an_event
|
25
|
+
assert_equal :ignite, @transition.event
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_should_have_a_qualified_event
|
29
|
+
assert_equal :ignite, @transition.qualified_event
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_should_have_a_human_event
|
33
|
+
assert_equal 'ignite', @transition.human_event
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_have_a_from_value
|
37
|
+
assert_equal 'parked', @transition.from
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_should_have_a_from_name
|
41
|
+
assert_equal :parked, @transition.from_name
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_should_have_a_qualified_from_name
|
45
|
+
assert_equal :parked, @transition.qualified_from_name
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_should_have_a_human_from_name
|
49
|
+
assert_equal 'parked', @transition.human_from_name
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_should_have_a_to_value
|
53
|
+
assert_equal 'idling', @transition.to
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_should_have_a_to_name
|
57
|
+
assert_equal :idling, @transition.to_name
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_should_have_a_qualified_to_name
|
61
|
+
assert_equal :idling, @transition.qualified_to_name
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_should_have_a_human_to_name
|
65
|
+
assert_equal 'idling', @transition.human_to_name
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_should_have_an_attribute
|
69
|
+
assert_equal :state, @transition.attribute
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_should_not_have_an_action
|
73
|
+
assert_nil @transition.action
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_should_not_be_transient
|
77
|
+
assert_equal false, @transition.transient?
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_should_generate_attributes
|
81
|
+
expected = {:object => @object, :attribute => :state, :event => :ignite, :from => 'parked', :to => 'idling'}
|
82
|
+
assert_equal expected, @transition.attributes
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_should_have_empty_args
|
86
|
+
assert_equal [], @transition.args
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_should_not_have_a_result
|
90
|
+
assert_nil @transition.result
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_should_use_pretty_inspect
|
94
|
+
assert_equal '#<StateMachine::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>', @transition.inspect
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class TransitionWithInvalidNodesTest < Test::Unit::TestCase
|
99
|
+
def setup
|
100
|
+
@klass = Class.new
|
101
|
+
@machine = StateMachine::Machine.new(@klass)
|
102
|
+
@machine.state :parked, :idling
|
103
|
+
@machine.event :ignite
|
104
|
+
|
105
|
+
@object = @klass.new
|
106
|
+
@object.state = 'parked'
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_should_raise_exception_without_event
|
110
|
+
assert_raise(IndexError) { StateMachine::Transition.new(@object, @machine, nil, :parked, :idling) }
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_should_raise_exception_with_invalid_event
|
114
|
+
assert_raise(IndexError) { StateMachine::Transition.new(@object, @machine, :invalid, :parked, :idling) }
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_should_raise_exception_with_invalid_from_state
|
118
|
+
assert_raise(IndexError) { StateMachine::Transition.new(@object, @machine, :ignite, :invalid, :idling) }
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_should_raise_exception_with_invalid_to_state
|
122
|
+
assert_raise(IndexError) { StateMachine::Transition.new(@object, @machine, :ignite, :parked, :invalid) }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class TransitionWithDynamicToValueTest < Test::Unit::TestCase
|
127
|
+
def setup
|
128
|
+
@klass = Class.new
|
129
|
+
@machine = StateMachine::Machine.new(@klass)
|
130
|
+
@machine.state :parked
|
131
|
+
@machine.state :idling, :value => lambda {1}
|
132
|
+
@machine.event :ignite
|
133
|
+
|
134
|
+
@object = @klass.new
|
135
|
+
@object.state = 'parked'
|
136
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_should_evaluate_to_value
|
140
|
+
assert_equal 1, @transition.to
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class TransitionLoopbackTest < Test::Unit::TestCase
|
145
|
+
def setup
|
146
|
+
@klass = Class.new
|
147
|
+
@machine = StateMachine::Machine.new(@klass)
|
148
|
+
@machine.state :parked
|
149
|
+
@machine.event :park
|
150
|
+
|
151
|
+
@object = @klass.new
|
152
|
+
@object.state = 'parked'
|
153
|
+
@transition = StateMachine::Transition.new(@object, @machine, :park, :parked, :parked)
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_should_be_loopback
|
157
|
+
assert @transition.loopback?
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class TransitionWithDifferentStatesTest < Test::Unit::TestCase
|
162
|
+
def setup
|
163
|
+
@klass = Class.new
|
164
|
+
@machine = StateMachine::Machine.new(@klass)
|
165
|
+
@machine.state :parked, :idling
|
166
|
+
@machine.event :ignite
|
167
|
+
|
168
|
+
@object = @klass.new
|
169
|
+
@object.state = 'parked'
|
170
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_should_not_be_loopback
|
174
|
+
assert !@transition.loopback?
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
class TransitionWithNamespaceTest < Test::Unit::TestCase
|
179
|
+
def setup
|
180
|
+
@klass = Class.new
|
181
|
+
@machine = StateMachine::Machine.new(@klass, :namespace => 'alarm')
|
182
|
+
@machine.state :off, :active
|
183
|
+
@machine.event :activate
|
184
|
+
|
185
|
+
@object = @klass.new
|
186
|
+
@object.state = 'off'
|
187
|
+
|
188
|
+
@transition = StateMachine::Transition.new(@object, @machine, :activate, :off, :active)
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_should_have_an_event
|
192
|
+
assert_equal :activate, @transition.event
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_should_have_a_qualified_event
|
196
|
+
assert_equal :activate_alarm, @transition.qualified_event
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_should_have_a_from_name
|
200
|
+
assert_equal :off, @transition.from_name
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_should_have_a_qualified_from_name
|
204
|
+
assert_equal :alarm_off, @transition.qualified_from_name
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_should_have_a_human_from_name
|
208
|
+
assert_equal 'off', @transition.human_from_name
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_should_have_a_to_name
|
212
|
+
assert_equal :active, @transition.to_name
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_should_have_a_qualified_to_name
|
216
|
+
assert_equal :alarm_active, @transition.qualified_to_name
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_should_have_a_human_to_name
|
220
|
+
assert_equal 'active', @transition.human_to_name
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
class TransitionWithCustomMachineAttributeTest < Test::Unit::TestCase
|
225
|
+
def setup
|
226
|
+
@klass = Class.new
|
227
|
+
@machine = StateMachine::Machine.new(@klass, :state, :attribute => :state_id)
|
228
|
+
@machine.state :off, :value => 1
|
229
|
+
@machine.state :active, :value => 2
|
230
|
+
@machine.event :activate
|
231
|
+
|
232
|
+
@object = @klass.new
|
233
|
+
@object.state_id = 1
|
234
|
+
|
235
|
+
@transition = StateMachine::Transition.new(@object, @machine, :activate, :off, :active)
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_should_persist
|
239
|
+
@transition.persist
|
240
|
+
assert_equal 2, @object.state_id
|
241
|
+
end
|
242
|
+
|
243
|
+
def test_should_rollback
|
244
|
+
@object.state_id = 2
|
245
|
+
@transition.rollback
|
246
|
+
|
247
|
+
assert_equal 1, @object.state_id
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
class TransitionWithoutReadingStateTest < Test::Unit::TestCase
|
252
|
+
def setup
|
253
|
+
@klass = Class.new
|
254
|
+
@machine = StateMachine::Machine.new(@klass)
|
255
|
+
@machine.state :parked, :idling
|
256
|
+
@machine.event :ignite
|
257
|
+
|
258
|
+
@object = @klass.new
|
259
|
+
@object.state = 'idling'
|
260
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling, false)
|
261
|
+
end
|
262
|
+
|
263
|
+
def test_should_not_read_from_value_from_object
|
264
|
+
assert_equal 'parked', @transition.from
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_should_have_to_value
|
268
|
+
assert_equal 'idling', @transition.to
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
class TransitionWithActionTest < Test::Unit::TestCase
|
273
|
+
def setup
|
274
|
+
@klass = Class.new do
|
275
|
+
def save
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
@machine = StateMachine::Machine.new(@klass, :action => :save)
|
280
|
+
@machine.state :parked, :idling
|
281
|
+
@machine.event :ignite
|
282
|
+
|
283
|
+
@object = @klass.new
|
284
|
+
@object.state = 'parked'
|
285
|
+
|
286
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
287
|
+
end
|
288
|
+
|
289
|
+
def test_should_have_an_action
|
290
|
+
assert_equal :save, @transition.action
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_should_not_have_a_result
|
294
|
+
assert_nil @transition.result
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
class TransitionAfterBeingPersistedTest < Test::Unit::TestCase
|
299
|
+
def setup
|
300
|
+
@klass = Class.new
|
301
|
+
@machine = StateMachine::Machine.new(@klass, :action => :save)
|
302
|
+
@machine.state :parked, :idling
|
303
|
+
@machine.event :ignite
|
304
|
+
|
305
|
+
@object = @klass.new
|
306
|
+
@object.state = 'parked'
|
307
|
+
|
308
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
309
|
+
@transition.persist
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_should_update_state_value
|
313
|
+
assert_equal 'idling', @object.state
|
314
|
+
end
|
315
|
+
|
316
|
+
def test_should_not_change_from_state
|
317
|
+
assert_equal 'parked', @transition.from
|
318
|
+
end
|
319
|
+
|
320
|
+
def test_should_not_change_to_state
|
321
|
+
assert_equal 'idling', @transition.to
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_should_not_be_able_to_persist_twice
|
325
|
+
@object.state = 'parked'
|
326
|
+
@transition.persist
|
327
|
+
assert_equal 'parked', @object.state
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_should_be_able_to_persist_again_after_resetting
|
331
|
+
@object.state = 'parked'
|
332
|
+
@transition.reset
|
333
|
+
@transition.persist
|
334
|
+
assert_equal 'idling', @object.state
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_should_revert_to_from_state_on_rollback
|
338
|
+
@transition.rollback
|
339
|
+
assert_equal 'parked', @object.state
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
class TransitionAfterBeingRolledBackTest < Test::Unit::TestCase
|
344
|
+
def setup
|
345
|
+
@klass = Class.new
|
346
|
+
@machine = StateMachine::Machine.new(@klass, :action => :save)
|
347
|
+
@machine.state :parked, :idling
|
348
|
+
@machine.event :ignite
|
349
|
+
|
350
|
+
@object = @klass.new
|
351
|
+
@object.state = 'parked'
|
352
|
+
|
353
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
354
|
+
@object.state = 'idling'
|
355
|
+
|
356
|
+
@transition.rollback
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_should_update_state_value_to_from_state
|
360
|
+
assert_equal 'parked', @object.state
|
361
|
+
end
|
362
|
+
|
363
|
+
def test_should_not_change_from_state
|
364
|
+
assert_equal 'parked', @transition.from
|
365
|
+
end
|
366
|
+
|
367
|
+
def test_should_not_change_to_state
|
368
|
+
assert_equal 'idling', @transition.to
|
369
|
+
end
|
370
|
+
|
371
|
+
def test_should_still_be_able_to_persist
|
372
|
+
@transition.persist
|
373
|
+
assert_equal 'idling', @object.state
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
class TransitionWithoutCallbacksTest < Test::Unit::TestCase
|
378
|
+
def setup
|
379
|
+
@klass = Class.new
|
380
|
+
|
381
|
+
@machine = StateMachine::Machine.new(@klass)
|
382
|
+
@machine.state :parked, :idling
|
383
|
+
@machine.event :ignite
|
384
|
+
|
385
|
+
@object = @klass.new
|
386
|
+
@object.state = 'parked'
|
387
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
388
|
+
end
|
389
|
+
|
390
|
+
def test_should_succeed
|
391
|
+
assert_equal true, @transition.run_callbacks
|
392
|
+
end
|
393
|
+
|
394
|
+
def test_should_succeed_if_after_callbacks_skipped
|
395
|
+
assert_equal true, @transition.run_callbacks(:after => false)
|
396
|
+
end
|
397
|
+
|
398
|
+
def test_should_call_block_if_provided
|
399
|
+
@transition.run_callbacks { @ran_block = true; {} }
|
400
|
+
assert @ran_block
|
401
|
+
end
|
402
|
+
|
403
|
+
def test_should_track_block_result
|
404
|
+
@transition.run_callbacks {{:result => 1}}
|
405
|
+
assert_equal 1, @transition.result
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
class TransitionWithBeforeCallbacksTest < Test::Unit::TestCase
|
410
|
+
def setup
|
411
|
+
@klass = Class.new
|
412
|
+
|
413
|
+
@machine = StateMachine::Machine.new(@klass)
|
414
|
+
@machine.state :parked, :idling
|
415
|
+
@machine.event :ignite
|
416
|
+
|
417
|
+
@object = @klass.new
|
418
|
+
@object.state = 'parked'
|
419
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
420
|
+
end
|
421
|
+
|
422
|
+
def test_should_run_before_callbacks
|
423
|
+
@machine.before_transition {@run = true}
|
424
|
+
result = @transition.run_callbacks
|
425
|
+
|
426
|
+
assert_equal true, result
|
427
|
+
assert_equal true, @run
|
428
|
+
end
|
429
|
+
|
430
|
+
def test_should_only_run_those_that_match_transition_context
|
431
|
+
@count = 0
|
432
|
+
callback = lambda {@count += 1}
|
433
|
+
|
434
|
+
@machine.before_transition :from => :parked, :to => :idling, :on => :park, :do => callback
|
435
|
+
@machine.before_transition :from => :parked, :to => :parked, :on => :park, :do => callback
|
436
|
+
@machine.before_transition :from => :parked, :to => :idling, :on => :ignite, :do => callback
|
437
|
+
@machine.before_transition :from => :idling, :to => :idling, :on => :park, :do => callback
|
438
|
+
@transition.run_callbacks
|
439
|
+
|
440
|
+
assert_equal 1, @count
|
441
|
+
end
|
442
|
+
|
443
|
+
def test_should_pass_transition_as_argument
|
444
|
+
@machine.before_transition {|*args| @args = args}
|
445
|
+
@transition.run_callbacks
|
446
|
+
|
447
|
+
assert_equal [@object, @transition], @args
|
448
|
+
end
|
449
|
+
|
450
|
+
def test_should_catch_halts
|
451
|
+
@machine.before_transition {throw :halt}
|
452
|
+
|
453
|
+
result = nil
|
454
|
+
assert_nothing_thrown { result = @transition.run_callbacks }
|
455
|
+
assert_equal false, result
|
456
|
+
end
|
457
|
+
|
458
|
+
def test_should_not_catch_exceptions
|
459
|
+
@machine.before_transition {raise ArgumentError}
|
460
|
+
assert_raise(ArgumentError) { @transition.run_callbacks }
|
461
|
+
end
|
462
|
+
|
463
|
+
def test_should_not_be_able_to_run_twice
|
464
|
+
@count = 0
|
465
|
+
@machine.before_transition {@count += 1}
|
466
|
+
@transition.run_callbacks
|
467
|
+
@transition.run_callbacks
|
468
|
+
assert_equal 1, @count
|
469
|
+
end
|
470
|
+
|
471
|
+
def test_should_be_able_to_run_again_after_halt
|
472
|
+
@count = 0
|
473
|
+
@machine.before_transition {@count += 1; throw :halt}
|
474
|
+
@transition.run_callbacks
|
475
|
+
@transition.run_callbacks
|
476
|
+
assert_equal 2, @count
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_should_be_able_to_run_again_after_resetting
|
480
|
+
@count = 0
|
481
|
+
@machine.before_transition {@count += 1}
|
482
|
+
@transition.run_callbacks
|
483
|
+
@transition.reset
|
484
|
+
@transition.run_callbacks
|
485
|
+
assert_equal 2, @count
|
486
|
+
end
|
487
|
+
|
488
|
+
def test_should_succeed_if_block_result_is_false
|
489
|
+
@machine.before_transition {@run = true}
|
490
|
+
assert_equal true, @transition.run_callbacks {{:result => false}}
|
491
|
+
assert @run
|
492
|
+
end
|
493
|
+
|
494
|
+
def test_should_succeed_if_block_result_is_true
|
495
|
+
@machine.before_transition {@run = true}
|
496
|
+
assert_equal true, @transition.run_callbacks {{:result => true}}
|
497
|
+
assert @run
|
498
|
+
end
|
499
|
+
|
500
|
+
def test_should_succeed_if_block_success_is_false
|
501
|
+
@machine.before_transition {@run = true}
|
502
|
+
assert_equal true, @transition.run_callbacks {{:success => false}}
|
503
|
+
assert @run
|
504
|
+
end
|
505
|
+
|
506
|
+
def test_should_succeed_if_block_success_is_true
|
507
|
+
@machine.before_transition {@run = true}
|
508
|
+
assert_equal true, @transition.run_callbacks {{:success => true}}
|
509
|
+
assert @run
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
class TransitionWithMultipleBeforeCallbacksTest < Test::Unit::TestCase
|
514
|
+
def setup
|
515
|
+
@klass = Class.new
|
516
|
+
|
517
|
+
@machine = StateMachine::Machine.new(@klass)
|
518
|
+
@machine.state :parked, :idling
|
519
|
+
@machine.event :ignite
|
520
|
+
|
521
|
+
@object = @klass.new
|
522
|
+
@object.state = 'parked'
|
523
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
524
|
+
end
|
525
|
+
|
526
|
+
def test_should_run_in_the_order_they_were_defined
|
527
|
+
@callbacks = []
|
528
|
+
@machine.before_transition {@callbacks << 1}
|
529
|
+
@machine.before_transition {@callbacks << 2}
|
530
|
+
@transition.run_callbacks
|
531
|
+
|
532
|
+
assert_equal [1, 2], @callbacks
|
533
|
+
end
|
534
|
+
|
535
|
+
def test_should_not_run_further_callbacks_if_halted
|
536
|
+
@callbacks = []
|
537
|
+
@machine.before_transition {@callbacks << 1; throw :halt}
|
538
|
+
@machine.before_transition {@callbacks << 2}
|
539
|
+
|
540
|
+
assert_equal false, @transition.run_callbacks
|
541
|
+
assert_equal [1], @callbacks
|
542
|
+
end
|
543
|
+
|
544
|
+
def test_should_fail_if_any_callback_halted
|
545
|
+
@machine.before_transition {true}
|
546
|
+
@machine.before_transition {throw :halt}
|
547
|
+
|
548
|
+
assert_equal false, @transition.run_callbacks
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
class TransitionWithAfterCallbacksTest < Test::Unit::TestCase
|
553
|
+
def setup
|
554
|
+
@klass = Class.new
|
555
|
+
|
556
|
+
@machine = StateMachine::Machine.new(@klass)
|
557
|
+
@machine.state :parked, :idling
|
558
|
+
@machine.event :ignite
|
559
|
+
|
560
|
+
@object = @klass.new
|
561
|
+
@object.state = 'parked'
|
562
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
563
|
+
end
|
564
|
+
|
565
|
+
def test_should_run_after_callbacks
|
566
|
+
@machine.after_transition {|object| @run = true}
|
567
|
+
result = @transition.run_callbacks
|
568
|
+
|
569
|
+
assert_equal true, result
|
570
|
+
assert_equal true, @run
|
571
|
+
end
|
572
|
+
|
573
|
+
def test_should_only_run_those_that_match_transition_context
|
574
|
+
@count = 0
|
575
|
+
callback = lambda {@count += 1}
|
576
|
+
|
577
|
+
@machine.after_transition :from => :parked, :to => :idling, :on => :park, :do => callback
|
578
|
+
@machine.after_transition :from => :parked, :to => :parked, :on => :park, :do => callback
|
579
|
+
@machine.after_transition :from => :parked, :to => :idling, :on => :ignite, :do => callback
|
580
|
+
@machine.after_transition :from => :idling, :to => :idling, :on => :park, :do => callback
|
581
|
+
@transition.run_callbacks
|
582
|
+
|
583
|
+
assert_equal 1, @count
|
584
|
+
end
|
585
|
+
|
586
|
+
def test_should_not_run_if_not_successful
|
587
|
+
@run = false
|
588
|
+
@machine.after_transition {|object| @run = true}
|
589
|
+
@transition.run_callbacks {{:success => false}}
|
590
|
+
assert !@run
|
591
|
+
end
|
592
|
+
|
593
|
+
def test_should_run_if_successful
|
594
|
+
@machine.after_transition {|object| @run = true}
|
595
|
+
@transition.run_callbacks {{:success => true}}
|
596
|
+
assert @run
|
597
|
+
end
|
598
|
+
|
599
|
+
def test_should_pass_transition_as_argument
|
600
|
+
@machine.after_transition {|*args| @args = args}
|
601
|
+
|
602
|
+
@transition.run_callbacks
|
603
|
+
assert_equal [@object, @transition], @args
|
604
|
+
end
|
605
|
+
|
606
|
+
def test_should_catch_halts
|
607
|
+
@machine.after_transition {throw :halt}
|
608
|
+
|
609
|
+
result = nil
|
610
|
+
assert_nothing_thrown { result = @transition.run_callbacks }
|
611
|
+
assert_equal true, result
|
612
|
+
end
|
613
|
+
|
614
|
+
def test_should_not_catch_exceptions
|
615
|
+
@machine.after_transition {raise ArgumentError}
|
616
|
+
assert_raise(ArgumentError) { @transition.run_callbacks }
|
617
|
+
end
|
618
|
+
|
619
|
+
def test_should_not_be_able_to_run_twice
|
620
|
+
@count = 0
|
621
|
+
@machine.after_transition {@count += 1}
|
622
|
+
@transition.run_callbacks
|
623
|
+
@transition.run_callbacks
|
624
|
+
assert_equal 1, @count
|
625
|
+
end
|
626
|
+
|
627
|
+
def test_should_not_be_able_to_run_twice_if_halted
|
628
|
+
@count = 0
|
629
|
+
@machine.after_transition {@count += 1; throw :halt}
|
630
|
+
@transition.run_callbacks
|
631
|
+
@transition.run_callbacks
|
632
|
+
assert_equal 1, @count
|
633
|
+
end
|
634
|
+
|
635
|
+
def test_should_be_able_to_run_again_after_resetting
|
636
|
+
@count = 0
|
637
|
+
@machine.after_transition {@count += 1}
|
638
|
+
@transition.run_callbacks
|
639
|
+
@transition.reset
|
640
|
+
@transition.run_callbacks
|
641
|
+
assert_equal 2, @count
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
class TransitionWithMultipleAfterCallbacksTest < Test::Unit::TestCase
|
646
|
+
def setup
|
647
|
+
@klass = Class.new
|
648
|
+
|
649
|
+
@machine = StateMachine::Machine.new(@klass)
|
650
|
+
@machine.state :parked, :idling
|
651
|
+
@machine.event :ignite
|
652
|
+
|
653
|
+
@object = @klass.new
|
654
|
+
@object.state = 'parked'
|
655
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
656
|
+
end
|
657
|
+
|
658
|
+
def test_should_run_in_the_order_they_were_defined
|
659
|
+
@callbacks = []
|
660
|
+
@machine.after_transition {@callbacks << 1}
|
661
|
+
@machine.after_transition {@callbacks << 2}
|
662
|
+
@transition.run_callbacks
|
663
|
+
|
664
|
+
assert_equal [1, 2], @callbacks
|
665
|
+
end
|
666
|
+
|
667
|
+
def test_should_not_run_further_callbacks_if_halted
|
668
|
+
@callbacks = []
|
669
|
+
@machine.after_transition {@callbacks << 1; throw :halt}
|
670
|
+
@machine.after_transition {@callbacks << 2}
|
671
|
+
|
672
|
+
assert_equal true, @transition.run_callbacks
|
673
|
+
assert_equal [1], @callbacks
|
674
|
+
end
|
675
|
+
|
676
|
+
def test_should_fail_if_any_callback_halted
|
677
|
+
@machine.after_transition {true}
|
678
|
+
@machine.after_transition {throw :halt}
|
679
|
+
|
680
|
+
assert_equal true, @transition.run_callbacks
|
681
|
+
end
|
682
|
+
end
|
683
|
+
|
684
|
+
class TransitionWithAroundCallbacksTest < Test::Unit::TestCase
|
685
|
+
def setup
|
686
|
+
@klass = Class.new
|
687
|
+
|
688
|
+
@machine = StateMachine::Machine.new(@klass)
|
689
|
+
@machine.state :parked, :idling
|
690
|
+
@machine.event :ignite
|
691
|
+
|
692
|
+
@object = @klass.new
|
693
|
+
@object.state = 'parked'
|
694
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
695
|
+
end
|
696
|
+
|
697
|
+
def test_should_run_around_callbacks
|
698
|
+
@machine.around_transition {|object, transition, block| @run_before = true; block.call; @run_after = true}
|
699
|
+
result = @transition.run_callbacks
|
700
|
+
|
701
|
+
assert_equal true, result
|
702
|
+
assert_equal true, @run_before
|
703
|
+
assert_equal true, @run_after
|
704
|
+
end
|
705
|
+
|
706
|
+
def test_should_only_run_those_that_match_transition_context
|
707
|
+
@count = 0
|
708
|
+
callback = lambda {|object, transition, block| @count += 1; block.call}
|
709
|
+
|
710
|
+
@machine.around_transition :from => :parked, :to => :idling, :on => :park, :do => callback
|
711
|
+
@machine.around_transition :from => :parked, :to => :parked, :on => :park, :do => callback
|
712
|
+
@machine.around_transition :from => :parked, :to => :idling, :on => :ignite, :do => callback
|
713
|
+
@machine.around_transition :from => :idling, :to => :idling, :on => :park, :do => callback
|
714
|
+
@transition.run_callbacks
|
715
|
+
|
716
|
+
assert_equal 1, @count
|
717
|
+
end
|
718
|
+
|
719
|
+
def test_should_pass_transition_as_argument
|
720
|
+
@machine.around_transition {|*args| block = args.pop; @args = args; block.call}
|
721
|
+
@transition.run_callbacks
|
722
|
+
|
723
|
+
assert_equal [@object, @transition], @args
|
724
|
+
end
|
725
|
+
|
726
|
+
def test_should_run_block_between_callback
|
727
|
+
@callbacks = []
|
728
|
+
@machine.around_transition {|block| @callbacks << :before; block.call; @callbacks << :after}
|
729
|
+
@transition.run_callbacks { @callbacks << :within; {:success => true} }
|
730
|
+
|
731
|
+
assert_equal [:before, :within, :after], @callbacks
|
732
|
+
end
|
733
|
+
|
734
|
+
def test_should_have_access_to_result_after_yield
|
735
|
+
@machine.around_transition {|block| @before_result = @transition.result; block.call; @after_result = @transition.result}
|
736
|
+
@transition.run_callbacks {{:result => 1, :success => true}}
|
737
|
+
|
738
|
+
assert_nil @before_result
|
739
|
+
assert_equal 1, @after_result
|
740
|
+
end
|
741
|
+
|
742
|
+
def test_should_catch_before_yield_halts
|
743
|
+
@machine.around_transition {throw :halt}
|
744
|
+
|
745
|
+
result = nil
|
746
|
+
assert_nothing_thrown { result = @transition.run_callbacks }
|
747
|
+
assert_equal false, result
|
748
|
+
end
|
749
|
+
|
750
|
+
def test_should_catch_after_yield_halts
|
751
|
+
@machine.around_transition {|block| block.call; throw :halt}
|
752
|
+
|
753
|
+
result = nil
|
754
|
+
assert_nothing_thrown { result = @transition.run_callbacks }
|
755
|
+
assert_equal true, result
|
756
|
+
end
|
757
|
+
|
758
|
+
def test_should_not_catch_before_yield
|
759
|
+
@machine.around_transition {raise ArgumentError}
|
760
|
+
assert_raise(ArgumentError) { @transition.run_callbacks }
|
761
|
+
end
|
762
|
+
|
763
|
+
def test_should_not_catch_after_yield
|
764
|
+
@machine.around_transition {|block| block.call; raise ArgumentError}
|
765
|
+
assert_raise(ArgumentError) { @transition.run_callbacks }
|
766
|
+
end
|
767
|
+
|
768
|
+
def test_should_fail_if_not_yielded
|
769
|
+
@machine.around_transition {}
|
770
|
+
|
771
|
+
result = nil
|
772
|
+
assert_nothing_thrown { result = @transition.run_callbacks }
|
773
|
+
assert_equal false, result
|
774
|
+
end
|
775
|
+
|
776
|
+
def test_should_not_be_able_to_run_twice
|
777
|
+
@before_count = 0
|
778
|
+
@after_count = 0
|
779
|
+
@machine.around_transition {|block| @before_count += 1; block.call; @after_count += 1}
|
780
|
+
@transition.run_callbacks
|
781
|
+
@transition.run_callbacks
|
782
|
+
assert_equal 1, @before_count
|
783
|
+
assert_equal 1, @after_count
|
784
|
+
end
|
785
|
+
|
786
|
+
def test_should_be_able_to_run_again_after_resetting
|
787
|
+
@before_count = 0
|
788
|
+
@after_count = 0
|
789
|
+
@machine.around_transition {|block| @before_count += 1; block.call; @after_count += 1}
|
790
|
+
@transition.run_callbacks
|
791
|
+
@transition.reset
|
792
|
+
@transition.run_callbacks
|
793
|
+
assert_equal 2, @before_count
|
794
|
+
assert_equal 2, @after_count
|
795
|
+
end
|
796
|
+
|
797
|
+
def test_should_succeed_if_block_result_is_false
|
798
|
+
@machine.around_transition {|block| @before_run = true; block.call; @after_run = true}
|
799
|
+
assert_equal true, @transition.run_callbacks {{:success => true, :result => false}}
|
800
|
+
assert @before_run
|
801
|
+
assert @after_run
|
802
|
+
end
|
803
|
+
|
804
|
+
def test_should_succeed_if_block_result_is_true
|
805
|
+
@machine.around_transition {|block| @before_run = true; block.call; @after_run = true}
|
806
|
+
assert_equal true, @transition.run_callbacks {{:success => true, :result => true}}
|
807
|
+
assert @before_run
|
808
|
+
assert @after_run
|
809
|
+
end
|
810
|
+
|
811
|
+
def test_should_only_run_before_if_block_success_is_false
|
812
|
+
@after_run = false
|
813
|
+
@machine.around_transition {|block| @before_run = true; block.call; @after_run = true}
|
814
|
+
assert_equal true, @transition.run_callbacks {{:success => false}}
|
815
|
+
assert @before_run
|
816
|
+
assert !@after_run
|
817
|
+
end
|
818
|
+
|
819
|
+
def test_should_succeed_if_block_success_is_false
|
820
|
+
@machine.around_transition {|block| @before_run = true; block.call; @after_run = true}
|
821
|
+
assert_equal true, @transition.run_callbacks {{:success => true}}
|
822
|
+
assert @before_run
|
823
|
+
assert @after_run
|
824
|
+
end
|
825
|
+
end
|
826
|
+
|
827
|
+
class TransitionWithMultipleAroundCallbacksTest < Test::Unit::TestCase
|
828
|
+
def setup
|
829
|
+
@klass = Class.new
|
830
|
+
|
831
|
+
@machine = StateMachine::Machine.new(@klass)
|
832
|
+
@machine.state :parked, :idling
|
833
|
+
@machine.event :ignite
|
834
|
+
|
835
|
+
@object = @klass.new
|
836
|
+
@object.state = 'parked'
|
837
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
838
|
+
end
|
839
|
+
|
840
|
+
def test_should_before_yield_in_the_order_they_were_defined
|
841
|
+
@callbacks = []
|
842
|
+
@machine.around_transition {|block| @callbacks << 1; block.call}
|
843
|
+
@machine.around_transition {|block| @callbacks << 2; block.call}
|
844
|
+
@transition.run_callbacks
|
845
|
+
|
846
|
+
assert_equal [1, 2], @callbacks
|
847
|
+
end
|
848
|
+
|
849
|
+
def test_should_before_yield_multiple_methods_in_the_order_they_were_defined
|
850
|
+
@callbacks = []
|
851
|
+
@machine.around_transition(lambda {|block| @callbacks << 1; block.call}, lambda {|block| @callbacks << 2; block.call})
|
852
|
+
@machine.around_transition(lambda {|block| @callbacks << 3; block.call}, lambda {|block| @callbacks << 4; block.call})
|
853
|
+
@transition.run_callbacks
|
854
|
+
|
855
|
+
assert_equal [1, 2, 3, 4], @callbacks
|
856
|
+
end
|
857
|
+
|
858
|
+
def test_should_after_yield_in_the_reverse_order_they_were_defined
|
859
|
+
@callbacks = []
|
860
|
+
@machine.around_transition {|block| block.call; @callbacks << 1}
|
861
|
+
@machine.around_transition {|block| block.call; @callbacks << 2}
|
862
|
+
@transition.run_callbacks
|
863
|
+
|
864
|
+
assert_equal [2, 1], @callbacks
|
865
|
+
end
|
866
|
+
|
867
|
+
def test_should_after_yield_multiple_methods_in_the_reverse_order_they_were_defined
|
868
|
+
@callbacks = []
|
869
|
+
@machine.around_transition(lambda {|block| block.call; @callbacks << 1}) {|block| block.call; @callbacks << 2}
|
870
|
+
@machine.around_transition(lambda {|block| block.call; @callbacks << 3}) {|block| block.call; @callbacks << 4}
|
871
|
+
@transition.run_callbacks
|
872
|
+
|
873
|
+
assert_equal [4, 3, 2, 1], @callbacks
|
874
|
+
end
|
875
|
+
|
876
|
+
def test_should_run_block_between_callback
|
877
|
+
@callbacks = []
|
878
|
+
@machine.around_transition {|block| @callbacks << :before_1; block.call; @callbacks << :after_1}
|
879
|
+
@machine.around_transition {|block| @callbacks << :before_2; block.call; @callbacks << :after_2}
|
880
|
+
@transition.run_callbacks { @callbacks << :within; {:success => true} }
|
881
|
+
|
882
|
+
assert_equal [:before_1, :before_2, :within, :after_2, :after_1], @callbacks
|
883
|
+
end
|
884
|
+
|
885
|
+
def test_should_have_access_to_result_after_yield
|
886
|
+
@machine.around_transition {|block| @before_result_1 = @transition.result; block.call; @after_result_1 = @transition.result}
|
887
|
+
@machine.around_transition {|block| @before_result_2 = @transition.result; block.call; @after_result_2 = @transition.result}
|
888
|
+
@transition.run_callbacks {{:result => 1, :success => true}}
|
889
|
+
|
890
|
+
assert_nil @before_result_1
|
891
|
+
assert_nil @before_result_2
|
892
|
+
assert_equal 1, @after_result_1
|
893
|
+
assert_equal 1, @after_result_2
|
894
|
+
end
|
895
|
+
|
896
|
+
def test_should_fail_if_any_before_yield_halted
|
897
|
+
@machine.around_transition {|block| block.call}
|
898
|
+
@machine.around_transition {throw :halt}
|
899
|
+
|
900
|
+
assert_equal false, @transition.run_callbacks
|
901
|
+
end
|
902
|
+
|
903
|
+
def test_should_not_continue_around_callbacks_if_before_yield_halted
|
904
|
+
@callbacks = []
|
905
|
+
@machine.around_transition {@callbacks << 1; throw :halt}
|
906
|
+
@machine.around_transition {|block| @callbacks << 2; block.call; @callbacks << 3}
|
907
|
+
|
908
|
+
assert_equal false, @transition.run_callbacks
|
909
|
+
assert_equal [1], @callbacks
|
910
|
+
end
|
911
|
+
|
912
|
+
def test_should_not_continue_around_callbacks_if_later_before_yield_halted
|
913
|
+
@callbacks = []
|
914
|
+
@machine.around_transition {|block| block.call; @callbacks << 1}
|
915
|
+
@machine.around_transition {throw :halt}
|
916
|
+
|
917
|
+
@transition.run_callbacks
|
918
|
+
assert_equal [], @callbacks
|
919
|
+
end
|
920
|
+
|
921
|
+
def test_should_not_run_further_callbacks_if_after_yield_halted
|
922
|
+
@callbacks = []
|
923
|
+
@machine.around_transition {|block| block.call; @callbacks << 1}
|
924
|
+
@machine.around_transition {|block| block.call; throw :halt}
|
925
|
+
|
926
|
+
assert_equal true, @transition.run_callbacks
|
927
|
+
assert_equal [], @callbacks
|
928
|
+
end
|
929
|
+
|
930
|
+
def test_should_fail_if_any_fail_to_yield
|
931
|
+
@callbacks = []
|
932
|
+
@machine.around_transition {@callbacks << 1}
|
933
|
+
@machine.around_transition {|block| @callbacks << 2; block.call; @callbacks << 3}
|
934
|
+
|
935
|
+
assert_equal false, @transition.run_callbacks
|
936
|
+
assert_equal [1], @callbacks
|
937
|
+
end
|
938
|
+
end
|
939
|
+
|
940
|
+
class TransitionWithFailureCallbacksTest < Test::Unit::TestCase
|
941
|
+
def setup
|
942
|
+
@klass = Class.new
|
943
|
+
|
944
|
+
@machine = StateMachine::Machine.new(@klass)
|
945
|
+
@machine.state :parked, :idling
|
946
|
+
@machine.event :ignite
|
947
|
+
|
948
|
+
@object = @klass.new
|
949
|
+
@object.state = 'parked'
|
950
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
951
|
+
end
|
952
|
+
|
953
|
+
def test_should_only_run_those_that_match_transition_context
|
954
|
+
@count = 0
|
955
|
+
callback = lambda {@count += 1}
|
956
|
+
|
957
|
+
@machine.after_failure :do => callback
|
958
|
+
@machine.after_failure :on => :park, :do => callback
|
959
|
+
@machine.after_failure :on => :ignite, :do => callback
|
960
|
+
@transition.run_callbacks {{:success => false}}
|
961
|
+
|
962
|
+
assert_equal 2, @count
|
963
|
+
end
|
964
|
+
|
965
|
+
def test_should_run_if_not_successful
|
966
|
+
@machine.after_failure {|object| @run = true}
|
967
|
+
@transition.run_callbacks {{:success => false}}
|
968
|
+
assert @run
|
969
|
+
end
|
970
|
+
|
971
|
+
def test_should_not_run_if_successful
|
972
|
+
@run = false
|
973
|
+
@machine.after_failure {|object| @run = true}
|
974
|
+
@transition.run_callbacks {{:success => true}}
|
975
|
+
assert !@run
|
976
|
+
end
|
977
|
+
|
978
|
+
def test_should_pass_transition_as_argument
|
979
|
+
@machine.after_failure {|*args| @args = args}
|
980
|
+
|
981
|
+
@transition.run_callbacks {{:success => false}}
|
982
|
+
assert_equal [@object, @transition], @args
|
983
|
+
end
|
984
|
+
|
985
|
+
def test_should_catch_halts
|
986
|
+
@machine.after_failure {throw :halt}
|
987
|
+
|
988
|
+
result = nil
|
989
|
+
assert_nothing_thrown { result = @transition.run_callbacks {{:success => false}} }
|
990
|
+
assert_equal true, result
|
991
|
+
end
|
992
|
+
|
993
|
+
def test_should_not_catch_exceptions
|
994
|
+
@machine.after_failure {raise ArgumentError}
|
995
|
+
assert_raise(ArgumentError) { @transition.run_callbacks {{:success => false}} }
|
996
|
+
end
|
997
|
+
|
998
|
+
def test_should_not_be_able_to_run_twice
|
999
|
+
@count = 0
|
1000
|
+
@machine.after_failure {@count += 1}
|
1001
|
+
@transition.run_callbacks {{:success => false}}
|
1002
|
+
@transition.run_callbacks {{:success => false}}
|
1003
|
+
assert_equal 1, @count
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
def test_should_not_be_able_to_run_twice_if_halted
|
1007
|
+
@count = 0
|
1008
|
+
@machine.after_failure {@count += 1; throw :halt}
|
1009
|
+
@transition.run_callbacks {{:success => false}}
|
1010
|
+
@transition.run_callbacks {{:success => false}}
|
1011
|
+
assert_equal 1, @count
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
def test_should_be_able_to_run_again_after_resetting
|
1015
|
+
@count = 0
|
1016
|
+
@machine.after_failure {@count += 1}
|
1017
|
+
@transition.run_callbacks {{:success => false}}
|
1018
|
+
@transition.reset
|
1019
|
+
@transition.run_callbacks {{:success => false}}
|
1020
|
+
assert_equal 2, @count
|
1021
|
+
end
|
1022
|
+
end
|
1023
|
+
|
1024
|
+
class TransitionWithMultipleFailureCallbacksTest < Test::Unit::TestCase
|
1025
|
+
def setup
|
1026
|
+
@klass = Class.new
|
1027
|
+
|
1028
|
+
@machine = StateMachine::Machine.new(@klass)
|
1029
|
+
@machine.state :parked, :idling
|
1030
|
+
@machine.event :ignite
|
1031
|
+
|
1032
|
+
@object = @klass.new
|
1033
|
+
@object.state = 'parked'
|
1034
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
def test_should_run_in_the_order_they_were_defined
|
1038
|
+
@callbacks = []
|
1039
|
+
@machine.after_failure {@callbacks << 1}
|
1040
|
+
@machine.after_failure {@callbacks << 2}
|
1041
|
+
@transition.run_callbacks {{:success => false}}
|
1042
|
+
|
1043
|
+
assert_equal [1, 2], @callbacks
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
def test_should_not_run_further_callbacks_if_halted
|
1047
|
+
@callbacks = []
|
1048
|
+
@machine.after_failure {@callbacks << 1; throw :halt}
|
1049
|
+
@machine.after_failure {@callbacks << 2}
|
1050
|
+
|
1051
|
+
assert_equal true, @transition.run_callbacks {{:success => false}}
|
1052
|
+
assert_equal [1], @callbacks
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
def test_should_fail_if_any_callback_halted
|
1056
|
+
@machine.after_failure {true}
|
1057
|
+
@machine.after_failure {throw :halt}
|
1058
|
+
|
1059
|
+
assert_equal true, @transition.run_callbacks {{:success => false}}
|
1060
|
+
end
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
class TransitionWithMixedCallbacksTest < Test::Unit::TestCase
|
1064
|
+
def setup
|
1065
|
+
@klass = Class.new
|
1066
|
+
|
1067
|
+
@machine = StateMachine::Machine.new(@klass)
|
1068
|
+
@machine.state :parked, :idling
|
1069
|
+
@machine.event :ignite
|
1070
|
+
|
1071
|
+
@object = @klass.new
|
1072
|
+
@object.state = 'parked'
|
1073
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
def test_should_before_and_around_callbacks_in_order_defined
|
1077
|
+
@callbacks = []
|
1078
|
+
@machine.before_transition {@callbacks << :before_1}
|
1079
|
+
@machine.around_transition {|block| @callbacks << :around; block.call}
|
1080
|
+
@machine.before_transition {@callbacks << :before_2}
|
1081
|
+
|
1082
|
+
assert_equal true, @transition.run_callbacks
|
1083
|
+
assert_equal [:before_1, :around, :before_2], @callbacks
|
1084
|
+
end
|
1085
|
+
|
1086
|
+
def test_should_run_around_callbacks_before_after_callbacks
|
1087
|
+
@callbacks = []
|
1088
|
+
@machine.after_transition {@callbacks << :after_1}
|
1089
|
+
@machine.around_transition {|block| block.call; @callbacks << :after_2}
|
1090
|
+
@machine.after_transition {@callbacks << :after_3}
|
1091
|
+
|
1092
|
+
assert_equal true, @transition.run_callbacks
|
1093
|
+
assert_equal [:after_2, :after_1, :after_3], @callbacks
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
def test_should_have_access_to_result_for_both_after_and_around_callbacks
|
1097
|
+
@machine.after_transition {@after_result = @transition.result}
|
1098
|
+
@machine.around_transition {|block| block.call; @around_result = @transition.result}
|
1099
|
+
|
1100
|
+
@transition.run_callbacks {{:result => 1, :success => true}}
|
1101
|
+
assert_equal 1, @after_result
|
1102
|
+
assert_equal 1, @around_result
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
def test_should_not_run_further_callbacks_if_before_callback_halts
|
1106
|
+
@callbacks = []
|
1107
|
+
@machine.before_transition {@callbacks << :before_1}
|
1108
|
+
@machine.around_transition {|block| @callbacks << :before_around_1; block.call; @callbacks << :after_around_1}
|
1109
|
+
@machine.before_transition {@callbacks << :before_2; throw :halt}
|
1110
|
+
@machine.around_transition {|block| @callbacks << :before_around_2; block.call; @callbacks << :after_around_2}
|
1111
|
+
@machine.after_transition {@callbacks << :after}
|
1112
|
+
|
1113
|
+
assert_equal false, @transition.run_callbacks
|
1114
|
+
assert_equal [:before_1, :before_around_1, :before_2], @callbacks
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
def test_should_not_run_further_callbacks_if_before_yield_halts
|
1118
|
+
@callbacks = []
|
1119
|
+
@machine.before_transition {@callbacks << :before_1}
|
1120
|
+
@machine.around_transition {|block| @callbacks << :before_around_1; throw :halt}
|
1121
|
+
@machine.before_transition {@callbacks << :before_2; throw :halt}
|
1122
|
+
@machine.around_transition {|block| @callbacks << :before_around_2; block.call; @callbacks << :after_around_2}
|
1123
|
+
@machine.after_transition {@callbacks << :after}
|
1124
|
+
|
1125
|
+
assert_equal false, @transition.run_callbacks
|
1126
|
+
assert_equal [:before_1, :before_around_1], @callbacks
|
1127
|
+
end
|
1128
|
+
|
1129
|
+
def test_should_not_run_further_callbacks_if_around_callback_fails_to_yield
|
1130
|
+
@callbacks = []
|
1131
|
+
@machine.before_transition {@callbacks << :before_1}
|
1132
|
+
@machine.around_transition {|block| @callbacks << :before_around_1}
|
1133
|
+
@machine.before_transition {@callbacks << :before_2; throw :halt}
|
1134
|
+
@machine.around_transition {|block| @callbacks << :before_around_2; block.call; @callbacks << :after_around_2}
|
1135
|
+
@machine.after_transition {@callbacks << :after}
|
1136
|
+
|
1137
|
+
assert_equal false, @transition.run_callbacks
|
1138
|
+
assert_equal [:before_1, :before_around_1], @callbacks
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
def test_should_not_run_further_callbacks_if_after_yield_halts
|
1142
|
+
@callbacks = []
|
1143
|
+
@machine.before_transition {@callbacks << :before_1}
|
1144
|
+
@machine.around_transition {|block| @callbacks << :before_around_1; block.call; @callbacks << :after_around_1; throw :halt}
|
1145
|
+
@machine.before_transition {@callbacks << :before_2}
|
1146
|
+
@machine.around_transition {|block| @callbacks << :before_around_2; block.call; @callbacks << :after_around_2}
|
1147
|
+
@machine.after_transition {@callbacks << :after}
|
1148
|
+
|
1149
|
+
assert_equal true, @transition.run_callbacks
|
1150
|
+
assert_equal [:before_1, :before_around_1, :before_2, :before_around_2, :after_around_2, :after_around_1], @callbacks
|
1151
|
+
end
|
1152
|
+
|
1153
|
+
def test_should_not_run_further_callbacks_if_after_callback_halts
|
1154
|
+
@callbacks = []
|
1155
|
+
@machine.before_transition {@callbacks << :before_1}
|
1156
|
+
@machine.around_transition {|block| @callbacks << :before_around_1; block.call; @callbacks << :after_around_1}
|
1157
|
+
@machine.before_transition {@callbacks << :before_2}
|
1158
|
+
@machine.around_transition {|block| @callbacks << :before_around_2; block.call; @callbacks << :after_around_2}
|
1159
|
+
@machine.after_transition {@callbacks << :after_1; throw :halt}
|
1160
|
+
@machine.after_transition {@callbacks << :after_2}
|
1161
|
+
|
1162
|
+
assert_equal true, @transition.run_callbacks
|
1163
|
+
assert_equal [:before_1, :before_around_1, :before_2, :before_around_2, :after_around_2, :after_around_1, :after_1], @callbacks
|
1164
|
+
end
|
1165
|
+
end
|
1166
|
+
|
1167
|
+
class TransitionWithBeforeCallbacksSkippedTest < Test::Unit::TestCase
|
1168
|
+
def setup
|
1169
|
+
@klass = Class.new
|
1170
|
+
|
1171
|
+
@machine = StateMachine::Machine.new(@klass)
|
1172
|
+
@machine.state :parked, :idling
|
1173
|
+
@machine.event :ignite
|
1174
|
+
|
1175
|
+
@object = @klass.new
|
1176
|
+
@object.state = 'parked'
|
1177
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1178
|
+
end
|
1179
|
+
|
1180
|
+
def test_should_not_run_before_callbacks
|
1181
|
+
@run = false
|
1182
|
+
@machine.before_transition {@run = true}
|
1183
|
+
|
1184
|
+
assert_equal false, @transition.run_callbacks(:before => false)
|
1185
|
+
assert !@run
|
1186
|
+
end
|
1187
|
+
|
1188
|
+
def test_should_run_failure_callbacks
|
1189
|
+
@machine.after_failure {@run = true}
|
1190
|
+
|
1191
|
+
assert_equal false, @transition.run_callbacks(:before => false)
|
1192
|
+
assert @run
|
1193
|
+
end
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
class TransitionWithAfterCallbacksSkippedTest < Test::Unit::TestCase
|
1197
|
+
def setup
|
1198
|
+
@klass = Class.new
|
1199
|
+
|
1200
|
+
@machine = StateMachine::Machine.new(@klass)
|
1201
|
+
@machine.state :parked, :idling
|
1202
|
+
@machine.event :ignite
|
1203
|
+
|
1204
|
+
@object = @klass.new
|
1205
|
+
@object.state = 'parked'
|
1206
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1207
|
+
end
|
1208
|
+
|
1209
|
+
def test_should_run_before_callbacks
|
1210
|
+
@machine.before_transition {@run = true}
|
1211
|
+
|
1212
|
+
assert_equal true, @transition.run_callbacks(:after => false)
|
1213
|
+
assert @run
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
def test_should_not_run_after_callbacks
|
1217
|
+
@run = false
|
1218
|
+
@machine.after_transition {@run = true}
|
1219
|
+
|
1220
|
+
assert_equal true, @transition.run_callbacks(:after => false)
|
1221
|
+
assert !@run
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
if StateMachine::Transition.pause_supported?
|
1225
|
+
def test_should_run_around_callbacks_before_yield
|
1226
|
+
@machine.around_transition {|block| @run = true; block.call}
|
1227
|
+
|
1228
|
+
assert_equal true, @transition.run_callbacks(:after => false)
|
1229
|
+
assert @run
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
def test_should_not_run_around_callbacks_after_yield
|
1233
|
+
@run = false
|
1234
|
+
@machine.around_transition {|block| block.call; @run = true}
|
1235
|
+
|
1236
|
+
assert_equal true, @transition.run_callbacks(:after => false)
|
1237
|
+
assert !@run
|
1238
|
+
end
|
1239
|
+
|
1240
|
+
def test_should_continue_around_transition_execution_on_second_call
|
1241
|
+
@callbacks = []
|
1242
|
+
@machine.around_transition {|block| @callbacks << :before_around_1; block.call; @callbacks << :after_around_1}
|
1243
|
+
@machine.around_transition {|block| @callbacks << :before_around_2; block.call; @callbacks << :after_around_2}
|
1244
|
+
@machine.after_transition {@callbacks << :after}
|
1245
|
+
|
1246
|
+
assert_equal true, @transition.run_callbacks(:after => false)
|
1247
|
+
assert_equal [:before_around_1, :before_around_2], @callbacks
|
1248
|
+
|
1249
|
+
assert_equal true, @transition.run_callbacks
|
1250
|
+
assert_equal [:before_around_1, :before_around_2, :after_around_2, :after_around_1, :after], @callbacks
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
def test_should_not_run_further_callbacks_if_halted_during_continue_around_transition
|
1254
|
+
@callbacks = []
|
1255
|
+
@machine.around_transition {|block| @callbacks << :before_around_1; block.call; @callbacks << :after_around_1}
|
1256
|
+
@machine.around_transition {|block| @callbacks << :before_around_2; block.call; @callbacks << :after_around_2; throw :halt}
|
1257
|
+
@machine.after_transition {@callbacks << :after}
|
1258
|
+
|
1259
|
+
assert_equal true, @transition.run_callbacks(:after => false)
|
1260
|
+
assert_equal [:before_around_1, :before_around_2], @callbacks
|
1261
|
+
|
1262
|
+
assert_equal true, @transition.run_callbacks
|
1263
|
+
assert_equal [:before_around_1, :before_around_2, :after_around_2], @callbacks
|
1264
|
+
end
|
1265
|
+
|
1266
|
+
def test_should_not_be_able_to_continue_twice
|
1267
|
+
@count = 0
|
1268
|
+
@machine.around_transition {|block| block.call; @count += 1}
|
1269
|
+
@machine.after_transition {@count += 1}
|
1270
|
+
|
1271
|
+
@transition.run_callbacks(:after => false)
|
1272
|
+
|
1273
|
+
2.times do
|
1274
|
+
assert_equal true, @transition.run_callbacks
|
1275
|
+
assert_equal 2, @count
|
1276
|
+
end
|
1277
|
+
end
|
1278
|
+
|
1279
|
+
def test_should_not_be_able_to_continue_again_after_halted
|
1280
|
+
@count = 0
|
1281
|
+
@machine.around_transition {|block| block.call; @count += 1; throw :halt}
|
1282
|
+
@machine.after_transition {@count += 1}
|
1283
|
+
|
1284
|
+
@transition.run_callbacks(:after => false)
|
1285
|
+
|
1286
|
+
2.times do
|
1287
|
+
assert_equal true, @transition.run_callbacks
|
1288
|
+
assert_equal 1, @count
|
1289
|
+
end
|
1290
|
+
end
|
1291
|
+
|
1292
|
+
def test_should_have_access_to_result_after_continued
|
1293
|
+
@machine.around_transition {|block| @around_before_result = @transition.result; block.call; @around_after_result = @transition.result}
|
1294
|
+
@machine.after_transition {@after_result = @transition.result}
|
1295
|
+
|
1296
|
+
@transition.run_callbacks(:after => false)
|
1297
|
+
@transition.run_callbacks {{:result => 1}}
|
1298
|
+
|
1299
|
+
assert_nil @around_before_result
|
1300
|
+
assert_equal 1, @around_after_result
|
1301
|
+
assert_equal 1, @after_result
|
1302
|
+
end
|
1303
|
+
|
1304
|
+
def test_should_raise_exceptions_during_around_callbacks_after_yield_in_second_execution
|
1305
|
+
@machine.around_transition {|block| block.call; raise ArgumentError}
|
1306
|
+
|
1307
|
+
assert_nothing_raised { @transition.run_callbacks(:after => false) }
|
1308
|
+
assert_raise(ArgumentError) { @transition.run_callbacks }
|
1309
|
+
end
|
1310
|
+
else
|
1311
|
+
def test_should_raise_exception_on_second_call
|
1312
|
+
@callbacks = []
|
1313
|
+
@machine.around_transition {|block| @callbacks << :before_around_1; block.call; @callbacks << :after_around_1}
|
1314
|
+
@machine.around_transition {|block| @callbacks << :before_around_2; block.call; @callbacks << :after_around_2}
|
1315
|
+
@machine.after_transition {@callbacks << :after}
|
1316
|
+
|
1317
|
+
assert_raise(ArgumentError) { @transition.run_callbacks(:after => false) }
|
1318
|
+
end
|
1319
|
+
end
|
1320
|
+
end
|
1321
|
+
|
1322
|
+
class TransitionAfterBeingPerformedTest < Test::Unit::TestCase
|
1323
|
+
def setup
|
1324
|
+
@klass = Class.new do
|
1325
|
+
attr_reader :saved, :save_state
|
1326
|
+
|
1327
|
+
def save
|
1328
|
+
@save_state = state
|
1329
|
+
@saved = true
|
1330
|
+
1
|
1331
|
+
end
|
1332
|
+
end
|
1333
|
+
|
1334
|
+
@machine = StateMachine::Machine.new(@klass, :action => :save)
|
1335
|
+
@machine.state :parked, :idling
|
1336
|
+
@machine.event :ignite
|
1337
|
+
|
1338
|
+
@object = @klass.new
|
1339
|
+
@object.state = 'parked'
|
1340
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1341
|
+
@result = @transition.perform
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
def test_should_have_empty_args
|
1345
|
+
assert_equal [], @transition.args
|
1346
|
+
end
|
1347
|
+
|
1348
|
+
def test_should_have_a_result
|
1349
|
+
assert_equal 1, @transition.result
|
1350
|
+
end
|
1351
|
+
|
1352
|
+
def test_should_be_successful
|
1353
|
+
assert_equal true, @result
|
1354
|
+
end
|
1355
|
+
|
1356
|
+
def test_should_change_the_current_state
|
1357
|
+
assert_equal 'idling', @object.state
|
1358
|
+
end
|
1359
|
+
|
1360
|
+
def test_should_run_the_action
|
1361
|
+
assert @object.saved
|
1362
|
+
end
|
1363
|
+
|
1364
|
+
def test_should_run_the_action_after_saving_the_state
|
1365
|
+
assert_equal 'idling', @object.save_state
|
1366
|
+
end
|
1367
|
+
end
|
1368
|
+
|
1369
|
+
class TransitionWithPerformArgumentsTest < Test::Unit::TestCase
|
1370
|
+
def setup
|
1371
|
+
@klass = Class.new do
|
1372
|
+
attr_reader :saved
|
1373
|
+
|
1374
|
+
def save
|
1375
|
+
@saved = true
|
1376
|
+
end
|
1377
|
+
end
|
1378
|
+
|
1379
|
+
@machine = StateMachine::Machine.new(@klass, :action => :save)
|
1380
|
+
@machine.state :parked, :idling
|
1381
|
+
@machine.event :ignite
|
1382
|
+
|
1383
|
+
@object = @klass.new
|
1384
|
+
@object.state = 'parked'
|
1385
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1386
|
+
end
|
1387
|
+
|
1388
|
+
def test_should_have_arguments
|
1389
|
+
@transition.perform(1, 2)
|
1390
|
+
|
1391
|
+
assert_equal [1, 2], @transition.args
|
1392
|
+
assert @object.saved
|
1393
|
+
end
|
1394
|
+
|
1395
|
+
def test_should_not_include_run_action_in_arguments
|
1396
|
+
@transition.perform(1, 2, false)
|
1397
|
+
|
1398
|
+
assert_equal [1, 2], @transition.args
|
1399
|
+
assert !@object.saved
|
1400
|
+
end
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
class TransitionWithoutRunningActionTest < Test::Unit::TestCase
|
1404
|
+
def setup
|
1405
|
+
@klass = Class.new do
|
1406
|
+
attr_reader :saved
|
1407
|
+
|
1408
|
+
def save
|
1409
|
+
@saved = true
|
1410
|
+
end
|
1411
|
+
end
|
1412
|
+
|
1413
|
+
@machine = StateMachine::Machine.new(@klass, :action => :save)
|
1414
|
+
@machine.state :parked, :idling
|
1415
|
+
@machine.event :ignite
|
1416
|
+
@machine.after_transition {|object| @run_after = true}
|
1417
|
+
|
1418
|
+
@object = @klass.new
|
1419
|
+
@object.state = 'parked'
|
1420
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1421
|
+
@result = @transition.perform(false)
|
1422
|
+
end
|
1423
|
+
|
1424
|
+
def test_should_have_empty_args
|
1425
|
+
assert_equal [], @transition.args
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
def test_should_not_have_a_result
|
1429
|
+
assert_nil @transition.result
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
def test_should_be_successful
|
1433
|
+
assert_equal true, @result
|
1434
|
+
end
|
1435
|
+
|
1436
|
+
def test_should_change_the_current_state
|
1437
|
+
assert_equal 'idling', @object.state
|
1438
|
+
end
|
1439
|
+
|
1440
|
+
def test_should_not_run_the_action
|
1441
|
+
assert !@object.saved
|
1442
|
+
end
|
1443
|
+
|
1444
|
+
def test_should_run_after_callbacks
|
1445
|
+
assert @run_after
|
1446
|
+
end
|
1447
|
+
end
|
1448
|
+
|
1449
|
+
class TransitionWithTransactionsTest < Test::Unit::TestCase
|
1450
|
+
def setup
|
1451
|
+
@klass = Class.new do
|
1452
|
+
class << self
|
1453
|
+
attr_accessor :running_transaction
|
1454
|
+
end
|
1455
|
+
|
1456
|
+
attr_accessor :result
|
1457
|
+
|
1458
|
+
def save
|
1459
|
+
@result = self.class.running_transaction
|
1460
|
+
true
|
1461
|
+
end
|
1462
|
+
end
|
1463
|
+
|
1464
|
+
@machine = StateMachine::Machine.new(@klass, :action => :save)
|
1465
|
+
@machine.state :parked, :idling
|
1466
|
+
@machine.event :ignite
|
1467
|
+
|
1468
|
+
@object = @klass.new
|
1469
|
+
@object.state = 'parked'
|
1470
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1471
|
+
|
1472
|
+
class << @machine
|
1473
|
+
def within_transaction(object)
|
1474
|
+
owner_class.running_transaction = object
|
1475
|
+
yield
|
1476
|
+
owner_class.running_transaction = false
|
1477
|
+
end
|
1478
|
+
end
|
1479
|
+
end
|
1480
|
+
|
1481
|
+
def test_should_run_blocks_within_transaction_for_object
|
1482
|
+
@transition.within_transaction do
|
1483
|
+
@result = @klass.running_transaction
|
1484
|
+
end
|
1485
|
+
|
1486
|
+
assert_equal @object, @result
|
1487
|
+
end
|
1488
|
+
end
|
1489
|
+
|
1490
|
+
class TransitionTransientTest < Test::Unit::TestCase
|
1491
|
+
def setup
|
1492
|
+
@klass = Class.new
|
1493
|
+
|
1494
|
+
@machine = StateMachine::Machine.new(@klass)
|
1495
|
+
@machine.state :parked, :idling
|
1496
|
+
@machine.event :ignite
|
1497
|
+
|
1498
|
+
@object = @klass.new
|
1499
|
+
@object.state = 'parked'
|
1500
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1501
|
+
@transition.transient = true
|
1502
|
+
end
|
1503
|
+
|
1504
|
+
def test_should_be_transient
|
1505
|
+
assert @transition.transient?
|
1506
|
+
end
|
1507
|
+
end
|
1508
|
+
|
1509
|
+
class TransitionEqualityTest < Test::Unit::TestCase
|
1510
|
+
def setup
|
1511
|
+
@klass = Class.new
|
1512
|
+
|
1513
|
+
@machine = StateMachine::Machine.new(@klass)
|
1514
|
+
@machine.state :parked, :idling
|
1515
|
+
@machine.event :ignite
|
1516
|
+
|
1517
|
+
@object = @klass.new
|
1518
|
+
@object.state = 'parked'
|
1519
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1520
|
+
end
|
1521
|
+
|
1522
|
+
def test_should_be_equal_with_same_properties
|
1523
|
+
transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1524
|
+
assert_equal transition, @transition
|
1525
|
+
end
|
1526
|
+
|
1527
|
+
def test_should_not_be_equal_with_different_machines
|
1528
|
+
machine = StateMachine::Machine.new(@klass, :status, :namespace => :other)
|
1529
|
+
machine.state :parked, :idling
|
1530
|
+
machine.event :ignite
|
1531
|
+
transition = StateMachine::Transition.new(@object, machine, :ignite, :parked, :idling)
|
1532
|
+
|
1533
|
+
assert_not_equal transition, @transition
|
1534
|
+
end
|
1535
|
+
|
1536
|
+
def test_should_not_be_equal_with_different_objects
|
1537
|
+
transition = StateMachine::Transition.new(@klass.new, @machine, :ignite, :parked, :idling)
|
1538
|
+
assert_not_equal transition, @transition
|
1539
|
+
end
|
1540
|
+
|
1541
|
+
def test_should_not_be_equal_with_different_event_names
|
1542
|
+
@machine.event :park
|
1543
|
+
transition = StateMachine::Transition.new(@object, @machine, :park, :parked, :idling)
|
1544
|
+
assert_not_equal transition, @transition
|
1545
|
+
end
|
1546
|
+
|
1547
|
+
def test_should_not_be_equal_with_different_from_state_names
|
1548
|
+
@machine.state :first_gear
|
1549
|
+
transition = StateMachine::Transition.new(@object, @machine, :ignite, :first_gear, :idling)
|
1550
|
+
assert_not_equal transition, @transition
|
1551
|
+
end
|
1552
|
+
|
1553
|
+
def test_should_not_be_equal_with_different_to_state_names
|
1554
|
+
@machine.state :first_gear
|
1555
|
+
transition = StateMachine::Transition.new(@object, @machine, :ignite, :idling, :first_gear)
|
1556
|
+
assert_not_equal transition, @transition
|
1557
|
+
end
|
1558
|
+
end
|