spree-state_machine 2.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +12 -0
  4. data/.yardopts +5 -0
  5. data/CHANGELOG.md +502 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +20 -0
  8. data/README.md +1246 -0
  9. data/Rakefile +20 -0
  10. data/examples/AutoShop_state.png +0 -0
  11. data/examples/Car_state.png +0 -0
  12. data/examples/Gemfile +5 -0
  13. data/examples/Gemfile.lock +14 -0
  14. data/examples/TrafficLight_state.png +0 -0
  15. data/examples/Vehicle_state.png +0 -0
  16. data/examples/auto_shop.rb +13 -0
  17. data/examples/car.rb +21 -0
  18. data/examples/doc/AutoShop.html +2856 -0
  19. data/examples/doc/AutoShop_state.png +0 -0
  20. data/examples/doc/Car.html +919 -0
  21. data/examples/doc/Car_state.png +0 -0
  22. data/examples/doc/TrafficLight.html +2230 -0
  23. data/examples/doc/TrafficLight_state.png +0 -0
  24. data/examples/doc/Vehicle.html +7921 -0
  25. data/examples/doc/Vehicle_state.png +0 -0
  26. data/examples/doc/_index.html +136 -0
  27. data/examples/doc/class_list.html +47 -0
  28. data/examples/doc/css/common.css +1 -0
  29. data/examples/doc/css/full_list.css +55 -0
  30. data/examples/doc/css/style.css +322 -0
  31. data/examples/doc/file_list.html +46 -0
  32. data/examples/doc/frames.html +13 -0
  33. data/examples/doc/index.html +136 -0
  34. data/examples/doc/js/app.js +205 -0
  35. data/examples/doc/js/full_list.js +173 -0
  36. data/examples/doc/js/jquery.js +16 -0
  37. data/examples/doc/method_list.html +734 -0
  38. data/examples/doc/top-level-namespace.html +105 -0
  39. data/examples/merb-rest/controller.rb +51 -0
  40. data/examples/merb-rest/model.rb +28 -0
  41. data/examples/merb-rest/view_edit.html.erb +24 -0
  42. data/examples/merb-rest/view_index.html.erb +23 -0
  43. data/examples/merb-rest/view_new.html.erb +13 -0
  44. data/examples/merb-rest/view_show.html.erb +17 -0
  45. data/examples/rails-rest/controller.rb +43 -0
  46. data/examples/rails-rest/migration.rb +7 -0
  47. data/examples/rails-rest/model.rb +23 -0
  48. data/examples/rails-rest/view__form.html.erb +34 -0
  49. data/examples/rails-rest/view_edit.html.erb +6 -0
  50. data/examples/rails-rest/view_index.html.erb +25 -0
  51. data/examples/rails-rest/view_new.html.erb +5 -0
  52. data/examples/rails-rest/view_show.html.erb +19 -0
  53. data/examples/traffic_light.rb +9 -0
  54. data/examples/vehicle.rb +33 -0
  55. data/lib/state_machine/assertions.rb +36 -0
  56. data/lib/state_machine/branch.rb +225 -0
  57. data/lib/state_machine/callback.rb +236 -0
  58. data/lib/state_machine/core.rb +7 -0
  59. data/lib/state_machine/core_ext/class/state_machine.rb +5 -0
  60. data/lib/state_machine/core_ext.rb +2 -0
  61. data/lib/state_machine/error.rb +13 -0
  62. data/lib/state_machine/eval_helpers.rb +87 -0
  63. data/lib/state_machine/event.rb +257 -0
  64. data/lib/state_machine/event_collection.rb +141 -0
  65. data/lib/state_machine/extensions.rb +149 -0
  66. data/lib/state_machine/graph.rb +92 -0
  67. data/lib/state_machine/helper_module.rb +17 -0
  68. data/lib/state_machine/initializers/rails.rb +25 -0
  69. data/lib/state_machine/initializers.rb +4 -0
  70. data/lib/state_machine/integrations/active_model/locale.rb +11 -0
  71. data/lib/state_machine/integrations/active_model/observer.rb +33 -0
  72. data/lib/state_machine/integrations/active_model/observer_update.rb +42 -0
  73. data/lib/state_machine/integrations/active_model/versions.rb +31 -0
  74. data/lib/state_machine/integrations/active_model.rb +585 -0
  75. data/lib/state_machine/integrations/active_record/locale.rb +20 -0
  76. data/lib/state_machine/integrations/active_record/versions.rb +123 -0
  77. data/lib/state_machine/integrations/active_record.rb +525 -0
  78. data/lib/state_machine/integrations/base.rb +100 -0
  79. data/lib/state_machine/integrations.rb +121 -0
  80. data/lib/state_machine/machine.rb +2287 -0
  81. data/lib/state_machine/machine_collection.rb +74 -0
  82. data/lib/state_machine/macro_methods.rb +522 -0
  83. data/lib/state_machine/matcher.rb +123 -0
  84. data/lib/state_machine/matcher_helpers.rb +54 -0
  85. data/lib/state_machine/node_collection.rb +222 -0
  86. data/lib/state_machine/path.rb +120 -0
  87. data/lib/state_machine/path_collection.rb +90 -0
  88. data/lib/state_machine/state.rb +297 -0
  89. data/lib/state_machine/state_collection.rb +112 -0
  90. data/lib/state_machine/state_context.rb +138 -0
  91. data/lib/state_machine/transition.rb +470 -0
  92. data/lib/state_machine/transition_collection.rb +245 -0
  93. data/lib/state_machine/version.rb +3 -0
  94. data/lib/state_machine/yard/handlers/base.rb +32 -0
  95. data/lib/state_machine/yard/handlers/event.rb +25 -0
  96. data/lib/state_machine/yard/handlers/machine.rb +344 -0
  97. data/lib/state_machine/yard/handlers/state.rb +25 -0
  98. data/lib/state_machine/yard/handlers/transition.rb +47 -0
  99. data/lib/state_machine/yard/handlers.rb +12 -0
  100. data/lib/state_machine/yard/templates/default/class/html/setup.rb +30 -0
  101. data/lib/state_machine/yard/templates/default/class/html/state_machines.erb +12 -0
  102. data/lib/state_machine/yard/templates.rb +3 -0
  103. data/lib/state_machine/yard.rb +8 -0
  104. data/lib/state_machine.rb +8 -0
  105. data/lib/yard-state_machine.rb +2 -0
  106. data/state_machine.gemspec +22 -0
  107. data/test/files/en.yml +17 -0
  108. data/test/files/switch.rb +15 -0
  109. data/test/functional/state_machine_test.rb +1066 -0
  110. data/test/test_helper.rb +7 -0
  111. data/test/unit/assertions_test.rb +40 -0
  112. data/test/unit/branch_test.rb +969 -0
  113. data/test/unit/callback_test.rb +704 -0
  114. data/test/unit/error_test.rb +43 -0
  115. data/test/unit/eval_helpers_test.rb +270 -0
  116. data/test/unit/event_collection_test.rb +398 -0
  117. data/test/unit/event_test.rb +1196 -0
  118. data/test/unit/graph_test.rb +98 -0
  119. data/test/unit/helper_module_test.rb +17 -0
  120. data/test/unit/integrations/active_model_test.rb +1245 -0
  121. data/test/unit/integrations/active_record_test.rb +2551 -0
  122. data/test/unit/integrations/base_test.rb +104 -0
  123. data/test/unit/integrations_test.rb +71 -0
  124. data/test/unit/invalid_event_test.rb +20 -0
  125. data/test/unit/invalid_parallel_transition_test.rb +18 -0
  126. data/test/unit/invalid_transition_test.rb +115 -0
  127. data/test/unit/machine_collection_test.rb +603 -0
  128. data/test/unit/machine_test.rb +3395 -0
  129. data/test/unit/matcher_helpers_test.rb +37 -0
  130. data/test/unit/matcher_test.rb +155 -0
  131. data/test/unit/node_collection_test.rb +362 -0
  132. data/test/unit/path_collection_test.rb +266 -0
  133. data/test/unit/path_test.rb +485 -0
  134. data/test/unit/state_collection_test.rb +352 -0
  135. data/test/unit/state_context_test.rb +441 -0
  136. data/test/unit/state_machine_test.rb +31 -0
  137. data/test/unit/state_test.rb +1101 -0
  138. data/test/unit/transition_collection_test.rb +2168 -0
  139. data/test/unit/transition_test.rb +1558 -0
  140. metadata +264 -0
