state_machine 0.4.3 → 0.5.0
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 +17 -0
- data/LICENSE +1 -1
- data/README.rdoc +54 -84
- data/Rakefile +1 -1
- data/examples/Car_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/traffic_light.rb +9 -0
- data/examples/vehicle.rb +35 -0
- data/lib/state_machine.rb +65 -52
- data/lib/state_machine/assertions.rb +1 -1
- data/lib/state_machine/callback.rb +13 -9
- data/lib/state_machine/eval_helpers.rb +4 -3
- data/lib/state_machine/event.rb +51 -33
- data/lib/state_machine/extensions.rb +2 -2
- data/lib/state_machine/guard.rb +47 -41
- data/lib/state_machine/integrations.rb +67 -0
- data/lib/state_machine/integrations/active_record.rb +62 -36
- data/lib/state_machine/integrations/active_record/observer.rb +41 -0
- data/lib/state_machine/integrations/data_mapper.rb +23 -37
- data/lib/state_machine/integrations/data_mapper/observer.rb +23 -9
- data/lib/state_machine/integrations/sequel.rb +23 -24
- data/lib/state_machine/machine.rb +380 -277
- data/lib/state_machine/node_collection.rb +142 -0
- data/lib/state_machine/state.rb +114 -69
- data/lib/state_machine/state_collection.rb +38 -0
- data/lib/state_machine/transition.rb +36 -17
- data/test/active_record.log +2940 -85664
- data/test/functional/state_machine_test.rb +49 -53
- data/test/sequel.log +747 -11990
- data/test/unit/assertions_test.rb +2 -1
- data/test/unit/callback_test.rb +14 -12
- data/test/unit/eval_helpers_test.rb +25 -6
- data/test/unit/event_test.rb +144 -124
- data/test/unit/guard_test.rb +118 -140
- data/test/unit/integrations/active_record_test.rb +102 -68
- data/test/unit/integrations/data_mapper_test.rb +48 -37
- data/test/unit/integrations/sequel_test.rb +34 -25
- data/test/unit/integrations_test.rb +42 -0
- data/test/unit/machine_test.rb +460 -531
- data/test/unit/node_collection_test.rb +208 -0
- data/test/unit/state_collection_test.rb +167 -0
- data/test/unit/state_machine_test.rb +1 -1
- data/test/unit/state_test.rb +223 -200
- data/test/unit/transition_test.rb +81 -46
- metadata +17 -3
- data/test/data_mapper.log +0 -30860
@@ -54,6 +54,7 @@ begin
|
|
54
54
|
def setup
|
55
55
|
@model = new_model
|
56
56
|
@machine = StateMachine::Machine.new(@model)
|
57
|
+
@machine.state :parked, :idling, :first_gear
|
57
58
|
end
|
58
59
|
|
59
60
|
def test_should_create_singular_with_scope
|
@@ -61,10 +62,10 @@ begin
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def test_should_only_include_records_with_state_in_singular_with_scope
|
64
|
-
|
65
|
-
|
65
|
+
parked = @model.create :state => 'parked'
|
66
|
+
idling = @model.create :state => 'idling'
|
66
67
|
|
67
|
-
assert_equal [
|
68
|
+
assert_equal [parked], @model.with_state(:parked).all
|
68
69
|
end
|
69
70
|
|
70
71
|
def test_should_create_plural_with_scope
|
@@ -72,10 +73,10 @@ begin
|
|
72
73
|
end
|
73
74
|
|
74
75
|
def test_should_only_include_records_with_states_in_plural_with_scope
|
75
|
-
|
76
|
-
|
76
|
+
parked = @model.create :state => 'parked'
|
77
|
+
idling = @model.create :state => 'idling'
|
77
78
|
|
78
|
-
assert_equal [
|
79
|
+
assert_equal [parked, idling], @model.with_states(:parked, :idling).all
|
79
80
|
end
|
80
81
|
|
81
82
|
def test_should_create_singular_without_scope
|
@@ -83,10 +84,10 @@ begin
|
|
83
84
|
end
|
84
85
|
|
85
86
|
def test_should_only_include_records_without_state_in_singular_without_scope
|
86
|
-
|
87
|
-
|
87
|
+
parked = @model.create :state => 'parked'
|
88
|
+
idling = @model.create :state => 'idling'
|
88
89
|
|
89
|
-
assert_equal [
|
90
|
+
assert_equal [parked], @model.without_state(:idling).all
|
90
91
|
end
|
91
92
|
|
92
93
|
def test_should_create_plural_without_scope
|
@@ -94,11 +95,18 @@ begin
|
|
94
95
|
end
|
95
96
|
|
96
97
|
def test_should_only_include_records_without_states_in_plural_without_scope
|
97
|
-
|
98
|
-
|
99
|
-
|
98
|
+
parked = @model.create :state => 'parked'
|
99
|
+
idling = @model.create :state => 'idling'
|
100
|
+
first_gear = @model.create :state => 'first_gear'
|
100
101
|
|
101
|
-
assert_equal [
|
102
|
+
assert_equal [parked, idling], @model.without_states(:first_gear).all
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_should_allow_chaining_scopes_and_fitlers
|
106
|
+
parked = @model.create :state => 'parked'
|
107
|
+
idling = @model.create :state => 'idling'
|
108
|
+
|
109
|
+
assert_equal [idling], @model.without_state(:parked).filter(:state => 'idling').all
|
102
110
|
end
|
103
111
|
|
104
112
|
def test_should_rollback_transaction_if_false
|
@@ -121,14 +129,14 @@ begin
|
|
121
129
|
|
122
130
|
def test_should_not_override_the_column_reader
|
123
131
|
record = @model.new
|
124
|
-
record[:state] = '
|
125
|
-
assert_equal '
|
132
|
+
record[:state] = 'parked'
|
133
|
+
assert_equal 'parked', record.state
|
126
134
|
end
|
127
135
|
|
128
136
|
def test_should_not_override_the_column_writer
|
129
137
|
record = @model.new
|
130
|
-
record.state = '
|
131
|
-
assert_equal '
|
138
|
+
record.state = 'parked'
|
139
|
+
assert_equal 'parked', record[:state]
|
132
140
|
end
|
133
141
|
end
|
134
142
|
|
@@ -145,19 +153,19 @@ begin
|
|
145
153
|
class MachineWithInitialStateTest < BaseTestCase
|
146
154
|
def setup
|
147
155
|
@model = new_model
|
148
|
-
@machine = StateMachine::Machine.new(@model, :initial => '
|
156
|
+
@machine = StateMachine::Machine.new(@model, :initial => 'parked')
|
149
157
|
@record = @model.new
|
150
158
|
end
|
151
159
|
|
152
160
|
def test_should_set_initial_state_on_created_object
|
153
|
-
assert_equal '
|
161
|
+
assert_equal 'parked', @record.state
|
154
162
|
end
|
155
163
|
end
|
156
164
|
|
157
165
|
class MachineWithNonColumnStateAttributeTest < BaseTestCase
|
158
166
|
def setup
|
159
167
|
@model = new_model
|
160
|
-
@machine = StateMachine::Machine.new(@model, :status, :initial => '
|
168
|
+
@machine = StateMachine::Machine.new(@model, :status, :initial => 'parked')
|
161
169
|
@record = @model.new
|
162
170
|
end
|
163
171
|
|
@@ -170,7 +178,7 @@ begin
|
|
170
178
|
end
|
171
179
|
|
172
180
|
def test_should_set_initial_state_on_created_object
|
173
|
-
assert_equal '
|
181
|
+
assert_equal 'parked', @record.status
|
174
182
|
end
|
175
183
|
end
|
176
184
|
|
@@ -178,8 +186,9 @@ begin
|
|
178
186
|
def setup
|
179
187
|
@model = new_model
|
180
188
|
@machine = StateMachine::Machine.new(@model)
|
181
|
-
@
|
182
|
-
@
|
189
|
+
@machine.state :parked, :idling
|
190
|
+
@record = @model.new(:state => 'parked')
|
191
|
+
@transition = StateMachine::Transition.new(@record, @machine, :ignite, :parked, :idling)
|
183
192
|
end
|
184
193
|
|
185
194
|
def test_should_run_before_callbacks
|
@@ -242,11 +251,11 @@ begin
|
|
242
251
|
callback_args = nil
|
243
252
|
|
244
253
|
klass = class << @record; self; end
|
245
|
-
klass.send(:define_method, :
|
254
|
+
klass.send(:define_method, :after_ignite) do |*args|
|
246
255
|
callback_args = args
|
247
256
|
end
|
248
257
|
|
249
|
-
@machine.before_transition(:
|
258
|
+
@machine.before_transition(:after_ignite)
|
250
259
|
|
251
260
|
@transition.perform
|
252
261
|
assert_equal [@transition], callback_args
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class IntegrationMatcherTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@klass = Class.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_should_return_nil_if_no_match_found
|
9
|
+
assert_nil StateMachine::Integrations.match(@klass)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_should_return_integration_class_if_match_found
|
13
|
+
integration = Module.new do
|
14
|
+
def self.matches?(klass)
|
15
|
+
true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
StateMachine::Integrations.const_set('Custom', integration)
|
19
|
+
|
20
|
+
assert_equal integration, StateMachine::Integrations.match(@klass)
|
21
|
+
ensure
|
22
|
+
StateMachine::Integrations.send(:remove_const, 'Custom')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class IntegrationFinderTest < Test::Unit::TestCase
|
27
|
+
def test_should_find_active_record
|
28
|
+
assert_equal StateMachine::Integrations::ActiveRecord, StateMachine::Integrations.find(:active_record)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_find_data_mapper
|
32
|
+
assert_equal StateMachine::Integrations::DataMapper, StateMachine::Integrations.find(:data_mapper)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_should_find_sequel
|
36
|
+
assert_equal StateMachine::Integrations::Sequel, StateMachine::Integrations.find(:sequel)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_should_raise_an_exception_if_invalid
|
40
|
+
assert_raise(NameError) { StateMachine::Integrations.find(:invalid) }
|
41
|
+
end
|
42
|
+
end
|
data/test/unit/machine_test.rb
CHANGED
@@ -12,15 +12,19 @@ class MachineByDefaultTest < Test::Unit::TestCase
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_should_have_an_attribute
|
15
|
-
assert_equal
|
15
|
+
assert_equal :state, @machine.attribute
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
18
|
+
def test_should_have_an_initial_state
|
19
|
+
assert_not_nil @machine.initial_state(@object)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_should_have_a_nil_initial_state
|
23
|
+
assert_nil @machine.initial_state(@object).value
|
20
24
|
end
|
21
25
|
|
22
26
|
def test_should_not_have_any_events
|
23
|
-
assert
|
27
|
+
assert !@machine.events.any?
|
24
28
|
end
|
25
29
|
|
26
30
|
def test_should_not_have_any_before_callbacks
|
@@ -35,6 +39,10 @@ class MachineByDefaultTest < Test::Unit::TestCase
|
|
35
39
|
assert_nil @machine.action
|
36
40
|
end
|
37
41
|
|
42
|
+
def test_should_not_have_a_namespace
|
43
|
+
assert_nil @machine.namespace
|
44
|
+
end
|
45
|
+
|
38
46
|
def test_should_have_a_nil_state
|
39
47
|
assert_equal [nil], @machine.states.keys
|
40
48
|
end
|
@@ -67,6 +75,10 @@ class MachineByDefaultTest < Test::Unit::TestCase
|
|
67
75
|
assert @object.respond_to?(:state?)
|
68
76
|
end
|
69
77
|
|
78
|
+
def test_should_define_a_name_reader_for_the_attribute
|
79
|
+
assert @object.respond_to?(:state_name)
|
80
|
+
end
|
81
|
+
|
70
82
|
def test_should_not_define_singular_with_scope
|
71
83
|
assert !@klass.respond_to?(:with_state)
|
72
84
|
end
|
@@ -92,7 +104,7 @@ class MachineByDefaultTest < Test::Unit::TestCase
|
|
92
104
|
end
|
93
105
|
|
94
106
|
def test_should_define_state_machines_reader
|
95
|
-
expected = {
|
107
|
+
expected = {:state => @machine}
|
96
108
|
assert_equal expected, @klass.state_machines
|
97
109
|
end
|
98
110
|
end
|
@@ -100,12 +112,12 @@ end
|
|
100
112
|
class MachineWithCustomAttributeTest < Test::Unit::TestCase
|
101
113
|
def setup
|
102
114
|
@klass = Class.new
|
103
|
-
@machine = StateMachine::Machine.new(@klass,
|
115
|
+
@machine = StateMachine::Machine.new(@klass, :status)
|
104
116
|
@object = @klass.new
|
105
117
|
end
|
106
118
|
|
107
119
|
def test_should_use_custom_attribute
|
108
|
-
assert_equal
|
120
|
+
assert_equal :status, @machine.attribute
|
109
121
|
end
|
110
122
|
|
111
123
|
def test_should_define_a_reader_attribute_for_the_attribute
|
@@ -119,6 +131,10 @@ class MachineWithCustomAttributeTest < Test::Unit::TestCase
|
|
119
131
|
def test_should_define_a_predicate_for_the_attribute
|
120
132
|
assert @object.respond_to?(:status?)
|
121
133
|
end
|
134
|
+
|
135
|
+
def test_should_define_a_name_reader_for_the_attribute
|
136
|
+
assert @object.respond_to?(:status_name)
|
137
|
+
end
|
122
138
|
end
|
123
139
|
|
124
140
|
class MachineWithStaticInitialStateTest < Test::Unit::TestCase
|
@@ -130,61 +146,35 @@ class MachineWithStaticInitialStateTest < Test::Unit::TestCase
|
|
130
146
|
end
|
131
147
|
end
|
132
148
|
|
133
|
-
@machine = StateMachine::Machine.new(@klass, :initial =>
|
149
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
134
150
|
end
|
135
151
|
|
136
152
|
def test_should_have_an_initial_state
|
137
153
|
object = @klass.new
|
138
|
-
assert_equal '
|
154
|
+
assert_equal 'parked', @machine.initial_state(object).value
|
139
155
|
end
|
140
156
|
|
141
157
|
def test_should_set_initial_on_state_object
|
142
|
-
assert @machine.state(
|
158
|
+
assert @machine.state(:parked).initial
|
143
159
|
end
|
144
160
|
|
145
161
|
def test_should_set_initial_state_if_existing_is_nil
|
146
162
|
object = @klass.new(:state => nil)
|
147
|
-
assert_equal '
|
163
|
+
assert_equal 'parked', object.state
|
148
164
|
end
|
149
165
|
|
150
166
|
def test_should_set_initial_state_if_existing_is_empty
|
151
167
|
object = @klass.new(:state => '')
|
152
|
-
assert_equal '
|
168
|
+
assert_equal 'parked', object.state
|
153
169
|
end
|
154
170
|
|
155
171
|
def test_should_not_set_initial_state_if_existing_is_not_empty
|
156
|
-
object = @klass.new(:state => '
|
157
|
-
assert_equal '
|
172
|
+
object = @klass.new(:state => 'idling')
|
173
|
+
assert_equal 'idling', object.state
|
158
174
|
end
|
159
175
|
|
160
176
|
def test_should_be_included_in_known_states
|
161
|
-
assert_equal
|
162
|
-
end
|
163
|
-
|
164
|
-
def test_should_order_state_before_transition_states
|
165
|
-
@machine.event :turn_on do
|
166
|
-
transition :from => 'off', :to => 'on'
|
167
|
-
end
|
168
|
-
assert_equal %w(off on), @machine.states_order
|
169
|
-
end
|
170
|
-
|
171
|
-
def test_should_order_state_before_states_with_behaviors
|
172
|
-
@machine.state 'error' do
|
173
|
-
def color
|
174
|
-
'red'
|
175
|
-
end
|
176
|
-
end
|
177
|
-
assert_equal %w(off error), @machine.states_order
|
178
|
-
end
|
179
|
-
|
180
|
-
def test_should_order_state_before_other_states
|
181
|
-
@machine.other_states 'on'
|
182
|
-
assert_equal %w(off on), @machine.states_order
|
183
|
-
end
|
184
|
-
|
185
|
-
def test_should_order_state_before_callback_states
|
186
|
-
@machine.before_transition :from => 'on', :do => lambda {}
|
187
|
-
assert_equal %w(off on), @machine.states_order
|
177
|
+
assert_equal [:parked], @machine.states.keys
|
188
178
|
end
|
189
179
|
end
|
190
180
|
|
@@ -193,25 +183,25 @@ class MachineWithDynamicInitialStateTest < Test::Unit::TestCase
|
|
193
183
|
@klass = Class.new do
|
194
184
|
attr_accessor :initial_state
|
195
185
|
end
|
196
|
-
@
|
197
|
-
@machine
|
186
|
+
@machine = StateMachine::Machine.new(@klass, :initial => lambda {|object| object.initial_state || :default})
|
187
|
+
@machine.state :parked, :idling, :default
|
198
188
|
@object = @klass.new
|
199
189
|
end
|
200
190
|
|
201
191
|
def test_should_use_the_record_for_determining_the_initial_state
|
202
|
-
@object.initial_state =
|
203
|
-
assert_equal
|
192
|
+
@object.initial_state = :parked
|
193
|
+
assert_equal :parked, @machine.initial_state(@object).name
|
204
194
|
|
205
|
-
@object.initial_state =
|
206
|
-
assert_equal
|
195
|
+
@object.initial_state = :idling
|
196
|
+
assert_equal :idling, @machine.initial_state(@object).name
|
207
197
|
end
|
208
198
|
|
209
199
|
def test_should_set_initial_state_on_created_object
|
210
200
|
assert_equal 'default', @object.state
|
211
201
|
end
|
212
202
|
|
213
|
-
def
|
214
|
-
assert_equal [
|
203
|
+
def test_should_not_be_included_in_known_states
|
204
|
+
assert_equal [:parked, :idling, :default], @machine.states.map {|state| state.name}
|
215
205
|
end
|
216
206
|
end
|
217
207
|
|
@@ -245,36 +235,6 @@ class MachineWithNilActionTest < Test::Unit::TestCase
|
|
245
235
|
end
|
246
236
|
end
|
247
237
|
|
248
|
-
class MachineWithCustomIntegrationTest < Test::Unit::TestCase
|
249
|
-
def setup
|
250
|
-
StateMachine::Integrations.const_set('Custom', Module.new)
|
251
|
-
@machine = StateMachine::Machine.new(Class.new, :integration => :custom)
|
252
|
-
end
|
253
|
-
|
254
|
-
def test_should_be_extended_by_the_integration
|
255
|
-
assert (class << @machine; ancestors; end).include?(StateMachine::Integrations::Custom)
|
256
|
-
end
|
257
|
-
|
258
|
-
def teardown
|
259
|
-
StateMachine::Integrations.send(:remove_const, 'Custom')
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
class MachineTest < Test::Unit::TestCase
|
264
|
-
def test_should_raise_exception_if_invalid_option_specified
|
265
|
-
assert_raise(ArgumentError) {StateMachine::Machine.new(Class.new, :invalid => true)}
|
266
|
-
end
|
267
|
-
|
268
|
-
def test_should_evaluate_a_block_during_initialization
|
269
|
-
called = true
|
270
|
-
StateMachine::Machine.new(Class.new) do
|
271
|
-
called = respond_to?(:event)
|
272
|
-
end
|
273
|
-
|
274
|
-
assert called
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
238
|
class MachineWithoutIntegrationTest < Test::Unit::TestCase
|
279
239
|
def setup
|
280
240
|
@klass = Class.new
|
@@ -292,6 +252,21 @@ class MachineWithoutIntegrationTest < Test::Unit::TestCase
|
|
292
252
|
end
|
293
253
|
end
|
294
254
|
|
255
|
+
class MachineWithCustomIntegrationTest < Test::Unit::TestCase
|
256
|
+
def setup
|
257
|
+
StateMachine::Integrations.const_set('Custom', Module.new)
|
258
|
+
@machine = StateMachine::Machine.new(Class.new, :integration => :custom)
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_should_be_extended_by_the_integration
|
262
|
+
assert (class << @machine; ancestors; end).include?(StateMachine::Integrations::Custom)
|
263
|
+
end
|
264
|
+
|
265
|
+
def teardown
|
266
|
+
StateMachine::Integrations.send(:remove_const, 'Custom')
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
295
270
|
class MachineWithIntegrationTest < Test::Unit::TestCase
|
296
271
|
def setup
|
297
272
|
@integration = Module.new do
|
@@ -308,12 +283,14 @@ class MachineWithIntegrationTest < Test::Unit::TestCase
|
|
308
283
|
:save
|
309
284
|
end
|
310
285
|
|
311
|
-
def
|
286
|
+
def create_with_scope(name)
|
312
287
|
StateMachine::Integrations::Custom.with_scopes << name
|
288
|
+
lambda {}
|
313
289
|
end
|
314
290
|
|
315
|
-
def
|
291
|
+
def create_without_scope(name)
|
316
292
|
StateMachine::Integrations::Custom.without_scopes << name
|
293
|
+
lambda {}
|
317
294
|
end
|
318
295
|
end
|
319
296
|
|
@@ -347,15 +324,65 @@ class MachineWithIntegrationTest < Test::Unit::TestCase
|
|
347
324
|
end
|
348
325
|
end
|
349
326
|
|
327
|
+
class MachineWithCustomPluralTest < Test::Unit::TestCase
|
328
|
+
def setup
|
329
|
+
@integration = Module.new do
|
330
|
+
class << self; attr_accessor :with_scopes, :without_scopes; end
|
331
|
+
@initialized = false
|
332
|
+
@with_scopes = []
|
333
|
+
@without_scopes = []
|
334
|
+
|
335
|
+
def create_with_scope(name)
|
336
|
+
StateMachine::Integrations::Custom.with_scopes << name
|
337
|
+
lambda {}
|
338
|
+
end
|
339
|
+
|
340
|
+
def create_without_scope(name)
|
341
|
+
StateMachine::Integrations::Custom.without_scopes << name
|
342
|
+
lambda {}
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
StateMachine::Integrations.const_set('Custom', @integration)
|
347
|
+
@machine = StateMachine::Machine.new(Class.new, :integration => :custom, :plural => 'staties')
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_should_define_a_singular_and_plural_with_scope
|
351
|
+
assert_equal %w(with_state with_staties), @integration.with_scopes
|
352
|
+
end
|
353
|
+
|
354
|
+
def test_should_define_a_singular_and_plural_without_scope
|
355
|
+
assert_equal %w(without_state without_staties), @integration.without_scopes
|
356
|
+
end
|
357
|
+
|
358
|
+
def teardown
|
359
|
+
StateMachine::Integrations.send(:remove_const, 'Custom')
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
class MachineTest < Test::Unit::TestCase
|
364
|
+
def test_should_raise_exception_if_invalid_option_specified
|
365
|
+
assert_raise(ArgumentError) {StateMachine::Machine.new(Class.new, :invalid => true)}
|
366
|
+
end
|
367
|
+
|
368
|
+
def test_should_evaluate_a_block_during_initialization
|
369
|
+
called = true
|
370
|
+
StateMachine::Machine.new(Class.new) do
|
371
|
+
called = respond_to?(:event)
|
372
|
+
end
|
373
|
+
|
374
|
+
assert called
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
350
378
|
class MachineAfterBeingCopiedTest < Test::Unit::TestCase
|
351
379
|
def setup
|
352
|
-
@machine = StateMachine::Machine.new(Class.new,
|
353
|
-
@machine.event(:
|
380
|
+
@machine = StateMachine::Machine.new(Class.new, :state, :initial => :parked)
|
381
|
+
@machine.event(:ignite) {}
|
354
382
|
@machine.before_transition(lambda {})
|
355
383
|
@machine.after_transition(lambda {})
|
356
|
-
@machine.states # Caches the states variable
|
357
384
|
|
358
|
-
@copied_machine = @machine.
|
385
|
+
@copied_machine = @machine.clone
|
359
386
|
end
|
360
387
|
|
361
388
|
def test_should_not_have_the_same_collection_of_states
|
@@ -363,15 +390,15 @@ class MachineAfterBeingCopiedTest < Test::Unit::TestCase
|
|
363
390
|
end
|
364
391
|
|
365
392
|
def test_should_copy_each_state
|
366
|
-
assert_not_same @copied_machine.states[
|
393
|
+
assert_not_same @copied_machine.states[:parked], @machine.states[:parked]
|
367
394
|
end
|
368
395
|
|
369
396
|
def test_should_update_machine_for_each_state
|
370
|
-
assert_equal @copied_machine, @copied_machine.states[
|
397
|
+
assert_equal @copied_machine, @copied_machine.states[:parked].machine
|
371
398
|
end
|
372
399
|
|
373
400
|
def test_should_not_update_machine_for_original_state
|
374
|
-
assert_equal @machine, @machine.states[
|
401
|
+
assert_equal @machine, @machine.states[:parked].machine
|
375
402
|
end
|
376
403
|
|
377
404
|
def test_should_not_have_the_same_collection_of_events
|
@@ -379,19 +406,15 @@ class MachineAfterBeingCopiedTest < Test::Unit::TestCase
|
|
379
406
|
end
|
380
407
|
|
381
408
|
def test_should_copy_each_event
|
382
|
-
assert_not_same @copied_machine.events[
|
409
|
+
assert_not_same @copied_machine.events[:ignite], @machine.events[:ignite]
|
383
410
|
end
|
384
411
|
|
385
412
|
def test_should_update_machine_for_each_event
|
386
|
-
assert_equal @copied_machine, @copied_machine.events[
|
413
|
+
assert_equal @copied_machine, @copied_machine.events[:ignite].machine
|
387
414
|
end
|
388
415
|
|
389
416
|
def test_should_not_update_machine_for_original_event
|
390
|
-
assert_equal @machine, @machine.events[
|
391
|
-
end
|
392
|
-
|
393
|
-
def test_should_not_have_the_same_events_order
|
394
|
-
assert_not_same @copied_machine.events_order, @machine.events_order
|
417
|
+
assert_equal @machine, @machine.events[:ignite].machine
|
395
418
|
end
|
396
419
|
|
397
420
|
def test_should_not_have_the_same_callbacks
|
@@ -407,21 +430,18 @@ class MachineAfterBeingCopiedTest < Test::Unit::TestCase
|
|
407
430
|
end
|
408
431
|
end
|
409
432
|
|
410
|
-
class
|
433
|
+
class MachineAfterChangingOwnerClassTest < Test::Unit::TestCase
|
411
434
|
def setup
|
412
435
|
@original_class = Class.new
|
413
|
-
@machine = StateMachine::Machine.new(@original_class
|
436
|
+
@machine = StateMachine::Machine.new(@original_class)
|
414
437
|
|
415
438
|
@new_class = Class.new(@original_class)
|
416
|
-
@new_machine = @machine.
|
439
|
+
@new_machine = @machine.clone
|
440
|
+
@new_machine.owner_class = @new_class
|
417
441
|
|
418
442
|
@object = @new_class.new
|
419
443
|
end
|
420
444
|
|
421
|
-
def test_should_create_copy_of_machine
|
422
|
-
assert_not_same @machine, @new_machine
|
423
|
-
end
|
424
|
-
|
425
445
|
def test_should_update_owner_class
|
426
446
|
assert_equal @new_class, @new_machine.owner_class
|
427
447
|
end
|
@@ -430,53 +450,38 @@ class MachineAfterChangingContextTest < Test::Unit::TestCase
|
|
430
450
|
assert_equal @original_class, @machine.owner_class
|
431
451
|
end
|
432
452
|
|
433
|
-
def
|
434
|
-
|
435
|
-
end
|
436
|
-
|
437
|
-
def test_should_allow_changing_the_initial_state
|
438
|
-
new_machine = @machine.within_context(@new_class, :initial => 'off')
|
439
|
-
|
440
|
-
assert_equal 'off', new_machine.initial_state(@object)
|
441
|
-
assert new_machine.state('off').initial
|
442
|
-
assert !new_machine.state(nil).initial
|
443
|
-
end
|
444
|
-
|
445
|
-
def test_should_not_change_original_initial_state_if_updated
|
446
|
-
new_machine = @machine.within_context(@new_class, :initial => 'off')
|
447
|
-
assert_nil @machine.initial_state(@object)
|
448
|
-
end
|
449
|
-
|
450
|
-
def test_should_not_update_initial_state_if_not_provided
|
451
|
-
assert_nil @new_machine.initial_state(@object)
|
453
|
+
def test_should_change_the_associated_machine_in_the_new_class
|
454
|
+
assert_equal @new_machine, @new_class.state_machines[:state]
|
452
455
|
end
|
453
456
|
|
454
|
-
def
|
455
|
-
|
456
|
-
new_machine = @machine.within_context(@new_class, :integration => :custom)
|
457
|
-
assert (class << new_machine; ancestors; end).include?(StateMachine::Integrations::Custom)
|
457
|
+
def test_should_not_change_the_associated_machine_in_the_original_class
|
458
|
+
assert_equal @machine, @original_class.state_machines[:state]
|
458
459
|
end
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
460
|
+
end
|
461
|
+
|
462
|
+
class MachineAfterChangingInitialState < Test::Unit::TestCase
|
463
|
+
def setup
|
464
|
+
@klass = Class.new
|
465
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
466
|
+
@machine.initial_state = :idling
|
467
|
+
|
468
|
+
@object = @klass.new
|
464
469
|
end
|
465
470
|
|
466
|
-
def
|
467
|
-
assert_equal
|
471
|
+
def test_should_change_the_initial_state
|
472
|
+
assert_equal :idling, @machine.initial_state(@object).name
|
468
473
|
end
|
469
474
|
|
470
|
-
def
|
471
|
-
assert_equal
|
475
|
+
def test_should_include_in_known_states
|
476
|
+
assert_equal [:parked, :idling], @machine.states.map {|state| state.name}
|
472
477
|
end
|
473
478
|
|
474
|
-
def
|
475
|
-
|
479
|
+
def test_should_reset_original_initial_state
|
480
|
+
assert !@machine.state(:parked).initial
|
476
481
|
end
|
477
482
|
|
478
|
-
def
|
479
|
-
|
483
|
+
def test_should_set_new_state_to_initial
|
484
|
+
assert @machine.state(:idling).initial
|
480
485
|
end
|
481
486
|
end
|
482
487
|
|
@@ -496,24 +501,32 @@ class MachineWithConflictingAttributeAccessorsTest < Test::Unit::TestCase
|
|
496
501
|
def state?
|
497
502
|
true
|
498
503
|
end
|
504
|
+
|
505
|
+
def state_name
|
506
|
+
:parked
|
507
|
+
end
|
499
508
|
end
|
500
509
|
@machine = StateMachine::Machine.new(@klass)
|
501
510
|
@object = @klass.new
|
502
511
|
end
|
503
512
|
|
504
513
|
def test_should_not_define_attribute_reader
|
505
|
-
@object.status = '
|
506
|
-
assert_equal '
|
514
|
+
@object.status = 'parked'
|
515
|
+
assert_equal 'parked', @object.state
|
507
516
|
end
|
508
517
|
|
509
518
|
def test_should_not_define_attribute_writer
|
510
|
-
@object.state = '
|
511
|
-
assert_equal '
|
519
|
+
@object.state = 'parked'
|
520
|
+
assert_equal 'parked', @object.status
|
512
521
|
end
|
513
522
|
|
514
523
|
def test_should_not_define_attribute_predicate
|
515
524
|
assert @object.state?
|
516
525
|
end
|
526
|
+
|
527
|
+
def test_should_define_attribute_name_reader
|
528
|
+
assert_nil @object.state_name
|
529
|
+
end
|
517
530
|
end
|
518
531
|
|
519
532
|
class MachineWithConflictingPrivateAttributeAccessorsTest < Test::Unit::TestCase
|
@@ -533,24 +546,32 @@ class MachineWithConflictingPrivateAttributeAccessorsTest < Test::Unit::TestCase
|
|
533
546
|
def state?
|
534
547
|
true
|
535
548
|
end
|
549
|
+
|
550
|
+
def state_name
|
551
|
+
:parked
|
552
|
+
end
|
536
553
|
end
|
537
554
|
@machine = StateMachine::Machine.new(@klass)
|
538
555
|
@object = @klass.new
|
539
556
|
end
|
540
557
|
|
541
558
|
def test_should_not_define_attribute_reader
|
542
|
-
@object.status = '
|
543
|
-
assert_equal '
|
559
|
+
@object.status = 'parked'
|
560
|
+
assert_equal 'parked', @object.send(:state)
|
544
561
|
end
|
545
562
|
|
546
563
|
def test_should_not_define_attribute_writer
|
547
|
-
@object.send(:state=, '
|
548
|
-
assert_equal '
|
564
|
+
@object.send(:state=, 'parked')
|
565
|
+
assert_equal 'parked', @object.status
|
549
566
|
end
|
550
567
|
|
551
568
|
def test_should_not_define_attribute_predicate
|
552
569
|
assert @object.send(:state?)
|
553
570
|
end
|
571
|
+
|
572
|
+
def test_should_define_attribute_name_reader
|
573
|
+
assert_nil @object.send(:state_name)
|
574
|
+
end
|
554
575
|
end
|
555
576
|
|
556
577
|
class MachineWithConflictingScopesTest < Test::Unit::TestCase
|
@@ -607,312 +628,316 @@ class MachineWithConflictingScopesTest < Test::Unit::TestCase
|
|
607
628
|
end
|
608
629
|
end
|
609
630
|
|
610
|
-
class
|
631
|
+
class MachineWithoutInitializeTest < Test::Unit::TestCase
|
611
632
|
def setup
|
612
|
-
@
|
633
|
+
@klass = Class.new
|
634
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
635
|
+
@object = @klass.new
|
613
636
|
end
|
614
637
|
|
615
|
-
def
|
616
|
-
|
617
|
-
assert_equal 'turn_on', event.name
|
638
|
+
def test_should_initialize_state
|
639
|
+
assert_equal 'parked', @object.state
|
618
640
|
end
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
641
|
+
end
|
642
|
+
|
643
|
+
class MachineWithInitializeWithoutSuperTest < Test::Unit::TestCase
|
644
|
+
def setup
|
645
|
+
@klass = Class.new do
|
646
|
+
def initialize
|
647
|
+
end
|
624
648
|
end
|
625
|
-
|
626
|
-
|
649
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
650
|
+
@object = @klass.new
|
627
651
|
end
|
628
652
|
|
629
|
-
def
|
630
|
-
@
|
631
|
-
|
653
|
+
def test_should_not_initialize_state
|
654
|
+
assert_nil @object.state
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
class MachineWithInitializeAndSuperTest < Test::Unit::TestCase
|
659
|
+
def setup
|
660
|
+
@klass = Class.new do
|
661
|
+
def initialize
|
662
|
+
super()
|
663
|
+
end
|
664
|
+
end
|
665
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
666
|
+
@object = @klass.new
|
632
667
|
end
|
633
668
|
|
634
|
-
def
|
635
|
-
|
669
|
+
def test_should_initialize_state
|
670
|
+
assert_equal 'parked', @object.state
|
636
671
|
end
|
637
672
|
end
|
638
673
|
|
639
|
-
class
|
674
|
+
class MachineWithInitializeArgumentsAndBlockTest < Test::Unit::TestCase
|
640
675
|
def setup
|
641
|
-
@
|
642
|
-
attr_reader :
|
676
|
+
@superclass = Class.new do
|
677
|
+
attr_reader :args
|
643
678
|
attr_reader :block_given
|
644
679
|
|
645
|
-
def initialize
|
646
|
-
@
|
680
|
+
def initialize(*args)
|
681
|
+
@args = args
|
647
682
|
@block_given = block_given?
|
648
|
-
super()
|
649
683
|
end
|
650
684
|
end
|
651
|
-
|
652
|
-
@machine = StateMachine::Machine.new(@klass, :initial =>
|
653
|
-
@object = @klass.new {}
|
685
|
+
@klass = Class.new(@superclass)
|
686
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
687
|
+
@object = @klass.new(1, 2, 3) {}
|
654
688
|
end
|
655
689
|
|
656
|
-
def
|
657
|
-
|
690
|
+
def test_should_initialize_state
|
691
|
+
assert_equal 'parked', @object.state
|
658
692
|
end
|
659
693
|
|
660
|
-
def
|
661
|
-
assert_equal
|
694
|
+
def test_should_preserve_arguments
|
695
|
+
assert_equal [1, 2, 3], @object.args
|
662
696
|
end
|
663
697
|
|
664
698
|
def test_should_preserve_block
|
665
699
|
assert @object.block_given
|
666
700
|
end
|
667
|
-
|
668
|
-
def test_should_not_include_initialize_in_instance_methods
|
669
|
-
assert !@klass.instance_methods(false).include?('initialize')
|
670
|
-
end
|
671
701
|
end
|
672
702
|
|
673
|
-
class
|
703
|
+
class MachineWithCustomInitializeTest < Test::Unit::TestCase
|
674
704
|
def setup
|
675
|
-
@klass = Class.new
|
676
|
-
@machine = StateMachine::Machine.new(@klass, :initial => 'off')
|
677
|
-
@klass.class_eval do
|
678
|
-
attr_reader :initialized
|
679
|
-
attr_reader :block_given
|
680
|
-
|
705
|
+
@klass = Class.new do
|
681
706
|
def initialize
|
682
|
-
|
683
|
-
@block_given = block_given?
|
684
|
-
super()
|
707
|
+
initialize_state_machines
|
685
708
|
end
|
686
709
|
end
|
710
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
711
|
+
@object = @klass.new
|
712
|
+
end
|
713
|
+
|
714
|
+
def test_should_initialize_state
|
715
|
+
assert_equal 'parked', @object.state
|
716
|
+
end
|
717
|
+
end
|
718
|
+
|
719
|
+
class MachineWithStatesTest < Test::Unit::TestCase
|
720
|
+
def setup
|
721
|
+
@klass = Class.new
|
722
|
+
@machine = StateMachine::Machine.new(@klass)
|
723
|
+
@parked, @idling = @machine.state :parked, :idling
|
687
724
|
|
688
|
-
@object = @klass.new
|
725
|
+
@object = @klass.new
|
689
726
|
end
|
690
727
|
|
691
|
-
def
|
692
|
-
|
728
|
+
def test_should_have_states
|
729
|
+
assert_equal [nil, :parked, :idling], @machine.states.map {|state| state.name}
|
693
730
|
end
|
694
731
|
|
695
|
-
def
|
696
|
-
assert_equal
|
732
|
+
def test_should_allow_state_lookup_by_name
|
733
|
+
assert_equal @parked, @machine.states[:parked]
|
697
734
|
end
|
698
735
|
|
699
|
-
def
|
700
|
-
|
736
|
+
def test_should_allow_state_lookup_by_value
|
737
|
+
assert_equal @parked, @machine.states['parked', :value]
|
701
738
|
end
|
702
739
|
|
703
|
-
def
|
704
|
-
|
740
|
+
def test_should_use_stringified_name_for_value
|
741
|
+
assert_equal 'parked', @parked.value
|
705
742
|
end
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
def setup
|
710
|
-
@superclass = Class.new do
|
711
|
-
attr_reader :initialized
|
712
|
-
attr_reader :block_given
|
713
|
-
|
714
|
-
def initialize
|
715
|
-
@initialized = true
|
716
|
-
@block_given = block_given?
|
717
|
-
end
|
718
|
-
end
|
719
|
-
@klass = Class.new(@superclass)
|
720
|
-
@machine = StateMachine::Machine.new(@klass, :initial => 'off')
|
721
|
-
@object = @klass.new {}
|
743
|
+
|
744
|
+
def test_should_not_use_custom_matcher
|
745
|
+
assert_nil @parked.matcher
|
722
746
|
end
|
723
747
|
|
724
|
-
def
|
725
|
-
|
748
|
+
def test_should_raise_exception_if_invalid_option_specified
|
749
|
+
exception = assert_raise(ArgumentError) {@machine.state(:first_gear, :invalid => true)}
|
750
|
+
assert_equal 'Invalid key(s): invalid', exception.message
|
726
751
|
end
|
727
752
|
|
728
|
-
def
|
729
|
-
|
753
|
+
def test_should_not_be_in_state_if_value_does_not_match
|
754
|
+
assert !@machine.state?(@object, :parked)
|
755
|
+
assert !@machine.state?(@object, :idling)
|
730
756
|
end
|
731
757
|
|
732
|
-
def
|
733
|
-
assert @object
|
758
|
+
def test_should_be_in_state_if_value_matches
|
759
|
+
assert @machine.state?(@object, nil)
|
734
760
|
end
|
735
761
|
|
736
|
-
def
|
737
|
-
|
762
|
+
def test_raise_exception_if_checking_invalid_state
|
763
|
+
assert_raise(ArgumentError) { @machine.state?(@object, :invalid) }
|
764
|
+
end
|
765
|
+
|
766
|
+
def test_should_find_state_for_object_if_value_is_known
|
767
|
+
@object.state = 'parked'
|
768
|
+
assert_equal @parked, @machine.state_for(@object)
|
769
|
+
end
|
770
|
+
|
771
|
+
def test_should_raise_exception_if_finding_state_for_object_with_unknown_value
|
772
|
+
@object.state = 'invalid'
|
773
|
+
exception = assert_raise(ArgumentError) { @machine.state_for(@object) }
|
774
|
+
assert_equal '"invalid" is not a known state value', exception.message
|
738
775
|
end
|
739
776
|
end
|
740
777
|
|
741
|
-
class
|
778
|
+
class MachineWithStatesWithCustomValuesTest < Test::Unit::TestCase
|
742
779
|
def setup
|
743
|
-
@
|
744
|
-
|
745
|
-
|
746
|
-
def initialize
|
747
|
-
@base_initialized = true
|
748
|
-
end
|
749
|
-
end
|
750
|
-
@klass = Class.new(@superclass) do
|
751
|
-
attr_reader :initialized
|
752
|
-
|
753
|
-
def initialize
|
754
|
-
super
|
755
|
-
@initialized = true
|
756
|
-
end
|
757
|
-
end
|
780
|
+
@klass = Class.new
|
781
|
+
@machine = StateMachine::Machine.new(@klass)
|
782
|
+
@state = @machine.state :parked, :value => 1
|
758
783
|
|
759
|
-
@machine = StateMachine::Machine.new(@klass, :initial => 'off')
|
760
784
|
@object = @klass.new
|
785
|
+
@object.state = 1
|
786
|
+
end
|
787
|
+
|
788
|
+
def test_should_use_custom_value
|
789
|
+
assert_equal 1, @state.value
|
761
790
|
end
|
762
791
|
|
763
|
-
def
|
764
|
-
|
792
|
+
def test_should_allow_lookup_by_custom_value
|
793
|
+
assert_equal @state, @machine.states[1, :value]
|
765
794
|
end
|
766
795
|
|
767
|
-
def
|
768
|
-
assert @object
|
796
|
+
def test_should_be_in_state_if_value_matches
|
797
|
+
assert @machine.state?(@object, :parked)
|
769
798
|
end
|
770
799
|
|
771
|
-
def
|
772
|
-
|
800
|
+
def test_should_not_be_in_state_if_value_does_not_match
|
801
|
+
@object.state = 2
|
802
|
+
assert !@machine.state?(@object, :parked)
|
773
803
|
end
|
774
804
|
|
775
|
-
def
|
776
|
-
|
805
|
+
def test_should_find_state_for_object_if_value_is_known
|
806
|
+
assert_equal @state, @machine.state_for(@object)
|
777
807
|
end
|
778
808
|
end
|
779
809
|
|
780
|
-
class
|
810
|
+
class MachineWithStateWithMatchersTest < Test::Unit::TestCase
|
781
811
|
def setup
|
782
|
-
@
|
783
|
-
|
784
|
-
|
785
|
-
def initialize
|
786
|
-
@base_initialized = true
|
787
|
-
end
|
788
|
-
end
|
789
|
-
@klass = Class.new(@superclass)
|
790
|
-
|
791
|
-
@machine = StateMachine::Machine.new(@klass, :initial => 'off')
|
792
|
-
@klass.class_eval do
|
793
|
-
attr_reader :initialized
|
794
|
-
|
795
|
-
def initialize
|
796
|
-
super
|
797
|
-
@initialized = true
|
798
|
-
end
|
799
|
-
end
|
812
|
+
@klass = Class.new
|
813
|
+
@machine = StateMachine::Machine.new(@klass)
|
814
|
+
@state = @machine.state :parked, :if => lambda {|value| !value.nil?}
|
800
815
|
|
801
816
|
@object = @klass.new
|
817
|
+
@object.state = 1
|
802
818
|
end
|
803
819
|
|
804
|
-
def
|
805
|
-
|
820
|
+
def test_should_use_custom_matcher
|
821
|
+
assert_not_nil @state.matcher
|
822
|
+
assert @state.matches?(1)
|
823
|
+
assert !@state.matches?(nil)
|
806
824
|
end
|
807
825
|
|
808
|
-
def
|
809
|
-
assert @object
|
826
|
+
def test_should_be_in_state_if_value_matches
|
827
|
+
assert @machine.state?(@object, :parked)
|
810
828
|
end
|
811
829
|
|
812
|
-
def
|
813
|
-
|
830
|
+
def test_should_not_be_in_state_if_value_does_not_match
|
831
|
+
@object.state = nil
|
832
|
+
assert !@machine.state?(@object, :parked)
|
814
833
|
end
|
815
834
|
|
816
|
-
def
|
817
|
-
|
835
|
+
def test_should_find_state_for_object_if_value_is_known
|
836
|
+
assert_equal @state, @machine.state_for(@object)
|
818
837
|
end
|
819
838
|
end
|
820
839
|
|
821
|
-
class
|
840
|
+
class MachineWithStatesWithBehaviorsTest < Test::Unit::TestCase
|
822
841
|
def setup
|
823
|
-
@
|
824
|
-
|
825
|
-
|
842
|
+
@klass = Class.new
|
843
|
+
@machine = StateMachine::Machine.new(@klass)
|
844
|
+
|
845
|
+
@parked, @idling = @machine.state :parked, :idling do
|
846
|
+
def speed
|
847
|
+
0
|
826
848
|
end
|
827
849
|
end
|
828
|
-
@klass = Class.new(@superclass)
|
829
|
-
@machine = StateMachine::Machine.new(@klass, :initial => 'off')
|
830
|
-
@object = @klass.new {}
|
831
850
|
end
|
832
851
|
|
833
|
-
def
|
834
|
-
|
852
|
+
def test_should_define_behaviors_for_each_state
|
853
|
+
assert_not_nil @parked.methods[:speed]
|
854
|
+
assert_not_nil @idling.methods[:speed]
|
855
|
+
end
|
856
|
+
|
857
|
+
def test_should_define_different_behaviors_for_each_state
|
858
|
+
assert_not_equal @parked.methods[:speed], @idling.methods[:speed]
|
835
859
|
end
|
836
860
|
end
|
837
861
|
|
838
|
-
class
|
862
|
+
class MachineWithExistingStateTest < Test::Unit::TestCase
|
839
863
|
def setup
|
840
|
-
@klass = Class.new
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
def method_added(method)
|
845
|
-
super
|
846
|
-
@called_method_added = true
|
847
|
-
end
|
848
|
-
end
|
849
|
-
end
|
850
|
-
@machine = StateMachine::Machine.new(@klass, :initial => 'off')
|
851
|
-
@object = @klass.new
|
864
|
+
@klass = Class.new
|
865
|
+
@machine = StateMachine::Machine.new(@klass)
|
866
|
+
@state = @machine.state :parked
|
867
|
+
@same_state = @machine.state :parked, :value => 1
|
852
868
|
end
|
853
869
|
|
854
|
-
def
|
855
|
-
|
870
|
+
def test_should_not_create_a_new_state
|
871
|
+
assert_same @state, @same_state
|
856
872
|
end
|
857
873
|
|
858
|
-
def
|
859
|
-
assert_equal
|
874
|
+
def test_should_update_attributes
|
875
|
+
assert_equal 1, @state.value
|
876
|
+
end
|
877
|
+
|
878
|
+
def test_should_no_longer_be_able_to_look_up_state_by_original_value
|
879
|
+
assert_nil @machine.states['parked', :value]
|
880
|
+
end
|
881
|
+
|
882
|
+
def test_should_be_able_to_look_up_state_by_new_value
|
883
|
+
assert_equal @state, @machine.states[1, :value]
|
860
884
|
end
|
861
885
|
end
|
862
886
|
|
863
|
-
class
|
887
|
+
class MachineWithOtherStates < Test::Unit::TestCase
|
864
888
|
def setup
|
865
|
-
@klass = Class.new
|
866
|
-
|
867
|
-
|
868
|
-
end
|
869
|
-
end
|
870
|
-
@machine = StateMachine::Machine.new(@klass, :initial => 'off')
|
871
|
-
@object = @klass.new
|
889
|
+
@klass = Class.new
|
890
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
891
|
+
@parked, @idling = @machine.other_states(:parked, :idling)
|
872
892
|
end
|
873
893
|
|
874
|
-
def
|
875
|
-
assert_equal
|
894
|
+
def test_should_include_other_states_in_known_states
|
895
|
+
assert_equal [@parked, @idling], @machine.states.to_a
|
896
|
+
end
|
897
|
+
|
898
|
+
def test_should_use_default_value
|
899
|
+
assert_equal 'idling', @idling.value
|
900
|
+
end
|
901
|
+
|
902
|
+
def test_should_not_create_matcher
|
903
|
+
assert_nil @idling.matcher
|
876
904
|
end
|
877
905
|
end
|
878
906
|
|
879
|
-
class
|
907
|
+
class MachineWithEventsTest < Test::Unit::TestCase
|
880
908
|
def setup
|
881
|
-
@machine = StateMachine::Machine.new(Class.new
|
882
|
-
@machine.state 'on' do
|
883
|
-
def color
|
884
|
-
'green'
|
885
|
-
end
|
886
|
-
end
|
909
|
+
@machine = StateMachine::Machine.new(Class.new)
|
887
910
|
end
|
888
911
|
|
889
|
-
def
|
890
|
-
|
912
|
+
def test_should_return_the_created_event
|
913
|
+
assert_instance_of StateMachine::Event, @machine.event(:ignite)
|
891
914
|
end
|
892
915
|
|
893
|
-
def
|
894
|
-
@machine.event
|
895
|
-
|
896
|
-
end
|
897
|
-
assert_equal %w(off error on), @machine.states_order
|
916
|
+
def test_should_create_event_with_given_name
|
917
|
+
event = @machine.event(:ignite) {}
|
918
|
+
assert_equal :ignite, event.name
|
898
919
|
end
|
899
920
|
|
900
|
-
def
|
901
|
-
|
902
|
-
|
921
|
+
def test_should_evaluate_block_within_event_context
|
922
|
+
responded = false
|
923
|
+
@machine.event :ignite do
|
924
|
+
responded = respond_to?(:transition)
|
925
|
+
end
|
926
|
+
|
927
|
+
assert responded
|
903
928
|
end
|
904
929
|
|
905
|
-
def
|
906
|
-
@machine.
|
907
|
-
assert_equal
|
930
|
+
def test_should_have_events
|
931
|
+
event = @machine.event(:ignite)
|
932
|
+
assert_equal [event], @machine.events.to_a
|
908
933
|
end
|
909
934
|
end
|
910
935
|
|
911
936
|
class MachineWithExistingEventTest < Test::Unit::TestCase
|
912
937
|
def setup
|
913
938
|
@machine = StateMachine::Machine.new(Class.new)
|
914
|
-
@event = @machine.event(:
|
915
|
-
@same_event = @machine.event(:
|
939
|
+
@event = @machine.event(:ignite)
|
940
|
+
@same_event = @machine.event(:ignite)
|
916
941
|
end
|
917
942
|
|
918
943
|
def test_should_not_create_new_event
|
@@ -920,103 +945,72 @@ class MachineWithExistingEventTest < Test::Unit::TestCase
|
|
920
945
|
end
|
921
946
|
|
922
947
|
def test_should_allow_accessing_event_without_block
|
923
|
-
assert_equal @event, @machine.event(:
|
948
|
+
assert_equal @event, @machine.event(:ignite)
|
924
949
|
end
|
925
950
|
end
|
926
951
|
|
927
952
|
class MachineWithEventsWithTransitionsTest < Test::Unit::TestCase
|
928
953
|
def setup
|
929
954
|
@klass = Class.new
|
930
|
-
@machine = StateMachine::Machine.new(@klass, :initial =>
|
931
|
-
@machine.event(:
|
932
|
-
transition :to =>
|
933
|
-
transition :to =>
|
955
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
956
|
+
@event = @machine.event(:ignite) do
|
957
|
+
transition :to => :idling, :from => :parked
|
958
|
+
transition :to => :idling, :from => :stalled
|
934
959
|
end
|
935
960
|
end
|
936
961
|
|
937
962
|
def test_should_have_events
|
938
|
-
assert_equal
|
963
|
+
assert_equal [@event], @machine.events.to_a
|
939
964
|
end
|
940
965
|
|
941
966
|
def test_should_track_states_defined_in_event_transitions
|
942
|
-
assert_equal
|
967
|
+
assert_equal [:parked, :idling, :stalled], @machine.states.map {|state| state.name}
|
943
968
|
end
|
944
969
|
|
945
970
|
def test_should_not_duplicate_states_defined_in_multiple_event_transitions
|
946
|
-
@machine.event :
|
947
|
-
transition :to =>
|
971
|
+
@machine.event :park do
|
972
|
+
transition :to => :parked, :from => :idling
|
948
973
|
end
|
949
974
|
|
950
|
-
assert_equal
|
975
|
+
assert_equal [:parked, :idling, :stalled], @machine.states.map {|state| state.name}
|
951
976
|
end
|
952
977
|
|
953
978
|
def test_should_track_state_from_new_events
|
954
|
-
@machine.
|
955
|
-
|
956
|
-
transition :to => 'maybe'
|
979
|
+
@machine.event :shift_up do
|
980
|
+
transition :to => :first_gear, :from => :idling
|
957
981
|
end
|
958
982
|
|
959
|
-
assert_equal
|
960
|
-
end
|
961
|
-
|
962
|
-
def test_should_order_states_after_initial_state
|
963
|
-
assert_equal %w(off on error unknown), @machine.states_order
|
964
|
-
end
|
965
|
-
|
966
|
-
def test_should_order_states_before_states_with_behaviors
|
967
|
-
@machine.state 'tripped' do
|
968
|
-
def color
|
969
|
-
'red'
|
970
|
-
end
|
971
|
-
end
|
972
|
-
assert_equal %w(off on error unknown tripped), @machine.states_order
|
973
|
-
end
|
974
|
-
|
975
|
-
def test_should_order_states_before_other_states
|
976
|
-
@machine.other_states 'tripped'
|
977
|
-
assert_equal %w(off on error unknown tripped), @machine.states_order
|
978
|
-
end
|
979
|
-
|
980
|
-
def test_should_order_state_before_callback_states
|
981
|
-
@machine.before_transition :to => 'tripped', :do => lambda {}
|
982
|
-
assert_equal %w(off on error unknown tripped), @machine.states_order
|
983
|
+
assert_equal [:parked, :idling, :stalled, :first_gear], @machine.states.map {|state| state.name}
|
983
984
|
end
|
984
985
|
end
|
985
986
|
|
986
987
|
class MachineWithMultipleEventsTest < Test::Unit::TestCase
|
987
988
|
def setup
|
988
989
|
@klass = Class.new
|
989
|
-
@machine = StateMachine::Machine.new(@klass, :initial =>
|
990
|
-
@
|
991
|
-
transition :to =>
|
990
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
991
|
+
@park, @shift_down = @machine.event(:park, :shift_down) do
|
992
|
+
transition :to => :parked, :from => :first_gear
|
992
993
|
end
|
993
994
|
end
|
994
995
|
|
995
996
|
def test_should_have_events
|
996
|
-
assert_equal
|
997
|
+
assert_equal [@park, @shift_down], @machine.events.to_a
|
997
998
|
end
|
998
999
|
|
999
1000
|
def test_should_define_transitions_for_each_event
|
1000
|
-
[
|
1001
|
+
[@park, @shift_down].each {|event| assert_equal 1, event.guards.size}
|
1001
1002
|
end
|
1002
1003
|
|
1003
1004
|
def test_should_transition_the_same_for_each_event
|
1004
1005
|
object = @klass.new
|
1005
|
-
object.
|
1006
|
-
|
1006
|
+
object.state = 'first_gear'
|
1007
|
+
object.park
|
1008
|
+
assert_equal 'parked', object.state
|
1007
1009
|
|
1008
1010
|
object = @klass.new
|
1009
|
-
object.
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
def test_should_return_all_created_events
|
1014
|
-
assert_instance_of Array, @result
|
1015
|
-
assert_equal 2, @result.size
|
1016
|
-
end
|
1017
|
-
|
1018
|
-
def test_should_track_events_order
|
1019
|
-
assert_equal %w(turn_on activate), @machine.events_order
|
1011
|
+
object.state = 'first_gear'
|
1012
|
+
object.shift_down
|
1013
|
+
assert_equal 'parked', object.state
|
1020
1014
|
end
|
1021
1015
|
end
|
1022
1016
|
|
@@ -1026,9 +1020,9 @@ class MachineWithTransitionCallbacksTest < Test::Unit::TestCase
|
|
1026
1020
|
attr_accessor :callbacks
|
1027
1021
|
end
|
1028
1022
|
|
1029
|
-
@machine = StateMachine::Machine.new(@klass, :initial =>
|
1030
|
-
@event = @machine.event :
|
1031
|
-
transition :to =>
|
1023
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
1024
|
+
@event = @machine.event :ignite do
|
1025
|
+
transition :to => :idling, :from => :parked
|
1032
1026
|
end
|
1033
1027
|
|
1034
1028
|
@object = @klass.new
|
@@ -1036,11 +1030,13 @@ class MachineWithTransitionCallbacksTest < Test::Unit::TestCase
|
|
1036
1030
|
end
|
1037
1031
|
|
1038
1032
|
def test_should_raise_exception_if_invalid_option_specified
|
1039
|
-
assert_raise(ArgumentError) {@machine.before_transition :invalid => true}
|
1033
|
+
exception = assert_raise(ArgumentError) {@machine.before_transition :invalid => true, :do => lambda {}}
|
1034
|
+
assert_equal 'Invalid key(s): invalid', exception.message
|
1040
1035
|
end
|
1041
1036
|
|
1042
1037
|
def test_should_raise_exception_if_do_option_not_specified
|
1043
|
-
assert_raise(ArgumentError) {@machine.before_transition :to =>
|
1038
|
+
exception = assert_raise(ArgumentError) {@machine.before_transition :to => :idling}
|
1039
|
+
assert_equal ':do callback must be specified', exception.message
|
1044
1040
|
end
|
1045
1041
|
|
1046
1042
|
def test_should_invoke_callbacks_during_transition
|
@@ -1052,142 +1048,70 @@ class MachineWithTransitionCallbacksTest < Test::Unit::TestCase
|
|
1052
1048
|
end
|
1053
1049
|
|
1054
1050
|
def test_should_support_from_requirement
|
1055
|
-
@machine.before_transition :from =>
|
1056
|
-
@machine.before_transition :from =>
|
1051
|
+
@machine.before_transition :from => :parked, :do => lambda {|object| object.callbacks << :parked}
|
1052
|
+
@machine.before_transition :from => :idling, :do => lambda {|object| object.callbacks << :idling}
|
1057
1053
|
|
1058
1054
|
@event.fire(@object)
|
1059
|
-
assert_equal
|
1055
|
+
assert_equal [:parked], @object.callbacks
|
1060
1056
|
end
|
1061
1057
|
|
1062
1058
|
def test_should_support_except_from_requirement
|
1063
|
-
@machine.before_transition :except_from =>
|
1064
|
-
@machine.before_transition :except_from =>
|
1059
|
+
@machine.before_transition :except_from => :parked, :do => lambda {|object| object.callbacks << :parked}
|
1060
|
+
@machine.before_transition :except_from => :idling, :do => lambda {|object| object.callbacks << :idling}
|
1065
1061
|
|
1066
1062
|
@event.fire(@object)
|
1067
|
-
assert_equal
|
1063
|
+
assert_equal [:idling], @object.callbacks
|
1068
1064
|
end
|
1069
1065
|
|
1070
1066
|
def test_should_support_to_requirement
|
1071
|
-
@machine.before_transition :to =>
|
1072
|
-
@machine.before_transition :to =>
|
1067
|
+
@machine.before_transition :to => :parked, :do => lambda {|object| object.callbacks << :parked}
|
1068
|
+
@machine.before_transition :to => :idling, :do => lambda {|object| object.callbacks << :idling}
|
1073
1069
|
|
1074
1070
|
@event.fire(@object)
|
1075
|
-
assert_equal
|
1071
|
+
assert_equal [:idling], @object.callbacks
|
1076
1072
|
end
|
1077
1073
|
|
1078
1074
|
def test_should_support_except_to_requirement
|
1079
|
-
@machine.before_transition :except_to =>
|
1080
|
-
@machine.before_transition :except_to =>
|
1075
|
+
@machine.before_transition :except_to => :parked, :do => lambda {|object| object.callbacks << :parked}
|
1076
|
+
@machine.before_transition :except_to => :idling, :do => lambda {|object| object.callbacks << :idling}
|
1081
1077
|
|
1082
1078
|
@event.fire(@object)
|
1083
|
-
assert_equal
|
1079
|
+
assert_equal [:parked], @object.callbacks
|
1084
1080
|
end
|
1085
1081
|
|
1086
1082
|
def test_should_support_on_requirement
|
1087
|
-
@machine.before_transition :on =>
|
1088
|
-
@machine.before_transition :on =>
|
1083
|
+
@machine.before_transition :on => :park, :do => lambda {|object| object.callbacks << :park}
|
1084
|
+
@machine.before_transition :on => :ignite, :do => lambda {|object| object.callbacks << :ignite}
|
1089
1085
|
|
1090
1086
|
@event.fire(@object)
|
1091
|
-
assert_equal
|
1087
|
+
assert_equal [:ignite], @object.callbacks
|
1092
1088
|
end
|
1093
1089
|
|
1094
1090
|
def test_should_support_except_on_requirement
|
1095
|
-
@machine.before_transition :except_on =>
|
1096
|
-
@machine.before_transition :except_on =>
|
1091
|
+
@machine.before_transition :except_on => :park, :do => lambda {|object| object.callbacks << :park}
|
1092
|
+
@machine.before_transition :except_on => :ignite, :do => lambda {|object| object.callbacks << :ignite}
|
1097
1093
|
|
1098
1094
|
@event.fire(@object)
|
1099
|
-
assert_equal
|
1095
|
+
assert_equal [:park], @object.callbacks
|
1100
1096
|
end
|
1101
1097
|
|
1102
1098
|
def test_should_track_states_defined_in_transition_callbacks
|
1103
|
-
@machine.before_transition :from =>
|
1104
|
-
@machine.after_transition :from =>
|
1099
|
+
@machine.before_transition :from => :parked, :to => :idling, :do => lambda {}
|
1100
|
+
@machine.after_transition :from => :first_gear, :to => :second_gear, :do => lambda {}
|
1105
1101
|
|
1106
|
-
assert_equal
|
1102
|
+
assert_equal [:parked, :idling, :first_gear, :second_gear], @machine.states.map {|state| state.name}
|
1107
1103
|
end
|
1108
1104
|
|
1109
1105
|
def test_should_not_duplicate_states_defined_in_multiple_event_transitions
|
1110
|
-
@machine.before_transition :from =>
|
1111
|
-
@machine.after_transition :from =>
|
1112
|
-
@machine.after_transition :from =>
|
1106
|
+
@machine.before_transition :from => :parked, :to => :idling, :do => lambda {}
|
1107
|
+
@machine.after_transition :from => :first_gear, :to => :second_gear, :do => lambda {}
|
1108
|
+
@machine.after_transition :from => :parked, :to => :idling, :do => lambda {}
|
1113
1109
|
|
1114
|
-
assert_equal
|
1110
|
+
assert_equal [:parked, :idling, :first_gear, :second_gear], @machine.states.map {|state| state.name}
|
1115
1111
|
end
|
1116
1112
|
|
1117
1113
|
def test_should_define_predicates_for_each_state
|
1118
|
-
[:
|
1119
|
-
end
|
1120
|
-
|
1121
|
-
def test_should_order_states_after_initial_state
|
1122
|
-
@machine.before_transition :to => 'unknown', :do => lambda {}
|
1123
|
-
assert_equal %w(off on unknown), @machine.states_order
|
1124
|
-
end
|
1125
|
-
|
1126
|
-
def test_should_order_states_after_transition_states
|
1127
|
-
@machine.before_transition :to => 'unknown', :do => lambda {}
|
1128
|
-
@machine.event :turn_on do
|
1129
|
-
transition :to => 'error'
|
1130
|
-
end
|
1131
|
-
assert_equal %w(off on error unknown), @machine.states_order
|
1132
|
-
end
|
1133
|
-
|
1134
|
-
def test_should_order_states_after_states_with_behaviors
|
1135
|
-
@machine.before_transition :to => 'unknown', :do => lambda {}
|
1136
|
-
@machine.state 'error' do
|
1137
|
-
def color
|
1138
|
-
'red'
|
1139
|
-
end
|
1140
|
-
end
|
1141
|
-
assert_equal %w(off on error unknown), @machine.states_order
|
1142
|
-
end
|
1143
|
-
|
1144
|
-
def test_should_order_states_after_other_states
|
1145
|
-
@machine.before_transition :to => 'unknown', :do => lambda {}
|
1146
|
-
@machine.other_states 'error'
|
1147
|
-
assert_equal %w(off on error unknown), @machine.states_order
|
1148
|
-
end
|
1149
|
-
end
|
1150
|
-
|
1151
|
-
class MachineWithOtherStates < Test::Unit::TestCase
|
1152
|
-
def setup
|
1153
|
-
@klass = Class.new
|
1154
|
-
@machine = StateMachine::Machine.new(@klass, :initial => 'off')
|
1155
|
-
@machine.other_states('off', 'on')
|
1156
|
-
end
|
1157
|
-
|
1158
|
-
def test_should_include_other_states_in_known_states
|
1159
|
-
assert_equal %w(off on), @machine.states.keys.sort
|
1160
|
-
end
|
1161
|
-
|
1162
|
-
def test_should_define_predicates_for_each_state
|
1163
|
-
object = @klass.new
|
1164
|
-
|
1165
|
-
[:on?, :off?].each {|predicate| assert object.respond_to?(predicate)}
|
1166
|
-
end
|
1167
|
-
|
1168
|
-
def test_should_order_states_after_initial_state
|
1169
|
-
assert_equal %w(off on), @machine.states_order
|
1170
|
-
end
|
1171
|
-
|
1172
|
-
def test_should_order_states_after_transition_states
|
1173
|
-
@machine.event :turn_on do
|
1174
|
-
transition :to => 'error'
|
1175
|
-
end
|
1176
|
-
assert_equal %w(off error on), @machine.states_order
|
1177
|
-
end
|
1178
|
-
|
1179
|
-
def test_should_order_states_after_states_with_behaviors
|
1180
|
-
@machine.state 'error' do
|
1181
|
-
def color
|
1182
|
-
'red'
|
1183
|
-
end
|
1184
|
-
end
|
1185
|
-
assert_equal %w(off error on), @machine.states_order
|
1186
|
-
end
|
1187
|
-
|
1188
|
-
def test_should_order_state_before_callback_states
|
1189
|
-
@machine.before_transition :to => 'error', :do => lambda {}
|
1190
|
-
assert_equal %w(off on error), @machine.states_order
|
1114
|
+
[:parked?, :idling?].each {|predicate| assert @object.respond_to?(predicate)}
|
1191
1115
|
end
|
1192
1116
|
end
|
1193
1117
|
|
@@ -1210,63 +1134,63 @@ end
|
|
1210
1134
|
class MachineWithExistingMachinesOnOwnerClassTest < Test::Unit::TestCase
|
1211
1135
|
def setup
|
1212
1136
|
@klass = Class.new
|
1213
|
-
@machine = StateMachine::Machine.new(@klass, :initial =>
|
1214
|
-
@second_machine = StateMachine::Machine.new(@klass,
|
1137
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
1138
|
+
@second_machine = StateMachine::Machine.new(@klass, :status, :initial => :idling)
|
1215
1139
|
@object = @klass.new
|
1216
1140
|
end
|
1217
1141
|
|
1218
1142
|
def test_should_track_each_state_machine
|
1219
|
-
expected = {
|
1143
|
+
expected = {:state => @machine, :status => @second_machine}
|
1220
1144
|
assert_equal expected, @klass.state_machines
|
1221
1145
|
end
|
1222
1146
|
|
1223
1147
|
def test_should_initialize_state_for_both_machines
|
1224
|
-
assert_equal '
|
1225
|
-
assert_equal '
|
1148
|
+
assert_equal 'parked', @object.state
|
1149
|
+
assert_equal 'idling', @object.status
|
1226
1150
|
end
|
1227
1151
|
end
|
1228
1152
|
|
1229
1153
|
class MachineWithNamespaceTest < Test::Unit::TestCase
|
1230
1154
|
def setup
|
1231
1155
|
@klass = Class.new
|
1232
|
-
@machine = StateMachine::Machine.new(@klass, :namespace => '
|
1233
|
-
event :
|
1234
|
-
transition :to =>
|
1156
|
+
@machine = StateMachine::Machine.new(@klass, :namespace => 'car', :initial => :parked) do
|
1157
|
+
event :ignite do
|
1158
|
+
transition :to => :idling, :from => :parked
|
1235
1159
|
end
|
1236
1160
|
|
1237
|
-
event :
|
1238
|
-
transition :to =>
|
1161
|
+
event :park do
|
1162
|
+
transition :to => :parked, :from => :idling
|
1239
1163
|
end
|
1240
1164
|
end
|
1241
1165
|
@object = @klass.new
|
1242
1166
|
end
|
1243
1167
|
|
1244
1168
|
def test_should_namespace_state_predicates
|
1245
|
-
[:
|
1169
|
+
[:car_parked?, :car_idling?].each do |name|
|
1246
1170
|
assert @object.respond_to?(name)
|
1247
1171
|
end
|
1248
1172
|
end
|
1249
1173
|
|
1250
1174
|
def test_should_namespace_event_checks
|
1251
|
-
[:
|
1175
|
+
[:can_ignite_car?, :can_park_car?].each do |name|
|
1252
1176
|
assert @object.respond_to?(name)
|
1253
1177
|
end
|
1254
1178
|
end
|
1255
1179
|
|
1256
1180
|
def test_should_namespace_event_transition_readers
|
1257
|
-
[:
|
1181
|
+
[:next_ignite_car_transition, :next_park_car_transition].each do |name|
|
1258
1182
|
assert @object.respond_to?(name)
|
1259
1183
|
end
|
1260
1184
|
end
|
1261
1185
|
|
1262
1186
|
def test_should_namespace_events
|
1263
|
-
[:
|
1187
|
+
[:ignite_car, :park_car].each do |name|
|
1264
1188
|
assert @object.respond_to?(name)
|
1265
1189
|
end
|
1266
1190
|
end
|
1267
1191
|
|
1268
1192
|
def test_should_namespace_bang_events
|
1269
|
-
[:
|
1193
|
+
[:ignite_car!, :park_car!].each do |name|
|
1270
1194
|
assert @object.respond_to?(name)
|
1271
1195
|
end
|
1272
1196
|
end
|
@@ -1292,7 +1216,7 @@ class MachineFinderWithoutExistingMachineTest < Test::Unit::TestCase
|
|
1292
1216
|
end
|
1293
1217
|
|
1294
1218
|
def test_should_use_default_state
|
1295
|
-
assert_equal
|
1219
|
+
assert_equal :state, @machine.attribute
|
1296
1220
|
end
|
1297
1221
|
end
|
1298
1222
|
|
@@ -1327,13 +1251,13 @@ class MachineFinderWithExistingMachineOnSuperclassTest < Test::Unit::TestCase
|
|
1327
1251
|
StateMachine::Integrations.const_set('Custom', integration)
|
1328
1252
|
|
1329
1253
|
@base_class = Class.new
|
1330
|
-
@base_machine = StateMachine::Machine.new(@base_class,
|
1331
|
-
@base_machine.event(:
|
1254
|
+
@base_machine = StateMachine::Machine.new(@base_class, :status, :action => :save, :integration => :custom)
|
1255
|
+
@base_machine.event(:ignite) {}
|
1332
1256
|
@base_machine.before_transition(lambda {})
|
1333
1257
|
@base_machine.after_transition(lambda {})
|
1334
1258
|
|
1335
1259
|
@klass = Class.new(@base_class)
|
1336
|
-
@machine = StateMachine::Machine.find_or_create(@klass,
|
1260
|
+
@machine = StateMachine::Machine.find_or_create(@klass, :status)
|
1337
1261
|
end
|
1338
1262
|
|
1339
1263
|
def test_should_accept_a_block
|
@@ -1351,7 +1275,7 @@ class MachineFinderWithExistingMachineOnSuperclassTest < Test::Unit::TestCase
|
|
1351
1275
|
end
|
1352
1276
|
|
1353
1277
|
def test_should_copy_the_base_attribute
|
1354
|
-
assert_equal
|
1278
|
+
assert_equal :status, @machine.attribute
|
1355
1279
|
end
|
1356
1280
|
|
1357
1281
|
def test_should_copy_the_base_configuration
|
@@ -1360,7 +1284,7 @@ class MachineFinderWithExistingMachineOnSuperclassTest < Test::Unit::TestCase
|
|
1360
1284
|
|
1361
1285
|
def test_should_copy_events
|
1362
1286
|
# Can't assert equal arrays since their machines change
|
1363
|
-
assert_equal 1, @machine.events.
|
1287
|
+
assert_equal 1, @machine.events.length
|
1364
1288
|
end
|
1365
1289
|
|
1366
1290
|
def test_should_copy_before_callbacks
|
@@ -1383,16 +1307,16 @@ end
|
|
1383
1307
|
class MachineFinderCustomOptionsTest < Test::Unit::TestCase
|
1384
1308
|
def setup
|
1385
1309
|
@klass = Class.new
|
1386
|
-
@machine = StateMachine::Machine.find_or_create(@klass,
|
1310
|
+
@machine = StateMachine::Machine.find_or_create(@klass, :status, :initial => :parked)
|
1387
1311
|
@object = @klass.new
|
1388
1312
|
end
|
1389
1313
|
|
1390
1314
|
def test_should_use_custom_attribute
|
1391
|
-
assert_equal
|
1315
|
+
assert_equal :status, @machine.attribute
|
1392
1316
|
end
|
1393
1317
|
|
1394
1318
|
def test_should_set_custom_initial_state
|
1395
|
-
assert_equal
|
1319
|
+
assert_equal :parked, @machine.initial_state(@object).name
|
1396
1320
|
end
|
1397
1321
|
end
|
1398
1322
|
|
@@ -1406,9 +1330,9 @@ begin
|
|
1406
1330
|
@klass = Class.new do
|
1407
1331
|
def self.name; 'Vehicle'; end
|
1408
1332
|
end
|
1409
|
-
@machine = StateMachine::Machine.new(@klass)
|
1333
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
1410
1334
|
@machine.event :ignite do
|
1411
|
-
transition :
|
1335
|
+
transition :to => :idling, :from => :parked
|
1412
1336
|
end
|
1413
1337
|
end
|
1414
1338
|
|
@@ -1450,10 +1374,12 @@ begin
|
|
1450
1374
|
@klass = Class.new do
|
1451
1375
|
def self.name; 'Vehicle'; end
|
1452
1376
|
end
|
1453
|
-
@machine = StateMachine::Machine.new(@klass, :state_id)
|
1377
|
+
@machine = StateMachine::Machine.new(@klass, :state_id, :initial => :parked)
|
1454
1378
|
@machine.event :ignite do
|
1455
|
-
transition :
|
1379
|
+
transition :to => :idling, :from => :parked
|
1456
1380
|
end
|
1381
|
+
@machine.state :parked, :value => 1
|
1382
|
+
@machine.state :idling, :value => 2
|
1457
1383
|
@machine.draw
|
1458
1384
|
end
|
1459
1385
|
|
@@ -1469,17 +1395,18 @@ begin
|
|
1469
1395
|
@klass = Class.new do
|
1470
1396
|
def self.name; 'Vehicle'; end
|
1471
1397
|
end
|
1472
|
-
@machine = StateMachine::Machine.new(@klass, :
|
1473
|
-
@machine.event :
|
1474
|
-
transition :
|
1398
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
1399
|
+
@machine.event :ignite do
|
1400
|
+
transition :to => :idling, :from => :parked
|
1475
1401
|
end
|
1402
|
+
@machine.state :parked, :value => nil
|
1476
1403
|
@machine.draw
|
1477
1404
|
end
|
1478
1405
|
|
1479
1406
|
def test_should_draw_machine
|
1480
|
-
assert File.exist?('./
|
1407
|
+
assert File.exist?('./Vehicle_state.png')
|
1481
1408
|
ensure
|
1482
|
-
FileUtils.rm('./
|
1409
|
+
FileUtils.rm('./Vehicle_state.png')
|
1483
1410
|
end
|
1484
1411
|
end
|
1485
1412
|
|
@@ -1488,17 +1415,18 @@ begin
|
|
1488
1415
|
@klass = Class.new do
|
1489
1416
|
def self.name; 'Vehicle'; end
|
1490
1417
|
end
|
1491
|
-
@machine = StateMachine::Machine.new(@klass, :
|
1418
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
1492
1419
|
@machine.event :activate do
|
1493
|
-
transition :
|
1420
|
+
transition :to => :idling, :from => :parked
|
1494
1421
|
end
|
1422
|
+
@machine.state :idling, :value => lambda {Time.now}
|
1495
1423
|
@machine.draw
|
1496
1424
|
end
|
1497
1425
|
|
1498
1426
|
def test_should_draw_machine
|
1499
|
-
assert File.exist?('./
|
1427
|
+
assert File.exist?('./Vehicle_state.png')
|
1500
1428
|
ensure
|
1501
|
-
FileUtils.rm('./
|
1429
|
+
FileUtils.rm('./Vehicle_state.png')
|
1502
1430
|
end
|
1503
1431
|
end
|
1504
1432
|
|
@@ -1509,12 +1437,13 @@ begin
|
|
1509
1437
|
end
|
1510
1438
|
@machine = StateMachine::Machine.new(@klass)
|
1511
1439
|
@machine.event :ignite do
|
1512
|
-
transition :
|
1440
|
+
transition :to => :idling, :from => :parked
|
1513
1441
|
end
|
1514
1442
|
end
|
1515
1443
|
|
1516
1444
|
def test_should_raise_exception_if_no_class_names_specified
|
1517
|
-
assert_raise(ArgumentError) {StateMachine::Machine.draw(nil)}
|
1445
|
+
exception = assert_raise(ArgumentError) {StateMachine::Machine.draw(nil)}
|
1446
|
+
assert_equal 'At least one class must be specified', exception.message
|
1518
1447
|
end
|
1519
1448
|
|
1520
1449
|
def test_should_load_files
|
@@ -1532,5 +1461,5 @@ begin
|
|
1532
1461
|
end
|
1533
1462
|
end
|
1534
1463
|
rescue LoadError
|
1535
|
-
$stderr.puts 'Skipping GraphViz tests. `gem install ruby-graphviz` and try again.'
|
1464
|
+
$stderr.puts 'Skipping GraphViz StateMachine::Machine tests. `gem install ruby-graphviz` and try again.'
|
1536
1465
|
end
|