state_machine 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +17 -0
- data/LICENSE +1 -1
- data/README.rdoc +162 -23
- data/Rakefile +3 -18
- data/lib/state_machine.rb +3 -4
- data/lib/state_machine/callback.rb +65 -13
- data/lib/state_machine/eval_helpers.rb +20 -4
- data/lib/state_machine/initializers.rb +4 -0
- data/lib/state_machine/initializers/merb.rb +1 -0
- data/lib/state_machine/initializers/rails.rb +7 -0
- data/lib/state_machine/integrations.rb +21 -6
- data/lib/state_machine/integrations/active_model.rb +414 -0
- data/lib/state_machine/integrations/active_model/locale.rb +11 -0
- data/lib/state_machine/integrations/{active_record → active_model}/observer.rb +7 -7
- data/lib/state_machine/integrations/active_record.rb +65 -129
- data/lib/state_machine/integrations/active_record/locale.rb +4 -11
- data/lib/state_machine/integrations/data_mapper.rb +24 -6
- data/lib/state_machine/integrations/data_mapper/observer.rb +36 -0
- data/lib/state_machine/integrations/mongo_mapper.rb +295 -0
- data/lib/state_machine/integrations/sequel.rb +33 -7
- data/lib/state_machine/machine.rb +121 -23
- data/lib/state_machine/machine_collection.rb +12 -103
- data/lib/state_machine/transition.rb +125 -164
- data/lib/state_machine/transition_collection.rb +244 -0
- data/lib/tasks/state_machine.rb +12 -15
- data/test/functional/state_machine_test.rb +11 -1
- data/test/unit/callback_test.rb +305 -32
- data/test/unit/eval_helpers_test.rb +103 -1
- data/test/unit/event_test.rb +2 -1
- data/test/unit/guard_test.rb +2 -1
- data/test/unit/integrations/active_model_test.rb +909 -0
- data/test/unit/integrations/active_record_test.rb +1542 -1292
- data/test/unit/integrations/data_mapper_test.rb +1369 -1041
- data/test/unit/integrations/mongo_mapper_test.rb +1349 -0
- data/test/unit/integrations/sequel_test.rb +1214 -985
- data/test/unit/integrations_test.rb +8 -0
- data/test/unit/machine_collection_test.rb +140 -513
- data/test/unit/machine_test.rb +212 -10
- data/test/unit/state_test.rb +2 -1
- data/test/unit/transition_collection_test.rb +2098 -0
- data/test/unit/transition_test.rb +704 -552
- metadata +16 -3
@@ -24,6 +24,10 @@ class IntegrationMatcherTest < Test::Unit::TestCase
|
|
24
24
|
end
|
25
25
|
|
26
26
|
class IntegrationFinderTest < Test::Unit::TestCase
|
27
|
+
def test_should_find_active_model
|
28
|
+
assert_equal StateMachine::Integrations::ActiveModel, StateMachine::Integrations.find(:active_model)
|
29
|
+
end
|
30
|
+
|
27
31
|
def test_should_find_active_record
|
28
32
|
assert_equal StateMachine::Integrations::ActiveRecord, StateMachine::Integrations.find(:active_record)
|
29
33
|
end
|
@@ -32,6 +36,10 @@ class IntegrationFinderTest < Test::Unit::TestCase
|
|
32
36
|
assert_equal StateMachine::Integrations::DataMapper, StateMachine::Integrations.find(:data_mapper)
|
33
37
|
end
|
34
38
|
|
39
|
+
def test_should_find_mongo_mapper
|
40
|
+
assert_equal StateMachine::Integrations::MongoMapper, StateMachine::Integrations.find(:mongo_mapper)
|
41
|
+
end
|
42
|
+
|
35
43
|
def test_should_find_sequel
|
36
44
|
assert_equal StateMachine::Integrations::Sequel, StateMachine::Integrations.find(:sequel)
|
37
45
|
end
|
@@ -101,9 +101,18 @@ class MachineCollectionStateInitializationTest < Test::Unit::TestCase
|
|
101
101
|
assert_equal 'parked', @object.state
|
102
102
|
assert_equal 'active', @object.alarm_state
|
103
103
|
end
|
104
|
+
|
105
|
+
def test_should_not_modify_ignore_option
|
106
|
+
ignore = ['state', 'alarm_state']
|
107
|
+
@machines.initialize_states(@object, :ignore => ignore)
|
108
|
+
|
109
|
+
assert_nil @object.state
|
110
|
+
assert_nil @object.alarm_state
|
111
|
+
assert_equal ['state', 'alarm_state'], ignore
|
112
|
+
end
|
104
113
|
end
|
105
114
|
|
106
|
-
class
|
115
|
+
class MachineCollectionFireTest < Test::Unit::TestCase
|
107
116
|
def setup
|
108
117
|
@machines = StateMachine::MachineCollection.new
|
109
118
|
|
@@ -171,7 +180,7 @@ class MachineCollectionFireExplicitTest < Test::Unit::TestCase
|
|
171
180
|
end
|
172
181
|
end
|
173
182
|
|
174
|
-
class
|
183
|
+
class MachineCollectionFireWithTransactionsTest < Test::Unit::TestCase
|
175
184
|
def setup
|
176
185
|
@machines = StateMachine::MachineCollection.new
|
177
186
|
|
@@ -231,7 +240,7 @@ class MachineCollectionFireExplicitWithTransactionsTest < Test::Unit::TestCase
|
|
231
240
|
end
|
232
241
|
end
|
233
242
|
|
234
|
-
class
|
243
|
+
class MachineCollectionFireWithValidationsTest < Test::Unit::TestCase
|
235
244
|
def setup
|
236
245
|
StateMachine::Integrations.const_set('Custom', Module.new do
|
237
246
|
def invalidate(object, attribute, message, values = [])
|
@@ -284,7 +293,7 @@ class MachineCollectionFireExplicitWithValidationsTest < Test::Unit::TestCase
|
|
284
293
|
end
|
285
294
|
end
|
286
295
|
|
287
|
-
class
|
296
|
+
class MachineCollectionTransitionsWithoutEventsTest < Test::Unit::TestCase
|
288
297
|
def setup
|
289
298
|
@klass = Class.new
|
290
299
|
|
@@ -294,507 +303,216 @@ class MachineCollectionFireImplicitTest < Test::Unit::TestCase
|
|
294
303
|
transition :parked => :idling
|
295
304
|
end
|
296
305
|
|
297
|
-
@saved = false
|
298
306
|
@object = @klass.new
|
299
|
-
end
|
300
|
-
|
301
|
-
def default_test
|
302
|
-
end
|
303
|
-
end
|
304
|
-
|
305
|
-
class MachineCollectionFireImplicitWithoutEventTest < MachineCollectionFireImplicitTest
|
306
|
-
def setup
|
307
|
-
super
|
308
|
-
|
309
307
|
@object.state_event = nil
|
310
|
-
@
|
311
|
-
end
|
312
|
-
|
313
|
-
def test_should_be_successful
|
314
|
-
assert_equal true, @result
|
315
|
-
end
|
316
|
-
|
317
|
-
def test_should_run_action
|
318
|
-
assert @saved
|
308
|
+
@transitions = @machines.transitions(@object, :save)
|
319
309
|
end
|
320
310
|
|
321
|
-
def
|
322
|
-
|
311
|
+
def test_should_be_empty
|
312
|
+
assert @transitions.empty?
|
323
313
|
end
|
324
314
|
|
325
|
-
def
|
326
|
-
|
327
|
-
end
|
328
|
-
|
329
|
-
def test_should_not_have_event_transition
|
330
|
-
assert_nil @object.send(:state_event_transition)
|
315
|
+
def test_should_perform
|
316
|
+
assert_equal true, @transitions.perform
|
331
317
|
end
|
332
318
|
end
|
333
319
|
|
334
|
-
class
|
320
|
+
class MachineCollectionTransitionsWithBlankEventsTest < Test::Unit::TestCase
|
335
321
|
def setup
|
336
|
-
|
322
|
+
@klass = Class.new
|
337
323
|
|
324
|
+
@machines = StateMachine::MachineCollection.new
|
325
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
326
|
+
@machine.event :ignite do
|
327
|
+
transition :parked => :idling
|
328
|
+
end
|
329
|
+
|
330
|
+
@object = @klass.new
|
338
331
|
@object.state_event = ''
|
339
|
-
@
|
332
|
+
@transitions = @machines.transitions(@object, :save)
|
340
333
|
end
|
341
334
|
|
342
|
-
def
|
343
|
-
|
335
|
+
def test_should_be_empty
|
336
|
+
assert @transitions.empty?
|
344
337
|
end
|
345
338
|
|
346
|
-
def
|
347
|
-
|
348
|
-
end
|
349
|
-
|
350
|
-
def test_should_not_transition_state
|
351
|
-
assert_equal 'parked', @object.state
|
352
|
-
end
|
353
|
-
|
354
|
-
def test_should_not_change_event_attribute
|
355
|
-
assert_nil @object.state_event
|
356
|
-
end
|
357
|
-
|
358
|
-
def test_should_not_have_event_transition
|
359
|
-
assert_nil @object.send(:state_event_transition)
|
339
|
+
def test_should_perform
|
340
|
+
assert_equal true, @transitions.perform
|
360
341
|
end
|
361
342
|
end
|
362
343
|
|
363
|
-
class
|
344
|
+
class MachineCollectionTransitionsWithInvalidEventsTest < Test::Unit::TestCase
|
364
345
|
def setup
|
365
|
-
|
346
|
+
@klass = Class.new
|
366
347
|
|
367
|
-
@
|
368
|
-
@
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
assert_equal false, @result
|
373
|
-
end
|
374
|
-
|
375
|
-
def test_should_not_run_action
|
376
|
-
assert !@saved
|
377
|
-
end
|
378
|
-
|
379
|
-
def test_should_not_transition_state
|
380
|
-
assert_equal 'parked', @object.state
|
381
|
-
end
|
382
|
-
|
383
|
-
def test_should_not_reset_event_attribute
|
384
|
-
assert_equal :invalid, @object.state_event
|
385
|
-
end
|
386
|
-
|
387
|
-
def test_should_not_have_event_transition
|
388
|
-
assert_nil @object.send(:state_event_transition)
|
389
|
-
end
|
390
|
-
end
|
391
|
-
|
392
|
-
class MachineCollectionFireImplicitWithoutTransitionTest < MachineCollectionFireImplicitTest
|
393
|
-
def setup
|
394
|
-
super
|
348
|
+
@machines = StateMachine::MachineCollection.new
|
349
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
350
|
+
@machine.event :ignite do
|
351
|
+
transition :parked => :idling
|
352
|
+
end
|
395
353
|
|
396
|
-
@object
|
397
|
-
@object.state_event = '
|
398
|
-
@
|
399
|
-
end
|
400
|
-
|
401
|
-
def test_should_not_be_successful
|
402
|
-
assert_equal false, @result
|
403
|
-
end
|
404
|
-
|
405
|
-
def test_should_not_run_action
|
406
|
-
assert !@saved
|
407
|
-
end
|
408
|
-
|
409
|
-
def test_should_not_transition_state
|
410
|
-
assert_equal 'idling', @object.state
|
354
|
+
@object = @klass.new
|
355
|
+
@object.state_event = 'invalid'
|
356
|
+
@transitions = @machines.transitions(@object, :save)
|
411
357
|
end
|
412
358
|
|
413
|
-
def
|
414
|
-
|
359
|
+
def test_should_be_empty
|
360
|
+
assert @transitions.empty?
|
415
361
|
end
|
416
362
|
|
417
|
-
def
|
418
|
-
|
363
|
+
def test_should_not_perform
|
364
|
+
assert_equal false, @transitions.perform
|
419
365
|
end
|
420
366
|
end
|
421
367
|
|
422
|
-
class
|
368
|
+
class MachineCollectionTransitionsWithoutTransitionTest < Test::Unit::TestCase
|
423
369
|
def setup
|
424
|
-
|
425
|
-
|
426
|
-
@state_event = nil
|
370
|
+
@klass = Class.new
|
427
371
|
|
428
|
-
@
|
429
|
-
@
|
430
|
-
|
431
|
-
|
372
|
+
@machines = StateMachine::MachineCollection.new
|
373
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
374
|
+
@machine.event :ignite do
|
375
|
+
transition :parked => :idling
|
432
376
|
end
|
433
|
-
end
|
434
|
-
|
435
|
-
def test_should_be_successful
|
436
|
-
assert_equal true, @result
|
437
|
-
end
|
438
|
-
|
439
|
-
def test_should_run_action
|
440
|
-
assert @saved
|
441
|
-
end
|
442
|
-
|
443
|
-
def test_should_not_have_event_while_running_action
|
444
|
-
assert_nil @state_event
|
445
|
-
end
|
446
|
-
|
447
|
-
def test_should_transition_state
|
448
|
-
assert_equal 'idling', @object.state
|
449
|
-
end
|
450
|
-
|
451
|
-
def test_should_reset_event_attribute
|
452
|
-
assert_nil @object.state_event
|
453
|
-
end
|
454
|
-
|
455
|
-
def test_should_not_have_event_transition
|
456
|
-
assert_nil @object.send(:state_event_transition)
|
457
|
-
end
|
458
|
-
|
459
|
-
def test_should_not_be_successful_if_fired_again
|
460
|
-
@object.state_event = 'ignite'
|
461
|
-
assert !@machines.fire_event_attributes(@object, :save) { true }
|
462
|
-
end
|
463
|
-
end
|
464
|
-
|
465
|
-
class MachineCollectionFireImplicitWithNonBooleanResultTest < MachineCollectionFireImplicitTest
|
466
|
-
def setup
|
467
|
-
super
|
468
|
-
|
469
|
-
@action_value = Object.new
|
470
377
|
|
378
|
+
@object = @klass.new
|
379
|
+
@object.state = 'idling'
|
471
380
|
@object.state_event = 'ignite'
|
472
|
-
@
|
473
|
-
@saved = true
|
474
|
-
@action_value
|
475
|
-
end
|
381
|
+
@transitions = @machines.transitions(@object, :save)
|
476
382
|
end
|
477
383
|
|
478
|
-
def
|
479
|
-
|
384
|
+
def test_should_be_empty
|
385
|
+
assert @transitions.empty?
|
480
386
|
end
|
481
387
|
|
482
|
-
def
|
483
|
-
|
484
|
-
end
|
485
|
-
|
486
|
-
def test_should_transition_state
|
487
|
-
assert_equal 'idling', @object.state
|
388
|
+
def test_should_not_perform
|
389
|
+
assert_equal false, @transitions.perform
|
488
390
|
end
|
489
391
|
end
|
490
392
|
|
491
|
-
class
|
393
|
+
class MachineCollectionTransitionsWithTransitionTest < Test::Unit::TestCase
|
492
394
|
def setup
|
493
|
-
|
395
|
+
@klass = Class.new
|
494
396
|
|
495
|
-
@
|
496
|
-
@
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
assert_equal false, @result
|
501
|
-
end
|
502
|
-
|
503
|
-
def test_should_not_transition_state
|
504
|
-
assert_equal 'parked', @object.state
|
505
|
-
end
|
506
|
-
|
507
|
-
def test_should_not_reset_event_attribute
|
508
|
-
assert_equal :ignite, @object.state_event
|
509
|
-
end
|
510
|
-
|
511
|
-
def test_should_not_have_event_transition
|
512
|
-
assert_nil @object.send(:state_event_transition)
|
513
|
-
end
|
514
|
-
end
|
515
|
-
|
516
|
-
class MachineCollectionFireImplicitWithActionErrorTest < MachineCollectionFireImplicitTest
|
517
|
-
def setup
|
518
|
-
super
|
397
|
+
@machines = StateMachine::MachineCollection.new
|
398
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
399
|
+
@machine.event :ignite do
|
400
|
+
transition :parked => :idling
|
401
|
+
end
|
519
402
|
|
403
|
+
@object = @klass.new
|
520
404
|
@object.state_event = 'ignite'
|
521
|
-
|
405
|
+
@transitions = @machines.transitions(@object, :save)
|
522
406
|
end
|
523
407
|
|
524
|
-
def
|
525
|
-
assert_equal
|
526
|
-
end
|
527
|
-
|
528
|
-
def test_should_not_reset_event_attribute
|
529
|
-
assert_equal :ignite, @object.state_event
|
408
|
+
def test_should_not_be_empty
|
409
|
+
assert_equal 1, @transitions.length
|
530
410
|
end
|
531
411
|
|
532
|
-
def
|
533
|
-
|
412
|
+
def test_should_perform
|
413
|
+
assert_equal true, @transitions.perform
|
534
414
|
end
|
535
415
|
end
|
536
416
|
|
537
|
-
class
|
417
|
+
class MachineCollectionTransitionsWithSameActionsTest < Test::Unit::TestCase
|
538
418
|
def setup
|
539
|
-
|
540
|
-
|
541
|
-
@state_event = nil
|
542
|
-
@state_event_transition = nil
|
419
|
+
@klass = Class.new
|
543
420
|
|
544
|
-
@
|
545
|
-
@
|
546
|
-
|
547
|
-
|
548
|
-
true
|
421
|
+
@machines = StateMachine::MachineCollection.new
|
422
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
423
|
+
@machine.event :ignite do
|
424
|
+
transition :parked => :idling
|
549
425
|
end
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
assert @result
|
554
|
-
end
|
555
|
-
|
556
|
-
def test_should_not_have_event_while_running_action
|
557
|
-
assert_nil @state_event
|
558
|
-
end
|
559
|
-
|
560
|
-
def test_should_not_have_event_transition_while_running_action
|
561
|
-
assert_nil @state_event_transition
|
562
|
-
end
|
563
|
-
|
564
|
-
def test_should_transition_state
|
565
|
-
assert_equal 'idling', @object.state
|
566
|
-
end
|
567
|
-
|
568
|
-
def test_should_reset_event_attribute
|
569
|
-
assert_nil @object.state_event
|
570
|
-
end
|
571
|
-
|
572
|
-
def test_should_have_event_transition
|
573
|
-
assert_not_nil @object.send(:state_event_transition)
|
574
|
-
end
|
575
|
-
|
576
|
-
def test_should_reset_event_after_next_fire_on_success
|
577
|
-
assert @machines.fire_event_attributes(@object, :save) { true }
|
578
|
-
assert_equal 'idling', @object.state
|
579
|
-
assert_nil @object.state_event
|
580
|
-
end
|
581
|
-
|
582
|
-
def test_should_reset_event_transition_after_next_fire_on_success
|
583
|
-
assert @machines.fire_event_attributes(@object, :save) { true }
|
584
|
-
assert_nil @object.send(:state_event_transition)
|
585
|
-
end
|
586
|
-
|
587
|
-
def test_should_guard_transition_after_next_fire_on_success
|
588
|
-
@machines.fire_event_attributes(@object, :save) { true }
|
589
|
-
|
590
|
-
@object.state = 'idling'
|
591
|
-
@object.state_event = 'ignite'
|
592
|
-
assert !@machines.fire_event_attributes(@object, :save) { true }
|
593
|
-
end
|
594
|
-
|
595
|
-
def test_should_rollback_all_attributes_after_next_fire_on_failure
|
596
|
-
assert !@machines.fire_event_attributes(@object, :save) { false }
|
597
|
-
assert_equal 'parked', @object.state
|
598
|
-
assert_equal :ignite, @object.state_event
|
599
|
-
assert_nil @object.send(:state_event_transition)
|
600
|
-
|
601
|
-
@object.state = 'idling'
|
602
|
-
assert !@machines.fire_event_attributes(@object, :save) { false }
|
603
|
-
end
|
604
|
-
|
605
|
-
def test_should_guard_transition_after_next_fire_on_failure
|
606
|
-
@machines.fire_event_attributes(@object, :save) { false }
|
607
|
-
|
608
|
-
@object.state = 'idling'
|
609
|
-
assert !@machines.fire_event_attributes(@object, :save) { true }
|
610
|
-
end
|
611
|
-
|
612
|
-
def test_should_rollback_all_attributes_after_next_fire_on_error
|
613
|
-
assert_raise(ArgumentError) { @machines.fire_event_attributes(@object, :save) { raise ArgumentError } }
|
614
|
-
assert_equal 'parked', @object.state
|
615
|
-
assert_equal :ignite, @object.state_event
|
616
|
-
assert_nil @object.send(:state_event_transition)
|
617
|
-
end
|
618
|
-
|
619
|
-
def test_should_guard_transition_after_next_fire_on_error
|
620
|
-
begin
|
621
|
-
@machines.fire_event_attributes(@object, :save) { raise ArgumentError }
|
622
|
-
rescue ArgumentError
|
426
|
+
@machines[:status] = @machine = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
427
|
+
@machine.event :shift_up do
|
428
|
+
transition :first_gear => :second_gear
|
623
429
|
end
|
624
430
|
|
625
|
-
@object
|
626
|
-
assert !@machines.fire_event_attributes(@object, :save) { true }
|
627
|
-
end
|
628
|
-
end
|
629
|
-
|
630
|
-
class MachineCollectionFireImplicitPartialWithCallbacksTest < MachineCollectionFireImplicitTest
|
631
|
-
def setup
|
632
|
-
super
|
633
|
-
|
431
|
+
@object = @klass.new
|
634
432
|
@object.state_event = 'ignite'
|
433
|
+
@object.status_event = 'shift_up'
|
434
|
+
@transitions = @machines.transitions(@object, :save)
|
635
435
|
end
|
636
436
|
|
637
|
-
def
|
638
|
-
|
639
|
-
@machine.before_transition { ran_callback = true }
|
640
|
-
@machines.fire_event_attributes(@object, :save, false) { true }
|
641
|
-
|
642
|
-
assert ran_callback
|
643
|
-
end
|
644
|
-
|
645
|
-
def test_should_not_have_event_during_before_callbacks
|
646
|
-
state_event = nil
|
647
|
-
@machine.before_transition {|object, transition| state_event = object.state_event }
|
648
|
-
@machines.fire_event_attributes(@object, :save, false) { true }
|
649
|
-
|
650
|
-
assert_nil state_event
|
651
|
-
end
|
652
|
-
|
653
|
-
def test_should_not_have_event_transition_during_before_callbacks
|
654
|
-
state_event_transition = nil
|
655
|
-
@machine.before_transition {|object, transition| state_event_transition = object.send(:state_event_transition) }
|
656
|
-
@machines.fire_event_attributes(@object, :save, false) { true }
|
657
|
-
|
658
|
-
assert_nil state_event_transition
|
437
|
+
def test_should_not_be_empty
|
438
|
+
assert_equal 2, @transitions.length
|
659
439
|
end
|
660
440
|
|
661
|
-
def
|
662
|
-
|
663
|
-
@machine.after_transition { ran_callback = true }
|
664
|
-
@machines.fire_event_attributes(@object, :save, false) { true }
|
665
|
-
|
666
|
-
assert !ran_callback
|
667
|
-
end
|
668
|
-
|
669
|
-
def test_should_not_have_event_during_after_callbacks
|
670
|
-
state_event = nil
|
671
|
-
@machine.after_transition {|object, transition| state_event = object.state_event }
|
672
|
-
@machines.fire_event_attributes(@object, :save, false) { true }
|
673
|
-
|
674
|
-
assert_nil state_event
|
675
|
-
end
|
676
|
-
|
677
|
-
def test_should_not_have_event_transition_during_after_callbacks
|
678
|
-
state_event_transition = nil
|
679
|
-
@machine.after_transition {|object, transition| state_event_transition = object.send(:state_event_transition) }
|
680
|
-
@machines.fire_event_attributes(@object, :save, false) { true }
|
681
|
-
|
682
|
-
assert_nil state_event_transition
|
441
|
+
def test_should_perform
|
442
|
+
assert_equal true, @transitions.perform
|
683
443
|
end
|
684
444
|
end
|
685
445
|
|
686
|
-
class
|
446
|
+
class MachineCollectionTransitionsWithDifferentActionsTest < Test::Unit::TestCase
|
687
447
|
def setup
|
688
|
-
|
448
|
+
@klass = Class.new
|
689
449
|
|
690
|
-
@
|
450
|
+
@machines = StateMachine::MachineCollection.new
|
451
|
+
@machines[:state] = @state = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
452
|
+
@state.event :ignite do
|
453
|
+
transition :parked => :idling
|
454
|
+
end
|
455
|
+
@machines[:status] = @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :persist)
|
456
|
+
@status.event :shift_up do
|
457
|
+
transition :first_gear => :second_gear
|
458
|
+
end
|
691
459
|
|
460
|
+
@object = @klass.new
|
692
461
|
@object.state_event = 'ignite'
|
693
|
-
@
|
694
|
-
|
695
|
-
true
|
696
|
-
end
|
697
|
-
end
|
698
|
-
|
699
|
-
def test_should_be_successful
|
700
|
-
assert @result
|
701
|
-
end
|
702
|
-
|
703
|
-
def test_should_have_successful_partial_fire
|
704
|
-
assert @partial_result
|
705
|
-
end
|
706
|
-
|
707
|
-
def test_should_transition_state
|
708
|
-
assert_equal 'idling', @object.state
|
462
|
+
@object.status_event = 'shift_up'
|
463
|
+
@transitions = @machines.transitions(@object, :save)
|
709
464
|
end
|
710
465
|
|
711
|
-
def
|
712
|
-
|
713
|
-
end
|
714
|
-
|
715
|
-
def test_should_reset_event_transition_attribute
|
716
|
-
assert_nil @object.send(:state_event_transition)
|
466
|
+
def test_should_only_select_matching_actions
|
467
|
+
assert_equal 1, @transitions.length
|
717
468
|
end
|
718
469
|
end
|
719
470
|
|
720
|
-
class
|
471
|
+
class MachineCollectionTransitionsWithExisitingTransitionsTest < Test::Unit::TestCase
|
721
472
|
def setup
|
722
|
-
|
473
|
+
@klass = Class.new
|
723
474
|
|
724
|
-
@machines
|
725
|
-
@
|
726
|
-
|
475
|
+
@machines = StateMachine::MachineCollection.new
|
476
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
477
|
+
@machine.event :ignite do
|
478
|
+
transition :parked => :idling
|
727
479
|
end
|
728
480
|
|
729
|
-
@saved = false
|
730
481
|
@object = @klass.new
|
731
|
-
@object.
|
732
|
-
@
|
733
|
-
|
734
|
-
@machines.fire_event_attributes(@object, :save) { true }
|
735
|
-
end
|
736
|
-
|
737
|
-
def test_should_transition_states_for_action
|
738
|
-
assert_equal 'idling', @object.state
|
482
|
+
@object.send(:state_event_transition=, StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling))
|
483
|
+
@transitions = @machines.transitions(@object, :save)
|
739
484
|
end
|
740
485
|
|
741
|
-
def
|
742
|
-
|
743
|
-
end
|
744
|
-
|
745
|
-
def test_should_reset_event_transition_attribute_for_action
|
746
|
-
assert_nil @object.send(:state_event_transition)
|
747
|
-
end
|
748
|
-
|
749
|
-
def test_should_not_transition_states_for_other_actions
|
750
|
-
assert_equal 'active', @object.alarm_state
|
486
|
+
def test_should_not_be_empty
|
487
|
+
assert_equal 1, @transitions.length
|
751
488
|
end
|
752
489
|
|
753
|
-
def
|
754
|
-
assert_equal
|
490
|
+
def test_should_perform
|
491
|
+
assert_equal true, @transitions.perform
|
755
492
|
end
|
756
493
|
end
|
757
494
|
|
758
|
-
class
|
495
|
+
class MachineCollectionTransitionsWithCustomOptionsTest < Test::Unit::TestCase
|
759
496
|
def setup
|
760
|
-
|
497
|
+
@klass = Class.new
|
761
498
|
|
762
|
-
@machines
|
763
|
-
@
|
764
|
-
|
499
|
+
@machines = StateMachine::MachineCollection.new
|
500
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
501
|
+
@machine.event :ignite do
|
502
|
+
transition :parked => :idling
|
765
503
|
end
|
766
504
|
|
767
|
-
@saved = false
|
768
505
|
@object = @klass.new
|
769
|
-
@
|
770
|
-
@object.alarm_state_event = 'disable'
|
771
|
-
|
772
|
-
@machines.fire_event_attributes(@object, :save) { true }
|
506
|
+
@transitions = @machines.transitions(@object, :save, :after => false)
|
773
507
|
end
|
774
508
|
|
775
|
-
def
|
776
|
-
|
777
|
-
assert_equal 'off', @object.alarm_state
|
778
|
-
end
|
779
|
-
|
780
|
-
def test_should_reset_all_event_attributes_for_action
|
781
|
-
assert_nil @object.state_event
|
782
|
-
assert_nil @object.alarm_state_event
|
509
|
+
def test_should_use_custom_options
|
510
|
+
assert @transitions.skip_after
|
783
511
|
end
|
784
512
|
end
|
785
513
|
|
786
|
-
class
|
514
|
+
class MachineCollectionFireAttributesWithValidationsTest < Test::Unit::TestCase
|
787
515
|
def setup
|
788
|
-
StateMachine::Integrations.const_set('Custom', Module.new do
|
789
|
-
def invalidate(object, attribute, message, values = [])
|
790
|
-
(object.errors ||= []) << generate_message(message, values)
|
791
|
-
end
|
792
|
-
|
793
|
-
def reset(object)
|
794
|
-
object.errors = []
|
795
|
-
end
|
796
|
-
end)
|
797
|
-
|
798
516
|
@klass = Class.new do
|
799
517
|
attr_accessor :errors
|
800
518
|
|
@@ -805,17 +523,27 @@ class MachineCollectionFireImplicitWithValidationsTest < Test::Unit::TestCase
|
|
805
523
|
end
|
806
524
|
|
807
525
|
@machines = StateMachine::MachineCollection.new
|
808
|
-
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save
|
526
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
809
527
|
@machine.event :ignite do
|
810
528
|
transition :parked => :idling
|
811
529
|
end
|
812
530
|
|
531
|
+
class << @machine
|
532
|
+
def invalidate(object, attribute, message, values = [])
|
533
|
+
(object.errors ||= []) << generate_message(message, values)
|
534
|
+
end
|
535
|
+
|
536
|
+
def reset(object)
|
537
|
+
object.errors = []
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
813
541
|
@object = @klass.new
|
814
542
|
end
|
815
543
|
|
816
544
|
def test_should_invalidate_if_event_is_invalid
|
817
545
|
@object.state_event = 'invalid'
|
818
|
-
@machines.
|
546
|
+
@machines.transitions(@object, :save)
|
819
547
|
|
820
548
|
assert !@object.errors.empty?
|
821
549
|
end
|
@@ -823,116 +551,15 @@ class MachineCollectionFireImplicitWithValidationsTest < Test::Unit::TestCase
|
|
823
551
|
def test_should_invalidate_if_no_transition_exists
|
824
552
|
@object.state = 'idling'
|
825
553
|
@object.state_event = 'ignite'
|
826
|
-
@machines.
|
554
|
+
@machines.transitions(@object, :save)
|
827
555
|
|
828
556
|
assert !@object.errors.empty?
|
829
557
|
end
|
830
558
|
|
831
559
|
def test_should_not_invalidate_if_transition_exists
|
832
560
|
@object.state_event = 'ignite'
|
833
|
-
@machines.
|
561
|
+
@machines.transitions(@object, :save)
|
834
562
|
|
835
563
|
assert @object.errors.empty?
|
836
564
|
end
|
837
|
-
|
838
|
-
def teardown
|
839
|
-
StateMachine::Integrations.send(:remove_const, 'Custom')
|
840
|
-
end
|
841
|
-
end
|
842
|
-
|
843
|
-
class MachineCollectionFireImplicitWithCustomMachineNameTest < MachineCollectionFireImplicitTest
|
844
|
-
def setup
|
845
|
-
super
|
846
|
-
|
847
|
-
@object.state_event = 'ignite'
|
848
|
-
end
|
849
|
-
|
850
|
-
def test_should_be_successful_on_complete_file
|
851
|
-
assert @machines.fire_event_attributes(@object, :save) { true }
|
852
|
-
assert_equal 'idling', @object.state
|
853
|
-
assert_nil @object.state_event
|
854
|
-
assert_nil @object.send(:state_event_transition)
|
855
|
-
end
|
856
|
-
|
857
|
-
def test_should_be_successful_on_partial_fire
|
858
|
-
@machines.fire_event_attributes(@object, :save, false) { true }
|
859
|
-
assert_equal 'idling', @object.state
|
860
|
-
assert_nil @object.state_event
|
861
|
-
assert_not_nil @object.send(:state_event_transition)
|
862
|
-
end
|
863
|
-
end
|
864
|
-
|
865
|
-
class MachineFireImplicitWithMarshallingTest < MachineCollectionFireImplicitTest
|
866
|
-
def setup
|
867
|
-
super
|
868
|
-
self.class.const_set('Example', @klass)
|
869
|
-
|
870
|
-
@object.state_event = 'ignite'
|
871
|
-
end
|
872
|
-
|
873
|
-
def test_should_marshal_during_before_callbacks
|
874
|
-
@machine.before_transition {|object, transition| Marshal.dump(object)}
|
875
|
-
assert_nothing_raised { @machines.fire_event_attributes(@object, :save) { true } }
|
876
|
-
end
|
877
|
-
|
878
|
-
def test_should_marshal_during_action
|
879
|
-
assert_nothing_raised do
|
880
|
-
@machines.fire_event_attributes(@object, :save) do
|
881
|
-
Marshal.dump(@object)
|
882
|
-
true
|
883
|
-
end
|
884
|
-
end
|
885
|
-
end
|
886
|
-
|
887
|
-
def test_should_marshal_during_after_callbacks
|
888
|
-
@machine.after_transition {|object, transition| Marshal.dump(object)}
|
889
|
-
assert_nothing_raised { @machines.fire_event_attributes(@object, :save) { true } }
|
890
|
-
end
|
891
|
-
|
892
|
-
def teardown
|
893
|
-
self.class.send(:remove_const, 'Example')
|
894
|
-
end
|
895
|
-
end
|
896
|
-
|
897
|
-
class MachineFireImplicitPartialWithMarshallingTest < MachineCollectionFireImplicitTest
|
898
|
-
def setup
|
899
|
-
super
|
900
|
-
self.class.const_set('Example', @klass)
|
901
|
-
|
902
|
-
@object.state_event = 'ignite'
|
903
|
-
end
|
904
|
-
|
905
|
-
def test_should_marshal_during_before_callbacks
|
906
|
-
@machine.before_transition {|object, transition| Marshal.dump(object)}
|
907
|
-
assert_nothing_raised do
|
908
|
-
@machines.fire_event_attributes(@object, :save, false) { true }
|
909
|
-
@machines.fire_event_attributes(@object, :save) { true }
|
910
|
-
end
|
911
|
-
end
|
912
|
-
|
913
|
-
def test_should_marshal_during_action
|
914
|
-
assert_nothing_raised do
|
915
|
-
@machines.fire_event_attributes(@object, :save, false) do
|
916
|
-
Marshal.dump(@object)
|
917
|
-
true
|
918
|
-
end
|
919
|
-
|
920
|
-
@machines.fire_event_attributes(@object, :save) do
|
921
|
-
Marshal.dump(@object)
|
922
|
-
true
|
923
|
-
end
|
924
|
-
end
|
925
|
-
end
|
926
|
-
|
927
|
-
def test_should_marshal_during_after_callbacks
|
928
|
-
@machine.after_transition {|object, transition| Marshal.dump(object)}
|
929
|
-
assert_nothing_raised do
|
930
|
-
@machines.fire_event_attributes(@object, :save, false) { true }
|
931
|
-
@machines.fire_event_attributes(@object, :save) { true }
|
932
|
-
end
|
933
|
-
end
|
934
|
-
|
935
|
-
def teardown
|
936
|
-
self.class.send(:remove_const, 'Example')
|
937
|
-
end
|
938
565
|
end
|