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.
Files changed (48) hide show
  1. data/CHANGELOG.rdoc +17 -0
  2. data/LICENSE +1 -1
  3. data/README.rdoc +54 -84
  4. data/Rakefile +1 -1
  5. data/examples/Car_state.png +0 -0
  6. data/examples/Vehicle_state.png +0 -0
  7. data/examples/auto_shop.rb +11 -0
  8. data/examples/car.rb +19 -0
  9. data/examples/traffic_light.rb +9 -0
  10. data/examples/vehicle.rb +35 -0
  11. data/lib/state_machine.rb +65 -52
  12. data/lib/state_machine/assertions.rb +1 -1
  13. data/lib/state_machine/callback.rb +13 -9
  14. data/lib/state_machine/eval_helpers.rb +4 -3
  15. data/lib/state_machine/event.rb +51 -33
  16. data/lib/state_machine/extensions.rb +2 -2
  17. data/lib/state_machine/guard.rb +47 -41
  18. data/lib/state_machine/integrations.rb +67 -0
  19. data/lib/state_machine/integrations/active_record.rb +62 -36
  20. data/lib/state_machine/integrations/active_record/observer.rb +41 -0
  21. data/lib/state_machine/integrations/data_mapper.rb +23 -37
  22. data/lib/state_machine/integrations/data_mapper/observer.rb +23 -9
  23. data/lib/state_machine/integrations/sequel.rb +23 -24
  24. data/lib/state_machine/machine.rb +380 -277
  25. data/lib/state_machine/node_collection.rb +142 -0
  26. data/lib/state_machine/state.rb +114 -69
  27. data/lib/state_machine/state_collection.rb +38 -0
  28. data/lib/state_machine/transition.rb +36 -17
  29. data/test/active_record.log +2940 -85664
  30. data/test/functional/state_machine_test.rb +49 -53
  31. data/test/sequel.log +747 -11990
  32. data/test/unit/assertions_test.rb +2 -1
  33. data/test/unit/callback_test.rb +14 -12
  34. data/test/unit/eval_helpers_test.rb +25 -6
  35. data/test/unit/event_test.rb +144 -124
  36. data/test/unit/guard_test.rb +118 -140
  37. data/test/unit/integrations/active_record_test.rb +102 -68
  38. data/test/unit/integrations/data_mapper_test.rb +48 -37
  39. data/test/unit/integrations/sequel_test.rb +34 -25
  40. data/test/unit/integrations_test.rb +42 -0
  41. data/test/unit/machine_test.rb +460 -531
  42. data/test/unit/node_collection_test.rb +208 -0
  43. data/test/unit/state_collection_test.rb +167 -0
  44. data/test/unit/state_machine_test.rb +1 -1
  45. data/test/unit/state_test.rb +223 -200
  46. data/test/unit/transition_test.rb +81 -46
  47. metadata +17 -3
  48. 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
- off = @model.create :state => 'off'
65
- on = @model.create :state => 'on'
65
+ parked = @model.create :state => 'parked'
66
+ idling = @model.create :state => 'idling'
66
67
 
67
- assert_equal [off], @model.with_state('off').all
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
- off = @model.create :state => 'off'
76
- on = @model.create :state => 'on'
76
+ parked = @model.create :state => 'parked'
77
+ idling = @model.create :state => 'idling'
77
78
 
78
- assert_equal [off, on], @model.with_states('off', 'on').all
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
- off = @model.create :state => 'off'
87
- on = @model.create :state => 'on'
87
+ parked = @model.create :state => 'parked'
88
+ idling = @model.create :state => 'idling'
88
89
 
89
- assert_equal [off], @model.without_state('on').all
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
- off = @model.create :state => 'off'
98
- on = @model.create :state => 'on'
99
- error = @model.create :state => 'error'
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 [off, on], @model.without_states('error').all
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] = 'off'
125
- assert_equal 'off', record.state
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 = 'off'
131
- assert_equal 'off', record[:state]
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 => 'off')
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 'off', @record.state
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 => 'off')
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 'off', @record.status
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
- @record = @model.new(:state => 'off')
182
- @transition = StateMachine::Transition.new(@record, @machine, 'turn_on', 'off', 'on')
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, :after_turn_on) do |*args|
254
+ klass.send(:define_method, :after_ignite) do |*args|
246
255
  callback_args = args
247
256
  end
