pluginaweek-state_machine 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/CHANGELOG.rdoc +273 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +466 -0
  4. data/Rakefile +98 -0
  5. data/examples/AutoShop_state.png +0 -0
  6. data/examples/Car_state.png +0 -0
  7. data/examples/TrafficLight_state.png +0 -0
  8. data/examples/Vehicle_state.png +0 -0
  9. data/examples/auto_shop.rb +11 -0
  10. data/examples/car.rb +19 -0
  11. data/examples/merb-rest/controller.rb +51 -0
  12. data/examples/merb-rest/model.rb +28 -0
  13. data/examples/merb-rest/view_edit.html.erb +24 -0
  14. data/examples/merb-rest/view_index.html.erb +23 -0
  15. data/examples/merb-rest/view_new.html.erb +13 -0
  16. data/examples/merb-rest/view_show.html.erb +17 -0
  17. data/examples/rails-rest/controller.rb +43 -0
  18. data/examples/rails-rest/migration.rb +11 -0
  19. data/examples/rails-rest/model.rb +23 -0
  20. data/examples/rails-rest/view_edit.html.erb +25 -0
  21. data/examples/rails-rest/view_index.html.erb +23 -0
  22. data/examples/rails-rest/view_new.html.erb +14 -0
  23. data/examples/rails-rest/view_show.html.erb +17 -0
  24. data/examples/traffic_light.rb +7 -0
  25. data/examples/vehicle.rb +31 -0
  26. data/init.rb +1 -0
  27. data/lib/state_machine.rb +429 -0
  28. data/lib/state_machine/assertions.rb +36 -0
  29. data/lib/state_machine/callback.rb +189 -0
  30. data/lib/state_machine/condition_proxy.rb +94 -0
  31. data/lib/state_machine/eval_helpers.rb +67 -0
  32. data/lib/state_machine/event.rb +251 -0
  33. data/lib/state_machine/event_collection.rb +113 -0
  34. data/lib/state_machine/extensions.rb +158 -0
  35. data/lib/state_machine/guard.rb +219 -0
  36. data/lib/state_machine/integrations.rb +68 -0
  37. data/lib/state_machine/integrations/active_record.rb +444 -0
  38. data/lib/state_machine/integrations/active_record/locale.rb +10 -0
  39. data/lib/state_machine/integrations/active_record/observer.rb +41 -0
  40. data/lib/state_machine/integrations/data_mapper.rb +325 -0
  41. data/lib/state_machine/integrations/data_mapper/observer.rb +139 -0
  42. data/lib/state_machine/integrations/sequel.rb +292 -0
  43. data/lib/state_machine/machine.rb +1431 -0
  44. data/lib/state_machine/machine_collection.rb +146 -0
  45. data/lib/state_machine/matcher.rb +123 -0
  46. data/lib/state_machine/matcher_helpers.rb +54 -0
  47. data/lib/state_machine/node_collection.rb +152 -0
  48. data/lib/state_machine/state.rb +249 -0
  49. data/lib/state_machine/state_collection.rb +112 -0
  50. data/lib/state_machine/transition.rb +367 -0
  51. data/tasks/state_machine.rake +1 -0
  52. data/tasks/state_machine.rb +30 -0
  53. data/test/classes/switch.rb +11 -0
  54. data/test/functional/state_machine_test.rb +941 -0
  55. data/test/test_helper.rb +4 -0
  56. data/test/unit/assertions_test.rb +40 -0
  57. data/test/unit/callback_test.rb +455 -0
  58. data/test/unit/condition_proxy_test.rb +328 -0
  59. data/test/unit/eval_helpers_test.rb +129 -0
  60. data/test/unit/event_collection_test.rb +293 -0
  61. data/test/unit/event_test.rb +605 -0
  62. data/test/unit/guard_test.rb +862 -0
  63. data/test/unit/integrations/active_record_test.rb +1001 -0
  64. data/test/unit/integrations/data_mapper_test.rb +694 -0
  65. data/test/unit/integrations/sequel_test.rb +486 -0
  66. data/test/unit/integrations_test.rb +42 -0
  67. data/test/unit/invalid_event_test.rb +7 -0
  68. data/test/unit/invalid_transition_test.rb +7 -0
  69. data/test/unit/machine_collection_test.rb +710 -0
  70. data/test/unit/machine_test.rb +1910 -0
  71. data/test/unit/matcher_helpers_test.rb +37 -0
  72. data/test/unit/matcher_test.rb +155 -0
  73. data/test/unit/node_collection_test.rb +207 -0
  74. data/test/unit/state_collection_test.rb +280 -0
  75. data/test/unit/state_machine_test.rb +31 -0
  76. data/test/unit/state_test.rb +795 -0
  77. data/test/unit/transition_test.rb +1113 -0
  78. metadata +161 -0