@@ -0,0 +1,1196 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class EventByDefaultTest < Test::Unit::TestCase
4
+ def setup
5
+ @klass = Class.new
6
+ @machine = StateMachine::Machine.new(@klass)
7
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
8
+
9
+ @object = @klass.new
10
+ end
11
+
12
+ def test_should_have_a_machine
13
+ assert_equal @machine, @event.machine
14
+ end
15
+
16
+ def test_should_have_a_name
17
+ assert_equal :ignite, @event.name
18
+ end
19
+
20
+ def test_should_have_a_qualified_name
21
+ assert_equal :ignite, @event.qualified_name
22
+ end
23
+
24
+ def test_should_have_a_human_name
25
+ assert_equal 'ignite', @event.human_name
26
+ end
27
+
28
+ def test_should_not_have_any_branches
29
+ assert @event.branches.empty?
30
+ end
31
+
32
+ def test_should_have_no_known_states
33
+ assert @event.known_states.empty?
34
+ end
35
+
36
+ def test_should_not_be_able_to_fire
37
+ assert !@event.can_fire?(@object)
38
+ end
39
+
40
+ def test_should_not_have_a_transition
41
+ assert_nil @event.transition_for(@object)
42
+ end
43
+
44
+ def test_should_define_a_predicate
45
+ assert @object.respond_to?(:can_ignite?)
46
+ end
47
+
48
+ def test_should_define_a_transition_accessor
49
+ assert @object.respond_to?(:ignite_transition)
50
+ end
51
+
52
+ def test_should_define_an_action
53
+ assert @object.respond_to?(:ignite)
54
+ end
55
+
56
+ def test_should_define_a_bang_action
57
+ assert @object.respond_to?(:ignite!)
58
+ end
59
+ end
60
+
61
+ class EventTest < Test::Unit::TestCase
62
+ def setup
63
+ @machine = StateMachine::Machine.new(Class.new)
64
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
65
+ @event.transition :parked => :idling
66
+ end
67
+
68
+ def test_should_allow_changing_machine
69
+ new_machine = StateMachine::Machine.new(Class.new)
70
+ @event.machine = new_machine
71
+ assert_equal new_machine, @event.machine
72
+ end
73
+
74
+ def test_should_allow_changing_human_name
75
+ @event.human_name = 'Stop'
76
+ assert_equal 'Stop', @event.human_name
77
+ end
78
+
79
+ def test_should_provide_matcher_helpers_during_initialization
80
+ matchers = []
81
+
82
+ @event.instance_eval do
83
+ matchers = [all, any, same]
84
+ end
85
+
86
+ assert_equal [StateMachine::AllMatcher.instance, StateMachine::AllMatcher.instance, StateMachine::LoopbackMatcher.instance], matchers
87
+ end
88
+
89
+ def test_should_use_pretty_inspect
90
+ assert_match "#<StateMachine::Event name=:ignite transitions=[:parked => :idling]>", @event.inspect
91
+ end
92
+ end
93
+
94
+ class EventWithHumanNameTest < Test::Unit::TestCase
95
+ def setup
96
+ @klass = Class.new
97
+ @machine = StateMachine::Machine.new(@klass)
98
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite, :human_name => 'start')
99
+ end
100
+
101
+ def test_should_use_custom_human_name
102
+ assert_equal 'start', @event.human_name
103
+ end
104
+ end
105
+
106
+ class EventWithDynamicHumanNameTest < Test::Unit::TestCase
107
+ def setup
108
+ @klass = Class.new
109
+ @machine = StateMachine::Machine.new(@klass)
110
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite, :human_name => lambda {|event, object| ['start', object]})
111
+ end
112
+
113
+ def test_should_use_custom_human_name
114
+ human_name, klass = @event.human_name
115
+ assert_equal 'start', human_name
116
+ assert_equal @klass, klass
117
+ end
118
+
119
+ def test_should_allow_custom_class_to_be_passed_through
120
+ human_name, klass = @event.human_name(1)
121
+ assert_equal 'start', human_name
122
+ assert_equal 1, klass
123
+ end
124
+
125
+ def test_should_not_cache_value
126
+ assert_not_same @event.human_name, @event.human_name
127
+ end
128
+ end
129
+
130
+ class EventWithConflictingHelpersBeforeDefinitionTest < Test::Unit::TestCase
131
+ def setup
132
+ require 'stringio'
133
+ @original_stderr, $stderr = $stderr, StringIO.new
134
+
135
+ @superclass = Class.new do
136
+ def can_ignite?
137
+ 0
138
+ end
139
+
140
+ def ignite_transition
141
+ 0
142
+ end
143
+
144
+ def ignite
145
+ 0
146
+ end
147
+
148
+ def ignite!
149
+ 0
150
+ end
151
+ end
152
+ @klass = Class.new(@superclass)
153
+ @machine = StateMachine::Machine.new(@klass)
154
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
155
+ @object = @klass.new
156
+ end
157
+
158
+ def test_should_not_redefine_predicate
159
+ assert_equal 0, @object.can_ignite?
160
+ end
161
+
162
+ def test_should_not_redefine_transition_accessor
163
+ assert_equal 0, @object.ignite_transition
164
+ end
165
+
166
+ def test_should_not_redefine_action
167
+ assert_equal 0, @object.ignite
168
+ end
169
+
170
+ def test_should_not_redefine_bang_action
171
+ assert_equal 0, @object.ignite!
172
+ end
173
+
174
+ def test_should_output_warning
175
+ expected = %w(can_ignite? ignite_transition ignite ignite!).map do |method|
176
+ "Instance method \"#{method}\" is already defined in #{@superclass.to_s}, use generic helper instead or set StateMachine::Machine.ignore_method_conflicts = true.\n"
177
+ end.join
178
+
179
+ assert_equal expected, $stderr.string
180
+ end
181
+
182
+ def teardown
183
+ $stderr = @original_stderr
184
+ end
185
+ end
186
+
187
+ class EventWithConflictingHelpersAfterDefinitionTest < Test::Unit::TestCase
188
+ def setup
189
+ require 'stringio'
190
+ @original_stderr, $stderr = $stderr, StringIO.new
191
+
192
+ @klass = Class.new do
193
+ def can_ignite?
194
+ 0
195
+ end
196
+
197
+ def ignite_transition
198
+ 0
199
+ end
200
+
201
+ def ignite
202
+ 0
203
+ end
204
+
205
+ def ignite!
206
+ 0
207
+ end
208
+ end
209
+ @machine = StateMachine::Machine.new(@klass)
210
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
211
+ @object = @klass.new
212
+ end
213
+
214
+ def test_should_not_redefine_predicate
215
+ assert_equal 0, @object.can_ignite?
216
+ end
217
+
218
+ def test_should_not_redefine_transition_accessor
219
+ assert_equal 0, @object.ignite_transition
220
+ end
221
+
222
+ def test_should_not_redefine_action
223
+ assert_equal 0, @object.ignite
224
+ end
225
+
226
+ def test_should_not_redefine_bang_action
227
+ assert_equal 0, @object.ignite!
228
+ end
229
+
230
+ def test_should_allow_super_chaining
231
+ @klass.class_eval do
232
+ def can_ignite?
233
+ super
234
+ end
235
+
236
+ def ignite_transition
237
+ super
238
+ end
239
+
240
+ def ignite
241
+ super
242
+ end
243
+
244
+ def ignite!
245
+ super
246
+ end
247
+ end
248
+
249
+ assert_equal false, @object.can_ignite?
250
+ assert_equal nil, @object.ignite_transition
251
+ assert_equal false, @object.ignite
252
+ assert_raise(StateMachine::InvalidTransition) { @object.ignite! }
253
+ end
254
+
255
+ def test_should_not_output_warning
256
+ assert_equal '', $stderr.string
257
+ end
258
+
259
+ def teardown
260
+ $stderr = @original_stderr
261
+ end
262
+ end
263
+
264
+ class EventWithConflictingMachineTest < Test::Unit::TestCase
265
+ def setup
266
+ require 'stringio'
267
+ @original_stderr, $stderr = $stderr, StringIO.new
268
+
269
+ @klass = Class.new
270
+ @state_machine = StateMachine::Machine.new(@klass, :state)
271
+ @state_machine.state :parked, :idling
272
+ @state_machine.events << @state_event = StateMachine::Event.new(@state_machine, :ignite)
273
+ end
274
+
275
+ def test_should_not_overwrite_first_event
276
+ @status_machine = StateMachine::Machine.new(@klass, :status)
277
+ @status_machine.state :first_gear, :second_gear
278
+ @status_machine.events << @status_event = StateMachine::Event.new(@status_machine, :ignite)
279
+
280
+ @object = @klass.new
281
+ @object.state = 'parked'
282
+ @object.status = 'first_gear'
283
+
284
+ @state_event.transition(:parked => :idling)
285
+ @status_event.transition(:parked => :first_gear)
286
+
287
+ @object.ignite
288
+ assert_equal 'idling', @object.state
289
+ assert_equal 'first_gear', @object.status
290
+ end
291
+
292
+ def test_should_output_warning
293
+ @status_machine = StateMachine::Machine.new(@klass, :status)
294
+ @status_machine.events << @status_event = StateMachine::Event.new(@status_machine, :ignite)
295
+
296
+ assert_equal "Event :ignite for :status is already defined in :state\n", $stderr.string
297
+ end
298
+
299
+ def test_should_not_output_warning_if_using_different_namespace
300
+ @status_machine = StateMachine::Machine.new(@klass, :status, :namespace => 'alarm')
301
+ @status_machine.events << @status_event = StateMachine::Event.new(@status_machine, :ignite)
302
+
303
+ assert_equal '', $stderr.string
304
+ end
305
+
306
+ def teardown
307
+ $stderr = @original_stderr
308
+ end
309
+ end
310
+
311
+ class EventWithNamespaceTest < Test::Unit::TestCase
312
+ def setup
313
+ @klass = Class.new
314
+ @machine = StateMachine::Machine.new(@klass, :namespace => 'alarm')
315
+ @machine.events << @event = StateMachine::Event.new(@machine, :enable)
316
+ @object = @klass.new
317
+ end
318
+
319
+ def test_should_have_a_name
320
+ assert_equal :enable, @event.name
321
+ end
322
+
323
+ def test_should_have_a_qualified_name
324
+ assert_equal :enable_alarm, @event.qualified_name
325
+ end
326
+
327
+ def test_should_namespace_predicate
328
+ assert @object.respond_to?(:can_enable_alarm?)
329
+ end
330
+
331
+ def test_should_namespace_transition_accessor
332
+ assert @object.respond_to?(:enable_alarm_transition)
333
+ end
334
+
335
+ def test_should_namespace_action
336
+ assert @object.respond_to?(:enable_alarm)
337
+ end
338
+
339
+ def test_should_namespace_bang_action
340
+ assert @object.respond_to?(:enable_alarm!)
341
+ end
342
+ end
343
+
344
+ class EventContextTest < Test::Unit::TestCase
345
+ def setup
346
+ @klass = Class.new
347
+ @machine = StateMachine::Machine.new(@klass)
348
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite, :human_name => 'start')
349
+ end
350
+
351
+ def test_should_evaluate_within_the_event
352
+ scope = nil
353
+ @event.context { scope = self }
354
+ assert_equal @event, scope
355
+ end
356
+ end
357
+
358
+ class EventTransitionsTest < Test::Unit::TestCase
359
+ def setup
360
+ @machine = StateMachine::Machine.new(Class.new)
361
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
362
+ end
363
+
364
+ def test_should_not_raise_exception_if_implicit_option_specified
365
+ assert_nothing_raised {@event.transition(:invalid => :valid)}
366
+ end
367
+
368
+ def test_should_not_allow_on_option
369
+ exception = assert_raise(ArgumentError) {@event.transition(:on => :ignite)}
370
+ assert_equal 'Invalid key(s): on', exception.message
371
+ end
372
+
373
+ def test_should_automatically_set_on_option
374
+ branch = @event.transition(:to => :idling)
375
+ assert_instance_of StateMachine::WhitelistMatcher, branch.event_requirement
376
+ assert_equal [:ignite], branch.event_requirement.values
377
+ end
378
+
379
+ def test_should_not_allow_except_on_option
380
+ exception = assert_raise(ArgumentError) {@event.transition(:except_on => :ignite)}
381
+ assert_equal 'Invalid key(s): except_on', exception.message
382
+ end
383
+
384
+ def test_should_allow_transitioning_without_a_to_state
385
+ assert_nothing_raised {@event.transition(:from => :parked)}
386
+ end
387
+
388
+ def test_should_allow_transitioning_without_a_from_state
389
+ assert_nothing_raised {@event.transition(:to => :idling)}
390
+ end
391
+
392
+ def test_should_allow_except_from_option
393
+ assert_nothing_raised {@event.transition(:except_from => :idling)}
394
+ end
395
+
396
+ def test_should_allow_except_to_option
397
+ assert_nothing_raised {@event.transition(:except_to => :idling)}
398
+ end
399
+
400
+ def test_should_allow_transitioning_from_a_single_state
401
+ assert @event.transition(:parked => :idling)
402
+ end
403
+
404
+ def test_should_allow_transitioning_from_multiple_states
405
+ assert @event.transition([:parked, :idling] => :idling)
406
+ end
407
+
408
+ def test_should_allow_transitions_to_multiple_states
409
+ assert @event.transition(:parked => [:parked, :idling])
410
+ end
411
+
412
+ def test_should_have_transitions
413
+ branch = @event.transition(:to => :idling)
414
+ assert_equal [branch], @event.branches
415
+ end
416
+ end
417
+
418
+ class EventAfterBeingCopiedTest < Test::Unit::TestCase
419
+ def setup
420
+ @machine = StateMachine::Machine.new(Class.new)
421
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
422
+ @copied_event = @event.dup
423
+ end
424
+
425
+ def test_should_not_have_the_same_collection_of_branches
426
+ assert_not_same @event.branches, @copied_event.branches
427
+ end
428
+
429
+ def test_should_not_have_the_same_collection_of_known_states
430
+ assert_not_same @event.known_states, @copied_event.known_states
431
+ end
432
+ end
433
+
434
+ class EventWithoutTransitionsTest < Test::Unit::TestCase
435
+ def setup
436
+ @klass = Class.new
437
+ @machine = StateMachine::Machine.new(@klass)
438
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
439
+ @object = @klass.new
440
+ end
441
+
442
+ def test_should_not_be_able_to_fire
443
+ assert !@event.can_fire?(@object)
444
+ end
445
+
446
+ def test_should_not_have_a_transition
447
+ assert_nil @event.transition_for(@object)
448
+ end
449
+
450
+ def test_should_not_fire
451
+ assert !@event.fire(@object)
452
+ end
453
+
454
+ def test_should_not_change_the_current_state
455
+ @event.fire(@object)
456
+ assert_nil @object.state
457
+ end
458
+ end
459
+
460
+ class EventWithTransitionsTest < Test::Unit::TestCase
461
+ def setup
462
+ @klass = Class.new
463
+ @machine = StateMachine::Machine.new(@klass)
464
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
465
+ @event.transition(:parked => :idling)
466
+ @event.transition(:first_gear => :idling)
467
+ end
468
+
469
+ def test_should_include_all_transition_states_in_known_states
470
+ assert_equal [:parked, :idling, :first_gear], @event.known_states
471
+ end
472
+
473
+ def test_should_include_new_transition_states_after_calling_known_states
474
+ @event.known_states
475
+ @event.transition(:stalled => :idling)
476
+
477
+ assert_equal [:parked, :idling, :first_gear, :stalled], @event.known_states
478
+ end
479
+
480
+ def test_should_clear_known_states_on_reset
481
+ @event.reset
482
+ assert_equal [], @event.known_states
483
+ end
484
+
485
+ def test_should_use_pretty_inspect
486
+ assert_match "#<StateMachine::Event name=:ignite transitions=[:parked => :idling, :first_gear => :idling]>", @event.inspect
487
+ end
488
+ end
489
+
490
+ class EventWithoutMatchingTransitionsTest < Test::Unit::TestCase
491
+ def setup
492
+ @klass = Class.new
493
+ @machine = StateMachine::Machine.new(@klass)
494
+ @machine.state :parked, :idling
495
+
496
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
497
+ @event.transition(:parked => :idling)
498
+
499
+ @object = @klass.new
500
+ @object.state = 'idling'
501
+ end
502
+
503
+ def test_should_not_be_able_to_fire
504
+ assert !@event.can_fire?(@object)
505
+ end
506
+
507
+ def test_should_be_able_to_fire_with_custom_from_state
508
+ assert @event.can_fire?(@object, :from => :parked)
509
+ end
510
+
511
+ def test_should_not_have_a_transition
512
+ assert_nil @event.transition_for(@object)
513
+ end
514
+
515
+ def test_should_have_a_transition_with_custom_from_state
516
+ assert_not_nil @event.transition_for(@object, :from => :parked)
517
+ end
518
+
519
+ def test_should_not_fire
520
+ assert !@event.fire(@object)
521
+ end
522
+
523
+ def test_should_not_change_the_current_state
524
+ @event.fire(@object)
525
+ assert_equal 'idling', @object.state
526
+ end
527
+ end
528
+
529
+ class EventWithMatchingDisabledTransitionsTest < Test::Unit::TestCase
530
+ def setup
531
+ StateMachine::Integrations.const_set('Custom', Module.new do
532
+ include StateMachine::Integrations::Base
533
+
534
+ def invalidate(object, attribute, message, values = [])
535
+ (object.errors ||= []) << generate_message(message, values)
536
+ end
537
+
538
+ def reset(object)
539
+ object.errors = []
540
+ end
541
+ end)
542
+
543
+ @klass = Class.new do
544
+ attr_accessor :errors
545
+ end
546
+
547
+ @machine = StateMachine::Machine.new(@klass, :integration => :custom)
548
+ @machine.state :parked, :idling
549
+
550
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
551
+ @event.transition(:parked => :idling, :if => lambda {false})
552
+
553
+ @object = @klass.new
554
+ @object.state = 'parked'
555
+ end
556
+
557
+ def test_should_not_be_able_to_fire
558
+ assert !@event.can_fire?(@object)
559
+ end
560
+
561
+ def test_should_be_able_to_fire_with_disabled_guards
562
+ assert @event.can_fire?(@object, :guard => false)
563
+ end
564
+
565
+ def test_should_not_have_a_transition
566
+ assert_nil @event.transition_for(@object)
567
+ end
568
+
569
+ def test_should_have_a_transition_with_disabled_guards
570
+ assert_not_nil @event.transition_for(@object, :guard => false)
571
+ end
572
+
573
+ def test_should_not_fire
574
+ assert !@event.fire(@object)
575
+ end
576
+
577
+ def test_should_not_change_the_current_state
578
+ @event.fire(@object)
579
+ assert_equal 'parked', @object.state
580
+ end
581
+
582
+ def test_should_invalidate_the_state
583
+ @event.fire(@object)
584
+ assert_equal ['cannot transition via "ignite"'], @object.errors
585
+ end
586
+
587
+ def test_should_invalidate_with_human_event_name
588
+ @event.human_name = 'start'
589
+ @event.fire(@object)
590
+ assert_equal ['cannot transition via "start"'], @object.errors
591
+ end
592
+
593
+ def test_should_invalid_with_human_state_name_if_specified
594
+ klass = Class.new do
595
+ attr_accessor :errors
596
+ end
597
+
598
+ machine = StateMachine::Machine.new(klass, :integration => :custom, :messages => {:invalid_transition => 'cannot transition via "%s" from "%s"'})
599
+ parked, idling = machine.state :parked, :idling
600
+ parked.human_name = 'stopped'
601
+
602
+ machine.events << event = StateMachine::Event.new(machine, :ignite)
603
+ event.transition(:parked => :idling, :if => lambda {false})
604
+
605
+ object = @klass.new
606
+ object.state = 'parked'
607
+
608
+ event.fire(object)
609
+ assert_equal ['cannot transition via "ignite" from "stopped"'], object.errors
610
+ end
611
+
612
+ def test_should_reset_existing_error
613
+ @object.errors = ['invalid']
614
+
615
+ @event.fire(@object)
616
+ assert_equal ['cannot transition via "ignite"'], @object.errors
617
+ end
618
+
619
+ def test_should_run_failure_callbacks
620
+ callback_args = nil
621
+ @machine.after_failure {|*args| callback_args = args}
622
+
623
+ @event.fire(@object)
624
+
625
+ object, transition = callback_args
626
+ assert_equal @object, object
627
+ assert_not_nil transition
628
+ assert_equal @object, transition.object
629
+ assert_equal @machine, transition.machine
630
+ assert_equal :ignite, transition.event
631
+ assert_equal :parked, transition.from_name
632
+ assert_equal :parked, transition.to_name
633
+ end
634
+
635
+ def teardown
636
+ StateMachine::Integrations.send(:remove_const, 'Custom')
637
+ end
638
+ end
639
+
640
+ class EventWithMatchingEnabledTransitionsTest < Test::Unit::TestCase
641
+ def setup
642
+ StateMachine::Integrations.const_set('Custom', Module.new do
643
+ include StateMachine::Integrations::Base
644
+
645
+ def invalidate(object, attribute, message, values = [])
646
+ (object.errors ||= []) << generate_message(message, values)
647
+ end
648
+
649
+ def reset(object)
650
+ object.errors = []
651
+ end
652
+ end)
653
+
654
+ @klass = Class.new do
655
+ attr_accessor :errors
656
+ end
657
+
658
+ @machine = StateMachine::Machine.new(@klass, :integration => :custom)
659
+ @machine.state :parked, :idling
660
+
661
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
662
+ @event.transition(:parked => :idling)
663
+
664
+ @object = @klass.new
665
+ @object.state = 'parked'
666
+ end
667
+
668
+ def test_should_be_able_to_fire
669
+ assert @event.can_fire?(@object)
670
+ end
671
+
672
+ def test_should_have_a_transition
673
+ transition = @event.transition_for(@object)
674
+ assert_not_nil transition
675
+ assert_equal 'parked', transition.from
676
+ assert_equal 'idling', transition.to
677
+ assert_equal :ignite, transition.event
678
+ end
679
+
680
+ def test_should_fire
681
+ assert @event.fire(@object)
682
+ end
683
+
684
+ def test_should_change_the_current_state
685
+ @event.fire(@object)
686
+ assert_equal 'idling', @object.state
687
+ end
688
+
689
+ def test_should_reset_existing_error
690
+ @object.errors = ['invalid']
691
+
692
+ @event.fire(@object)
693
+ assert_equal [], @object.errors
694
+ end
695
+
696
+ def test_should_not_invalidate_the_state
697
+ @event.fire(@object)
698
+ assert_equal [], @object.errors
699
+ end
700
+
701
+ def test_should_not_be_able_to_fire_on_reset
702
+ @event.reset
703
+ assert !@event.can_fire?(@object)
704
+ end
705
+
706
+ def teardown
707
+ StateMachine::Integrations.send(:remove_const, 'Custom')
708
+ end
709
+ end
710
+
711
+ class EventWithTransitionWithoutToStateTest < Test::Unit::TestCase
712
+ def setup
713
+ @klass = Class.new
714
+ @machine = StateMachine::Machine.new(@klass)
715
+ @machine.state :parked
716
+
717
+ @machine.events << @event = StateMachine::Event.new(@machine, :park)
718
+ @event.transition(:from => :parked)
719
+
720
+ @object = @klass.new
721
+ @object.state = 'parked'
722
+ end
723
+
724
+ def test_should_be_able_to_fire
725
+ assert @event.can_fire?(@object)
726
+ end
727
+
728
+ def test_should_have_a_transition
729
+ transition = @event.transition_for(@object)
730
+ assert_not_nil transition
731
+ assert_equal 'parked', transition.from
732
+ assert_equal 'parked', transition.to
733
+ assert_equal :park, transition.event
734
+ end
735
+
736
+ def test_should_fire
737
+ assert @event.fire(@object)
738
+ end
739
+
740
+ def test_should_not_change_the_current_state
741
+ @event.fire(@object)
742
+ assert_equal 'parked', @object.state
743
+ end
744
+ end
745
+
746
+ class EventWithTransitionWithNilToStateTest < Test::Unit::TestCase
747
+ def setup
748
+ @klass = Class.new
749
+ @machine = StateMachine::Machine.new(@klass)
750
+ @machine.state nil, :idling
751
+
752
+ @machine.events << @event = StateMachine::Event.new(@machine, :park)
753
+ @event.transition(:idling => nil)
754
+
755
+ @object = @klass.new
756
+ @object.state = 'idling'
757
+ end
758
+
759
+ def test_should_be_able_to_fire
760
+ assert @event.can_fire?(@object)
761
+ end
762
+
763
+ def test_should_have_a_transition
764
+ transition = @event.transition_for(@object)
765
+ assert_not_nil transition
766
+ assert_equal 'idling', transition.from
767
+ assert_equal nil, transition.to
768
+ assert_equal :park, transition.event
769
+ end
770
+
771
+ def test_should_fire
772
+ assert @event.fire(@object)
773
+ end
774
+
775
+ def test_should_not_change_the_current_state
776
+ @event.fire(@object)
777
+ assert_equal nil, @object.state
778
+ end
779
+ end
780
+
781
+ class EventWithTransitionWithLoopbackStateTest < Test::Unit::TestCase
782
+ def setup
783
+ @klass = Class.new
784
+ @machine = StateMachine::Machine.new(@klass)
785
+ @machine.state :parked
786
+
787
+ @machine.events << @event = StateMachine::Event.new(@machine, :park)
788
+ @event.transition(:from => :parked, :to => StateMachine::LoopbackMatcher.instance)
789
+
790
+ @object = @klass.new
791
+ @object.state = 'parked'
792
+ end
793
+
794
+ def test_should_be_able_to_fire
795
+ assert @event.can_fire?(@object)
796
+ end
797
+
798
+ def test_should_have_a_transition
799
+ transition = @event.transition_for(@object)
800
+ assert_not_nil transition
801
+ assert_equal 'parked', transition.from
802
+ assert_equal 'parked', transition.to
803
+ assert_equal :park, transition.event
804
+ end
805
+
806
+ def test_should_fire
807
+ assert @event.fire(@object)
808
+ end
809
+
810
+ def test_should_not_change_the_current_state
811
+ @event.fire(@object)
812
+ assert_equal 'parked', @object.state
813
+ end
814
+ end
815
+
816
+ class EventWithTransitionWithBlacklistedToStateTest < Test::Unit::TestCase
817
+ def setup
818
+ @klass = Class.new
819
+ @machine = StateMachine::Machine.new(@klass, :initial => :parked)
820
+ @machine.state :parked, :idling, :first_gear, :second_gear
821
+
822
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
823
+ @event.transition(:from => :parked, :to => StateMachine::BlacklistMatcher.new([:parked, :idling]))
824
+
825
+ @object = @klass.new
826
+ @object.state = 'parked'
827
+ end
828
+
829
+ def test_should_be_able_to_fire
830
+ assert @event.can_fire?(@object)
831
+ end
832
+
833
+ def test_should_have_a_transition
834
+ transition = @event.transition_for(@object)
835
+ assert_not_nil transition
836
+ assert_equal 'parked', transition.from
837
+ assert_equal 'first_gear', transition.to
838
+ assert_equal :ignite, transition.event
839
+ end
840
+
841
+ def test_should_allow_loopback_first_when_possible
842
+ @event.transition(:from => :second_gear, :to => StateMachine::BlacklistMatcher.new([:parked, :idling]))
843
+ @object.state = 'second_gear'
844
+
845
+ transition = @event.transition_for(@object)
846
+ assert_not_nil transition
847
+ assert_equal 'second_gear', transition.from
848
+ assert_equal 'second_gear', transition.to
849
+ assert_equal :ignite, transition.event
850
+ end
851
+
852
+ def test_should_allow_specific_transition_selection_using_to
853
+ transition = @event.transition_for(@object, :from => :parked, :to => :second_gear)
854
+
855
+ assert_not_nil transition
856
+ assert_equal 'parked', transition.from
857
+ assert_equal 'second_gear', transition.to
858
+ assert_equal :ignite, transition.event
859
+ end
860
+
861
+ def test_should_not_allow_transition_selection_if_not_matching
862
+ transition = @event.transition_for(@object, :from => :parked, :to => :parked)
863
+ assert_nil transition
864
+ end
865
+
866
+ def test_should_fire
867
+ assert @event.fire(@object)
868
+ end
869
+
870
+ def test_should_change_the_current_state
871
+ @event.fire(@object)
872
+ assert_equal 'first_gear', @object.state
873
+ end
874
+ end
875
+
876
+ class EventWithTransitionWithWhitelistedToStateTest < Test::Unit::TestCase
877
+ def setup
878
+ @klass = Class.new
879
+ @machine = StateMachine::Machine.new(@klass, :initial => :parked)
880
+ @machine.state :parked, :idling, :first_gear, :second_gear
881
+
882
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
883
+ @event.transition(:from => :parked, :to => StateMachine::WhitelistMatcher.new([:first_gear, :second_gear]))
884
+
885
+ @object = @klass.new
886
+ @object.state = 'parked'
887
+ end
888
+
889
+ def test_should_be_able_to_fire
890
+ assert @event.can_fire?(@object)
891
+ end
892
+
893
+ def test_should_have_a_transition
894
+ transition = @event.transition_for(@object)
895
+ assert_not_nil transition
896
+ assert_equal 'parked', transition.from
897
+ assert_equal 'first_gear', transition.to
898
+ assert_equal :ignite, transition.event
899
+ end
900
+
901
+ def test_should_allow_specific_transition_selection_using_to
902
+ transition = @event.transition_for(@object, :from => :parked, :to => :second_gear)
903
+
904
+ assert_not_nil transition
905
+ assert_equal 'parked', transition.from
906
+ assert_equal 'second_gear', transition.to
907
+ assert_equal :ignite, transition.event
908
+ end
909
+
910
+ def test_should_not_allow_transition_selection_if_not_matching
911
+ transition = @event.transition_for(@object, :from => :parked, :to => :parked)
912
+ assert_nil transition
913
+ end
914
+
915
+ def test_should_fire
916
+ assert @event.fire(@object)
917
+ end
918
+
919
+ def test_should_change_the_current_state
920
+ @event.fire(@object)
921
+ assert_equal 'first_gear', @object.state
922
+ end
923
+ end
924
+
925
+ class EventWithMultipleTransitionsTest < Test::Unit::TestCase
926
+ def setup
927
+ @klass = Class.new
928
+ @machine = StateMachine::Machine.new(@klass)
929
+ @machine.state :parked, :idling
930
+
931
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
932
+ @event.transition(:idling => :idling)
933
+ @event.transition(:parked => :idling)
934
+ @event.transition(:parked => :parked)
935
+
936
+ @object = @klass.new
937
+ @object.state = 'parked'
938
+ end
939
+
940
+ def test_should_be_able_to_fire
941
+ assert @event.can_fire?(@object)
942
+ end
943
+
944
+ def test_should_have_a_transition
945
+ transition = @event.transition_for(@object)
946
+ assert_not_nil transition
947
+ assert_equal 'parked', transition.from
948
+ assert_equal 'idling', transition.to
949
+ assert_equal :ignite, transition.event
950
+ end
951
+
952
+ def test_should_allow_specific_transition_selection_using_from
953
+ transition = @event.transition_for(@object, :from => :idling)
954
+
955
+ assert_not_nil transition
956
+ assert_equal 'idling', transition.from
957
+ assert_equal 'idling', transition.to
958
+ assert_equal :ignite, transition.event
959
+ end
960
+
961
+ def test_should_allow_specific_transition_selection_using_to
962
+ transition = @event.transition_for(@object, :from => :parked, :to => :parked)
963
+
964
+ assert_not_nil transition
965
+ assert_equal 'parked', transition.from
966
+ assert_equal 'parked', transition.to
967
+ assert_equal :ignite, transition.event
968
+ end
969
+
970
+ def test_should_not_allow_specific_transition_selection_using_on
971
+ exception = assert_raise(ArgumentError) { @event.transition_for(@object, :on => :park) }
972
+ assert_equal 'Invalid key(s): on', exception.message
973
+ end
974
+
975
+ def test_should_fire
976
+ assert @event.fire(@object)
977
+ end
978
+
979
+ def test_should_change_the_current_state
980
+ @event.fire(@object)
981
+ assert_equal 'idling', @object.state
982
+ end
983
+ end
984
+
985
+ class EventWithMachineActionTest < Test::Unit::TestCase
986
+ def setup
987
+ @klass = Class.new do
988
+ attr_reader :saved
989
+
990
+ def save
991
+ @saved = true
992
+ end
993
+ end
994
+
995
+ @machine = StateMachine::Machine.new(@klass, :action => :save)
996
+ @machine.state :parked, :idling
997
+
998
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
999
+ @event.transition(:parked => :idling)
1000
+
1001
+ @object = @klass.new
1002
+ @object.state = 'parked'
1003
+ end
1004
+
1005
+ def test_should_run_action_on_fire
1006
+ @event.fire(@object)
1007
+ assert @object.saved
1008
+ end
1009
+
1010
+ def test_should_not_run_action_if_configured_to_skip
1011
+ @event.fire(@object, false)
1012
+ assert !@object.saved
1013
+ end
1014
+ end
1015
+
1016
+ class EventWithInvalidCurrentStateTest < Test::Unit::TestCase
1017
+ def setup
1018
+ @klass = Class.new
1019
+ @machine = StateMachine::Machine.new(@klass)
1020
+ @machine.state :parked, :idling
1021
+
1022
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
1023
+ @event.transition(:parked => :idling)
1024
+
1025
+ @object = @klass.new
1026
+ @object.state = 'invalid'
1027
+ end
1028
+
1029
+ def test_should_raise_exception_when_checking_availability
1030
+ exception = assert_raise(ArgumentError) { @event.can_fire?(@object) }
1031
+ assert_equal '"invalid" is not a known state value', exception.message
1032
+ end
1033
+
1034
+ def test_should_raise_exception_when_finding_transition
1035
+ exception = assert_raise(ArgumentError) { @event.transition_for(@object) }
1036
+ assert_equal '"invalid" is not a known state value', exception.message
1037
+ end
1038
+
1039
+ def test_should_raise_exception_when_firing
1040
+ exception = assert_raise(ArgumentError) { @event.fire(@object) }
1041
+ assert_equal '"invalid" is not a known state value', exception.message
1042
+ end
1043
+ end
1044
+
1045
+ class EventOnFailureTest < Test::Unit::TestCase
1046
+ def setup
1047
+ StateMachine::Integrations.const_set('Custom', Module.new do
1048
+ include StateMachine::Integrations::Base
1049
+
1050
+ def invalidate(object, attribute, message, values = [])
1051
+ (object.errors ||= []) << generate_message(message, values)
1052
+ end
1053
+
1054
+ def reset(object)
1055
+ object.errors = []
1056
+ end
1057
+ end)
1058
+
1059
+ @klass = Class.new do
1060
+ attr_accessor :errors
1061
+ end
1062
+
1063
+ @machine = StateMachine::Machine.new(@klass, :integration => :custom)
1064
+ @machine.state :parked
1065
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
1066
+
1067
+ @object = @klass.new
1068
+ @object.state = 'parked'
1069
+ end
1070
+
1071
+ def test_should_invalidate_the_state
1072
+ @event.fire(@object)
1073
+ assert_equal ['cannot transition via "ignite"'], @object.errors
1074
+ end
1075
+
1076
+ def test_should_run_failure_callbacks
1077
+ callback_args = nil
1078
+ @machine.after_failure {|*args| callback_args = args}
1079
+
1080
+ @event.fire(@object)
1081
+
1082
+ object, transition = callback_args
1083
+ assert_equal @object, object
1084
+ assert_not_nil transition
1085
+ assert_equal @object, transition.object
1086
+ assert_equal @machine, transition.machine
1087
+ assert_equal :ignite, transition.event
1088
+ assert_equal :parked, transition.from_name
1089
+ assert_equal :parked, transition.to_name
1090
+ end
1091
+
1092
+ def teardown
1093
+ StateMachine::Integrations.send(:remove_const, 'Custom')
1094
+ end
1095
+ end
1096
+
1097
+ class EventWithMarshallingTest < Test::Unit::TestCase
1098
+ def setup
1099
+ @klass = Class.new do
1100
+ def save
1101
+ true
1102
+ end
1103
+ end
1104
+ self.class.const_set('Example', @klass)
1105
+
1106
+ @machine = StateMachine::Machine.new(@klass, :action => :save)
1107
+ @machine.state :parked, :idling
1108
+
1109
+ @machine.events << @event = StateMachine::Event.new(@machine, :ignite)
1110
+ @event.transition(:parked => :idling)
1111
+
1112
+ @object = @klass.new
1113
+ @object.state = 'parked'
1114
+ end
1115
+
1116
+ def test_should_marshal_during_before_callbacks
1117
+ @machine.before_transition {|object, transition| Marshal.dump(object)}
1118
+ assert_nothing_raised { @event.fire(@object) }
1119
+ end
1120
+
1121
+ def test_should_marshal_during_action
1122
+ @klass.class_eval do
1123
+ remove_method :save
1124
+ def save
1125
+ Marshal.dump(self)
1126
+ end
1127
+ end
1128
+
1129
+ assert_nothing_raised { @event.fire(@object) }
1130
+ end
1131
+
1132
+ def test_should_marshal_during_after_callbacks
1133
+ @machine.after_transition {|object, transition| Marshal.dump(object)}
1134
+ assert_nothing_raised { @event.fire(@object) }
1135
+ end
1136
+
1137
+ def teardown
1138
+ self.class.send(:remove_const, 'Example')
1139
+ end
1140
+ end
1141
+
1142
+ begin
1143
+ # Load library
1144
+ require 'graphviz'
1145
+
1146
+ class EventDrawingTest < Test::Unit::TestCase
1147
+ def setup
1148
+ states = [:parked, :idling, :first_gear]
1149
+
1150
+ @machine = StateMachine::Machine.new(Class.new, :initial => :parked)
1151
+ @machine.other_states(*states)
1152
+
1153
+ @graph = StateMachine::Graph.new('test')
1154
+ states.each {|state| @graph.add_nodes(state.to_s)}
1155
+
1156
+ @machine.events << @event = StateMachine::Event.new(@machine , :park)
1157
+ @event.transition :parked => :idling
1158
+ @event.transition :first_gear => :parked
1159
+ @event.transition :except_from => :parked, :to => :parked
1160
+
1161
+ @event.draw(@graph)
1162
+ end
1163
+
1164
+ def test_should_generate_edges_for_each_transition
1165
+ assert_equal 4, @graph.edge_count
1166
+ end
1167
+
1168
+ def test_should_use_event_name_for_edge_label
1169
+ assert_equal 'park', @graph.get_edge_at_index(0)['label'].to_s.gsub('"', '')
1170
+ end
1171
+ end
1172
+
1173
+ class EventDrawingWithHumanNameTest < Test::Unit::TestCase
1174
+ def setup
1175
+ states = [:parked, :idling]
1176
+
1177
+ @machine = StateMachine::Machine.new(Class.new, :initial => :parked)
1178
+ @machine.other_states(*states)
1179
+
1180
+ graph = StateMachine::Graph.new('test')
1181
+ states.each {|state| graph.add_nodes(state.to_s)}
1182
+
1183
+ @machine.events << @event = StateMachine::Event.new(@machine , :park, :human_name => 'Park')
1184
+ @event.transition :parked => :idling
1185
+
1186
+ @event.draw(graph, :human_name => true)
1187
+ @edge = graph.get_edge_at_index(0)
1188
+ end
1189
+
1190
+ def test_should_use_event_human_name_for_edge_label
1191
+ assert_equal 'Park', @edge['label'].to_s.gsub('"', '')
1192
+ end
1193
+ end
1194
+ rescue LoadError
1195
+ $stderr.puts 'Skipping GraphViz StateMachine::Event tests. `gem install ruby-graphviz` >= v0.9.17 and try again.'
1196
+ end unless ENV['TRAVIS']