248
257
 
249
- @machine.before_transition(:after_turn_on)
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
@@ -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 'state', @machine.attribute
15
+ assert_equal :state, @machine.attribute
16
16
  end
17
17
 
18
- def test_should_not_have_an_initial_state
19
- assert_nil @machine.initial_state(@object)
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 @machine.events.empty?
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 = {'state' => @machine}
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, 'status')
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 'status', @machine.attribute
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 => 'off')
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 'off', @machine.initial_state(object)
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('off').initial
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 'off', object.state
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 'off', object.state
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 => 'on')
157
- assert_equal 'on', object.state
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 %w(off), @machine.states.keys
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
- @initial_state = lambda {|object| object.initial_state || 'default'}
197
- @machine = StateMachine::Machine.new(@klass, :initial => @initial_state)
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 = 'off'
203
- assert_equal 'off', @machine.initial_state(@object)
192
+ @object.initial_state = :parked
193
+ assert_equal :parked, @machine.initial_state(@object).name
204
194
 
205
- @object.initial_state = 'on'
206
- assert_equal 'on', @machine.initial_state(@object)
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 test_should_be_included_in_known_states
214
- assert_equal [@initial_state], @machine.states.keys
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 define_with_scope(name)
286
+ def create_with_scope(name)
312
287
  StateMachine::Integrations::Custom.with_scopes << name
288
+ lambda {}
313
289
  end
314
290
 
315
- def define_without_scope(name)
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, 'state', :initial => 'off')
353
- @machine.event(:turn_on) {}
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.dup
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['off'], @machine.states['off']
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['off'].machine
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['off'].machine
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['turn_on'], @machine.events['turn_on']
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['turn_on'].machine
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['turn_on'].machine
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 MachineAfterChangingContextTest < Test::Unit::TestCase
433
+ class MachineAfterChangingOwnerClassTest < Test::Unit::TestCase
411
434
  def setup
412
435
  @original_class = Class.new
413
- @machine = StateMachine::Machine.new(@original_class, 'state')
436
+ @machine = StateMachine::Machine.new(@original_class)
414
437
 
415
438
  @new_class = Class.new(@original_class)
416
- @new_machine = @machine.within_context(@new_class)
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 test_should_still_have_an_initial_state
434
- assert @new_machine.states[nil].initial
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 test_should_allow_changing_the_integration
455
- StateMachine::Integrations.const_set('Custom', Module.new)
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
- def test_should_not_change_original_integration_if_updated
461
- StateMachine::Integrations.const_set('Custom', Module.new)
462
- new_machine = @machine.within_context(@new_class, :integration => :custom)
463
- assert !(class << @machine; ancestors; end).include?(StateMachine::Integrations::Custom)
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 test_should_change_the_associated_machine_in_the_new_class
467
- assert_equal @new_machine, @new_class.state_machines['state']
471
+ def test_should_change_the_initial_state
472
+ assert_equal :idling, @machine.initial_state(@object).name
468
473
  end
469
474
 
470
- def test_should_not_change_the_associated_machine_in_the_original_class
471
- assert_equal @machine, @original_class.state_machines['state']
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 test_raise_exception_if_invalid_option_specified
475
- assert_raise(ArgumentError) {@machine.within_context(@new_class, :invalid => true)}
479
+ def test_should_reset_original_initial_state
480
+ assert !@machine.state(:parked).initial
476
481
  end
477
482
 
478
- def teardown
479
- StateMachine::Integrations.send(:remove_const, 'Custom') if StateMachine::Integrations.const_defined?('Custom')
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 = 'on'
506
- assert_equal 'on', @object.state
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 = 'on'
511
- assert_equal 'on', @object.status
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 = 'on'
543
- assert_equal 'on', @object.send(:state)
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=, 'on')
548
- assert_equal 'on', @object.status
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 MachineWithEventsTest < Test::Unit::TestCase
631
+ class MachineWithoutInitializeTest < Test::Unit::TestCase
611
632
  def setup
612
- @machine = StateMachine::Machine.new(Class.new)
633
+ @klass = Class.new
634
+ @machine = StateMachine::Machine.new(@klass, :initial => :parked)
635
+ @object = @klass.new
613
636
  end
614
637
 
615
- def test_should_create_event_with_given_name
616
- event = @machine.event(:turn_on) {}
617
- assert_equal 'turn_on', event.name
638
+ def test_should_initialize_state
639
+ assert_equal 'parked', @object.state
618
640
  end