@@ -0,0 +1,862 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class GuardTest < Test::Unit::TestCase
4
+ def setup
5
+ @guard = StateMachine::Guard.new(:from => :parked, :to => :idling)
6
+ end
7
+
8
+ def test_should_not_raise_exception_if_implicit_option_specified
9
+ assert_nothing_raised { StateMachine::Guard.new(:invalid => :valid) }
10
+ end
11
+
12
+ def test_should_not_have_an_if_condition
13
+ assert_nil @guard.if_condition
14
+ end
15
+
16
+ def test_should_not_have_an_unless_condition
17
+ assert_nil @guard.unless_condition
18
+ end
19
+
20
+ def test_should_have_a_state_requirement
21
+ assert_equal 1, @guard.state_requirements.length
22
+ end
23
+ end
24
+
25
+ class GuardWithNoRequirementsTest < Test::Unit::TestCase
26
+ def setup
27
+ @object = Object.new
28
+ @guard = StateMachine::Guard.new
29
+ end
30
+
31
+ def test_should_use_all_matcher_for_event_requirement
32
+ assert_equal StateMachine::AllMatcher.instance, @guard.event_requirement
33
+ end
34
+
35
+ def test_should_use_all_matcher_for_from_state_requirement
36
+ assert_equal StateMachine::AllMatcher.instance, @guard.state_requirements.first[:from]
37
+ end
38
+
39
+ def test_should_use_all_matcher_for_to_state_requirement
40
+ assert_equal StateMachine::AllMatcher.instance, @guard.state_requirements.first[:to]
41
+ end
42
+
43
+ def test_should_match_nil_query
44
+ assert @guard.matches?(@object, nil)
45
+ end
46
+
47
+ def test_should_match_empty_query
48
+ assert @guard.matches?(@object, {})
49
+ end
50
+
51
+ def test_should_match_non_empty_query
52
+ assert @guard.matches?(@object, :to => :idling, :from => :parked, :on => :ignite)
53
+ end
54
+
55
+ def test_should_include_all_requirements_in_match
56
+ match = @guard.match(@object, nil)
57
+
58
+ assert_equal @guard.state_requirements.first[:from], match[:from]
59
+ assert_equal @guard.state_requirements.first[:to], match[:to]
60
+ assert_equal @guard.event_requirement, match[:on]
61
+ end
62
+ end
63
+
64
+ class GuardWithFromRequirementTest < Test::Unit::TestCase
65
+ def setup
66
+ @object = Object.new
67
+ @guard = StateMachine::Guard.new(:from => :parked)
68
+ end
69
+
70
+ def test_should_use_a_whitelist_matcher
71
+ assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:from]
72
+ end
73
+
74
+ def test_should_match_if_not_specified
75
+ assert @guard.matches?(@object, :to => :idling)
76
+ end
77
+
78
+ def test_should_match_if_included
79
+ assert @guard.matches?(@object, :from => :parked)
80
+ end
81
+
82
+ def test_should_not_match_if_not_included
83
+ assert !@guard.matches?(@object, :from => :idling)
84
+ end
85
+
86
+ def test_should_not_match_if_nil
87
+ assert !@guard.matches?(@object, :from => nil)
88
+ end
89
+
90
+ def test_should_ignore_to
91
+ assert @guard.matches?(@object, :from => :parked, :to => :idling)
92
+ end
93
+
94
+ def test_should_ignore_on
95
+ assert @guard.matches?(@object, :from => :parked, :on => :ignite)
96
+ end
97
+
98
+ def test_should_be_included_in_known_states
99
+ assert_equal [:parked], @guard.known_states
100
+ end
101
+
102
+ def test_should_include_requirement_in_match
103
+ match = @guard.match(@object, :from => :parked)
104
+ assert_equal @guard.state_requirements.first[:from], match[:from]
105
+ end
106
+ end
107
+
108
+ class GuardWithMultipleFromRequirementsTest < Test::Unit::TestCase
109
+ def setup
110
+ @object = Object.new
111
+ @guard = StateMachine::Guard.new(:from => [:idling, :parked])
112
+ end
113
+
114
+ def test_should_match_if_included
115
+ assert @guard.matches?(@object, :from => :idling)
116
+ end
117
+
118
+ def test_should_not_match_if_not_included
119
+ assert !@guard.matches?(@object, :from => :first_gear)
120
+ end
121
+
122
+ def test_should_be_included_in_known_states
123
+ assert_equal [:idling, :parked], @guard.known_states
124
+ end
125
+ end
126
+
127
+ class GuardWithToRequirementTest < Test::Unit::TestCase
128
+ def setup
129
+ @object = Object.new
130
+ @guard = StateMachine::Guard.new(:to => :idling)
131
+ end
132
+
133
+ def test_should_use_a_whitelist_matcher
134
+ assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:to]
135
+ end
136
+
137
+ def test_should_match_if_not_specified
138
+ assert @guard.matches?(@object, :from => :parked)
139
+ end
140
+
141
+ def test_should_match_if_included
142
+ assert @guard.matches?(@object, :to => :idling)
143
+ end
144
+
145
+ def test_should_not_match_if_not_included
146
+ assert !@guard.matches?(@object, :to => :parked)
147
+ end
148
+
149
+ def test_should_not_match_if_nil
150
+ assert !@guard.matches?(@object, :to => nil)
151
+ end
152
+
153
+ def test_should_ignore_from
154
+ assert @guard.matches?(@object, :to => :idling, :from => :parked)
155
+ end
156
+
157
+ def test_should_ignore_on
158
+ assert @guard.matches?(@object, :to => :idling, :on => :ignite)
159
+ end
160
+
161
+ def test_should_be_included_in_known_states
162
+ assert_equal [:idling], @guard.known_states
163
+ end
164
+
165
+ def test_should_include_requirement_in_match
166
+ match = @guard.match(@object, :to => :idling)
167
+ assert_equal @guard.state_requirements.first[:to], match[:to]
168
+ end
169
+ end
170
+
171
+ class GuardWithMultipleToRequirementsTest < Test::Unit::TestCase
172
+ def setup
173
+ @object = Object.new
174
+ @guard = StateMachine::Guard.new(:to => [:idling, :parked])
175
+ end
176
+
177
+ def test_should_match_if_included
178
+ assert @guard.matches?(@object, :to => :idling)
179
+ end
180
+
181
+ def test_should_not_match_if_not_included
182
+ assert !@guard.matches?(@object, :to => :first_gear)
183
+ end
184
+
185
+ def test_should_be_included_in_known_states
186
+ assert_equal [:idling, :parked], @guard.known_states
187
+ end
188
+ end
189
+
190
+ class GuardWithOnRequirementTest < Test::Unit::TestCase
191
+ def setup
192
+ @object = Object.new
193
+ @guard = StateMachine::Guard.new(:on => :ignite)
194
+ end
195
+
196
+ def test_should_use_a_whitelist_matcher
197
+ assert_instance_of StateMachine::WhitelistMatcher, @guard.event_requirement
198
+ end
199
+
200
+ def test_should_match_if_not_specified
201
+ assert @guard.matches?(@object, :from => :parked)
202
+ end
203
+
204
+ def test_should_match_if_included
205
+ assert @guard.matches?(@object, :on => :ignite)
206
+ end
207
+
208
+ def test_should_not_match_if_not_included
209
+ assert !@guard.matches?(@object, :on => :park)
210
+ end
211
+
212
+ def test_should_not_match_if_nil
213
+ assert !@guard.matches?(@object, :on => nil)
214
+ end
215
+
216
+ def test_should_ignore_to
217
+ assert @guard.matches?(@object, :on => :ignite, :to => :parked)
218
+ end
219
+
220
+ def test_should_ignore_from
221
+ assert @guard.matches?(@object, :on => :ignite, :from => :parked)
222
+ end
223
+
224
+ def test_should_not_be_included_in_known_states
225
+ assert_equal [], @guard.known_states
226
+ end
227
+
228
+ def test_should_include_requirement_in_match
229
+ match = @guard.match(@object, :on => :ignite)
230
+ assert_equal @guard.event_requirement, match[:on]
231
+ end
232
+ end
233
+
234
+ class GuardWithMultipleOnRequirementsTest < Test::Unit::TestCase
235
+ def setup
236
+ @object = Object.new
237
+ @guard = StateMachine::Guard.new(:on => [:ignite, :park])
238
+ end
239
+
240
+ def test_should_match_if_included
241
+ assert @guard.matches?(@object, :on => :ignite)
242
+ end
243
+
244
+ def test_should_not_match_if_not_included
245
+ assert !@guard.matches?(@object, :on => :shift_up)
246
+ end
247
+ end
248
+
249
+ class GuardWithExceptFromRequirementTest < Test::Unit::TestCase
250
+ def setup
251
+ @object = Object.new
252
+ @guard = StateMachine::Guard.new(:except_from => :parked)
253
+ end
254
+
255
+ def test_should_use_a_blacklist_matcher
256
+ assert_instance_of StateMachine::BlacklistMatcher, @guard.state_requirements.first[:from]
257
+ end
258
+
259
+ def test_should_match_if_not_included
260
+ assert @guard.matches?(@object, :from => :idling)
261
+ end
262
+
263
+ def test_should_not_match_if_included
264
+ assert !@guard.matches?(@object, :from => :parked)
265
+ end
266
+
267
+ def test_should_match_if_nil
268
+ assert @guard.matches?(@object, :from => nil)
269
+ end
270
+
271
+ def test_should_ignore_to
272
+ assert @guard.matches?(@object, :from => :idling, :to => :parked)
273
+ end
274
+
275
+ def test_should_ignore_on
276
+ assert @guard.matches?(@object, :from => :idling, :on => :ignite)
277
+ end
278
+
279
+ def test_should_be_included_in_known_states
280
+ assert_equal [:parked], @guard.known_states
281
+ end
282
+ end
283
+
284
+ class GuardWithMultipleExceptFromRequirementsTest < Test::Unit::TestCase
285
+ def setup
286
+ @object = Object.new
287
+ @guard = StateMachine::Guard.new(:except_from => [:idling, :parked])
288
+ end
289
+
290
+ def test_should_match_if_not_included
291
+ assert @guard.matches?(@object, :from => :first_gear)
292
+ end
293
+
294
+ def test_should_not_match_if_included
295
+ assert !@guard.matches?(@object, :from => :idling)
296
+ end
297
+
298
+ def test_should_be_included_in_known_states
299
+ assert_equal [:idling, :parked], @guard.known_states
300
+ end
301
+ end
302
+
303
+ class GuardWithExceptToRequirementTest < Test::Unit::TestCase
304
+ def setup
305
+ @object = Object.new
306
+ @guard = StateMachine::Guard.new(:except_to => :idling)
307
+ end
308
+
309
+ def test_should_use_a_blacklist_matcher
310
+ assert_instance_of StateMachine::BlacklistMatcher, @guard.state_requirements.first[:to]
311
+ end
312
+
313
+ def test_should_match_if_not_included
314
+ assert @guard.matches?(@object, :to => :parked)
315
+ end
316
+
317
+ def test_should_not_match_if_included
318
+ assert !@guard.matches?(@object, :to => :idling)
319
+ end
320
+
321
+ def test_should_match_if_nil
322
+ assert @guard.matches?(@object, :to => nil)
323
+ end
324
+
325
+ def test_should_ignore_from
326
+ assert @guard.matches?(@object, :to => :parked, :from => :idling)
327
+ end
328
+
329
+ def test_should_ignore_on
330
+ assert @guard.matches?(@object, :to => :parked, :on => :ignite)
331
+ end
332
+
333
+ def test_should_be_included_in_known_states
334
+ assert_equal [:idling], @guard.known_states
335
+ end
336
+ end
337
+
338
+ class GuardWithMultipleExceptToRequirementsTest < Test::Unit::TestCase
339
+ def setup
340
+ @object = Object.new
341
+ @guard = StateMachine::Guard.new(:except_to => [:idling, :parked])
342
+ end
343
+
344
+ def test_should_match_if_not_included
345
+ assert @guard.matches?(@object, :to => :first_gear)
346
+ end
347
+
348
+ def test_should_not_match_if_included
349
+ assert !@guard.matches?(@object, :to => :idling)
350
+ end
351
+
352
+ def test_should_be_included_in_known_states
353
+ assert_equal [:idling, :parked], @guard.known_states
354
+ end
355
+ end
356
+
357
+ class GuardWithExceptOnRequirementTest < Test::Unit::TestCase
358
+ def setup
359
+ @object = Object.new
360
+ @guard = StateMachine::Guard.new(:except_on => :ignite)
361
+ end
362
+
363
+ def test_should_use_a_blacklist_matcher
364
+ assert_instance_of StateMachine::BlacklistMatcher, @guard.event_requirement
365
+ end
366
+
367
+ def test_should_match_if_not_included
368
+ assert @guard.matches?(@object, :on => :park)
369
+ end
370
+
371
+ def test_should_not_match_if_included
372
+ assert !@guard.matches?(@object, :on => :ignite)
373
+ end
374
+
375
+ def test_should_match_if_nil
376
+ assert @guard.matches?(@object, :on => nil)
377
+ end
378
+
379
+ def test_should_ignore_to
380
+ assert @guard.matches?(@object, :on => :park, :to => :idling)
381
+ end
382
+
383
+ def test_should_ignore_from
384
+ assert @guard.matches?(@object, :on => :park, :from => :parked)
385
+ end
386
+
387
+ def test_should_not_be_included_in_known_states
388
+ assert_equal [], @guard.known_states
389
+ end
390
+ end
391
+
392
+ class GuardWithMultipleExceptOnRequirementsTest < Test::Unit::TestCase
393
+ def setup
394
+ @object = Object.new
395
+ @guard = StateMachine::Guard.new(:except_on => [:ignite, :park])
396
+ end
397
+
398
+ def test_should_match_if_not_included
399
+ assert @guard.matches?(@object, :on => :shift_up)
400
+ end
401
+
402
+ def test_should_not_match_if_included
403
+ assert !@guard.matches?(@object, :on => :ignite)
404
+ end
405
+ end
406
+
407
+ class GuardWithConflictingFromRequirementsTest < Test::Unit::TestCase
408
+ def test_should_raise_an_exception
409
+ exception = assert_raise(ArgumentError) { StateMachine::Guard.new(:from => :parked, :except_from => :parked) }
410
+ assert_equal 'Conflicting keys: from, except_from', exception.message
411
+ end
412
+ end
413
+
414
+ class GuardWithConflictingToRequirementsTest < Test::Unit::TestCase
415
+ def test_should_raise_an_exception
416
+ exception = assert_raise(ArgumentError) { StateMachine::Guard.new(:to => :idling, :except_to => :idling) }
417
+ assert_equal 'Conflicting keys: to, except_to', exception.message
418
+ end
419
+ end
420
+
421
+ class GuardWithConflictingOnRequirementsTest < Test::Unit::TestCase
422
+ def test_should_raise_an_exception
423
+ exception = assert_raise(ArgumentError) { StateMachine::Guard.new(:on => :ignite, :except_on => :ignite) }
424
+ assert_equal 'Conflicting keys: on, except_on', exception.message
425
+ end
426
+ end
427
+
428
+ class GuardWithDifferentRequirementsTest < Test::Unit::TestCase
429
+ def setup
430
+ @object = Object.new
431
+ @guard = StateMachine::Guard.new(:from => :parked, :to => :idling, :on => :ignite)
432
+ end
433
+
434
+ def test_should_match_empty_query
435
+ assert @guard.matches?(@object)
436
+ end
437
+
438
+ def test_should_match_if_all_requirements_match
439
+ assert @guard.matches?(@object, :from => :parked, :to => :idling, :on => :ignite)
440
+ end
441
+
442
+ def test_should_not_match_if_from_not_included
443
+ assert !@guard.matches?(@object, :from => :idling)
444
+ end
445
+
446
+ def test_should_not_match_if_to_not_included
447
+ assert !@guard.matches?(@object, :to => :parked)
448
+ end
449
+
450
+ def test_should_not_match_if_on_not_included
451
+ assert !@guard.matches?(@object, :on => :park)
452
+ end
453
+
454
+ def test_should_be_nil_if_unmatched
455
+ assert_nil @guard.match(@object, :from => :parked, :to => :idling, :on => :park)
456
+ end
457
+
458
+ def test_should_include_all_known_states
459
+ assert_equal [:parked, :idling], @guard.known_states
460
+ end
461
+
462
+ def test_should_not_duplicate_known_statse
463
+ guard = StateMachine::Guard.new(:except_from => :idling, :to => :idling, :on => :ignite)
464
+ assert_equal [:idling], guard.known_states
465
+ end
466
+ end
467
+
468
+ class GuardWithNilRequirementsTest < Test::Unit::TestCase
469
+ def setup
470
+ @object = Object.new
471
+ @guard = StateMachine::Guard.new(:from => nil, :to => nil)
472
+ end
473
+
474
+ def test_should_match_empty_query
475
+ assert @guard.matches?(@object)
476
+ end
477
+
478
+ def test_should_match_if_all_requirements_match
479
+ assert @guard.matches?(@object, :from => nil, :to => nil)
480
+ end
481
+
482
+ def test_should_not_match_if_from_not_included
483
+ assert !@guard.matches?(@object, :from => :parked)
484
+ end
485
+
486
+ def test_should_not_match_if_to_not_included
487
+ assert !@guard.matches?(@object, :to => :idling)
488
+ end
489
+
490
+ def test_should_include_all_known_states
491
+ assert_equal [nil], @guard.known_states
492
+ end
493
+ end
494
+
495
+ class GuardWithImplicitRequirementTest < Test::Unit::TestCase
496
+ def setup
497
+ @guard = StateMachine::Guard.new(:parked => :idling, :on => :ignite)
498
+ end
499
+
500
+ def test_should_create_an_event_requirement
501
+ assert_instance_of StateMachine::WhitelistMatcher, @guard.event_requirement
502
+ assert_equal [:ignite], @guard.event_requirement.values
503
+ end
504
+
505
+ def test_should_use_a_whitelist_from_matcher
506
+ assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:from]
507
+ end
508
+
509
+ def test_should_use_a_whitelist_to_matcher
510
+ assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:to]
511
+ end
512
+ end
513
+
514
+ class GuardWithMultipleImplicitRequirementsTest < Test::Unit::TestCase
515
+ def setup
516
+ @object = Object.new
517
+ @guard = StateMachine::Guard.new(:parked => :idling, :idling => :first_gear, :on => :ignite)
518
+ end
519
+
520
+ def test_should_create_multiple_state_requirements
521
+ assert_equal 2, @guard.state_requirements.length
522
+ end
523
+
524
+ def test_should_not_match_event_as_state_requirement
525
+ assert !@guard.matches?(@object, :from => :on, :to => :ignite)
526
+ end
527
+
528
+ def test_should_match_if_from_included_in_any
529
+ assert @guard.matches?(@object, :from => :parked)
530
+ assert @guard.matches?(@object, :from => :idling)
531
+ end
532
+
533
+ def test_should_not_match_if_from_not_included_in_any
534
+ assert !@guard.matches?(@object, :from => :first_gear)
535
+ end
536
+
537
+ def test_should_match_if_to_included_in_any
538
+ assert @guard.matches?(@object, :to => :idling)
539
+ assert @guard.matches?(@object, :to => :first_gear)
540
+ end
541
+
542
+ def test_should_not_match_if_to_not_included_in_any
543
+ assert !@guard.matches?(@object, :to => :parked)
544
+ end
545
+
546
+ def test_should_match_if_all_options_match
547
+ assert @guard.matches?(@object, :from => :parked, :to => :idling, :on => :ignite)
548
+ assert @guard.matches?(@object, :from => :idling, :to => :first_gear, :on => :ignite)
549
+ end
550
+
551
+ def test_should_not_match_if_any_options_do_not_match
552
+ assert !@guard.matches?(@object, :from => :parked, :to => :idling, :on => :park)
553
+ assert !@guard.matches?(@object, :from => :parked, :to => :first_gear, :on => :park)
554
+ end
555
+
556
+ def test_should_include_all_known_states
557
+ assert_equal [:first_gear, :idling, :parked], @guard.known_states.sort_by {|state| state.to_s}
558
+ end
559
+
560
+ def test_should_not_duplicate_known_statse
561
+ guard = StateMachine::Guard.new(:parked => :idling, :first_gear => :idling)
562
+ assert_equal [:first_gear, :idling, :parked], guard.known_states.sort_by {|state| state.to_s}
563
+ end
564
+ end
565
+
566
+ class GuardWithImplicitFromRequirementMatcherTest < Test::Unit::TestCase
567
+ def setup
568
+ @matcher = StateMachine::BlacklistMatcher.new(:parked)
569
+ @guard = StateMachine::Guard.new(@matcher => :idling)
570
+ end
571
+
572
+ def test_should_not_convert_from_to_whitelist_matcher
573
+ assert_equal @matcher, @guard.state_requirements.first[:from]
574
+ end
575
+
576
+ def test_should_convert_to_to_whitelist_matcher
577
+ assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:to]
578
+ end
579
+ end
580
+
581
+ class GuardWithImplicitToRequirementMatcherTest < Test::Unit::TestCase
582
+ def setup
583
+ @matcher = StateMachine::BlacklistMatcher.new(:idling)
584
+ @guard = StateMachine::Guard.new(:parked => @matcher)
585
+ end
586
+
587
+ def test_should_convert_from_to_whitelist_matcher
588
+ assert_instance_of StateMachine::WhitelistMatcher, @guard.state_requirements.first[:from]
589
+ end
590
+
591
+ def test_should_not_convert_to_to_whitelist_matcher
592
+ assert_equal @matcher, @guard.state_requirements.first[:to]
593
+ end
594
+ end
595
+
596
+ class GuardWithImplicitAndExplicitRequirementsTest < Test::Unit::TestCase
597
+ def setup
598
+ @guard = StateMachine::Guard.new(:parked => :idling, :from => :parked)
599
+ end
600
+
601
+ def test_should_create_multiple_requirements
602
+ assert_equal 2, @guard.state_requirements.length
603
+ end
604
+
605
+ def test_should_create_implicit_requirements_for_implicit_options
606
+ assert(@guard.state_requirements.any? do |state_requirement|
607
+ state_requirement[:from].values == [:parked] && state_requirement[:to].values == [:idling]
608
+ end)
609
+ end
610
+
611
+ def test_should_create_implicit_requirements_for_explicit_options
612
+ assert(@guard.state_requirements.any? do |state_requirement|
613
+ state_requirement[:from].values == [:from] && state_requirement[:to].values == [:parked]
614
+ end)
615
+ end
616
+ end
617
+
618
+ class GuardWithIfConditionalTest < Test::Unit::TestCase
619
+ def setup
620
+ @object = Object.new
621
+ end
622
+
623
+ def test_should_have_an_if_condition
624
+ guard = StateMachine::Guard.new(:if => lambda {true})
625
+ assert_not_nil guard.if_condition
626
+ end
627
+
628
+ def test_should_match_if_true
629
+ guard = StateMachine::Guard.new(:if => lambda {true})
630
+ assert guard.matches?(@object)
631
+ end
632
+
633
+ def test_should_not_match_if_false
634
+ guard = StateMachine::Guard.new(:if => lambda {false})
635
+ assert !guard.matches?(@object)
636
+ end
637
+
638
+ def test_should_be_nil_if_unmatched
639
+ guard = StateMachine::Guard.new(:if => lambda {false})
640
+ assert_nil guard.match(@object)
641
+ end
642
+ end
643
+
644
+ class GuardWithMultipleIfConditionalsTest < Test::Unit::TestCase
645
+ def setup
646
+ @object = Object.new
647
+ end
648
+
649
+ def test_should_match_if_all_are_true
650
+ guard = StateMachine::Guard.new(:if => [lambda {true}, lambda {true}])
651
+ assert guard.match(@object)
652
+ end
653
+
654
+ def test_should_not_match_if_any_are_false
655
+ guard = StateMachine::Guard.new(:if => [lambda {true}, lambda {false}])
656
+ assert !guard.match(@object)
657
+
658
+ guard = StateMachine::Guard.new(:if => [lambda {false}, lambda {true}])
659
+ assert !guard.match(@object)
660
+ end
661
+ end
662
+
663
+ class GuardWithUnlessConditionalTest < Test::Unit::TestCase
664
+ def setup
665
+ @object = Object.new
666
+ end
667
+
668
+ def test_should_have_an_unless_condition
669
+ guard = StateMachine::Guard.new(:unless => lambda {true})
670
+ assert_not_nil guard.unless_condition
671
+ end
672
+
673
+ def test_should_match_if_false
674
+ guard = StateMachine::Guard.new(:unless => lambda {false})
675
+ assert guard.matches?(@object)
676
+ end
677
+
678
+ def test_should_not_match_if_true
679
+ guard = StateMachine::Guard.new(:unless => lambda {true})
680
+ assert !guard.matches?(@object)
681
+ end
682
+
683
+ def test_should_be_nil_if_unmatched
684
+ guard = StateMachine::Guard.new(:unless => lambda {true})
685
+ assert_nil guard.match(@object)
686
+ end
687
+ end
688
+
689
+ class GuardWithMultipleUnlessConditionalsTest < Test::Unit::TestCase
690
+ def setup
691
+ @object = Object.new
692
+ end
693
+
694
+ def test_should_match_if_all_are_false
695
+ guard = StateMachine::Guard.new(:unless => [lambda {false}, lambda {false}])
696
+ assert guard.match(@object)
697
+ end
698
+
699
+ def test_should_not_match_if_any_are_true
700
+ guard = StateMachine::Guard.new(:unless => [lambda {true}, lambda {false}])
701
+ assert !guard.match(@object)
702
+
703
+ guard = StateMachine::Guard.new(:unless => [lambda {false}, lambda {true}])
704
+ assert !guard.match(@object)
705
+ end
706
+ end
707
+
708
+ class GuardWithConflictingConditionalsTest < Test::Unit::TestCase
709
+ def test_should_match_if_if_is_true_and_unless_is_false
710
+ guard = StateMachine::Guard.new(:if => lambda {true}, :unless => lambda {false})
711
+ assert guard.match(@object)
712
+ end
713
+
714
+ def test_should_not_match_if_if_is_false_and_unless_is_true
715
+ guard = StateMachine::Guard.new(:if => lambda {false}, :unless => lambda {true})
716
+ assert !guard.match(@object)
717
+ end
718
+
719
+ def test_should_not_match_if_if_is_false_and_unless_is_false
720
+ guard = StateMachine::Guard.new(:if => lambda {false}, :unless => lambda {false})
721
+ assert !guard.match(@object)
722
+ end
723
+
724
+ def test_should_not_match_if_if_is_true_and_unless_is_true
725
+ guard = StateMachine::Guard.new(:if => lambda {true}, :unless => lambda {true})
726
+ assert !guard.match(@object)
727
+ end
728
+ end
729
+
730
+ begin
731
+ # Load library
732
+ require 'rubygems'
733
+ require 'graphviz'
734
+
735
+ class GuardDrawingTest < Test::Unit::TestCase
736
+ def setup
737
+ @machine = StateMachine::Machine.new(Class.new)
738
+ states = [:parked, :idling]
739
+
740
+ graph = GraphViz.new('G')
741
+ states.each {|state| graph.add_node(state.to_s)}
742
+
743
+ @guard = StateMachine::Guard.new(:from => :idling, :to => :parked)
744
+ @edges = @guard.draw(graph, :park, states)
745
+ end
746
+
747
+ def test_should_create_edges
748
+ assert_equal 1, @edges.size
749
+ end
750
+
751
+ def test_should_use_from_state_from_start_node
752
+ assert_equal 'idling', @edges.first.instance_variable_get('@xNodeOne')
753
+ end
754
+
755
+ def test_should_use_to_state_for_end_node
756
+ assert_equal 'parked', @edges.first.instance_variable_get('@xNodeTwo')
757
+ end
758
+
759
+ def test_should_use_event_name_as_label
760
+ assert_equal 'park', @edges.first['label']
761
+ end
762
+ end
763
+
764
+ class GuardDrawingWithFromRequirementTest < Test::Unit::TestCase
765
+ def setup
766
+ @machine = StateMachine::Machine.new(Class.new)
767
+ states = [:parked, :idling, :first_gear]
768
+
769
+ graph = GraphViz.new('G')
770
+ states.each {|state| graph.add_node(state.to_s)}
771
+
772
+ @guard = StateMachine::Guard.new(:from => [:idling, :first_gear], :to => :parked)
773
+ @edges = @guard.draw(graph, :park, states)
774
+ end
775
+
776
+ def test_should_generate_edges_for_each_valid_from_state
777
+ [:idling, :first_gear].each_with_index do |from_state, index|
778
+ edge = @edges[index]
779
+ assert_equal from_state.to_s, edge.instance_variable_get('@xNodeOne')
780
+ assert_equal 'parked', edge.instance_variable_get('@xNodeTwo')
781
+ end
782
+ end
783
+ end
784
+
785
+ class GuardDrawingWithExceptFromRequirementTest < Test::Unit::TestCase
786
+ def setup
787
+ @machine = StateMachine::Machine.new(Class.new)
788
+ states = [:parked, :idling, :first_gear]
789
+
790
+ graph = GraphViz.new('G')
791
+ states.each {|state| graph.add_node(state.to_s)}
792
+
793
+ @guard = StateMachine::Guard.new(:except_from => :parked, :to => :parked)
794
+ @edges = @guard.draw(graph, :park, states)
795
+ end
796
+
797
+ def test_should_generate_edges_for_each_valid_from_state
798
+ %w(idling first_gear).each_with_index do |from_state, index|
799
+ edge = @edges[index]
800
+ assert_equal from_state, edge.instance_variable_get('@xNodeOne')
801
+ assert_equal 'parked', edge.instance_variable_get('@xNodeTwo')
802
+ end
803
+ end
804
+ end
805
+
806
+ class GuardDrawingWithoutFromRequirementTest < Test::Unit::TestCase
807
+ def setup
808
+ @machine = StateMachine::Machine.new(Class.new)
809
+ states = [:parked, :idling, :first_gear]
810
+
811
+ graph = GraphViz.new('G')
812
+ states.each {|state| graph.add_node(state.to_s)}
813
+
814
+ @guard = StateMachine::Guard.new(:to => :parked)
815
+ @edges = @guard.draw(graph, :park, states)
816
+ end
817
+
818
+ def test_should_generate_edges_for_each_valid_from_state
819
+ %w(parked idling first_gear).each_with_index do |from_state, index|
820
+ edge = @edges[index]
821
+ assert_equal from_state, edge.instance_variable_get('@xNodeOne')
822
+ assert_equal 'parked', edge.instance_variable_get('@xNodeTwo')
823
+ end
824
+ end
825
+ end
826
+
827
+ class GuardDrawingWithoutToRequirementTest < Test::Unit::TestCase
828
+ def setup
829
+ @machine = StateMachine::Machine.new(Class.new)
830
+
831
+ graph = GraphViz.new('G')
832
+ graph.add_node('parked')
833
+
834
+ @guard = StateMachine::Guard.new(:from => :parked)
835
+ @edges = @guard.draw(graph, :park, [:parked])
836
+ end
837
+
838
+ def test_should_create_loopback_edge
839
+ assert_equal 'parked', @edges.first.instance_variable_get('@xNodeOne')
840
+ assert_equal 'parked', @edges.first.instance_variable_get('@xNodeTwo')
841
+ end
842
+ end
843
+
844
+ class GuardDrawingWithNilStateTest < Test::Unit::TestCase
845
+ def setup
846
+ @machine = StateMachine::Machine.new(Class.new)
847
+
848
+ graph = GraphViz.new('G')
849
+ graph.add_node('parked')
850
+
851
+ @guard = StateMachine::Guard.new(:from => :idling, :to => nil)
852
+ @edges = @guard.draw(graph, :park, [nil, :idling])
853
+ end
854
+
855
+ def test_should_generate_edges_for_each_valid_from_state
856
+ assert_equal 'idling', @edges.first.instance_variable_get('@xNodeOne')
857
+ assert_equal 'nil', @edges.first.instance_variable_get('@xNodeTwo')
858
+ end
859
+ end
860
+ rescue LoadError
861
+ $stderr.puts 'Skipping GraphViz StateMachine::Guard tests. `gem install ruby-graphviz` and try again.'
862
+ end