pluginaweek-state_machine 0.7.6
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.
- data/CHANGELOG.rdoc +273 -0
- data/LICENSE +20 -0
- data/README.rdoc +466 -0
- data/Rakefile +98 -0
- data/examples/AutoShop_state.png +0 -0
- data/examples/Car_state.png +0 -0
- data/examples/TrafficLight_state.png +0 -0
- data/examples/Vehicle_state.png +0 -0
- data/examples/auto_shop.rb +11 -0
- data/examples/car.rb +19 -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 +11 -0
- data/examples/rails-rest/model.rb +23 -0
- data/examples/rails-rest/view_edit.html.erb +25 -0
- data/examples/rails-rest/view_index.html.erb +23 -0
- data/examples/rails-rest/view_new.html.erb +14 -0
- data/examples/rails-rest/view_show.html.erb +17 -0
- data/examples/traffic_light.rb +7 -0
- data/examples/vehicle.rb +31 -0
- data/init.rb +1 -0
- data/lib/state_machine.rb +429 -0
- data/lib/state_machine/assertions.rb +36 -0
- data/lib/state_machine/callback.rb +189 -0
- data/lib/state_machine/condition_proxy.rb +94 -0
- data/lib/state_machine/eval_helpers.rb +67 -0
- data/lib/state_machine/event.rb +251 -0
- data/lib/state_machine/event_collection.rb +113 -0
- data/lib/state_machine/extensions.rb +158 -0
- data/lib/state_machine/guard.rb +219 -0
- data/lib/state_machine/integrations.rb +68 -0
- data/lib/state_machine/integrations/active_record.rb +444 -0
- data/lib/state_machine/integrations/active_record/locale.rb +10 -0
- data/lib/state_machine/integrations/active_record/observer.rb +41 -0
- data/lib/state_machine/integrations/data_mapper.rb +325 -0
- data/lib/state_machine/integrations/data_mapper/observer.rb +139 -0
- data/lib/state_machine/integrations/sequel.rb +292 -0
- data/lib/state_machine/machine.rb +1431 -0
- data/lib/state_machine/machine_collection.rb +146 -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 +152 -0
- data/lib/state_machine/state.rb +249 -0
- data/lib/state_machine/state_collection.rb +112 -0
- data/lib/state_machine/transition.rb +367 -0
- data/tasks/state_machine.rake +1 -0
- data/tasks/state_machine.rb +30 -0
- data/test/classes/switch.rb +11 -0
- data/test/functional/state_machine_test.rb +941 -0
- data/test/test_helper.rb +4 -0
- data/test/unit/assertions_test.rb +40 -0
- data/test/unit/callback_test.rb +455 -0
- data/test/unit/condition_proxy_test.rb +328 -0
- data/test/unit/eval_helpers_test.rb +129 -0
- data/test/unit/event_collection_test.rb +293 -0
- data/test/unit/event_test.rb +605 -0
- data/test/unit/guard_test.rb +862 -0
- data/test/unit/integrations/active_record_test.rb +1001 -0
- data/test/unit/integrations/data_mapper_test.rb +694 -0
- data/test/unit/integrations/sequel_test.rb +486 -0
- data/test/unit/integrations_test.rb +42 -0
- data/test/unit/invalid_event_test.rb +7 -0
- data/test/unit/invalid_transition_test.rb +7 -0
- data/test/unit/machine_collection_test.rb +710 -0
- data/test/unit/machine_test.rb +1910 -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 +207 -0
- data/test/unit/state_collection_test.rb +280 -0
- data/test/unit/state_machine_test.rb +31 -0
- data/test/unit/state_test.rb +795 -0
- data/test/unit/transition_test.rb +1113 -0
- metadata +161 -0
data/test/test_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class AssertionsTest < Test::Unit::TestCase
|
4
|
+
include StateMachine::Assertions
|
5
|
+
|
6
|
+
def default_test
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class AssertValidKeysTest < AssertionsTest
|
11
|
+
def test_should_not_raise_exception_if_key_is_valid
|
12
|
+
assert_nothing_raised { assert_valid_keys({:name => 'foo', :value => 'bar'}, :name, :value, :force) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_raise_exception_if_key_is_invalid
|
16
|
+
exception = assert_raise(ArgumentError) { assert_valid_keys({:name => 'foo', :value => 'bar', :invalid => true}, :name, :value, :force) }
|
17
|
+
assert_equal 'Invalid key(s): invalid', exception.message
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class AssertExclusiveKeysTest < AssertionsTest
|
22
|
+
def test_should_not_raise_exception_if_no_keys_found
|
23
|
+
assert_nothing_raised { assert_exclusive_keys({:on => :park}, :only, :except) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_should_not_raise_exception_if_one_key_found
|
27
|
+
assert_nothing_raised { assert_exclusive_keys({:only => :parked}, :only, :except) }
|
28
|
+
assert_nothing_raised { assert_exclusive_keys({:except => :parked}, :only, :except) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_raise_exception_if_two_keys_found
|
32
|
+
exception = assert_raise(ArgumentError) { assert_exclusive_keys({:only => :parked, :except => :parked}, :only, :except) }
|
33
|
+
assert_equal 'Conflicting keys: only, except', exception.message
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_raise_exception_if_multiple_keys_found
|
37
|
+
exception = assert_raise(ArgumentError) { assert_exclusive_keys({:only => :parked, :except => :parked, :on => :park}, :only, :except, :with) }
|
38
|
+
assert_equal 'Conflicting keys: only, except', exception.message
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,455 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class CallbackTest < Test::Unit::TestCase
|
4
|
+
def test_should_raise_exception_if_no_methods_specified
|
5
|
+
exception = assert_raise(ArgumentError) { StateMachine::Callback.new }
|
6
|
+
assert_equal 'Method(s) for callback must be specified', exception.message
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_should_not_raise_exception_if_method_specified_in_do_option
|
10
|
+
assert_nothing_raised { StateMachine::Callback.new(:do => :run) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_should_not_raise_exception_if_method_specified_as_argument
|
14
|
+
assert_nothing_raised { StateMachine::Callback.new(:run) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_should_not_raise_exception_if_method_specified_as_block
|
18
|
+
assert_nothing_raised { StateMachine::Callback.new(:run) {} }
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_not_raise_exception_if_implicit_option_specified
|
22
|
+
assert_nothing_raised { StateMachine::Callback.new(:do => :run, :invalid => :valid) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_should_not_bind_to_objects
|
26
|
+
assert !StateMachine::Callback.bind_to_object
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_should_not_have_a_terminator
|
30
|
+
assert_nil StateMachine::Callback.terminator
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class CallbackByDefaultTest < Test::Unit::TestCase
|
35
|
+
def setup
|
36
|
+
@callback = StateMachine::Callback.new(:do => lambda {})
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_should_not_have_a_terminator
|
40
|
+
assert_nil @callback.terminator
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_should_have_a_guard_with_all_matcher_requirements
|
44
|
+
assert_equal StateMachine::AllMatcher.instance, @callback.guard.event_requirement
|
45
|
+
assert_equal StateMachine::AllMatcher.instance, @callback.guard.state_requirements.first[:from]
|
46
|
+
assert_equal StateMachine::AllMatcher.instance, @callback.guard.state_requirements.first[:to]
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_should_not_have_any_known_states
|
50
|
+
assert_equal [], @callback.known_states
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class CallbackWithMethodArgumentTest < Test::Unit::TestCase
|
55
|
+
def setup
|
56
|
+
@callback = StateMachine::Callback.new(lambda {|*args| @args = args})
|
57
|
+
|
58
|
+
@object = Object.new
|
59
|
+
@result = @callback.call(@object)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_should_be_successful
|
63
|
+
assert @result
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_should_call_with_empty_context
|
67
|
+
assert_equal [@object], @args
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class CallbackWithMultipleMethodArgumentsTest < Test::Unit::TestCase
|
72
|
+
def setup
|
73
|
+
@callback = StateMachine::Callback.new(:run_1, :run_2)
|
74
|
+
|
75
|
+
class << @object = Object.new
|
76
|
+
attr_accessor :callbacks
|
77
|
+
|
78
|
+
def run_1
|
79
|
+
(@callbacks ||= []) << :run_1
|
80
|
+
end
|
81
|
+
|
82
|
+
def run_2
|
83
|
+
(@callbacks ||= []) << :run_2
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
@result = @callback.call(@object)
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_should_be_successful
|
91
|
+
assert @result
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_should_call_each_callback_in_order
|
95
|
+
assert_equal [:run_1, :run_2], @object.callbacks
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class CallbackWithDoMethodTest < Test::Unit::TestCase
|
100
|
+
def setup
|
101
|
+
@callback = StateMachine::Callback.new(:do => lambda {|*args| @args = args})
|
102
|
+
|
103
|
+
@object = Object.new
|
104
|
+
@result = @callback.call(@object)
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_should_be_successful
|
108
|
+
assert @result
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_should_call_with_empty_context
|
112
|
+
assert_equal [@object], @args
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class CallbackWithMultipleDoMethodsTest < Test::Unit::TestCase
|
117
|
+
def setup
|
118
|
+
@callback = StateMachine::Callback.new(:do => [:run_1, :run_2])
|
119
|
+
|
120
|
+
class << @object = Object.new
|
121
|
+
attr_accessor :callbacks
|
122
|
+
|
123
|
+
def run_1
|
124
|
+
(@callbacks ||= []) << :run_1
|
125
|
+
end
|
126
|
+
|
127
|
+
def run_2
|
128
|
+
(@callbacks ||= []) << :run_2
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
@result = @callback.call(@object)
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_should_be_successful
|
136
|
+
assert @result
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_should_call_each_callback_in_order
|
140
|
+
assert_equal [:run_1, :run_2], @object.callbacks
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class CallbackWithBlockTest < Test::Unit::TestCase
|
145
|
+
def setup
|
146
|
+
@callback = StateMachine::Callback.new do |*args|
|
147
|
+
@args = args
|
148
|
+
end
|
149
|
+
|
150
|
+
@object = Object.new
|
151
|
+
@result = @callback.call(@object)
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_should_be_successful
|
155
|
+
assert @result
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_should_call_with_empty_context
|
159
|
+
assert_equal [@object], @args
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
class CallbackWithMixedMethodsTest < Test::Unit::TestCase
|
164
|
+
def setup
|
165
|
+
@callback = StateMachine::Callback.new(:run_argument, :do => :run_do) do |object|
|
166
|
+
object.callbacks << :block
|
167
|
+
end
|
168
|
+
|
169
|
+
class << @object = Object.new
|
170
|
+
attr_accessor :callbacks
|
171
|
+
|
172
|
+
def run_argument
|
173
|
+
(@callbacks ||= []) << :argument
|
174
|
+
end
|
175
|
+
|
176
|
+
def run_do
|
177
|
+
(@callbacks ||= []) << :do
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
@result = @callback.call(@object)
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_should_be_successful
|
185
|
+
assert @result
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_should_call_each_callback_in_order
|
189
|
+
assert_equal [:argument, :do, :block], @object.callbacks
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
class CallbackWithExplicitRequirementsTest < Test::Unit::TestCase
|
194
|
+
def setup
|
195
|
+
@object = Object.new
|
196
|
+
@callback = StateMachine::Callback.new(:from => :parked, :to => :idling, :on => :ignite, :do => lambda {})
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_should_call_with_empty_context
|
200
|
+
assert @callback.call(@object, {})
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_should_not_call_if_from_not_included
|
204
|
+
assert !@callback.call(@object, :from => :idling)
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_should_not_call_if_to_not_included
|
208
|
+
assert !@callback.call(@object, :to => :parked)
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_should_not_call_if_on_not_included
|
212
|
+
assert !@callback.call(@object, :on => :park)
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_should_call_if_all_requirements_met
|
216
|
+
assert @callback.call(@object, :from => :parked, :to => :idling, :on => :ignite)
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_should_include_in_known_states
|
220
|
+
assert_equal [:parked, :idling], @callback.known_states
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
class CallbackWithImplicitRequirementsTest < Test::Unit::TestCase
|
225
|
+
def setup
|
226
|
+
@object = Object.new
|
227
|
+
@callback = StateMachine::Callback.new(:parked => :idling, :on => :ignite, :do => lambda {})
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_should_call_with_empty_context
|
231
|
+
assert @callback.call(@object, {})
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_should_not_call_if_from_not_included
|
235
|
+
assert !@callback.call(@object, :from => :idling)
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_should_not_call_if_to_not_included
|
239
|
+
assert !@callback.call(@object, :to => :parked)
|
240
|
+
end
|
241
|
+
|
242
|
+
def test_should_not_call_if_on_not_included
|
243
|
+
assert !@callback.call(@object, :on => :park)
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_should_call_if_all_requirements_met
|
247
|
+
assert @callback.call(@object, :from => :parked, :to => :idling, :on => :ignite)
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_should_include_in_known_states
|
251
|
+
assert_equal [:parked, :idling], @callback.known_states
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
class CallbackWithIfConditionTest < Test::Unit::TestCase
|
256
|
+
def setup
|
257
|
+
@object = Object.new
|
258
|
+
end
|
259
|
+
|
260
|
+
def test_should_call_if_true
|
261
|
+
callback = StateMachine::Callback.new(:if => lambda {true}, :do => lambda {})
|
262
|
+
assert callback.call(@object)
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_should_not_call_if_false
|
266
|
+
callback = StateMachine::Callback.new(:if => lambda {false}, :do => lambda {})
|
267
|
+
assert !callback.call(@object)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
class CallbackWithUnlessConditionTest < Test::Unit::TestCase
|
272
|
+
def setup
|
273
|
+
@object = Object.new
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_should_call_if_false
|
277
|
+
callback = StateMachine::Callback.new(:unless => lambda {false}, :do => lambda {})
|
278
|
+
assert callback.call(@object)
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_should_not_call_if_true
|
282
|
+
callback = StateMachine::Callback.new(:unless => lambda {true}, :do => lambda {})
|
283
|
+
assert !callback.call(@object)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
class CallbackWithoutTerminatorTest < Test::Unit::TestCase
|
288
|
+
def setup
|
289
|
+
@object = Object.new
|
290
|
+
end
|
291
|
+
|
292
|
+
def test_should_not_halt_if_result_is_false
|
293
|
+
callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => nil)
|
294
|
+
assert_nothing_thrown { callback.call(@object) }
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
class CallbackWithTerminatorTest < Test::Unit::TestCase
|
299
|
+
def setup
|
300
|
+
@object = Object.new
|
301
|
+
end
|
302
|
+
|
303
|
+
def test_should_not_halt_if_terminator_does_not_match
|
304
|
+
callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => lambda {|result| result == true})
|
305
|
+
assert_nothing_thrown { callback.call(@object) }
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_should_halt_if_terminator_matches
|
309
|
+
callback = StateMachine::Callback.new(:do => lambda {false}, :terminator => lambda {|result| result == false})
|
310
|
+
assert_throws(:halt) { callback.call(@object) }
|
311
|
+
end
|
312
|
+
|
313
|
+
def test_should_halt_if_terminator_matches_any_method
|
314
|
+
callback = StateMachine::Callback.new(:do => [lambda {true}, lambda {false}], :terminator => lambda {|result| result == false})
|
315
|
+
assert_throws(:halt) { callback.call(@object) }
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
class CallbackWithoutArgumentsTest < Test::Unit::TestCase
|
320
|
+
def setup
|
321
|
+
@callback = StateMachine::Callback.new(:do => lambda {|object| @arg = object})
|
322
|
+
|
323
|
+
@object = Object.new
|
324
|
+
@callback.call(@object, {}, 1, 2, 3)
|
325
|
+
end
|
326
|
+
|
327
|
+
def test_should_call_method_with_object_as_argument
|
328
|
+
assert_equal @object, @arg
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
class CallbackWithArgumentsTest < Test::Unit::TestCase
|
333
|
+
def setup
|
334
|
+
@callback = StateMachine::Callback.new(:do => lambda {|*args| @args = args})
|
335
|
+
|
336
|
+
@object = Object.new
|
337
|
+
@callback.call(@object, {}, 1, 2, 3)
|
338
|
+
end
|
339
|
+
|
340
|
+
def test_should_call_method_with_all_arguments
|
341
|
+
assert_equal [@object, 1, 2, 3], @args
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
class CallbackWithUnboundMethodTest < Test::Unit::TestCase
|
346
|
+
def setup
|
347
|
+
@callback = StateMachine::Callback.new(:do => lambda {|*args| @context = args.unshift(self)})
|
348
|
+
|
349
|
+
@object = Object.new
|
350
|
+
@callback.call(@object, {}, 1, 2, 3)
|
351
|
+
end
|
352
|
+
|
353
|
+
def test_should_call_method_outside_the_context_of_the_object
|
354
|
+
assert_equal [self, @object, 1, 2, 3], @context
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
class CallbackWithBoundMethodTest < Test::Unit::TestCase
|
359
|
+
def setup
|
360
|
+
@object = Object.new
|
361
|
+
end
|
362
|
+
|
363
|
+
def test_should_call_method_within_the_context_of_the_object_for_block_methods
|
364
|
+
context = nil
|
365
|
+
callback = StateMachine::Callback.new(:do => lambda {|*args| context = [self] + args}, :bind_to_object => true)
|
366
|
+
callback.call(@object, {}, 1, 2, 3)
|
367
|
+
|
368
|
+
assert_equal [@object, 1, 2, 3], context
|
369
|
+
end
|
370
|
+
|
371
|
+
def test_should_ignore_option_for_symbolic_methods
|
372
|
+
class << @object
|
373
|
+
attr_reader :context
|
374
|
+
|
375
|
+
def after_ignite(*args)
|
376
|
+
@context = args
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
callback = StateMachine::Callback.new(:do => :after_ignite, :bind_to_object => true)
|
381
|
+
callback.call(@object)
|
382
|
+
|
383
|
+
assert_equal [], @object.context
|
384
|
+
end
|
385
|
+
|
386
|
+
def test_should_ignore_option_for_string_methods
|
387
|
+
callback = StateMachine::Callback.new(:do => '[1, 2, 3]', :bind_to_object => true)
|
388
|
+
assert callback.call(@object)
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
class CallbackWithMultipleBoundMethodsTest < Test::Unit::TestCase
|
393
|
+
def setup
|
394
|
+
@object = Object.new
|
395
|
+
|
396
|
+
first_context = nil
|
397
|
+
second_context = nil
|
398
|
+
|
399
|
+
@callback = StateMachine::Callback.new(:do => [lambda {first_context = self}, lambda {second_context = self}], :bind_to_object => true)
|
400
|
+
@callback.call(@object)
|
401
|
+
|
402
|
+
@first_context = first_context
|
403
|
+
@second_context = second_context
|
404
|
+
end
|
405
|
+
|
406
|
+
def test_should_call_each_method_within_the_context_of_the_object
|
407
|
+
assert_equal @object, @first_context
|
408
|
+
assert_equal @object, @second_context
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
class CallbackWithApplicationBoundObjectTest < Test::Unit::TestCase
|
413
|
+
def setup
|
414
|
+
@original_bind_to_object = StateMachine::Callback.bind_to_object
|
415
|
+
StateMachine::Callback.bind_to_object = true
|
416
|
+
|
417
|
+
context = nil
|
418
|
+
@callback = StateMachine::Callback.new(:do => lambda {|*args| context = self})
|
419
|
+
|
420
|
+
@object = Object.new
|
421
|
+
@callback.call(@object)
|
422
|
+
@context = context
|
423
|
+
end
|
424
|
+
|
425
|
+
def test_should_call_method_within_the_context_of_the_object
|
426
|
+
assert_equal @object, @context
|
427
|
+
end
|
428
|
+
|
429
|
+
def teardown
|
430
|
+
StateMachine::Callback.bind_to_object = @original_bind_to_object
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
class CallbackWithApplicationTerminatorTest < Test::Unit::TestCase
|
435
|
+
def setup
|
436
|
+
@original_terminator = StateMachine::Callback.bind_to_object
|
437
|
+
StateMachine::Callback.terminator = lambda {|result| result == false}
|
438
|
+
|
439
|
+
@object = Object.new
|
440
|
+
end
|
441
|
+
|
442
|
+
def test_should_not_halt_if_terminator_does_not_match
|
443
|
+
callback = StateMachine::Callback.new(:do => lambda {true})
|
444
|
+
assert_nothing_thrown { callback.call(@object) }
|
445
|
+
end
|
446
|
+
|
447
|
+
def test_should_halt_if_terminator_matches
|
448
|
+
callback = StateMachine::Callback.new(:do => lambda {false})
|
449
|
+
assert_throws(:halt) { callback.call(@object) }
|
450
|
+
end
|
451
|
+
|
452
|
+
def teardown
|
453
|
+
StateMachine::Callback.bind_to_object = @original_bind_to_object
|
454
|
+
end
|
455
|
+
end
|