619
-
620
- def test_should_evaluate_block_within_event_context
621
- responded = false
622
- @machine.event :turn_on do
623
- responded = respond_to?(:transition)
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
- assert responded
649
+ @machine = StateMachine::Machine.new(@klass, :initial => :parked)
650
+ @object = @klass.new
627
651
  end
628
652
 
629
- def test_should_have_events
630
- @machine.event(:turn_on)
631
- assert_equal %w(turn_on), @machine.events.keys
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 test_should_return_the_created_event
635
- assert_instance_of StateMachine::Event, @machine.event(:turn_on)
669
+ def test_should_initialize_state
670
+ assert_equal 'parked', @object.state
636
671
  end
637
672
  end
638
673
 
639
- class MachineWithConflictingPredefinedInitializeTest < Test::Unit::TestCase
674
+ class MachineWithInitializeArgumentsAndBlockTest < Test::Unit::TestCase
640
675
  def setup
641
- @klass = Class.new do
642
- attr_reader :initialized
676
+ @superclass = Class.new do
677
+ attr_reader :args
643
678
  attr_reader :block_given
644
679
 
645
- def initialize
646
- @initialized = true
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 => 'off')
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 test_should_not_override_existing_method
657
- assert @object.initialized
690
+ def test_should_initialize_state
691
+ assert_equal 'parked', @object.state
658
692
  end
659
693
 
660
- def test_should_still_initialize_state
661
- assert_equal 'off', @object.state
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 MachineWithConflictingPostdefinedInitializeTest < Test::Unit::TestCase
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
- @initialized = true
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 test_should_not_override_existing_method
692
- assert @object.initialized
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 test_should_still_initialize_state
696
- assert_equal 'off', @object.state
732
+ def test_should_allow_state_lookup_by_name
733
+ assert_equal @parked, @machine.states[:parked]
697
734
  end
698
735
 
699
- def test_should_preserve_block
700
- assert @object.block_given
736
+ def test_should_allow_state_lookup_by_value
737
+ assert_equal @parked, @machine.states['parked', :value]
701
738
  end
702
739
 
703
- def test_should_not_include_initialize_in_instance_methods
704
- assert !@klass.instance_methods(false).include?('initialize')
740
+ def test_should_use_stringified_name_for_value
741
+ assert_equal 'parked', @parked.value
705
742
  end
706
- end
707
-
708
- class MachineWithConflictingSuperclassInitializeTest < Test::Unit::TestCase
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 test_should_not_override_existing_method
725
- assert @object.initialized
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 test_should_still_initialize_state
729
- assert_equal 'off', @object.state
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 test_should_preserve_block
733
- assert @object.block_given
758
+ def test_should_be_in_state_if_value_matches
759
+ assert @machine.state?(@object, nil)
734
760
  end
735
761
 
736
- def test_should_not_include_initialize_in_instance_methods
737
- assert !@klass.instance_methods(false).include?('initialize')
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 MachineWithConflictingPredefinedAndSuperclassInitializeTest < Test::Unit::TestCase
778
+ class MachineWithStatesWithCustomValuesTest < Test::Unit::TestCase
742
779
  def setup
743
- @superclass = Class.new do
744
- attr_reader :base_initialized
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 test_should_not_override_base_method
764
- assert @object.base_initialized
792
+ def test_should_allow_lookup_by_custom_value
793
+ assert_equal @state, @machine.states[1, :value]
765
794
  end
766
795
 
767
- def test_should_not_override_existing_method
768
- assert @object.initialized
796
+ def test_should_be_in_state_if_value_matches
797
+ assert @machine.state?(@object, :parked)
769
798
  end
770
799
 
771
- def test_should_still_initialize_state
772
- assert_equal 'off', @object.state
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 test_should_not_include_initialize_in_instance_methods
776
- assert !@klass.instance_methods(false).include?('initialize')
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 MachineWithConflictingPostdefinedAndSuperclassInitializeTest < Test::Unit::TestCase
810
+ class MachineWithStateWithMatchersTest < Test::Unit::TestCase
781
811
  def setup
