state_machine 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +0 -2
- data/.yardopts +3 -2
- data/Appraisals +48 -0
- data/{CHANGELOG.rdoc → CHANGELOG.md} +63 -46
- data/README.md +1029 -0
- data/gemfiles/active_model-3.0.0.gemfile.lock +1 -3
- data/gemfiles/active_model-3.0.5.gemfile.lock +1 -3
- data/gemfiles/active_model-3.1.1.gemfile +7 -0
- data/gemfiles/active_model-3.1.1.gemfile.lock +32 -0
- data/gemfiles/active_record-2.0.0.gemfile.lock +1 -3
- data/gemfiles/active_record-2.0.5.gemfile.lock +1 -3
- data/gemfiles/active_record-2.1.0.gemfile.lock +1 -3
- data/gemfiles/active_record-2.1.2.gemfile.lock +1 -3
- data/gemfiles/active_record-2.2.3.gemfile.lock +1 -3
- data/gemfiles/active_record-2.3.12.gemfile.lock +1 -3
- data/gemfiles/active_record-3.0.0.gemfile.lock +1 -3
- data/gemfiles/active_record-3.0.5.gemfile.lock +1 -3
- data/gemfiles/active_record-3.1.1.gemfile +8 -0
- data/gemfiles/active_record-3.1.1.gemfile.lock +43 -0
- data/gemfiles/data_mapper-0.10.2.gemfile.lock +1 -3
- data/gemfiles/data_mapper-0.9.11.gemfile.lock +1 -3
- data/gemfiles/data_mapper-0.9.4.gemfile.lock +1 -3
- data/gemfiles/data_mapper-0.9.7.gemfile.lock +1 -3
- data/gemfiles/data_mapper-1.0.0.gemfile.lock +1 -3
- data/gemfiles/data_mapper-1.0.1.gemfile.lock +1 -3
- data/gemfiles/data_mapper-1.0.2.gemfile.lock +1 -3
- data/gemfiles/data_mapper-1.1.0.gemfile.lock +1 -3
- data/gemfiles/data_mapper-1.2.0.gemfile +12 -0
- data/gemfiles/data_mapper-1.2.0.gemfile.lock +49 -0
- data/gemfiles/default.gemfile.lock +1 -3
- data/gemfiles/graphviz-0.9.0.gemfile +7 -0
- data/gemfiles/graphviz-0.9.0.gemfile.lock +24 -0
- data/gemfiles/graphviz-0.9.21.gemfile +7 -0
- data/gemfiles/graphviz-0.9.21.gemfile.lock +24 -0
- data/gemfiles/graphviz-1.0.0.gemfile +7 -0
- data/gemfiles/graphviz-1.0.0.gemfile.lock +24 -0
- data/gemfiles/mongo_mapper-0.10.0.gemfile +7 -0
- data/gemfiles/mongo_mapper-0.10.0.gemfile.lock +41 -0
- data/gemfiles/mongo_mapper-0.5.5.gemfile.lock +1 -3
- data/gemfiles/mongo_mapper-0.5.8.gemfile.lock +1 -3
- data/gemfiles/mongo_mapper-0.6.0.gemfile.lock +1 -3
- data/gemfiles/mongo_mapper-0.6.10.gemfile.lock +1 -3
- data/gemfiles/mongo_mapper-0.7.0.gemfile.lock +1 -3
- data/gemfiles/mongo_mapper-0.7.5.gemfile.lock +1 -3
- data/gemfiles/mongo_mapper-0.8.0.gemfile.lock +1 -3
- data/gemfiles/mongo_mapper-0.8.3.gemfile.lock +1 -3
- data/gemfiles/mongo_mapper-0.8.4.gemfile.lock +1 -3
- data/gemfiles/mongo_mapper-0.8.6.gemfile.lock +1 -3
- data/gemfiles/mongo_mapper-0.9.0.gemfile.lock +1 -3
- data/gemfiles/mongoid-2.0.0.gemfile.lock +1 -3
- data/gemfiles/mongoid-2.1.4.gemfile.lock +1 -3
- data/gemfiles/mongoid-2.2.4.gemfile +7 -0
- data/gemfiles/mongoid-2.2.4.gemfile.lock +40 -0
- data/gemfiles/mongoid-2.3.3.gemfile +7 -0
- data/gemfiles/mongoid-2.3.3.gemfile.lock +40 -0
- data/gemfiles/sequel-2.11.0.gemfile.lock +1 -3
- data/gemfiles/sequel-2.12.0.gemfile.lock +1 -3
- data/gemfiles/sequel-2.8.0.gemfile.lock +1 -3
- data/gemfiles/sequel-3.0.0.gemfile.lock +1 -3
- data/gemfiles/sequel-3.13.0.gemfile.lock +1 -3
- data/gemfiles/sequel-3.14.0.gemfile.lock +1 -3
- data/gemfiles/sequel-3.23.0.gemfile.lock +1 -3
- data/gemfiles/sequel-3.24.0.gemfile.lock +1 -3
- data/gemfiles/sequel-3.29.0.gemfile +8 -0
- data/gemfiles/sequel-3.29.0.gemfile.lock +26 -0
- data/lib/state_machine.rb +45 -0
- data/lib/state_machine/event.rb +18 -3
- data/lib/state_machine/event_collection.rb +1 -1
- data/lib/state_machine/integrations/active_model.rb +59 -16
- data/lib/state_machine/integrations/active_model/observer.rb +3 -15
- data/lib/state_machine/integrations/active_record.rb +46 -9
- data/lib/state_machine/integrations/data_mapper.rb +42 -2
- data/lib/state_machine/integrations/data_mapper/versions.rb +22 -10
- data/lib/state_machine/integrations/mongo_mapper.rb +55 -0
- data/lib/state_machine/integrations/mongo_mapper/versions.rb +3 -3
- data/lib/state_machine/integrations/mongoid.rb +57 -12
- data/lib/state_machine/integrations/mongoid/versions.rb +22 -4
- data/lib/state_machine/integrations/sequel.rb +45 -0
- data/lib/state_machine/integrations/sequel/versions.rb +3 -0
- data/lib/state_machine/machine.rb +148 -34
- data/lib/state_machine/node_collection.rb +36 -3
- data/lib/state_machine/state.rb +6 -3
- data/lib/state_machine/state_collection.rb +1 -1
- data/lib/state_machine/version.rb +1 -1
- data/lib/tasks/state_machine.rb +11 -9
- data/state_machine.gemspec +2 -3
- data/test/functional/state_machine_test.rb +54 -1
- data/test/unit/event_collection_test.rb +4 -0
- data/test/unit/event_test.rb +34 -1
- data/test/unit/integrations/active_model_test.rb +80 -0
- data/test/unit/integrations/active_record_test.rb +105 -2
- data/test/unit/integrations/data_mapper_test.rb +27 -25
- data/test/unit/integrations/mongo_mapper_test.rb +80 -25
- data/test/unit/integrations/mongoid_test.rb +61 -6
- data/test/unit/integrations/sequel_test.rb +8 -2
- data/test/unit/machine_test.rb +87 -9
- data/test/unit/node_collection_test.rb +129 -12
- data/test/unit/state_collection_test.rb +4 -0
- data/test/unit/state_test.rb +2 -2
- metadata +30 -24
- data/README.rdoc +0 -844
@@ -281,14 +281,14 @@ module MongoidTest
|
|
281
281
|
@machine = StateMachine::Machine.new(@model)
|
282
282
|
@machine.state :state
|
283
283
|
|
284
|
-
assert_match /^Instance method "state\?" is already defined in .*, use generic helper instead
|
284
|
+
assert_match /^Instance method "state\?" is already defined in .*, use generic helper instead.*\n$/, $stderr.string
|
285
285
|
end
|
286
286
|
|
287
287
|
def test_should_output_warning_with_same_machine_attribute
|
288
288
|
@machine = StateMachine::Machine.new(@model, :public_state, :attribute => :state)
|
289
289
|
@machine.state :state
|
290
290
|
|
291
|
-
assert_match /^Instance method "state\?" is already defined in .*, use generic helper instead
|
291
|
+
assert_match /^Instance method "state\?" is already defined in .*, use generic helper instead.*\n$/, $stderr.string
|
292
292
|
end
|
293
293
|
|
294
294
|
def teardown
|
@@ -474,7 +474,7 @@ module MongoidTest
|
|
474
474
|
|
475
475
|
def test_should_allow_different_initial_state_when_dynamic
|
476
476
|
@machine.initial_state = lambda {:parked}
|
477
|
-
record = @model.new(:state => 'idling')
|
477
|
+
record = silence_warnings { @model.new(:state => 'idling') }
|
478
478
|
assert_equal 'idling', record.state
|
479
479
|
end
|
480
480
|
|
@@ -491,7 +491,7 @@ module MongoidTest
|
|
491
491
|
class MachineMultipleTest < BaseTestCase
|
492
492
|
def setup
|
493
493
|
@model = new_model do
|
494
|
-
|
494
|
+
field :status, :type => String, :default => 'idling'
|
495
495
|
end
|
496
496
|
@state_machine = StateMachine::Machine.new(@model, :initial => :parked)
|
497
497
|
@status_machine = StateMachine::Machine.new(@model, :status, :initial => :idling)
|
@@ -587,7 +587,7 @@ module MongoidTest
|
|
587
587
|
class MachineWithDirtyAttributesAndCustomAttributeTest < BaseTestCase
|
588
588
|
def setup
|
589
589
|
@model = new_model do
|
590
|
-
|
590
|
+
field :status, :type => String, :default => 'idling'
|
591
591
|
end
|
592
592
|
@machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
|
593
593
|
@machine.event :ignite
|
@@ -618,7 +618,7 @@ module MongoidTest
|
|
618
618
|
class MachineWithDirtyAttributeAndCustomAttributesDuringLoopbackTest < BaseTestCase
|
619
619
|
def setup
|
620
620
|
@model = new_model do
|
621
|
-
|
621
|
+
field :status, :type => String, :default => 'idling'
|
622
622
|
end
|
623
623
|
@machine = StateMachine::Machine.new(@model, :status, :initial => :parked)
|
624
624
|
@machine.event :park
|
@@ -744,6 +744,22 @@ module MongoidTest
|
|
744
744
|
assert_equal self, context
|
745
745
|
end
|
746
746
|
|
747
|
+
def test_should_run_after_callbacks_if_model_callback_added_prior_to_state_machine_definition
|
748
|
+
model = new_model do
|
749
|
+
after_save { nil }
|
750
|
+
end
|
751
|
+
machine = StateMachine::Machine.new(model, :initial => :parked)
|
752
|
+
machine.other_states :idling
|
753
|
+
machine.event :ignite
|
754
|
+
after_called = false
|
755
|
+
machine.after_transition {after_called = true}
|
756
|
+
|
757
|
+
record = model.new(:state => 'parked')
|
758
|
+
transition = StateMachine::Transition.new(record, machine, :ignite, :parked, :idling)
|
759
|
+
transition.perform
|
760
|
+
assert_equal true, after_called
|
761
|
+
end
|
762
|
+
|
747
763
|
def test_should_run_around_callbacks
|
748
764
|
before_called = false
|
749
765
|
after_called = false
|
@@ -1371,6 +1387,13 @@ module MongoidTest
|
|
1371
1387
|
assert_equal [parked, idling], @model.with_states(:parked, :idling).to_a
|
1372
1388
|
end
|
1373
1389
|
|
1390
|
+
def test_should_allow_lookup_by_string_name
|
1391
|
+
parked = @model.create :state => 'parked'
|
1392
|
+
idling = @model.create :state => 'idling'
|
1393
|
+
|
1394
|
+
assert_equal [parked, idling], @model.with_states('parked', 'idling').to_a
|
1395
|
+
end
|
1396
|
+
|
1374
1397
|
def test_should_create_singular_without_scope
|
1375
1398
|
assert @model.respond_to?(:without_state)
|
1376
1399
|
end
|
@@ -1534,6 +1557,17 @@ module MongoidTest
|
|
1534
1557
|
assert_equal 'shutdown', machine.state(:parked).human_name
|
1535
1558
|
end
|
1536
1559
|
|
1560
|
+
def test_should_allow_customized_state_key_scoped_to_class
|
1561
|
+
I18n.backend.store_translations(:en, {
|
1562
|
+
:mongoid => {:state_machines => {:'mongoid_test/foo' => {:states => {:parked => 'shutdown'}}}}
|
1563
|
+
})
|
1564
|
+
|
1565
|
+
machine = StateMachine::Machine.new(@model)
|
1566
|
+
machine.state :parked
|
1567
|
+
|
1568
|
+
assert_equal 'shutdown', machine.state(:parked).human_name
|
1569
|
+
end
|
1570
|
+
|
1537
1571
|
def test_should_allow_customized_state_key_scoped_to_machine
|
1538
1572
|
I18n.backend.store_translations(:en, {
|
1539
1573
|
:mongoid => {:state_machines => {:state => {:states => {:parked => 'shutdown'}}}}
|
@@ -1556,6 +1590,16 @@ module MongoidTest
|
|
1556
1590
|
assert_equal 'shutdown', machine.state(:parked).human_name
|
1557
1591
|
end
|
1558
1592
|
|
1593
|
+
def test_should_support_nil_state_key
|
1594
|
+
I18n.backend.store_translations(:en, {
|
1595
|
+
:mongoid => {:state_machines => {:states => {:nil => 'empty'}}}
|
1596
|
+
})
|
1597
|
+
|
1598
|
+
machine = StateMachine::Machine.new(@model)
|
1599
|
+
|
1600
|
+
assert_equal 'empty', machine.state(nil).human_name
|
1601
|
+
end
|
1602
|
+
|
1559
1603
|
def test_should_allow_customized_event_key_scoped_to_class_and_machine
|
1560
1604
|
I18n.backend.store_translations(:en, {
|
1561
1605
|
:mongoid => {:state_machines => {:'mongoid_test/foo' => {:state => {:events => {:park => 'stop'}}}}}
|
@@ -1567,6 +1611,17 @@ module MongoidTest
|
|
1567
1611
|
assert_equal 'stop', machine.event(:park).human_name
|
1568
1612
|
end
|
1569
1613
|
|
1614
|
+
def test_should_allow_customized_event_key_scoped_to_class
|
1615
|
+
I18n.backend.store_translations(:en, {
|
1616
|
+
:mongoid => {:state_machines => {:'mongoid_test/foo' => {:events => {:park => 'stop'}}}}
|
1617
|
+
})
|
1618
|
+
|
1619
|
+
machine = StateMachine::Machine.new(@model)
|
1620
|
+
machine.event :park
|
1621
|
+
|
1622
|
+
assert_equal 'stop', machine.event(:park).human_name
|
1623
|
+
end
|
1624
|
+
|
1570
1625
|
def test_should_allow_customized_event_key_scoped_to_machine
|
1571
1626
|
I18n.backend.store_translations(:en, {
|
1572
1627
|
:mongoid => {:state_machines => {:state => {:events => {:park => 'stop'}}}}
|
@@ -34,8 +34,6 @@ module SequelTest
|
|
34
34
|
define_method(:name) { "SequelTest::#{table_name.to_s.capitalize}" }
|
35
35
|
end
|
36
36
|
end
|
37
|
-
model.plugin(:validation_class_methods) if model.respond_to?(:plugin)
|
38
|
-
model.plugin(:hook_class_methods) if model.respond_to?(:plugin)
|
39
37
|
model.class_eval(&block) if block_given?
|
40
38
|
model
|
41
39
|
end
|
@@ -856,6 +854,7 @@ module SequelTest
|
|
856
854
|
class MachineWithFailedActionTest < BaseTestCase
|
857
855
|
def setup
|
858
856
|
@model = new_model do
|
857
|
+
plugin(:validation_class_methods) if respond_to?(:plugin)
|
859
858
|
validates_each :state do |object, attribute, value|
|
860
859
|
object.errors[attribute] << 'is invalid' unless %w(first_gear).include?(value)
|
861
860
|
end
|
@@ -1403,6 +1402,13 @@ module SequelTest
|
|
1403
1402
|
assert_equal [parked, idling], @model.with_states(:parked, :idling).all
|
1404
1403
|
end
|
1405
1404
|
|
1405
|
+
def test_should_allow_lookup_by_string_name
|
1406
|
+
parked = @model.create :state => 'parked'
|
1407
|
+
idling = @model.create :state => 'idling'
|
1408
|
+
|
1409
|
+
assert_equal [parked, idling], @model.with_states('parked', 'idling').all
|
1410
|
+
end
|
1411
|
+
|
1406
1412
|
def test_should_create_singular_without_scope
|
1407
1413
|
assert @model.respond_to?(:without_state)
|
1408
1414
|
end
|
data/test/unit/machine_test.rb
CHANGED
@@ -1126,7 +1126,7 @@ class MachineWithInstanceHelpersTest < Test::Unit::TestCase
|
|
1126
1126
|
machine = StateMachine::Machine.new(klass)
|
1127
1127
|
|
1128
1128
|
machine.define_helper(:instance, :park) {}
|
1129
|
-
assert_equal "Instance method \"park\" is already defined in #{superclass.to_s}, use generic helper instead.\n", $stderr.string
|
1129
|
+
assert_equal "Instance method \"park\" is already defined in #{superclass.to_s}, use generic helper instead or set StateMachine::Machine.ignore_method_conflicts = true.\n", $stderr.string
|
1130
1130
|
ensure
|
1131
1131
|
$stderr = @original_stderr
|
1132
1132
|
end
|
@@ -1147,7 +1147,7 @@ class MachineWithInstanceHelpersTest < Test::Unit::TestCase
|
|
1147
1147
|
machine = StateMachine::Machine.new(klass)
|
1148
1148
|
|
1149
1149
|
machine.define_helper(:instance, :park) {}
|
1150
|
-
assert_equal "Instance method \"park\" is already defined in #{superclass1.to_s}, use generic helper instead.\n", $stderr.string
|
1150
|
+
assert_equal "Instance method \"park\" is already defined in #{superclass1.to_s}, use generic helper instead or set StateMachine::Machine.ignore_method_conflicts = true.\n", $stderr.string
|
1151
1151
|
ensure
|
1152
1152
|
$stderr = @original_stderr
|
1153
1153
|
end
|
@@ -1166,7 +1166,7 @@ class MachineWithInstanceHelpersTest < Test::Unit::TestCase
|
|
1166
1166
|
machine = StateMachine::Machine.new(klass)
|
1167
1167
|
|
1168
1168
|
machine.define_helper(:instance, :park) {}
|
1169
|
-
assert_equal "Instance method \"park\" is already defined in #{mod.to_s}, use generic helper instead.\n", $stderr.string
|
1169
|
+
assert_equal "Instance method \"park\" is already defined in #{mod.to_s}, use generic helper instead or set StateMachine::Machine.ignore_method_conflicts = true.\n", $stderr.string
|
1170
1170
|
ensure
|
1171
1171
|
$stderr = @original_stderr
|
1172
1172
|
end
|
@@ -1224,7 +1224,7 @@ class MachineWithInstanceHelpersTest < Test::Unit::TestCase
|
|
1224
1224
|
@machine.define_helper(:instance, :park) {}
|
1225
1225
|
@machine.define_helper(:instance, :park) {}
|
1226
1226
|
|
1227
|
-
assert_equal "Instance method \"park\" is already defined in #{@klass} :state instance helpers, use generic helper instead.\n", $stderr.string
|
1227
|
+
assert_equal "Instance method \"park\" is already defined in #{@klass} :state instance helpers, use generic helper instead or set StateMachine::Machine.ignore_method_conflicts = true.\n", $stderr.string
|
1228
1228
|
ensure
|
1229
1229
|
$stderr = @original_stderr
|
1230
1230
|
end
|
@@ -1308,7 +1308,7 @@ class MachineWithClassHelpersTest < Test::Unit::TestCase
|
|
1308
1308
|
machine = StateMachine::Machine.new(klass)
|
1309
1309
|
|
1310
1310
|
machine.define_helper(:class, :park) {}
|
1311
|
-
assert_equal "Class method \"park\" is already defined in #{superclass.to_s}, use generic helper instead.\n", $stderr.string
|
1311
|
+
assert_equal "Class method \"park\" is already defined in #{superclass.to_s}, use generic helper instead or set StateMachine::Machine.ignore_method_conflicts = true.\n", $stderr.string
|
1312
1312
|
ensure
|
1313
1313
|
$stderr = @original_stderr
|
1314
1314
|
end
|
@@ -1329,7 +1329,7 @@ class MachineWithClassHelpersTest < Test::Unit::TestCase
|
|
1329
1329
|
machine = StateMachine::Machine.new(klass)
|
1330
1330
|
|
1331
1331
|
machine.define_helper(:class, :park) {}
|
1332
|
-
assert_equal "Class method \"park\" is already defined in #{superclass1.to_s}, use generic helper instead.\n", $stderr.string
|
1332
|
+
assert_equal "Class method \"park\" is already defined in #{superclass1.to_s}, use generic helper instead or set StateMachine::Machine.ignore_method_conflicts = true.\n", $stderr.string
|
1333
1333
|
ensure
|
1334
1334
|
$stderr = @original_stderr
|
1335
1335
|
end
|
@@ -1348,7 +1348,7 @@ class MachineWithClassHelpersTest < Test::Unit::TestCase
|
|
1348
1348
|
machine = StateMachine::Machine.new(klass)
|
1349
1349
|
|
1350
1350
|
machine.define_helper(:class, :park) {}
|
1351
|
-
assert_equal "Class method \"park\" is already defined in #{mod.to_s}, use generic helper instead.\n", $stderr.string
|
1351
|
+
assert_equal "Class method \"park\" is already defined in #{mod.to_s}, use generic helper instead or set StateMachine::Machine.ignore_method_conflicts = true.\n", $stderr.string
|
1352
1352
|
ensure
|
1353
1353
|
$stderr = @original_stderr
|
1354
1354
|
end
|
@@ -1406,7 +1406,7 @@ class MachineWithClassHelpersTest < Test::Unit::TestCase
|
|
1406
1406
|
@machine.define_helper(:class, :states) {}
|
1407
1407
|
@machine.define_helper(:class, :states) {}
|
1408
1408
|
|
1409
|
-
assert_equal "Class method \"states\" is already defined in #{@klass} :state class helpers, use generic helper instead.\n", $stderr.string
|
1409
|
+
assert_equal "Class method \"states\" is already defined in #{@klass} :state class helpers, use generic helper instead or set StateMachine::Machine.ignore_method_conflicts = true.\n", $stderr.string
|
1410
1410
|
ensure
|
1411
1411
|
$stderr = @original_stderr
|
1412
1412
|
end
|
@@ -1591,7 +1591,7 @@ class MachineWithConflictingHelpersBeforeDefinitionTest < Test::Unit::TestCase
|
|
1591
1591
|
'Class method "without_state"',
|
1592
1592
|
'Class method "with_states"',
|
1593
1593
|
'Class method "without_states"'
|
1594
|
-
].map {|method| "#{method} is already defined in #{@superclass.to_s}, use generic helper instead.\n"}.join
|
1594
|
+
].map {|method| "#{method} is already defined in #{@superclass.to_s}, use generic helper instead or set StateMachine::Machine.ignore_method_conflicts = true.\n"}.join
|
1595
1595
|
|
1596
1596
|
assert_equal expected, $stderr.string
|
1597
1597
|
end
|
@@ -2184,6 +2184,45 @@ class MachineWithExistingStateTest < Test::Unit::TestCase
|
|
2184
2184
|
end
|
2185
2185
|
end
|
2186
2186
|
|
2187
|
+
class MachineWithStateMatchersTest < Test::Unit::TestCase
|
2188
|
+
def setup
|
2189
|
+
@klass = Class.new
|
2190
|
+
@machine = StateMachine::Machine.new(@klass)
|
2191
|
+
end
|
2192
|
+
|
2193
|
+
def test_should_empty_array_for_all_matcher
|
2194
|
+
assert_equal [], @machine.state(StateMachine::AllMatcher.instance)
|
2195
|
+
end
|
2196
|
+
|
2197
|
+
def test_should_return_referenced_states_for_blacklist_matcher
|
2198
|
+
assert_instance_of StateMachine::State, @machine.state(StateMachine::BlacklistMatcher.new([:parked]))
|
2199
|
+
end
|
2200
|
+
|
2201
|
+
def test_should_not_allow_configurations
|
2202
|
+
exception = assert_raise(ArgumentError) { @machine.state(StateMachine::BlacklistMatcher.new([:parked]), :human_name => 'Parked') }
|
2203
|
+
assert_equal 'Cannot configure states when using matchers (using {:human_name=>"Parked"})', exception.message
|
2204
|
+
end
|
2205
|
+
|
2206
|
+
def test_should_track_referenced_states
|
2207
|
+
@machine.state(StateMachine::BlacklistMatcher.new([:parked]))
|
2208
|
+
assert_equal [nil, :parked], @machine.states.map {|state| state.name}
|
2209
|
+
end
|
2210
|
+
|
2211
|
+
def test_should_eval_context_for_matching_states
|
2212
|
+
contexts_run = []
|
2213
|
+
@machine.event(StateMachine::BlacklistMatcher.new([:parked])) { contexts_run << self.name }
|
2214
|
+
|
2215
|
+
@machine.event :parked
|
2216
|
+
assert_equal [], contexts_run
|
2217
|
+
|
2218
|
+
@machine.event :idling
|
2219
|
+
assert_equal [:idling], contexts_run
|
2220
|
+
|
2221
|
+
@machine.event :first_gear, :second_gear
|
2222
|
+
assert_equal [:idling, :first_gear, :second_gear], contexts_run
|
2223
|
+
end
|
2224
|
+
end
|
2225
|
+
|
2187
2226
|
class MachineWithOtherStates < Test::Unit::TestCase
|
2188
2227
|
def setup
|
2189
2228
|
@klass = Class.new
|
@@ -2281,6 +2320,45 @@ class MachineWithEventsWithCustomHumanNamesTest < Test::Unit::TestCase
|
|
2281
2320
|
end
|
2282
2321
|
end
|
2283
2322
|
|
2323
|
+
class MachineWithEventMatchersTest < Test::Unit::TestCase
|
2324
|
+
def setup
|
2325
|
+
@klass = Class.new
|
2326
|
+
@machine = StateMachine::Machine.new(@klass)
|
2327
|
+
end
|
2328
|
+
|
2329
|
+
def test_should_empty_array_for_all_matcher
|
2330
|
+
assert_equal [], @machine.event(StateMachine::AllMatcher.instance)
|
2331
|
+
end
|
2332
|
+
|
2333
|
+
def test_should_return_referenced_events_for_blacklist_matcher
|
2334
|
+
assert_instance_of StateMachine::Event, @machine.event(StateMachine::BlacklistMatcher.new([:park]))
|
2335
|
+
end
|
2336
|
+
|
2337
|
+
def test_should_not_allow_configurations
|
2338
|
+
exception = assert_raise(ArgumentError) { @machine.event(StateMachine::BlacklistMatcher.new([:park]), :human_name => 'Park') }
|
2339
|
+
assert_equal 'Cannot configure events when using matchers (using {:human_name=>"Park"})', exception.message
|
2340
|
+
end
|
2341
|
+
|
2342
|
+
def test_should_track_referenced_events
|
2343
|
+
event = @machine.event(StateMachine::BlacklistMatcher.new([:park]))
|
2344
|
+
assert_equal [:park], @machine.events.map {|event| event.name}
|
2345
|
+
end
|
2346
|
+
|
2347
|
+
def test_should_eval_context_for_matching_events
|
2348
|
+
contexts_run = []
|
2349
|
+
@machine.event(StateMachine::BlacklistMatcher.new([:park])) { contexts_run << self.name }
|
2350
|
+
|
2351
|
+
@machine.event :park
|
2352
|
+
assert_equal [], contexts_run
|
2353
|
+
|
2354
|
+
@machine.event :ignite
|
2355
|
+
assert_equal [:ignite], contexts_run
|
2356
|
+
|
2357
|
+
@machine.event :shift_up, :shift_down
|
2358
|
+
assert_equal [:ignite, :shift_up, :shift_down], contexts_run
|
2359
|
+
end
|
2360
|
+
end
|
2361
|
+
|
2284
2362
|
class MachineWithEventsWithTransitionsTest < Test::Unit::TestCase
|
2285
2363
|
def setup
|
2286
2364
|
@klass = Class.new
|
@@ -1,5 +1,15 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
2
|
|
3
|
+
class Node < Struct.new(:name, :value, :machine)
|
4
|
+
def name_to_s
|
5
|
+
name.to_s
|
6
|
+
end
|
7
|
+
|
8
|
+
def context
|
9
|
+
yield
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
3
13
|
class NodeCollectionByDefaultTest < Test::Unit::TestCase
|
4
14
|
def setup
|
5
15
|
@machine = StateMachine::Machine.new(Class.new)
|
@@ -15,7 +25,7 @@ class NodeCollectionByDefaultTest < Test::Unit::TestCase
|
|
15
25
|
end
|
16
26
|
|
17
27
|
def test_should_index_by_name
|
18
|
-
@collection << object =
|
28
|
+
@collection << object = Node.new(:parked)
|
19
29
|
assert_equal object, @collection[:parked]
|
20
30
|
end
|
21
31
|
end
|
@@ -46,10 +56,15 @@ class NodeCollectionAfterBeingCopiedTest < Test::Unit::TestCase
|
|
46
56
|
def setup
|
47
57
|
machine = StateMachine::Machine.new(Class.new)
|
48
58
|
@collection = StateMachine::NodeCollection.new(machine)
|
49
|
-
@collection << @parked =
|
59
|
+
@collection << @parked = Node.new(:parked)
|
60
|
+
|
61
|
+
@contexts_run = contexts_run = []
|
62
|
+
@collection.context([:parked]) {contexts_run << :parked}
|
63
|
+
@contexts_run.clear
|
50
64
|
|
51
65
|
@copied_collection = @collection.dup
|
52
|
-
@copied_collection << @idling =
|
66
|
+
@copied_collection << @idling = Node.new(:idling)
|
67
|
+
@copied_collection.context([:first_gear]) {contexts_run << :first_gear}
|
53
68
|
end
|
54
69
|
|
55
70
|
def test_should_not_modify_the_original_list
|
@@ -65,6 +80,20 @@ class NodeCollectionAfterBeingCopiedTest < Test::Unit::TestCase
|
|
65
80
|
def test_should_copy_each_node
|
66
81
|
assert_not_same @parked, @copied_collection[:parked]
|
67
82
|
end
|
83
|
+
|
84
|
+
def test_should_not_run_contexts
|
85
|
+
assert_equal [], @contexts_run
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_should_not_modify_contexts
|
89
|
+
@collection << Node.new(:first_gear)
|
90
|
+
assert_equal [], @contexts_run
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_should_copy_contexts
|
94
|
+
@copied_collection << Node.new(:parked)
|
95
|
+
assert !@contexts_run.empty?
|
96
|
+
end
|
68
97
|
end
|
69
98
|
|
70
99
|
class NodeCollectionWithoutIndicesTest < Test::Unit::TestCase
|
@@ -101,7 +130,7 @@ class NodeCollectionWithIndicesTest < Test::Unit::TestCase
|
|
101
130
|
machine = StateMachine::Machine.new(Class.new)
|
102
131
|
@collection = StateMachine::NodeCollection.new(machine, :index => [:name, :value])
|
103
132
|
|
104
|
-
@object =
|
133
|
+
@object = Node.new(:parked, 1)
|
105
134
|
@collection << @object
|
106
135
|
end
|
107
136
|
|
@@ -141,9 +170,8 @@ class NodeCollectionWithNodesTest < Test::Unit::TestCase
|
|
141
170
|
@machine = StateMachine::Machine.new(Class.new)
|
142
171
|
@collection = StateMachine::NodeCollection.new(@machine)
|
143
172
|
|
144
|
-
@
|
145
|
-
@
|
146
|
-
@idling = @klass.new(:idling, @machine)
|
173
|
+
@parked = Node.new(:parked, nil, @machine)
|
174
|
+
@idling = Node.new(:idling, nil, @machine)
|
147
175
|
|
148
176
|
@collection << @parked
|
149
177
|
@collection << @idling
|
@@ -157,8 +185,8 @@ class NodeCollectionWithNodesTest < Test::Unit::TestCase
|
|
157
185
|
end
|
158
186
|
|
159
187
|
def test_should_be_able_to_concatenate_multiple_nodes
|
160
|
-
@first_gear =
|
161
|
-
@second_gear =
|
188
|
+
@first_gear = Node.new(:first_gear, nil, @machine)
|
189
|
+
@second_gear = Node.new(:second_gear, nil, @machine)
|
162
190
|
@collection.concat([@first_gear, @second_gear])
|
163
191
|
|
164
192
|
order = []
|
@@ -186,9 +214,8 @@ class NodeCollectionAfterUpdateTest < Test::Unit::TestCase
|
|
186
214
|
machine = StateMachine::Machine.new(Class.new)
|
187
215
|
@collection = StateMachine::NodeCollection.new(machine, :index => [:name, :value])
|
188
216
|
|
189
|
-
@
|
190
|
-
@
|
191
|
-
@idling = @klass.new(:idling, 2)
|
217
|
+
@parked = Node.new(:parked, 1)
|
218
|
+
@idling = Node.new(:idling, 2)
|
192
219
|
|
193
220
|
@collection << @parked << @idling
|
194
221
|
|
@@ -215,3 +242,93 @@ class NodeCollectionAfterUpdateTest < Test::Unit::TestCase
|
|
215
242
|
assert_nil @collection[1, :value]
|
216
243
|
end
|
217
244
|
end
|
245
|
+
|
246
|
+
class NodeCollectionWithStringIndexTest < Test::Unit::TestCase
|
247
|
+
def setup
|
248
|
+
machine = StateMachine::Machine.new(Class.new)
|
249
|
+
@collection = StateMachine::NodeCollection.new(machine, :index => [:name, :name_to_s, :value])
|
250
|
+
|
251
|
+
@parked = Node.new(:parked, 1)
|
252
|
+
@collection << @parked
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_should_index_by_name
|
256
|
+
assert_equal @parked, @collection[:parked]
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_should_index_by_string_name
|
260
|
+
assert_equal @parked, @collection['parked', :name_to_s]
|
261
|
+
end
|
262
|
+
|
263
|
+
def test_should_fallback_to_string_index
|
264
|
+
assert_equal @parked, @collection['parked']
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_should_not_fallback_to_string_index_if_not_available
|
268
|
+
assert_nil @collection['1', :value]
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
class NodeCollectionWithPredefinedContextsTest < Test::Unit::TestCase
|
273
|
+
def setup
|
274
|
+
machine = StateMachine::Machine.new(Class.new)
|
275
|
+
@collection = StateMachine::NodeCollection.new(machine)
|
276
|
+
|
277
|
+
@contexts_run = contexts_run = []
|
278
|
+
@collection.context([:parked]) { contexts_run << :parked }
|
279
|
+
@collection.context([:parked]) { contexts_run << :second_parked }
|
280
|
+
end
|
281
|
+
|
282
|
+
def test_should_run_contexts_in_the_order_defined
|
283
|
+
@collection << Node.new(:parked)
|
284
|
+
assert_equal [:parked, :second_parked], @contexts_run
|
285
|
+
end
|
286
|
+
|
287
|
+
def test_should_not_run_contexts_if_not_matched
|
288
|
+
@collection << Node.new(:idling)
|
289
|
+
assert_equal [], @contexts_run
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
class NodeCollectionWithPostdefinedContextsTest < Test::Unit::TestCase
|
294
|
+
def setup
|
295
|
+
machine = StateMachine::Machine.new(Class.new)
|
296
|
+
@collection = StateMachine::NodeCollection.new(machine)
|
297
|
+
@collection << Node.new(:parked)
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_should_run_context_if_matched
|
301
|
+
contexts_run = []
|
302
|
+
@collection.context([:parked]) { contexts_run << :parked }
|
303
|
+
assert_equal [:parked], contexts_run
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_should_not_run_contexts_if_not_matched
|
307
|
+
contexts_run = []
|
308
|
+
@collection.context([:idling]) { contexts_run << :idling }
|
309
|
+
assert_equal [], contexts_run
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
class NodeCollectionWithMatcherContextsTest < Test::Unit::TestCase
|
314
|
+
def setup
|
315
|
+
machine = StateMachine::Machine.new(Class.new)
|
316
|
+
@collection = StateMachine::NodeCollection.new(machine)
|
317
|
+
@collection << Node.new(:parked)
|
318
|
+
end
|
319
|
+
|
320
|
+
def test_should_always_run_all_matcher_context
|
321
|
+
contexts_run = []
|
322
|
+
@collection.context([StateMachine::AllMatcher.instance]) { contexts_run << :all }
|
323
|
+
assert_equal [:all], contexts_run
|
324
|
+
end
|
325
|
+
|
326
|
+
def test_should_only_run_blacklist_matcher_if_not_matched
|
327
|
+
contexts_run = []
|
328
|
+
@collection.context([StateMachine::BlacklistMatcher.new([:parked])]) { contexts_run << :blacklist }
|
329
|
+
assert_equal [], contexts_run
|
330
|
+
|
331
|
+
@collection << Node.new(:idling)
|
332
|
+
assert_equal [:blacklist], contexts_run
|
333
|
+
end
|
334
|
+
end
|