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,2168 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class TransitionCollectionTest < Test::Unit::TestCase
|
4
|
+
def test_should_raise_exception_if_invalid_option_specified
|
5
|
+
exception = assert_raise(ArgumentError) {StateMachine::TransitionCollection.new([], :invalid => true)}
|
6
|
+
assert_equal 'Invalid key(s): invalid', exception.message
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_should_raise_exception_if_multiple_transitions_for_same_attribute_specified
|
10
|
+
@klass = Class.new
|
11
|
+
|
12
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
13
|
+
@machine.state :parked, :idling
|
14
|
+
@machine.event :ignite
|
15
|
+
|
16
|
+
@object = @klass.new
|
17
|
+
|
18
|
+
exception = assert_raise(ArgumentError) do
|
19
|
+
StateMachine::TransitionCollection.new([
|
20
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
|
21
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
22
|
+
])
|
23
|
+
end
|
24
|
+
assert_equal 'Cannot perform multiple transitions in parallel for the same state machine attribute', exception.message
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class TransitionCollectionByDefaultTest < Test::Unit::TestCase
|
29
|
+
def setup
|
30
|
+
@transitions = StateMachine::TransitionCollection.new
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_should_not_skip_actions
|
34
|
+
assert !@transitions.skip_actions
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_should_not_skip_after
|
38
|
+
assert !@transitions.skip_after
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_should_use_transaction
|
42
|
+
assert @transitions.use_transaction
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_should_be_empty
|
46
|
+
assert @transitions.empty?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class TransitionCollectionEmptyWithoutBlockTest < Test::Unit::TestCase
|
51
|
+
def setup
|
52
|
+
@transitions = StateMachine::TransitionCollection.new
|
53
|
+
@result = @transitions.perform
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_should_succeed
|
57
|
+
assert_equal true, @result
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
class TransitionCollectionEmptyWithBlockTest < Test::Unit::TestCase
|
63
|
+
def setup
|
64
|
+
@transitions = StateMachine::TransitionCollection.new
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_should_raise_exception_if_perform_raises_exception
|
68
|
+
assert_raise(ArgumentError) { @transitions.perform { raise ArgumentError } }
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_should_use_block_result_if_non_boolean
|
72
|
+
assert_equal 1, @transitions.perform { 1 }
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_should_use_block_result_if_false
|
76
|
+
assert_equal false, @transitions.perform { false }
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_should_use_block_reslut_if_nil
|
80
|
+
assert_equal nil, @transitions.perform { nil }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class TransitionCollectionInvalidTest < Test::Unit::TestCase
|
85
|
+
def setup
|
86
|
+
@transitions = StateMachine::TransitionCollection.new([false])
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_should_be_empty
|
90
|
+
assert @transitions.empty?
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_should_not_succeed
|
94
|
+
assert_equal false, @transitions.perform
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_should_not_run_perform_block
|
98
|
+
ran_block = false
|
99
|
+
@transitions.perform { ran_block = true }
|
100
|
+
assert !ran_block
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class TransitionCollectionPartialInvalidTest < Test::Unit::TestCase
|
105
|
+
def setup
|
106
|
+
@klass = Class.new do
|
107
|
+
attr_accessor :ran_transaction
|
108
|
+
end
|
109
|
+
|
110
|
+
@callbacks = []
|
111
|
+
|
112
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
113
|
+
@machine.state :idling
|
114
|
+
@machine.event :ignite
|
115
|
+
@machine.before_transition {@callbacks << :before}
|
116
|
+
@machine.after_transition {@callbacks << :after}
|
117
|
+
@machine.around_transition {|block| @callbacks << :around_before; block.call; @callbacks << :around_after}
|
118
|
+
|
119
|
+
class << @machine
|
120
|
+
def within_transaction(object)
|
121
|
+
object.ran_transaction = true
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
@object = @klass.new
|
126
|
+
|
127
|
+
@transitions = StateMachine::TransitionCollection.new([
|
128
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
|
129
|
+
false
|
130
|
+
])
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_should_not_store_invalid_values
|
134
|
+
assert_equal 1, @transitions.length
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_should_not_succeed
|
138
|
+
assert_equal false, @transitions.perform
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_should_not_start_transaction
|
142
|
+
assert !@object.ran_transaction
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_should_not_run_perform_block
|
146
|
+
ran_block = false
|
147
|
+
@transitions.perform { ran_block = true }
|
148
|
+
assert !ran_block
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_should_not_run_before_callbacks
|
152
|
+
assert !@callbacks.include?(:before)
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_should_not_persist_states
|
156
|
+
assert_equal 'parked', @object.state
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_should_not_run_after_callbacks
|
160
|
+
assert !@callbacks.include?(:after)
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_should_not_run_around_callbacks_before_yield
|
164
|
+
assert !@callbacks.include?(:around_before)
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_should_not_run_around_callbacks_after_yield
|
168
|
+
assert !@callbacks.include?(:around_after)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
class TransitionCollectionValidTest < Test::Unit::TestCase
|
173
|
+
def setup
|
174
|
+
@klass = Class.new do
|
175
|
+
attr_reader :persisted
|
176
|
+
|
177
|
+
def initialize
|
178
|
+
@persisted = nil
|
179
|
+
super
|
180
|
+
@persisted = []
|
181
|
+
end
|
182
|
+
|
183
|
+
def state=(value)
|
184
|
+
@persisted << 'state' if @persisted
|
185
|
+
@state = value
|
186
|
+
end
|
187
|
+
|
188
|
+
def status=(value)
|
189
|
+
@persisted << 'status' if @persisted
|
190
|
+
@status = value
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked)
|
195
|
+
@state.state :idling
|
196
|
+
@state.event :ignite
|
197
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear)
|
198
|
+
@status.state :second_gear
|
199
|
+
@status.event :shift_up
|
200
|
+
|
201
|
+
@object = @klass.new
|
202
|
+
|
203
|
+
@result = StateMachine::TransitionCollection.new([
|
204
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
205
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
206
|
+
]).perform
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_should_succeed
|
210
|
+
assert_equal true, @result
|
211
|
+
end
|
212
|
+
|
213
|
+
def test_should_persist_each_state
|
214
|
+
assert_equal 'idling', @object.state
|
215
|
+
assert_equal 'second_gear', @object.status
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_should_persist_in_order
|
219
|
+
assert_equal ['state', 'status'], @object.persisted
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_should_store_results_in_transitions
|
223
|
+
assert_nil @state_transition.result
|
224
|
+
assert_nil @status_transition.result
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
class TransitionCollectionWithoutTransactionsTest < Test::Unit::TestCase
|
229
|
+
def setup
|
230
|
+
@klass = Class.new do
|
231
|
+
attr_accessor :ran_transaction
|
232
|
+
end
|
233
|
+
|
234
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
235
|
+
@machine.state :idling
|
236
|
+
@machine.event :ignite
|
237
|
+
|
238
|
+
class << @machine
|
239
|
+
def within_transaction(object)
|
240
|
+
object.ran_transaction = true
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
@object = @klass.new
|
245
|
+
@transitions = StateMachine::TransitionCollection.new([
|
246
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
247
|
+
], :transaction => false)
|
248
|
+
@transitions.perform
|
249
|
+
end
|
250
|
+
|
251
|
+
def test_should_not_run_within_transaction
|
252
|
+
assert !@object.ran_transaction
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
class TransitionCollectionWithTransactionsTest < Test::Unit::TestCase
|
257
|
+
def setup
|
258
|
+
@klass = Class.new do
|
259
|
+
attr_accessor :running_transaction, :cancelled_transaction
|
260
|
+
end
|
261
|
+
|
262
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
263
|
+
@machine.state :idling
|
264
|
+
@machine.event :ignite
|
265
|
+
|
266
|
+
class << @machine
|
267
|
+
def within_transaction(object)
|
268
|
+
object.running_transaction = true
|
269
|
+
object.cancelled_transaction = yield == false
|
270
|
+
object.running_transaction = false
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
@object = @klass.new
|
275
|
+
@transitions = StateMachine::TransitionCollection.new([
|
276
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
277
|
+
], :transaction => true)
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_should_run_before_callbacks_within_transaction
|
281
|
+
@machine.before_transition {|object| @in_transaction = object.running_transaction}
|
282
|
+
@transitions.perform
|
283
|
+
|
284
|
+
assert @in_transaction
|
285
|
+
end
|
286
|
+
|
287
|
+
def test_should_run_action_within_transaction
|
288
|
+
@transitions.perform { @in_transaction = @object.running_transaction }
|
289
|
+
|
290
|
+
assert @in_transaction
|
291
|
+
end
|
292
|
+
|
293
|
+
def test_should_run_after_callbacks_within_transaction
|
294
|
+
@machine.after_transition {|object| @in_transaction = object.running_transaction}
|
295
|
+
@transitions.perform
|
296
|
+
|
297
|
+
assert @in_transaction
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_should_cancel_the_transaction_on_before_halt
|
301
|
+
@machine.before_transition {throw :halt}
|
302
|
+
|
303
|
+
@transitions.perform
|
304
|
+
assert @object.cancelled_transaction
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_should_cancel_the_transaction_on_action_failure
|
308
|
+
@transitions.perform { false }
|
309
|
+
assert @object.cancelled_transaction
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_should_not_cancel_the_transaction_on_after_halt
|
313
|
+
@machine.after_transition {throw :halt}
|
314
|
+
|
315
|
+
@transitions.perform
|
316
|
+
assert !@object.cancelled_transaction
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
class TransitionCollectionWithEmptyActionsTest < Test::Unit::TestCase
|
321
|
+
def setup
|
322
|
+
@klass = Class.new
|
323
|
+
|
324
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked)
|
325
|
+
@state.state :idling
|
326
|
+
@state.event :ignite
|
327
|
+
|
328
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear)
|
329
|
+
@status.state :second_gear
|
330
|
+
@status.event :shift_up
|
331
|
+
|
332
|
+
@object = @klass.new
|
333
|
+
|
334
|
+
@transitions = StateMachine::TransitionCollection.new([
|
335
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
336
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
337
|
+
])
|
338
|
+
|
339
|
+
@object.state = 'idling'
|
340
|
+
@object.status = 'second_gear'
|
341
|
+
|
342
|
+
@result = @transitions.perform
|
343
|
+
end
|
344
|
+
|
345
|
+
def test_should_succeed
|
346
|
+
assert_equal true, @result
|
347
|
+
end
|
348
|
+
|
349
|
+
def test_should_persist_states
|
350
|
+
assert_equal 'idling', @object.state
|
351
|
+
assert_equal 'second_gear', @object.status
|
352
|
+
end
|
353
|
+
|
354
|
+
def test_should_store_results_in_transitions
|
355
|
+
assert_nil @state_transition.result
|
356
|
+
assert_nil @status_transition.result
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
class TransitionCollectionWithSkippedActionsTest < Test::Unit::TestCase
|
361
|
+
def setup
|
362
|
+
@klass = Class.new do
|
363
|
+
attr_reader :actions
|
364
|
+
|
365
|
+
def save_state
|
366
|
+
(@actions ||= []) << :save_state
|
367
|
+
:save_state
|
368
|
+
end
|
369
|
+
|
370
|
+
def save_status
|
371
|
+
(@actions ||= []) << :save_status
|
372
|
+
:save_status
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
@callbacks = []
|
377
|
+
|
378
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save_state)
|
379
|
+
@state.state :idling
|
380
|
+
@state.event :ignite
|
381
|
+
@state.before_transition {@callbacks << :state_before}
|
382
|
+
@state.after_transition {@callbacks << :state_after}
|
383
|
+
@state.around_transition {|block| @callbacks << :state_around_before; block.call; @callbacks << :state_around_after}
|
384
|
+
|
385
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save_status)
|
386
|
+
@status.state :second_gear
|
387
|
+
@status.event :shift_up
|
388
|
+
@status.before_transition {@callbacks << :status_before}
|
389
|
+
@status.after_transition {@callbacks << :status_after}
|
390
|
+
@status.around_transition {|block| @callbacks << :status_around_before; block.call; @callbacks << :status_around_after}
|
391
|
+
|
392
|
+
@object = @klass.new
|
393
|
+
|
394
|
+
@transitions = StateMachine::TransitionCollection.new([
|
395
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
396
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
397
|
+
], :actions => false)
|
398
|
+
@result = @transitions.perform
|
399
|
+
end
|
400
|
+
|
401
|
+
def test_should_skip_actions
|
402
|
+
assert_equal true, @transitions.skip_actions
|
403
|
+
end
|
404
|
+
|
405
|
+
def test_should_succeed
|
406
|
+
assert_equal true, @result
|
407
|
+
end
|
408
|
+
|
409
|
+
def test_should_persist_states
|
410
|
+
assert_equal 'idling', @object.state
|
411
|
+
assert_equal 'second_gear', @object.status
|
412
|
+
end
|
413
|
+
|
414
|
+
def test_should_not_run_actions
|
415
|
+
assert_nil @object.actions
|
416
|
+
end
|
417
|
+
|
418
|
+
def test_should_store_results_in_transitions
|
419
|
+
assert_nil @state_transition.result
|
420
|
+
assert_nil @status_transition.result
|
421
|
+
end
|
422
|
+
|
423
|
+
def test_should_run_all_callbacks
|
424
|
+
assert_equal [:state_before, :state_around_before, :status_before, :status_around_before, :status_around_after, :status_after, :state_around_after, :state_after], @callbacks
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
class TransitionCollectionWithSkippedActionsAndBlockTest < Test::Unit::TestCase
|
429
|
+
def setup
|
430
|
+
@klass = Class.new
|
431
|
+
|
432
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save_state)
|
433
|
+
@machine.state :idling
|
434
|
+
@machine.event :ignite
|
435
|
+
|
436
|
+
@object = @klass.new
|
437
|
+
|
438
|
+
@transitions = StateMachine::TransitionCollection.new([
|
439
|
+
@state_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
440
|
+
], :actions => false)
|
441
|
+
@result = @transitions.perform { @ran_block = true; 1 }
|
442
|
+
end
|
443
|
+
|
444
|
+
def test_should_succeed
|
445
|
+
assert_equal 1, @result
|
446
|
+
end
|
447
|
+
|
448
|
+
def test_should_persist_states
|
449
|
+
assert_equal 'idling', @object.state
|
450
|
+
end
|
451
|
+
|
452
|
+
def test_should_run_block
|
453
|
+
assert @ran_block
|
454
|
+
end
|
455
|
+
|
456
|
+
def test_should_store_results_in_transitions
|
457
|
+
assert_equal 1, @state_transition.result
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
class TransitionCollectionWithDuplicateActionsTest < Test::Unit::TestCase
|
462
|
+
def setup
|
463
|
+
@klass = Class.new do
|
464
|
+
attr_reader :actions
|
465
|
+
|
466
|
+
def save
|
467
|
+
(@actions ||= []) << :save
|
468
|
+
:save
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
473
|
+
@state.state :idling
|
474
|
+
@state.event :ignite
|
475
|
+
|
476
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
477
|
+
@status.state :second_gear
|
478
|
+
@status.event :shift_up
|
479
|
+
|
480
|
+
@object = @klass.new
|
481
|
+
|
482
|
+
@transitions = StateMachine::TransitionCollection.new([
|
483
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
484
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
485
|
+
])
|
486
|
+
@result = @transitions.perform
|
487
|
+
end
|
488
|
+
|
489
|
+
def test_should_succeed
|
490
|
+
assert_equal :save, @result
|
491
|
+
end
|
492
|
+
|
493
|
+
def test_should_persist_states
|
494
|
+
assert_equal 'idling', @object.state
|
495
|
+
assert_equal 'second_gear', @object.status
|
496
|
+
end
|
497
|
+
|
498
|
+
def test_should_run_action_once
|
499
|
+
assert_equal [:save], @object.actions
|
500
|
+
end
|
501
|
+
|
502
|
+
def test_should_store_results_in_transitions
|
503
|
+
assert_equal :save, @state_transition.result
|
504
|
+
assert_equal :save, @status_transition.result
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
class TransitionCollectionWithDifferentActionsTest < Test::Unit::TestCase
|
509
|
+
def setup
|
510
|
+
@klass = Class.new do
|
511
|
+
attr_reader :actions
|
512
|
+
|
513
|
+
def save_state
|
514
|
+
(@actions ||= []) << :save_state
|
515
|
+
:save_state
|
516
|
+
end
|
517
|
+
|
518
|
+
def save_status
|
519
|
+
(@actions ||= []) << :save_status
|
520
|
+
:save_status
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save_state)
|
525
|
+
@state.state :idling
|
526
|
+
@state.event :ignite
|
527
|
+
|
528
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save_status)
|
529
|
+
@status.state :second_gear
|
530
|
+
@status.event :shift_up
|
531
|
+
|
532
|
+
@object = @klass.new
|
533
|
+
|
534
|
+
@transitions = StateMachine::TransitionCollection.new([
|
535
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
536
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
537
|
+
])
|
538
|
+
end
|
539
|
+
|
540
|
+
def test_should_succeed
|
541
|
+
assert_equal true, @transitions.perform
|
542
|
+
end
|
543
|
+
|
544
|
+
def test_should_persist_states
|
545
|
+
@transitions.perform
|
546
|
+
assert_equal 'idling', @object.state
|
547
|
+
assert_equal 'second_gear', @object.status
|
548
|
+
end
|
549
|
+
|
550
|
+
def test_should_run_actions_in_order
|
551
|
+
@transitions.perform
|
552
|
+
assert_equal [:save_state, :save_status], @object.actions
|
553
|
+
end
|
554
|
+
|
555
|
+
def test_should_store_results_in_transitions
|
556
|
+
@transitions.perform
|
557
|
+
assert_equal :save_state, @state_transition.result
|
558
|
+
assert_equal :save_status, @status_transition.result
|
559
|
+
end
|
560
|
+
|
561
|
+
def test_should_not_halt_if_action_fails_for_first_transition
|
562
|
+
@klass.class_eval do
|
563
|
+
remove_method :save_state
|
564
|
+
def save_state
|
565
|
+
(@actions ||= []) << :save_state
|
566
|
+
false
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
570
|
+
|
571
|
+
assert_equal false, @transitions.perform
|
572
|
+
assert_equal [:save_state, :save_status], @object.actions
|
573
|
+
end
|
574
|
+
|
575
|
+
def test_should_halt_if_action_fails_for_second_transition
|
576
|
+
@klass.class_eval do
|
577
|
+
remove_method :save_status
|
578
|
+
def save_status
|
579
|
+
(@actions ||= []) << :save_status
|
580
|
+
false
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
584
|
+
assert_equal false, @transitions.perform
|
585
|
+
assert_equal [:save_state, :save_status], @object.actions
|
586
|
+
end
|
587
|
+
|
588
|
+
def test_should_rollback_if_action_errors_for_first_transition
|
589
|
+
@klass.class_eval do
|
590
|
+
remove_method :save_state
|
591
|
+
def save_state
|
592
|
+
raise ArgumentError
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
begin; @transitions.perform; rescue; end
|
597
|
+
assert_equal 'parked', @object.state
|
598
|
+
assert_equal 'first_gear', @object.status
|
599
|
+
end
|
600
|
+
|
601
|
+
def test_should_rollback_if_action_errors_for_second_transition
|
602
|
+
@klass.class_eval do
|
603
|
+
remove_method :save_status
|
604
|
+
def save_status
|
605
|
+
raise ArgumentError
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
begin; @transitions.perform; rescue; end
|
610
|
+
assert_equal 'parked', @object.state
|
611
|
+
assert_equal 'first_gear', @object.status
|
612
|
+
end
|
613
|
+
|
614
|
+
def test_should_not_run_after_callbacks_if_action_fails_for_first_transition
|
615
|
+
@klass.class_eval do
|
616
|
+
remove_method :save_state
|
617
|
+
def save_state
|
618
|
+
false
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
@callbacks = []
|
623
|
+
@state.after_transition { @callbacks << :state_after }
|
624
|
+
@state.around_transition {|block| block.call; @callbacks << :state_around }
|
625
|
+
@status.after_transition { @callbacks << :status_after }
|
626
|
+
@status.around_transition {|block| block.call; @callbacks << :status_around }
|
627
|
+
|
628
|
+
@transitions.perform
|
629
|
+
assert_equal [], @callbacks
|
630
|
+
end
|
631
|
+
|
632
|
+
def test_should_not_run_after_callbacks_if_action_fails_for_second_transition
|
633
|
+
@klass.class_eval do
|
634
|
+
remove_method :save_status
|
635
|
+
def save_status
|
636
|
+
false
|
637
|
+
end
|
638
|
+
end
|
639
|
+
|
640
|
+
@callbacks = []
|
641
|
+
@state.after_transition { @callbacks << :state_after }
|
642
|
+
@state.around_transition {|block| block.call; @callbacks << :state_around }
|
643
|
+
@status.after_transition { @callbacks << :status_after }
|
644
|
+
@status.around_transition {|block| block.call; @callbacks << :status_around }
|
645
|
+
|
646
|
+
@transitions.perform
|
647
|
+
assert_equal [], @callbacks
|
648
|
+
end
|
649
|
+
|
650
|
+
def test_should_run_after_failure_callbacks_if_action_fails_for_first_transition
|
651
|
+
@klass.class_eval do
|
652
|
+
remove_method :save_state
|
653
|
+
def save_state
|
654
|
+
false
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
@callbacks = []
|
659
|
+
@state.after_failure { @callbacks << :state_after }
|
660
|
+
@status.after_failure { @callbacks << :status_after }
|
661
|
+
|
662
|
+
@transitions.perform
|
663
|
+
assert_equal [:status_after, :state_after], @callbacks
|
664
|
+
end
|
665
|
+
|
666
|
+
def test_should_run_after_failure_callbacks_if_action_fails_for_second_transition
|
667
|
+
@klass.class_eval do
|
668
|
+
remove_method :save_status
|
669
|
+
def save_status
|
670
|
+
false
|
671
|
+
end
|
672
|
+
end
|
673
|
+
|
674
|
+
@callbacks = []
|
675
|
+
@state.after_failure { @callbacks << :state_after }
|
676
|
+
@status.after_failure { @callbacks << :status_after }
|
677
|
+
|
678
|
+
@transitions.perform
|
679
|
+
assert_equal [:status_after, :state_after], @callbacks
|
680
|
+
end
|
681
|
+
end
|
682
|
+
|
683
|
+
class TransitionCollectionWithMixedActionsTest < Test::Unit::TestCase
|
684
|
+
def setup
|
685
|
+
@klass = Class.new do
|
686
|
+
def save
|
687
|
+
true
|
688
|
+
end
|
689
|
+
end
|
690
|
+
|
691
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
692
|
+
@state.state :idling
|
693
|
+
@state.event :ignite
|
694
|
+
|
695
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear)
|
696
|
+
@status.state :second_gear
|
697
|
+
@status.event :shift_up
|
698
|
+
|
699
|
+
@object = @klass.new
|
700
|
+
|
701
|
+
@transitions = StateMachine::TransitionCollection.new([
|
702
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
703
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
704
|
+
])
|
705
|
+
@result = @transitions.perform
|
706
|
+
end
|
707
|
+
|
708
|
+
def test_should_succeed
|
709
|
+
assert_equal true, @result
|
710
|
+
end
|
711
|
+
|
712
|
+
def test_should_persist_states
|
713
|
+
assert_equal 'idling', @object.state
|
714
|
+
assert_equal 'second_gear', @object.status
|
715
|
+
end
|
716
|
+
|
717
|
+
def test_should_store_results_in_transitions
|
718
|
+
assert_equal true, @state_transition.result
|
719
|
+
assert_nil @status_transition.result
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
723
|
+
class TransitionCollectionWithBlockTest < Test::Unit::TestCase
|
724
|
+
def setup
|
725
|
+
@klass = Class.new do
|
726
|
+
attr_reader :actions
|
727
|
+
|
728
|
+
def save
|
729
|
+
(@actions ||= []) << :save
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
@state = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
734
|
+
@state.state :idling
|
735
|
+
@state.event :ignite
|
736
|
+
|
737
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
738
|
+
@status.state :second_gear
|
739
|
+
@status.event :shift_up
|
740
|
+
|
741
|
+
@object = @klass.new
|
742
|
+
@transitions = StateMachine::TransitionCollection.new([
|
743
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
744
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
745
|
+
])
|
746
|
+
@result = @transitions.perform { 1 }
|
747
|
+
end
|
748
|
+
|
749
|
+
def test_should_succeed
|
750
|
+
assert_equal 1, @result
|
751
|
+
end
|
752
|
+
|
753
|
+
def test_should_persist_states
|
754
|
+
assert_equal 'idling', @object.state
|
755
|
+
assert_equal 'second_gear', @object.status
|
756
|
+
end
|
757
|
+
|
758
|
+
def test_should_not_run_machine_actions
|
759
|
+
assert_nil @object.actions
|
760
|
+
end
|
761
|
+
|
762
|
+
def test_should_use_result_as_transition_result
|
763
|
+
assert_equal 1, @state_transition.result
|
764
|
+
assert_equal 1, @status_transition.result
|
765
|
+
end
|
766
|
+
end
|
767
|
+
|
768
|
+
class TransitionCollectionWithActionFailedTest < Test::Unit::TestCase
|
769
|
+
def setup
|
770
|
+
@klass = Class.new do
|
771
|
+
def save
|
772
|
+
false
|
773
|
+
end
|
774
|
+
end
|
775
|
+
@before_count = 0
|
776
|
+
@around_before_count = 0
|
777
|
+
@after_count = 0
|
778
|
+
@around_after_count = 0
|
779
|
+
@failure_count = 0
|
780
|
+
|
781
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
782
|
+
@machine.state :idling
|
783
|
+
@machine.event :ignite
|
784
|
+
|
785
|
+
@machine.before_transition {@before_count += 1}
|
786
|
+
@machine.after_transition {@after_count += 1}
|
787
|
+
@machine.around_transition {|block| @around_before_count += 1; block.call; @around_after_count += 1}
|
788
|
+
@machine.after_failure {@failure_count += 1}
|
789
|
+
|
790
|
+
@object = @klass.new
|
791
|
+
|
792
|
+
@transitions = StateMachine::TransitionCollection.new([
|
793
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
794
|
+
])
|
795
|
+
@result = @transitions.perform
|
796
|
+
end
|
797
|
+
|
798
|
+
def test_should_not_succeed
|
799
|
+
assert_equal false, @result
|
800
|
+
end
|
801
|
+
|
802
|
+
def test_should_not_persist_state
|
803
|
+
assert_equal 'parked', @object.state
|
804
|
+
end
|
805
|
+
|
806
|
+
def test_should_run_before_callbacks
|
807
|
+
assert_equal 1, @before_count
|
808
|
+
end
|
809
|
+
|
810
|
+
def test_should_run_around_callbacks_before_yield
|
811
|
+
assert_equal 1, @around_before_count
|
812
|
+
end
|
813
|
+
|
814
|
+
def test_should_not_run_after_callbacks
|
815
|
+
assert_equal 0, @after_count
|
816
|
+
end
|
817
|
+
|
818
|
+
def test_should_not_run_around_callbacks
|
819
|
+
assert_equal 0, @around_after_count
|
820
|
+
end
|
821
|
+
|
822
|
+
def test_should_run_failure_callbacks
|
823
|
+
assert_equal 1, @failure_count
|
824
|
+
end
|
825
|
+
end
|
826
|
+
|
827
|
+
class TransitionCollectionWithActionErrorTest < Test::Unit::TestCase
|
828
|
+
def setup
|
829
|
+
@klass = Class.new do
|
830
|
+
def save
|
831
|
+
raise ArgumentError
|
832
|
+
end
|
833
|
+
end
|
834
|
+
@before_count = 0
|
835
|
+
@around_before_count = 0
|
836
|
+
@after_count = 0
|
837
|
+
@around_after_count = 0
|
838
|
+
@failure_count = 0
|
839
|
+
|
840
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
841
|
+
@machine.state :idling
|
842
|
+
@machine.event :ignite
|
843
|
+
|
844
|
+
@machine.before_transition {@before_count += 1}
|
845
|
+
@machine.after_transition {@after_count += 1}
|
846
|
+
@machine.around_transition {|block| @around_before_count += 1; block.call; @around_after_count += 1}
|
847
|
+
@machine.after_failure {@failure_count += 1}
|
848
|
+
|
849
|
+
@object = @klass.new
|
850
|
+
|
851
|
+
@transitions = StateMachine::TransitionCollection.new([
|
852
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
853
|
+
])
|
854
|
+
|
855
|
+
@raised = true
|
856
|
+
begin
|
857
|
+
@transitions.perform
|
858
|
+
@raised = false
|
859
|
+
rescue ArgumentError
|
860
|
+
end
|
861
|
+
end
|
862
|
+
|
863
|
+
def test_should_not_catch_exception
|
864
|
+
assert @raised
|
865
|
+
end
|
866
|
+
|
867
|
+
def test_should_not_persist_state
|
868
|
+
assert_equal 'parked', @object.state
|
869
|
+
end
|
870
|
+
|
871
|
+
def test_should_run_before_callbacks
|
872
|
+
assert_equal 1, @before_count
|
873
|
+
end
|
874
|
+
|
875
|
+
def test_should_run_around_callbacks_before_yield
|
876
|
+
assert_equal 1, @around_before_count
|
877
|
+
end
|
878
|
+
|
879
|
+
def test_should_not_run_after_callbacks
|
880
|
+
assert_equal 0, @after_count
|
881
|
+
end
|
882
|
+
|
883
|
+
def test_should_not_run_around_callbacks_after_yield
|
884
|
+
assert_equal 0, @around_after_count
|
885
|
+
end
|
886
|
+
|
887
|
+
def test_should_not_run_failure_callbacks
|
888
|
+
assert_equal 0, @failure_count
|
889
|
+
end
|
890
|
+
end
|
891
|
+
|
892
|
+
class TransitionCollectionWithCallbacksTest < Test::Unit::TestCase
|
893
|
+
def setup
|
894
|
+
@klass = Class.new do
|
895
|
+
attr_reader :saved
|
896
|
+
|
897
|
+
def save
|
898
|
+
@saved = true
|
899
|
+
end
|
900
|
+
end
|
901
|
+
|
902
|
+
@before_callbacks = []
|
903
|
+
@after_callbacks = []
|
904
|
+
|
905
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
906
|
+
@state.state :idling
|
907
|
+
@state.event :ignite
|
908
|
+
@state.before_transition {@before_callbacks << :state_before}
|
909
|
+
@state.after_transition {@after_callbacks << :state_after}
|
910
|
+
@state.around_transition {|block| @before_callbacks << :state_around; block.call; @after_callbacks << :state_around}
|
911
|
+
|
912
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
913
|
+
@status.state :second_gear
|
914
|
+
@status.event :shift_up
|
915
|
+
@status.before_transition {@before_callbacks << :status_before}
|
916
|
+
@status.after_transition {@after_callbacks << :status_after}
|
917
|
+
@status.around_transition {|block| @before_callbacks << :status_around; block.call; @after_callbacks << :status_around}
|
918
|
+
|
919
|
+
@object = @klass.new
|
920
|
+
@transitions = StateMachine::TransitionCollection.new([
|
921
|
+
StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
922
|
+
StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
923
|
+
])
|
924
|
+
end
|
925
|
+
|
926
|
+
def test_should_run_before_callbacks_in_order
|
927
|
+
@transitions.perform
|
928
|
+
assert_equal [:state_before, :state_around, :status_before, :status_around], @before_callbacks
|
929
|
+
end
|
930
|
+
|
931
|
+
def test_should_halt_if_before_callback_halted_for_first_transition
|
932
|
+
@state.before_transition {throw :halt}
|
933
|
+
|
934
|
+
assert_equal false, @transitions.perform
|
935
|
+
assert_equal [:state_before, :state_around], @before_callbacks
|
936
|
+
end
|
937
|
+
|
938
|
+
def test_should_halt_if_before_callback_halted_for_second_transition
|
939
|
+
@status.before_transition {throw :halt}
|
940
|
+
|
941
|
+
assert_equal false, @transitions.perform
|
942
|
+
assert_equal [:state_before, :state_around, :status_before, :status_around], @before_callbacks
|
943
|
+
end
|
944
|
+
|
945
|
+
def test_should_halt_if_around_callback_halted_before_yield_for_first_transition
|
946
|
+
@state.around_transition {throw :halt}
|
947
|
+
|
948
|
+
assert_equal false, @transitions.perform
|
949
|
+
assert_equal [:state_before, :state_around], @before_callbacks
|
950
|
+
end
|
951
|
+
|
952
|
+
def test_should_halt_if_around_callback_halted_before_yield_for_second_transition
|
953
|
+
@status.around_transition {throw :halt}
|
954
|
+
|
955
|
+
assert_equal false, @transitions.perform
|
956
|
+
assert_equal [:state_before, :state_around, :status_before, :status_around], @before_callbacks
|
957
|
+
end
|
958
|
+
|
959
|
+
def test_should_run_after_callbacks_in_reverse_order
|
960
|
+
@transitions.perform
|
961
|
+
assert_equal [:status_around, :status_after, :state_around, :state_after], @after_callbacks
|
962
|
+
end
|
963
|
+
|
964
|
+
def test_should_not_halt_if_after_callback_halted_for_first_transition
|
965
|
+
@state.after_transition {throw :halt}
|
966
|
+
|
967
|
+
assert_equal true, @transitions.perform
|
968
|
+
assert_equal [:status_around, :status_after, :state_around, :state_after], @after_callbacks
|
969
|
+
end
|
970
|
+
|
971
|
+
def test_should_not_halt_if_around_callback_halted_for_second_transition
|
972
|
+
@status.around_transition {|block| block.call; throw :halt}
|
973
|
+
|
974
|
+
assert_equal true, @transitions.perform
|
975
|
+
assert_equal [:state_around, :state_after], @after_callbacks
|
976
|
+
end
|
977
|
+
|
978
|
+
def test_should_run_before_callbacks_before_persisting_the_state
|
979
|
+
@state.before_transition {|object| @before_state = object.state}
|
980
|
+
@state.around_transition {|object, transition, block| @around_state = object.state; block.call}
|
981
|
+
@transitions.perform
|
982
|
+
|
983
|
+
assert_equal 'parked', @before_state
|
984
|
+
assert_equal 'parked', @around_state
|
985
|
+
end
|
986
|
+
|
987
|
+
def test_should_persist_state_before_running_action
|
988
|
+
@klass.class_eval do
|
989
|
+
attr_reader :saved_on_persist
|
990
|
+
|
991
|
+
def state=(value)
|
992
|
+
@state = value
|
993
|
+
@saved_on_persist = saved
|
994
|
+
end
|
995
|
+
end
|
996
|
+
|
997
|
+
@transitions.perform
|
998
|
+
assert !@object.saved_on_persist
|
999
|
+
end
|
1000
|
+
|
1001
|
+
def test_should_persist_state_before_running_action_block
|
1002
|
+
@klass.class_eval do
|
1003
|
+
attr_writer :saved
|
1004
|
+
attr_reader :saved_on_persist
|
1005
|
+
|
1006
|
+
def state=(value)
|
1007
|
+
@state = value
|
1008
|
+
@saved_on_persist = saved
|
1009
|
+
end
|
1010
|
+
end
|
1011
|
+
|
1012
|
+
@transitions.perform { @object.saved = true }
|
1013
|
+
assert !@object.saved_on_persist
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
def test_should_run_after_callbacks_after_running_the_action
|
1017
|
+
@state.after_transition {|object| @after_saved = object.saved}
|
1018
|
+
@state.around_transition {|object, transition, block| block.call; @around_saved = object.saved}
|
1019
|
+
@transitions.perform
|
1020
|
+
|
1021
|
+
assert @after_saved
|
1022
|
+
assert @around_saved
|
1023
|
+
end
|
1024
|
+
end
|
1025
|
+
|
1026
|
+
class TransitionCollectionWithBeforeCallbackHaltTest < Test::Unit::TestCase
|
1027
|
+
def setup
|
1028
|
+
@klass = Class.new do
|
1029
|
+
attr_reader :saved
|
1030
|
+
|
1031
|
+
def save
|
1032
|
+
@saved = true
|
1033
|
+
end
|
1034
|
+
end
|
1035
|
+
@before_count = 0
|
1036
|
+
@after_count = 0
|
1037
|
+
|
1038
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1039
|
+
@machine.state :idling
|
1040
|
+
@machine.event :ignite
|
1041
|
+
|
1042
|
+
@machine.before_transition {@before_count += 1; throw :halt}
|
1043
|
+
@machine.before_transition {@before_count += 1}
|
1044
|
+
@machine.after_transition {@after_count += 1}
|
1045
|
+
@machine.around_transition {|block| @before_count += 1; block.call; @after_count += 1}
|
1046
|
+
|
1047
|
+
@object = @klass.new
|
1048
|
+
|
1049
|
+
@transitions = StateMachine::TransitionCollection.new([
|
1050
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1051
|
+
])
|
1052
|
+
@result = @transitions.perform
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
def test_should_not_succeed
|
1056
|
+
assert_equal false, @result
|
1057
|
+
end
|
1058
|
+
|
1059
|
+
def test_should_not_persist_state
|
1060
|
+
assert_equal 'parked', @object.state
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
def test_should_not_run_action
|
1064
|
+
assert !@object.saved
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
def test_should_not_run_further_before_callbacks
|
1068
|
+
assert_equal 1, @before_count
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
def test_should_not_run_after_callbacks
|
1072
|
+
assert_equal 0, @after_count
|
1073
|
+
end
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
class TransitionCollectionWithAfterCallbackHaltTest < Test::Unit::TestCase
|
1077
|
+
def setup
|
1078
|
+
@klass = Class.new do
|
1079
|
+
attr_reader :saved
|
1080
|
+
|
1081
|
+
def save
|
1082
|
+
@saved = true
|
1083
|
+
end
|
1084
|
+
end
|
1085
|
+
@before_count = 0
|
1086
|
+
@after_count = 0
|
1087
|
+
|
1088
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1089
|
+
@machine.state :idling
|
1090
|
+
@machine.event :ignite
|
1091
|
+
|
1092
|
+
@machine.before_transition {@before_count += 1}
|
1093
|
+
@machine.after_transition {@after_count += 1; throw :halt}
|
1094
|
+
@machine.after_transition {@after_count += 1}
|
1095
|
+
@machine.around_transition {|block| @before_count += 1; block.call; @after_count += 1}
|
1096
|
+
|
1097
|
+
@object = @klass.new
|
1098
|
+
|
1099
|
+
@transitions = StateMachine::TransitionCollection.new([
|
1100
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1101
|
+
])
|
1102
|
+
@result = @transitions.perform
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
def test_should_succeed
|
1106
|
+
assert_equal true, @result
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
def test_should_persist_state
|
1110
|
+
assert_equal 'idling', @object.state
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
def test_should_run_before_callbacks
|
1114
|
+
assert_equal 2, @before_count
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
def test_should_not_run_further_after_callbacks
|
1118
|
+
assert_equal 2, @after_count
|
1119
|
+
end
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
class TransitionCollectionWithSkippedAfterCallbacksTest < Test::Unit::TestCase
|
1123
|
+
def setup
|
1124
|
+
@klass = Class.new
|
1125
|
+
|
1126
|
+
@callbacks = []
|
1127
|
+
|
1128
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
1129
|
+
@machine.state :idling
|
1130
|
+
@machine.event :ignite
|
1131
|
+
@machine.after_transition {@callbacks << :after}
|
1132
|
+
|
1133
|
+
@object = @klass.new
|
1134
|
+
|
1135
|
+
@transitions = StateMachine::TransitionCollection.new([
|
1136
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1137
|
+
], :after => false)
|
1138
|
+
@result = @transitions.perform
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
def test_should_succeed
|
1142
|
+
assert_equal true, @result
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
def test_should_not_run_after_callbacks
|
1146
|
+
assert !@callbacks.include?(:after)
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
def test_should_run_after_callbacks_on_subsequent_perform
|
1150
|
+
StateMachine::TransitionCollection.new([@transition]).perform
|
1151
|
+
assert @callbacks.include?(:after)
|
1152
|
+
end
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
if StateMachine::Transition.pause_supported?
|
1156
|
+
class TransitionCollectionWithSkippedAfterCallbacksAndAroundCallbacksTest < Test::Unit::TestCase
|
1157
|
+
def setup
|
1158
|
+
@klass = Class.new
|
1159
|
+
|
1160
|
+
@callbacks = []
|
1161
|
+
|
1162
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
1163
|
+
@machine.state :idling
|
1164
|
+
@machine.event :ignite
|
1165
|
+
@machine.around_transition {|block| @callbacks << :around_before; block.call; @callbacks << :around_after}
|
1166
|
+
|
1167
|
+
@object = @klass.new
|
1168
|
+
|
1169
|
+
@transitions = StateMachine::TransitionCollection.new([
|
1170
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1171
|
+
], :after => false)
|
1172
|
+
@result = @transitions.perform
|
1173
|
+
end
|
1174
|
+
|
1175
|
+
def test_should_succeed
|
1176
|
+
assert_equal true, @result
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
def test_should_not_run_around_callbacks_after_yield
|
1180
|
+
assert !@callbacks.include?(:around_after)
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
def test_should_run_around_callbacks_after_yield_on_subsequent_perform
|
1184
|
+
StateMachine::TransitionCollection.new([@transition]).perform
|
1185
|
+
assert @callbacks.include?(:around_after)
|
1186
|
+
end
|
1187
|
+
|
1188
|
+
def test_should_not_rerun_around_callbacks_before_yield_on_subsequent_perform
|
1189
|
+
@callbacks = []
|
1190
|
+
StateMachine::TransitionCollection.new([@transition]).perform
|
1191
|
+
|
1192
|
+
assert !@callbacks.include?(:around_before)
|
1193
|
+
end
|
1194
|
+
end
|
1195
|
+
else
|
1196
|
+
class TransitionCollectionWithSkippedAfterCallbacksAndAroundCallbacksTest < Test::Unit::TestCase
|
1197
|
+
def setup
|
1198
|
+
@klass = Class.new
|
1199
|
+
|
1200
|
+
@callbacks = []
|
1201
|
+
|
1202
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
1203
|
+
@machine.state :idling
|
1204
|
+
@machine.event :ignite
|
1205
|
+
@machine.around_transition {|block| @callbacks << :around_before; block.call; @callbacks << :around_after}
|
1206
|
+
|
1207
|
+
@object = @klass.new
|
1208
|
+
|
1209
|
+
@transitions = StateMachine::TransitionCollection.new([
|
1210
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1211
|
+
], :after => false)
|
1212
|
+
end
|
1213
|
+
|
1214
|
+
def test_should_raise_exception
|
1215
|
+
assert_raise(ArgumentError) { @transitions.perform }
|
1216
|
+
end
|
1217
|
+
end
|
1218
|
+
end
|
1219
|
+
|
1220
|
+
class TransitionCollectionWithActionHookBaseTest < Test::Unit::TestCase
|
1221
|
+
def setup
|
1222
|
+
@superclass = Class.new do
|
1223
|
+
def save
|
1224
|
+
true
|
1225
|
+
end
|
1226
|
+
end
|
1227
|
+
|
1228
|
+
@klass = Class.new(@superclass) do
|
1229
|
+
attr_reader :saved, :state_on_save, :state_event_on_save, :state_event_transition_on_save
|
1230
|
+
|
1231
|
+
def save
|
1232
|
+
@saved = true
|
1233
|
+
@state_on_save = state
|
1234
|
+
@state_event_on_save = state_event
|
1235
|
+
@state_event_transition_on_save = state_event_transition
|
1236
|
+
super
|
1237
|
+
end
|
1238
|
+
end
|
1239
|
+
|
1240
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1241
|
+
@machine.state :idling
|
1242
|
+
@machine.event :ignite
|
1243
|
+
|
1244
|
+
@object = @klass.new
|
1245
|
+
|
1246
|
+
@transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1247
|
+
end
|
1248
|
+
|
1249
|
+
def default_test
|
1250
|
+
end
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
class TransitionCollectionWithActionHookAndSkippedActionTest < TransitionCollectionWithActionHookBaseTest
|
1254
|
+
def setup
|
1255
|
+
super
|
1256
|
+
@result = StateMachine::TransitionCollection.new([@transition], :actions => false).perform
|
1257
|
+
end
|
1258
|
+
|
1259
|
+
def test_should_succeed
|
1260
|
+
assert_equal true, @result
|
1261
|
+
end
|
1262
|
+
|
1263
|
+
def test_should_not_run_action
|
1264
|
+
assert !@object.saved
|
1265
|
+
end
|
1266
|
+
end
|
1267
|
+
|
1268
|
+
class TransitionCollectionWithActionHookAndSkippedAfterCallbacksTest < TransitionCollectionWithActionHookBaseTest
|
1269
|
+
def setup
|
1270
|
+
super
|
1271
|
+
@result = StateMachine::TransitionCollection.new([@transition], :after => false).perform
|
1272
|
+
end
|
1273
|
+
|
1274
|
+
def test_should_succeed
|
1275
|
+
assert_equal true, @result
|
1276
|
+
end
|
1277
|
+
|
1278
|
+
def test_should_run_action
|
1279
|
+
assert @object.saved
|
1280
|
+
end
|
1281
|
+
|
1282
|
+
def test_should_have_already_persisted_when_running_action
|
1283
|
+
assert_equal 'idling', @object.state_on_save
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
def test_should_not_have_event_during_action
|
1287
|
+
assert_nil @object.state_event_on_save
|
1288
|
+
end
|
1289
|
+
|
1290
|
+
def test_should_not_write_event
|
1291
|
+
assert_nil @object.state_event
|
1292
|
+
end
|
1293
|
+
|
1294
|
+
def test_should_not_have_event_transition_during_save
|
1295
|
+
assert_nil @object.state_event_transition_on_save
|
1296
|
+
end
|
1297
|
+
|
1298
|
+
def test_should_not_write_event_attribute
|
1299
|
+
assert_nil @object.send(:state_event_transition)
|
1300
|
+
end
|
1301
|
+
end
|
1302
|
+
|
1303
|
+
class TransitionCollectionWithActionHookAndBlockTest < TransitionCollectionWithActionHookBaseTest
|
1304
|
+
def setup
|
1305
|
+
super
|
1306
|
+
@result = StateMachine::TransitionCollection.new([@transition]).perform { true }
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
def test_should_succeed
|
1310
|
+
assert_equal true, @result
|
1311
|
+
end
|
1312
|
+
|
1313
|
+
def test_should_not_run_action
|
1314
|
+
assert !@object.saved
|
1315
|
+
end
|
1316
|
+
end
|
1317
|
+
|
1318
|
+
class TransitionCollectionWithActionHookInvalidTest < TransitionCollectionWithActionHookBaseTest
|
1319
|
+
def setup
|
1320
|
+
super
|
1321
|
+
@result = StateMachine::TransitionCollection.new([@transition, nil]).perform
|
1322
|
+
end
|
1323
|
+
|
1324
|
+
def test_should_not_succeed
|
1325
|
+
assert_equal false, @result
|
1326
|
+
end
|
1327
|
+
|
1328
|
+
def test_should_not_run_action
|
1329
|
+
assert !@object.saved
|
1330
|
+
end
|
1331
|
+
end
|
1332
|
+
|
1333
|
+
class TransitionCollectionWithActionHookWithNilActionTest < TransitionCollectionWithActionHookBaseTest
|
1334
|
+
def setup
|
1335
|
+
super
|
1336
|
+
|
1337
|
+
@machine = StateMachine::Machine.new(@klass, :status, :initial => :first_gear)
|
1338
|
+
@machine.state :second_gear
|
1339
|
+
@machine.event :shift_up
|
1340
|
+
|
1341
|
+
@result = StateMachine::TransitionCollection.new([@transition, StateMachine::Transition.new(@object, @machine, :shift_up, :first_gear, :second_gear)]).perform
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
def test_should_succeed
|
1345
|
+
assert_equal true, @result
|
1346
|
+
end
|
1347
|
+
|
1348
|
+
def test_should_run_action
|
1349
|
+
assert @object.saved
|
1350
|
+
end
|
1351
|
+
|
1352
|
+
def test_should_have_already_persisted_when_running_action
|
1353
|
+
assert_equal 'idling', @object.state_on_save
|
1354
|
+
end
|
1355
|
+
|
1356
|
+
def test_should_not_have_event_during_action
|
1357
|
+
assert_nil @object.state_event_on_save
|
1358
|
+
end
|
1359
|
+
|
1360
|
+
def test_should_not_write_event
|
1361
|
+
assert_nil @object.state_event
|
1362
|
+
end
|
1363
|
+
|
1364
|
+
def test_should_not_have_event_transition_during_save
|
1365
|
+
assert_nil @object.state_event_transition_on_save
|
1366
|
+
end
|
1367
|
+
|
1368
|
+
def test_should_not_write_event_attribute
|
1369
|
+
assert_nil @object.send(:state_event_transition)
|
1370
|
+
end
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
class TransitionCollectionWithActionHookWithDifferentActionsTest < TransitionCollectionWithActionHookBaseTest
|
1374
|
+
def setup
|
1375
|
+
super
|
1376
|
+
|
1377
|
+
@klass.class_eval do
|
1378
|
+
def save_status
|
1379
|
+
true
|
1380
|
+
end
|
1381
|
+
end
|
1382
|
+
|
1383
|
+
@machine = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save_status)
|
1384
|
+
@machine.state :second_gear
|
1385
|
+
@machine.event :shift_up
|
1386
|
+
|
1387
|
+
@result = StateMachine::TransitionCollection.new([@transition, StateMachine::Transition.new(@object, @machine, :shift_up, :first_gear, :second_gear)]).perform
|
1388
|
+
end
|
1389
|
+
|
1390
|
+
def test_should_succeed
|
1391
|
+
assert_equal true, @result
|
1392
|
+
end
|
1393
|
+
|
1394
|
+
def test_should_run_action
|
1395
|
+
assert @object.saved
|
1396
|
+
end
|
1397
|
+
|
1398
|
+
def test_should_have_already_persisted_when_running_action
|
1399
|
+
assert_equal 'idling', @object.state_on_save
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
def test_should_not_have_event_during_action
|
1403
|
+
assert_nil @object.state_event_on_save
|
1404
|
+
end
|
1405
|
+
|
1406
|
+
def test_should_not_write_event
|
1407
|
+
assert_nil @object.state_event
|
1408
|
+
end
|
1409
|
+
|
1410
|
+
def test_should_not_have_event_transition_during_save
|
1411
|
+
assert_nil @object.state_event_transition_on_save
|
1412
|
+
end
|
1413
|
+
|
1414
|
+
def test_should_not_write_event_attribute
|
1415
|
+
assert_nil @object.send(:state_event_transition)
|
1416
|
+
end
|
1417
|
+
end
|
1418
|
+
|
1419
|
+
class TransitionCollectionWithActionHookTest < TransitionCollectionWithActionHookBaseTest
|
1420
|
+
def setup
|
1421
|
+
super
|
1422
|
+
@result = StateMachine::TransitionCollection.new([@transition]).perform
|
1423
|
+
end
|
1424
|
+
|
1425
|
+
def test_should_succeed
|
1426
|
+
assert_equal true, @result
|
1427
|
+
end
|
1428
|
+
|
1429
|
+
def test_should_run_action
|
1430
|
+
assert @object.saved
|
1431
|
+
end
|
1432
|
+
|
1433
|
+
def test_should_not_have_already_persisted_when_running_action
|
1434
|
+
assert_equal 'parked', @object.state_on_save
|
1435
|
+
end
|
1436
|
+
|
1437
|
+
def test_should_persist
|
1438
|
+
assert_equal 'idling', @object.state
|
1439
|
+
end
|
1440
|
+
|
1441
|
+
def test_should_not_have_event_during_action
|
1442
|
+
assert_nil @object.state_event_on_save
|
1443
|
+
end
|
1444
|
+
|
1445
|
+
def test_should_not_write_event
|
1446
|
+
assert_nil @object.state_event
|
1447
|
+
end
|
1448
|
+
|
1449
|
+
def test_should_have_event_transition_during_action
|
1450
|
+
assert_equal @transition, @object.state_event_transition_on_save
|
1451
|
+
end
|
1452
|
+
|
1453
|
+
def test_should_not_write_event_transition
|
1454
|
+
assert_nil @object.send(:state_event_transition)
|
1455
|
+
end
|
1456
|
+
|
1457
|
+
def test_should_mark_event_transition_as_transient
|
1458
|
+
assert @transition.transient?
|
1459
|
+
end
|
1460
|
+
end
|
1461
|
+
|
1462
|
+
class TransitionCollectionWithActionHookMultipleTest < TransitionCollectionWithActionHookBaseTest
|
1463
|
+
def setup
|
1464
|
+
super
|
1465
|
+
|
1466
|
+
@status_machine = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
1467
|
+
@status_machine.state :second_gear
|
1468
|
+
@status_machine.event :shift_up
|
1469
|
+
|
1470
|
+
@klass.class_eval do
|
1471
|
+
attr_reader :status_on_save, :status_event_on_save, :status_event_transition_on_save
|
1472
|
+
|
1473
|
+
remove_method :save
|
1474
|
+
def save
|
1475
|
+
@saved = true
|
1476
|
+
@state_on_save = state
|
1477
|
+
@state_event_on_save = state_event
|
1478
|
+
@state_event_transition_on_save = state_event_transition
|
1479
|
+
@status_on_save = status
|
1480
|
+
@status_event_on_save = status_event
|
1481
|
+
@status_event_transition_on_save = status_event_transition
|
1482
|
+
super
|
1483
|
+
1
|
1484
|
+
end
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
@object = @klass.new
|
1488
|
+
@state_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1489
|
+
@status_transition = StateMachine::Transition.new(@object, @status_machine, :shift_up, :first_gear, :second_gear)
|
1490
|
+
|
1491
|
+
@result = StateMachine::TransitionCollection.new([@state_transition, @status_transition]).perform
|
1492
|
+
end
|
1493
|
+
|
1494
|
+
def test_should_succeed
|
1495
|
+
assert_equal 1, @result
|
1496
|
+
end
|
1497
|
+
|
1498
|
+
def test_should_run_action
|
1499
|
+
assert @object.saved
|
1500
|
+
end
|
1501
|
+
|
1502
|
+
def test_should_not_have_already_persisted_when_running_action
|
1503
|
+
assert_equal 'parked', @object.state_on_save
|
1504
|
+
assert_equal 'first_gear', @object.status_on_save
|
1505
|
+
end
|
1506
|
+
|
1507
|
+
def test_should_persist
|
1508
|
+
assert_equal 'idling', @object.state
|
1509
|
+
assert_equal 'second_gear', @object.status
|
1510
|
+
end
|
1511
|
+
|
1512
|
+
def test_should_not_have_events_during_action
|
1513
|
+
assert_nil @object.state_event_on_save
|
1514
|
+
assert_nil @object.status_event_on_save
|
1515
|
+
end
|
1516
|
+
|
1517
|
+
def test_should_not_write_events
|
1518
|
+
assert_nil @object.state_event
|
1519
|
+
assert_nil @object.status_event
|
1520
|
+
end
|
1521
|
+
|
1522
|
+
def test_should_have_event_transitions_during_action
|
1523
|
+
assert_equal @state_transition, @object.state_event_transition_on_save
|
1524
|
+
assert_equal @status_transition, @object.status_event_transition_on_save
|
1525
|
+
end
|
1526
|
+
|
1527
|
+
def test_should_not_write_event_transitions
|
1528
|
+
assert_nil @object.send(:state_event_transition)
|
1529
|
+
assert_nil @object.send(:status_event_transition)
|
1530
|
+
end
|
1531
|
+
|
1532
|
+
def test_should_mark_event_transitions_as_transient
|
1533
|
+
assert @state_transition.transient?
|
1534
|
+
assert @status_transition.transient?
|
1535
|
+
end
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
class TransitionCollectionWithActionHookErrorTest < TransitionCollectionWithActionHookBaseTest
|
1539
|
+
def setup
|
1540
|
+
super
|
1541
|
+
|
1542
|
+
@superclass.class_eval do
|
1543
|
+
remove_method :save
|
1544
|
+
def save
|
1545
|
+
raise ArgumentError
|
1546
|
+
end
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
begin; StateMachine::TransitionCollection.new([@transition]).perform; rescue; end
|
1550
|
+
end
|
1551
|
+
|
1552
|
+
def test_should_not_write_event
|
1553
|
+
assert_nil @object.state_event
|
1554
|
+
end
|
1555
|
+
|
1556
|
+
def test_should_not_write_event_transition
|
1557
|
+
assert_nil @object.send(:state_event_transition)
|
1558
|
+
end
|
1559
|
+
end
|
1560
|
+
|
1561
|
+
class AttributeTransitionCollectionByDefaultTest < Test::Unit::TestCase
|
1562
|
+
def setup
|
1563
|
+
@transitions = StateMachine::AttributeTransitionCollection.new
|
1564
|
+
end
|
1565
|
+
|
1566
|
+
def test_should_skip_actions
|
1567
|
+
assert @transitions.skip_actions
|
1568
|
+
end
|
1569
|
+
|
1570
|
+
def test_should_not_skip_after
|
1571
|
+
assert !@transitions.skip_after
|
1572
|
+
end
|
1573
|
+
|
1574
|
+
def test_should_not_use_transaction
|
1575
|
+
assert !@transitions.use_transaction
|
1576
|
+
end
|
1577
|
+
|
1578
|
+
def test_should_be_empty
|
1579
|
+
assert @transitions.empty?
|
1580
|
+
end
|
1581
|
+
end
|
1582
|
+
|
1583
|
+
class AttributeTransitionCollectionWithEventsTest < Test::Unit::TestCase
|
1584
|
+
def setup
|
1585
|
+
@klass = Class.new
|
1586
|
+
|
1587
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1588
|
+
@state.state :idling
|
1589
|
+
@state.event :ignite
|
1590
|
+
|
1591
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
1592
|
+
@status.state :second_gear
|
1593
|
+
@status.event :shift_up
|
1594
|
+
|
1595
|
+
@object = @klass.new
|
1596
|
+
@object.state_event = 'ignite'
|
1597
|
+
@object.status_event = 'shift_up'
|
1598
|
+
|
1599
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
1600
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
1601
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
1602
|
+
])
|
1603
|
+
@result = @transitions.perform
|
1604
|
+
end
|
1605
|
+
|
1606
|
+
def test_should_succeed
|
1607
|
+
assert_equal true, @result
|
1608
|
+
end
|
1609
|
+
|
1610
|
+
def test_should_persist_states
|
1611
|
+
assert_equal 'idling', @object.state
|
1612
|
+
assert_equal 'second_gear', @object.status
|
1613
|
+
end
|
1614
|
+
|
1615
|
+
def test_should_clear_events
|
1616
|
+
assert_nil @object.state_event
|
1617
|
+
assert_nil @object.status_event
|
1618
|
+
end
|
1619
|
+
|
1620
|
+
def test_should_not_write_event_transitions
|
1621
|
+
assert_nil @object.send(:state_event_transition)
|
1622
|
+
assert_nil @object.send(:status_event_transition)
|
1623
|
+
end
|
1624
|
+
end
|
1625
|
+
|
1626
|
+
class AttributeTransitionCollectionWithEventTransitionsTest < Test::Unit::TestCase
|
1627
|
+
def setup
|
1628
|
+
@klass = Class.new
|
1629
|
+
|
1630
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1631
|
+
@state.state :idling
|
1632
|
+
@state.event :ignite
|
1633
|
+
|
1634
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
1635
|
+
@status.state :second_gear
|
1636
|
+
@status.event :shift_up
|
1637
|
+
|
1638
|
+
@object = @klass.new
|
1639
|
+
@object.send(:state_event_transition=, @state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling))
|
1640
|
+
@object.send(:status_event_transition=, @status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear))
|
1641
|
+
|
1642
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([@state_transition, @status_transition])
|
1643
|
+
@result = @transitions.perform
|
1644
|
+
end
|
1645
|
+
|
1646
|
+
def test_should_succeed
|
1647
|
+
assert_equal true, @result
|
1648
|
+
end
|
1649
|
+
|
1650
|
+
def test_should_persist_states
|
1651
|
+
assert_equal 'idling', @object.state
|
1652
|
+
assert_equal 'second_gear', @object.status
|
1653
|
+
end
|
1654
|
+
|
1655
|
+
def test_should_not_write_events
|
1656
|
+
assert_nil @object.state_event
|
1657
|
+
assert_nil @object.status_event
|
1658
|
+
end
|
1659
|
+
|
1660
|
+
def test_should_clear_event_transitions
|
1661
|
+
assert_nil @object.send(:state_event_transition)
|
1662
|
+
assert_nil @object.send(:status_event_transition)
|
1663
|
+
end
|
1664
|
+
end
|
1665
|
+
|
1666
|
+
class AttributeTransitionCollectionWithActionFailedTest < Test::Unit::TestCase
|
1667
|
+
def setup
|
1668
|
+
@klass = Class.new
|
1669
|
+
|
1670
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1671
|
+
@state.state :idling
|
1672
|
+
@state.event :ignite
|
1673
|
+
|
1674
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
1675
|
+
@status.state :second_gear
|
1676
|
+
@status.event :shift_up
|
1677
|
+
|
1678
|
+
@object = @klass.new
|
1679
|
+
@object.state_event = 'ignite'
|
1680
|
+
@object.status_event = 'shift_up'
|
1681
|
+
|
1682
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
1683
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
1684
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
1685
|
+
])
|
1686
|
+
@result = @transitions.perform { false }
|
1687
|
+
end
|
1688
|
+
|
1689
|
+
def test_should_not_succeed
|
1690
|
+
assert_equal false, @result
|
1691
|
+
end
|
1692
|
+
|
1693
|
+
def test_should_not_persist_states
|
1694
|
+
assert_equal 'parked', @object.state
|
1695
|
+
assert_equal 'first_gear', @object.status
|
1696
|
+
end
|
1697
|
+
|
1698
|
+
def test_should_not_clear_events
|
1699
|
+
assert_equal :ignite, @object.state_event
|
1700
|
+
assert_equal :shift_up, @object.status_event
|
1701
|
+
end
|
1702
|
+
|
1703
|
+
def test_should_not_write_event_transitions
|
1704
|
+
assert_nil @object.send(:state_event_transition)
|
1705
|
+
assert_nil @object.send(:status_event_transition)
|
1706
|
+
end
|
1707
|
+
end
|
1708
|
+
|
1709
|
+
class AttributeTransitionCollectionWithActionErrorTest < Test::Unit::TestCase
|
1710
|
+
def setup
|
1711
|
+
@klass = Class.new
|
1712
|
+
|
1713
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1714
|
+
@state.state :idling
|
1715
|
+
@state.event :ignite
|
1716
|
+
|
1717
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
1718
|
+
@status.state :second_gear
|
1719
|
+
@status.event :shift_up
|
1720
|
+
|
1721
|
+
@object = @klass.new
|
1722
|
+
@object.state_event = 'ignite'
|
1723
|
+
@object.status_event = 'shift_up'
|
1724
|
+
|
1725
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
1726
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
1727
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
1728
|
+
])
|
1729
|
+
|
1730
|
+
begin; @transitions.perform { raise ArgumentError }; rescue; end
|
1731
|
+
end
|
1732
|
+
|
1733
|
+
def test_should_not_persist_states
|
1734
|
+
assert_equal 'parked', @object.state
|
1735
|
+
assert_equal 'first_gear', @object.status
|
1736
|
+
end
|
1737
|
+
|
1738
|
+
def test_should_not_clear_events
|
1739
|
+
assert_equal :ignite, @object.state_event
|
1740
|
+
assert_equal :shift_up, @object.status_event
|
1741
|
+
end
|
1742
|
+
|
1743
|
+
def test_should_not_write_event_transitions
|
1744
|
+
assert_nil @object.send(:state_event_transition)
|
1745
|
+
assert_nil @object.send(:status_event_transition)
|
1746
|
+
end
|
1747
|
+
end
|
1748
|
+
|
1749
|
+
class AttributeTransitionCollectionWithCallbacksTest < Test::Unit::TestCase
|
1750
|
+
def setup
|
1751
|
+
@klass = Class.new
|
1752
|
+
|
1753
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1754
|
+
@state.state :idling
|
1755
|
+
@state.event :ignite
|
1756
|
+
|
1757
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
1758
|
+
@status.state :second_gear
|
1759
|
+
@status.event :shift_up
|
1760
|
+
|
1761
|
+
@object = @klass.new
|
1762
|
+
|
1763
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
1764
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
1765
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
1766
|
+
])
|
1767
|
+
end
|
1768
|
+
|
1769
|
+
def test_should_not_have_events_during_before_callbacks
|
1770
|
+
@state.before_transition {|object, transition| @before_state_event = object.state_event }
|
1771
|
+
@state.around_transition {|object, transition, block| @around_state_event = object.state_event; block.call }
|
1772
|
+
@transitions.perform
|
1773
|
+
|
1774
|
+
assert_nil @before_state_event
|
1775
|
+
assert_nil @around_state_event
|
1776
|
+
end
|
1777
|
+
|
1778
|
+
def test_should_not_have_events_during_action
|
1779
|
+
@transitions.perform { @state_event = @object.state_event }
|
1780
|
+
|
1781
|
+
assert_nil @state_event
|
1782
|
+
end
|
1783
|
+
|
1784
|
+
def test_should_not_have_events_during_after_callbacks
|
1785
|
+
@state.after_transition {|object, transition| @after_state_event = object.state_event }
|
1786
|
+
@state.around_transition {|object, transition, block| block.call; @around_state_event = object.state_event }
|
1787
|
+
@transitions.perform
|
1788
|
+
|
1789
|
+
assert_nil @after_state_event
|
1790
|
+
assert_nil @around_state_event
|
1791
|
+
end
|
1792
|
+
|
1793
|
+
def test_should_not_have_event_transitions_during_before_callbacks
|
1794
|
+
@state.before_transition {|object, transition| @state_event_transition = object.send(:state_event_transition) }
|
1795
|
+
@transitions.perform
|
1796
|
+
|
1797
|
+
assert_nil @state_event_transition
|
1798
|
+
end
|
1799
|
+
|
1800
|
+
def test_should_not_have_event_transitions_during_action
|
1801
|
+
@transitions.perform { @state_event_transition = @object.send(:state_event_transition) }
|
1802
|
+
|
1803
|
+
assert_nil @state_event_transition
|
1804
|
+
end
|
1805
|
+
|
1806
|
+
def test_should_not_have_event_transitions_during_after_callbacks
|
1807
|
+
@state.after_transition {|object, transition| @after_state_event_transition = object.send(:state_event_transition) }
|
1808
|
+
@state.around_transition {|object, transition, block| block.call; @around_state_event_transition = object.send(:state_event_transition) }
|
1809
|
+
@transitions.perform
|
1810
|
+
|
1811
|
+
assert_nil @after_state_event_transition
|
1812
|
+
assert_nil @around_state_event_transition
|
1813
|
+
end
|
1814
|
+
end
|
1815
|
+
|
1816
|
+
class AttributeTransitionCollectionWithBeforeCallbackHaltTest < Test::Unit::TestCase
|
1817
|
+
def setup
|
1818
|
+
@klass = Class.new
|
1819
|
+
|
1820
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1821
|
+
@machine.state :idling
|
1822
|
+
@machine.event :ignite
|
1823
|
+
|
1824
|
+
@machine.before_transition {throw :halt}
|
1825
|
+
|
1826
|
+
@object = @klass.new
|
1827
|
+
@object.state_event = 'ignite'
|
1828
|
+
|
1829
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
1830
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1831
|
+
])
|
1832
|
+
@result = @transitions.perform
|
1833
|
+
end
|
1834
|
+
|
1835
|
+
def test_should_not_succeed
|
1836
|
+
assert_equal false, @result
|
1837
|
+
end
|
1838
|
+
|
1839
|
+
def test_should_not_clear_event
|
1840
|
+
assert_equal :ignite, @object.state_event
|
1841
|
+
end
|
1842
|
+
|
1843
|
+
def test_should_not_write_event_transition
|
1844
|
+
assert_nil @object.send(:state_event_transition)
|
1845
|
+
end
|
1846
|
+
end
|
1847
|
+
|
1848
|
+
class AttributeTransitionCollectionWithBeforeCallbackErrorTest < Test::Unit::TestCase
|
1849
|
+
def setup
|
1850
|
+
@klass = Class.new
|
1851
|
+
|
1852
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1853
|
+
@machine.state :idling
|
1854
|
+
@machine.event :ignite
|
1855
|
+
|
1856
|
+
@machine.before_transition {raise ArgumentError}
|
1857
|
+
|
1858
|
+
@object = @klass.new
|
1859
|
+
@object.state_event = 'ignite'
|
1860
|
+
|
1861
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
1862
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1863
|
+
])
|
1864
|
+
begin; @transitions.perform; rescue; end
|
1865
|
+
end
|
1866
|
+
|
1867
|
+
def test_should_not_clear_event
|
1868
|
+
assert_equal :ignite, @object.state_event
|
1869
|
+
end
|
1870
|
+
|
1871
|
+
def test_should_not_write_event_transition
|
1872
|
+
assert_nil @object.send(:state_event_transition)
|
1873
|
+
end
|
1874
|
+
end
|
1875
|
+
|
1876
|
+
class AttributeTransitionCollectionWithAroundCallbackBeforeYieldHaltTest < Test::Unit::TestCase
|
1877
|
+
def setup
|
1878
|
+
@klass = Class.new
|
1879
|
+
|
1880
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1881
|
+
@machine.state :idling
|
1882
|
+
@machine.event :ignite
|
1883
|
+
|
1884
|
+
@machine.around_transition {throw :halt}
|
1885
|
+
|
1886
|
+
@object = @klass.new
|
1887
|
+
@object.state_event = 'ignite'
|
1888
|
+
|
1889
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
1890
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1891
|
+
])
|
1892
|
+
@result = @transitions.perform
|
1893
|
+
end
|
1894
|
+
|
1895
|
+
def test_should_not_succeed
|
1896
|
+
assert_equal false, @result
|
1897
|
+
end
|
1898
|
+
|
1899
|
+
def test_should_not_clear_event
|
1900
|
+
assert_equal :ignite, @object.state_event
|
1901
|
+
end
|
1902
|
+
|
1903
|
+
def test_should_not_write_event_transition
|
1904
|
+
assert_nil @object.send(:state_event_transition)
|
1905
|
+
end
|
1906
|
+
end
|
1907
|
+
|
1908
|
+
class AttributeTransitionCollectionWithAroundAfterYieldCallbackErrorTest < Test::Unit::TestCase
|
1909
|
+
def setup
|
1910
|
+
@klass = Class.new
|
1911
|
+
|
1912
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1913
|
+
@machine.state :idling
|
1914
|
+
@machine.event :ignite
|
1915
|
+
|
1916
|
+
@machine.before_transition {raise ArgumentError}
|
1917
|
+
|
1918
|
+
@object = @klass.new
|
1919
|
+
@object.state_event = 'ignite'
|
1920
|
+
|
1921
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
1922
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1923
|
+
])
|
1924
|
+
begin; @transitions.perform; rescue; end
|
1925
|
+
end
|
1926
|
+
|
1927
|
+
def test_should_not_clear_event
|
1928
|
+
assert_equal :ignite, @object.state_event
|
1929
|
+
end
|
1930
|
+
|
1931
|
+
def test_should_not_write_event_transition
|
1932
|
+
assert_nil @object.send(:state_event_transition)
|
1933
|
+
end
|
1934
|
+
end
|
1935
|
+
|
1936
|
+
class AttributeTransitionCollectionWithSkippedAfterCallbacksTest < Test::Unit::TestCase
|
1937
|
+
def setup
|
1938
|
+
@klass = Class.new
|
1939
|
+
|
1940
|
+
@state = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1941
|
+
@state.state :idling
|
1942
|
+
@state.event :ignite
|
1943
|
+
|
1944
|
+
@status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
1945
|
+
@status.state :second_gear
|
1946
|
+
@status.event :shift_up
|
1947
|
+
|
1948
|
+
@object = @klass.new
|
1949
|
+
@object.state_event = 'ignite'
|
1950
|
+
@object.status_event = 'shift_up'
|
1951
|
+
|
1952
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
1953
|
+
@state_transition = StateMachine::Transition.new(@object, @state, :ignite, :parked, :idling),
|
1954
|
+
@status_transition = StateMachine::Transition.new(@object, @status, :shift_up, :first_gear, :second_gear)
|
1955
|
+
], :after => false)
|
1956
|
+
end
|
1957
|
+
|
1958
|
+
def test_should_clear_events
|
1959
|
+
@transitions.perform
|
1960
|
+
assert_nil @object.state_event
|
1961
|
+
assert_nil @object.status_event
|
1962
|
+
end
|
1963
|
+
|
1964
|
+
def test_should_write_event_transitions_if_success
|
1965
|
+
@transitions.perform { true }
|
1966
|
+
assert_equal @state_transition, @object.send(:state_event_transition)
|
1967
|
+
assert_equal @status_transition, @object.send(:status_event_transition)
|
1968
|
+
end
|
1969
|
+
|
1970
|
+
def test_should_not_write_event_transitions_if_failed
|
1971
|
+
@transitions.perform { false }
|
1972
|
+
assert_nil @object.send(:state_event_transition)
|
1973
|
+
assert_nil @object.send(:status_event_transition)
|
1974
|
+
end
|
1975
|
+
end
|
1976
|
+
|
1977
|
+
class AttributeTransitionCollectionWithAfterCallbackHaltTest < Test::Unit::TestCase
|
1978
|
+
def setup
|
1979
|
+
@klass = Class.new
|
1980
|
+
|
1981
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
1982
|
+
@machine.state :idling
|
1983
|
+
@machine.event :ignite
|
1984
|
+
|
1985
|
+
@machine.after_transition {throw :halt}
|
1986
|
+
|
1987
|
+
@object = @klass.new
|
1988
|
+
@object.state_event = 'ignite'
|
1989
|
+
|
1990
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
1991
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
1992
|
+
])
|
1993
|
+
@result = @transitions.perform
|
1994
|
+
end
|
1995
|
+
|
1996
|
+
def test_should_succeed
|
1997
|
+
assert_equal true, @result
|
1998
|
+
end
|
1999
|
+
|
2000
|
+
def test_should_clear_event
|
2001
|
+
assert_nil @object.state_event
|
2002
|
+
end
|
2003
|
+
|
2004
|
+
def test_should_not_write_event_transition
|
2005
|
+
assert_nil @object.send(:state_event_transition)
|
2006
|
+
end
|
2007
|
+
end
|
2008
|
+
|
2009
|
+
class AttributeTransitionCollectionWithAfterCallbackErrorTest < Test::Unit::TestCase
|
2010
|
+
def setup
|
2011
|
+
@klass = Class.new
|
2012
|
+
|
2013
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
2014
|
+
@machine.state :idling
|
2015
|
+
@machine.event :ignite
|
2016
|
+
|
2017
|
+
@machine.after_transition {raise ArgumentError}
|
2018
|
+
|
2019
|
+
@object = @klass.new
|
2020
|
+
@object.state_event = 'ignite'
|
2021
|
+
|
2022
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
2023
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
2024
|
+
])
|
2025
|
+
begin; @transitions.perform; rescue; end
|
2026
|
+
end
|
2027
|
+
|
2028
|
+
def test_should_clear_event
|
2029
|
+
assert_nil @object.state_event
|
2030
|
+
end
|
2031
|
+
|
2032
|
+
def test_should_not_write_event_transition
|
2033
|
+
assert_nil @object.send(:state_event_transition)
|
2034
|
+
end
|
2035
|
+
end
|
2036
|
+
|
2037
|
+
class AttributeTransitionCollectionWithAroundCallbackAfterYieldHaltTest < Test::Unit::TestCase
|
2038
|
+
def setup
|
2039
|
+
@klass = Class.new
|
2040
|
+
|
2041
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
2042
|
+
@machine.state :idling
|
2043
|
+
@machine.event :ignite
|
2044
|
+
|
2045
|
+
@machine.around_transition {|block| block.call; throw :halt}
|
2046
|
+
|
2047
|
+
@object = @klass.new
|
2048
|
+
@object.state_event = 'ignite'
|
2049
|
+
|
2050
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
2051
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
2052
|
+
])
|
2053
|
+
@result = @transitions.perform
|
2054
|
+
end
|
2055
|
+
|
2056
|
+
def test_should_succeed
|
2057
|
+
assert_equal true, @result
|
2058
|
+
end
|
2059
|
+
|
2060
|
+
def test_should_clear_event
|
2061
|
+
assert_nil @object.state_event
|
2062
|
+
end
|
2063
|
+
|
2064
|
+
def test_should_not_write_event_transition
|
2065
|
+
assert_nil @object.send(:state_event_transition)
|
2066
|
+
end
|
2067
|
+
end
|
2068
|
+
|
2069
|
+
class AttributeTransitionCollectionWithAroundCallbackAfterYieldErrorTest < Test::Unit::TestCase
|
2070
|
+
def setup
|
2071
|
+
@klass = Class.new
|
2072
|
+
|
2073
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
2074
|
+
@machine.state :idling
|
2075
|
+
@machine.event :ignite
|
2076
|
+
|
2077
|
+
@machine.around_transition {|block| block.call; raise ArgumentError}
|
2078
|
+
|
2079
|
+
@object = @klass.new
|
2080
|
+
@object.state_event = 'ignite'
|
2081
|
+
|
2082
|
+
@transitions = StateMachine::AttributeTransitionCollection.new([
|
2083
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
2084
|
+
])
|
2085
|
+
begin; @transitions.perform; rescue; end
|
2086
|
+
end
|
2087
|
+
|
2088
|
+
def test_should_clear_event
|
2089
|
+
assert_nil @object.state_event
|
2090
|
+
end
|
2091
|
+
|
2092
|
+
def test_should_not_write_event_transition
|
2093
|
+
assert_nil @object.send(:state_event_transition)
|
2094
|
+
end
|
2095
|
+
end
|
2096
|
+
|
2097
|
+
class AttributeTransitionCollectionMarshallingTest < Test::Unit::TestCase
|
2098
|
+
def setup
|
2099
|
+
@klass = Class.new
|
2100
|
+
self.class.const_set('Example', @klass)
|
2101
|
+
|
2102
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked, :action => :save)
|
2103
|
+
@machine.state :idling
|
2104
|
+
@machine.event :ignite
|
2105
|
+
|
2106
|
+
@object = @klass.new
|
2107
|
+
@object.state_event = 'ignite'
|
2108
|
+
end
|
2109
|
+
|
2110
|
+
def test_should_marshal_during_before_callbacks
|
2111
|
+
@machine.before_transition {|object, transition| Marshal.dump(object)}
|
2112
|
+
assert_nothing_raised do
|
2113
|
+
transitions(:after => false).perform { true }
|
2114
|
+
transitions.perform { true }
|
2115
|
+
end
|
2116
|
+
end
|
2117
|
+
|
2118
|
+
def test_should_marshal_during_action
|
2119
|
+
assert_nothing_raised do
|
2120
|
+
transitions(:after => false).perform do
|
2121
|
+
Marshal.dump(@object)
|
2122
|
+
true
|
2123
|
+
end
|
2124
|
+
|
2125
|
+
transitions.perform do
|
2126
|
+
Marshal.dump(@object)
|
2127
|
+
true
|
2128
|
+
end
|
2129
|
+
end
|
2130
|
+
end
|
2131
|
+
|
2132
|
+
def test_should_marshal_during_after_callbacks
|
2133
|
+
@machine.after_transition {|object, transition| Marshal.dump(object)}
|
2134
|
+
assert_nothing_raised do
|
2135
|
+
transitions(:after => false).perform { true }
|
2136
|
+
transitions.perform { true }
|
2137
|
+
end
|
2138
|
+
end
|
2139
|
+
|
2140
|
+
if StateMachine::Transition.pause_supported?
|
2141
|
+
def test_should_marshal_during_around_callbacks_before_yield
|
2142
|
+
@machine.around_transition {|object, transition, block| Marshal.dump(object); block.call}
|
2143
|
+
assert_nothing_raised do
|
2144
|
+
transitions(:after => false).perform { true }
|
2145
|
+
transitions.perform { true }
|
2146
|
+
end
|
2147
|
+
end
|
2148
|
+
|
2149
|
+
def test_should_marshal_during_around_callbacks_after_yield
|
2150
|
+
@machine.around_transition {|object, transition, block| block.call; Marshal.dump(object)}
|
2151
|
+
assert_nothing_raised do
|
2152
|
+
transitions(:after => false).perform { true }
|
2153
|
+
transitions.perform { true }
|
2154
|
+
end
|
2155
|
+
end
|
2156
|
+
end
|
2157
|
+
|
2158
|
+
def teardown
|
2159
|
+
self.class.send(:remove_const, 'Example')
|
2160
|
+
end
|
2161
|
+
|
2162
|
+
private
|
2163
|
+
def transitions(options = {})
|
2164
|
+
StateMachine::AttributeTransitionCollection.new([
|
2165
|
+
StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
|
2166
|
+
], options)
|
2167
|
+
end
|
2168
|
+
end
|