782
- @superclass = Class.new do
783
- attr_reader :base_initialized
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 test_should_not_override_base_method
805
- assert @object.base_initialized
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 test_should_not_override_existing_method
809
- assert @object.initialized
826
+ def test_should_be_in_state_if_value_matches
827
+ assert @machine.state?(@object, :parked)
810
828
  end
811
829
 
812
- def test_should_still_initialize_state
813
- assert_equal 'off', @object.state
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 test_should_not_include_initialize_in_instance_methods
817
- assert !@klass.instance_methods(false).include?('initialize')
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 MachineWithCustomStateMachineInitializationTest < Test::Unit::TestCase
840
+ class MachineWithStatesWithBehaviorsTest < Test::Unit::TestCase
822
841
  def setup
823
- @superclass = Class.new do
824
- def initialize
825
- initialize_state_machines
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 test_should_still_initialize_state
834
- assert_equal 'off', @object.state
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 MachineWithConflictingMethodAddedTest < Test::Unit::TestCase
862
+ class MachineWithExistingStateTest < Test::Unit::TestCase
839
863
  def setup
840
- @klass = Class.new do
841
- class << self
842
- attr_reader :called_method_added
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 test_should_not_override_existing_method
855
- assert @klass.called_method_added
870
+ def test_should_not_create_a_new_state
871
+ assert_same @state, @same_state
856
872
  end
857
873
 
858
- def test_should_still_initialize_state
859
- assert_equal 'off', @object.state
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 MachineWithExistingAttributeValue < Test::Unit::TestCase
887
+ class MachineWithOtherStates < Test::Unit::TestCase
864
888
  def setup
865
- @klass = Class.new do
866
- def initialize
867
- @state = 'on'
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 test_should_not_set_the_initial_state
875
- assert_equal 'on', @object.state
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 MachineWithStateDrivenBehaviorsTest < Test::Unit::TestCase
907
+ class MachineWithEventsTest < Test::Unit::TestCase
880
908
  def setup
881
- @machine = StateMachine::Machine.new(Class.new, :initial => 'off')
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 test_should_order_states_after_initial_state
890
- assert_equal %w(off on), @machine.states_order
912
+ def test_should_return_the_created_event
913
+ assert_instance_of StateMachine::Event, @machine.event(:ignite)
891
914
  end
892
915
 
893
- def test_should_order_states_after_transition_states
894
- @machine.event :turn_on do
895
- transition :to => 'error'
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 test_should_order_states_before_other_states
901
- @machine.other_states 'error'
902
- assert_equal %w(off on error), @machine.states_order
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 test_should_order_state_before_callback_states
906
- @machine.before_transition :to => 'error', :do => lambda {}
907
- assert_equal %w(off on error), @machine.states_order
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(:turn_on)
915
- @same_event = @machine.event(:turn_on)
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(:turn_on)
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 => 'off')
931
- @machine.event(:turn_on) do
932
- transition :to => 'on', :from => 'off'
933
- transition :to => 'error', :from => 'unknown'
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 %w(turn_on), @machine.events.keys
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 %w(error off on unknown), @machine.states.keys.sort
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 :turn_off do
947
- transition :to => 'off', :from => 'on'
971
+ @machine.event :park do
972
+ transition :to => :parked, :from => :idling
948
973
  end
949
974
 
950
- assert_equal %w(error off on unknown), @machine.states.keys.sort
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.states
955
- @machine.event :turn_off do
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 %w(error maybe off on unknown), @machine.states.keys.sort
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 => 'off')
990
- @result = @machine.event(:turn_on, :activate) do
991
- transition :to => 'on', :from => 'off'
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 %w(activate turn_on), @machine.events.keys.sort
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
- [:turn_on, :activate].each {|event| assert_equal 1, @machine.event(event).guards.size}
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.turn_on
1006
- assert_equal 'on', object.state
1006
+ object.state = 'first_gear'
1007
+ object.park
1008
+ assert_equal 'parked', object.state
1007
1009
 
1008
1010
  object = @klass.new
1009
- object.activate
1010
- assert_equal 'on', object.state
1011
- end
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 => 'off')
1030
- @event = @machine.event :turn_on do
1031
- transition :to => 'on', :from => 'off'
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 => 'on'}
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 => 'off', :do => lambda {|object| object.callbacks << 'off'}
1056
- @machine.before_transition :from => 'on', :do => lambda {|object| object.callbacks << 'on'}
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 %w(off), @object.callbacks
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 => 'off', :do => lambda {|object| object.callbacks << 'off'}
1064
- @machine.before_transition :except_from => 'on', :do => lambda {|object| object.callbacks << 'on'}
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 %w(on), @object.callbacks
1063
+ assert_equal [:idling], @object.callbacks
1068
1064
  end
1069
1065
 
1070
1066
  def test_should_support_to_requirement
1071
- @machine.before_transition :to => 'off', :do => lambda {|object| object.callbacks << 'off'}
1072
- @machine.before_transition :to => 'on', :do => lambda {|object| object.callbacks << 'on'}
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 %w(on), @object.callbacks
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 => 'off', :do => lambda {|object| object.callbacks << 'off'}
1080
- @machine.before_transition :except_to => 'on', :do => lambda {|object| object.callbacks << 'on'}
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 %w(off), @object.callbacks
1079
+ assert_equal [:parked], @object.callbacks
1084
1080
  end
1085
1081
 
1086
1082
  def test_should_support_on_requirement
1087
- @machine.before_transition :on => 'turn_off', :do => lambda {|object| object.callbacks << 'turn_off'}
1088
- @machine.before_transition :on => 'turn_on', :do => lambda {|object| object.callbacks << 'turn_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 %w(turn_on), @object.callbacks
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 => 'turn_off', :do => lambda {|object| object.callbacks << 'turn_off'}
1096
- @machine.before_transition :except_on => 'turn_on', :do => lambda {|object| object.callbacks << 'turn_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 %w(turn_off), @object.callbacks
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 => 'off', :to => 'on', :do => lambda {}
1104
- @machine.after_transition :from => 'unknown', :to => 'error', :do => lambda {}
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 %w(error off on unknown), @machine.states.keys.sort
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 => 'off', :to => 'on', :do => lambda {}
1111
- @machine.after_transition :from => 'unknown', :to => 'error', :do => lambda {}
1112
- @machine.after_transition :from => 'off', :to => 'on', :do => lambda {}
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 %w(error off on unknown), @machine.states.keys.sort
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
- [:on?, :off?].each {|predicate| assert @object.respond_to?(predicate)}
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 => 'off')
1214
- @second_machine = StateMachine::Machine.new(@klass, 'status', :initial => 'active')
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 = {'state' => @machine, 'status' => @second_machine}
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 'off', @object.state
1225
- assert_equal 'active', @object.status
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 => 'switch', :initial => 'off') do
1233
- event :turn_on do
1234
- transition :to => 'on', :from => 'off'
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 :turn_off do
1238
- transition :to => 'off', :from => 'on'
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
- [:switch_off?, :switch_on?].each do |name|
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
- [:can_turn_on_switch?, :can_turn_off_switch?].each do |name|
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
- [:next_turn_on_switch_transition, :next_turn_off_switch_transition].each do |name|
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
- [:turn_on_switch, :turn_off_switch].each do |name|
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
- [:turn_on_switch!, :turn_off_switch!].each do |name|
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 'state', @machine.attribute
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, 'status', :action => :save, :integration => :custom)
1331
- @base_machine.event(:turn_on) {}
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, 'status')
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 'status', @machine.attribute
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.size
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, 'status', :initial => 'off')
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 'status', @machine.attribute
1315
+ assert_equal :status, @machine.attribute
1392
1316
  end
1393
1317
 
1394
1318
  def test_should_set_custom_initial_state
1395
- assert_equal 'off', @machine.initial_state(@object)
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 :from => 'parked', :to => 'idling'
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 :from => 2, :to => 1
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, :activated_at, :initial => 'inactive')
1473
- @machine.event :activate do
1474
- transition :from => nil, :to => 'active'
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?('./Vehicle_activated_at.png')
1407
+ assert File.exist?('./Vehicle_state.png')
1481
1408
  ensure
1482
- FileUtils.rm('./Vehicle_activated_at.png')
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, :activated_at, :initial => 'inactive')
1418
+ @machine = StateMachine::Machine.new(@klass, :initial => :parked)
1492
1419
  @machine.event :activate do
1493
- transition :from => 'inactive', :to => lambda {Time.now}
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?('./Vehicle_activated_at.png')
1427
+ assert File.exist?('./Vehicle_state.png')
1500
1428
  ensure
1501
- FileUtils.rm('./Vehicle_activated_at.png')
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 :from => 'parked', :to => 'idling'
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