telvue_state_machine 1.2.1
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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +72 -0
- data/.yardopts +5 -0
- data/Appraisals +491 -0
- data/CHANGELOG.md +502 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +1263 -0
- data/Rakefile +41 -0
- data/examples/AutoShop_state.png +0 -0
- data/examples/Car_state.png +0 -0
- data/examples/Gemfile +5 -0
- data/examples/Gemfile.lock +14 -0
- data/examples/TrafficLight_state.png +0 -0
- data/examples/Vehicle_state.png +0 -0
- data/examples/auto_shop.rb +13 -0
- data/examples/car.rb +21 -0
- data/examples/doc/AutoShop.html +2856 -0
- data/examples/doc/AutoShop_state.png +0 -0
- data/examples/doc/Car.html +919 -0
- data/examples/doc/Car_state.png +0 -0
- data/examples/doc/TrafficLight.html +2230 -0
- data/examples/doc/TrafficLight_state.png +0 -0
- data/examples/doc/Vehicle.html +7921 -0
- data/examples/doc/Vehicle_state.png +0 -0
- data/examples/doc/_index.html +136 -0
- data/examples/doc/class_list.html +47 -0
- data/examples/doc/css/common.css +1 -0
- data/examples/doc/css/full_list.css +55 -0
- data/examples/doc/css/style.css +322 -0
- data/examples/doc/file_list.html +46 -0
- data/examples/doc/frames.html +13 -0
- data/examples/doc/index.html +136 -0
- data/examples/doc/js/app.js +205 -0
- data/examples/doc/js/full_list.js +173 -0
- data/examples/doc/js/jquery.js +16 -0
- data/examples/doc/method_list.html +734 -0
- data/examples/doc/top-level-namespace.html +105 -0
- data/examples/merb-rest/controller.rb +51 -0
- data/examples/merb-rest/model.rb +28 -0
- data/examples/merb-rest/view_edit.html.erb +24 -0
- data/examples/merb-rest/view_index.html.erb +23 -0
- data/examples/merb-rest/view_new.html.erb +13 -0
- data/examples/merb-rest/view_show.html.erb +17 -0
- data/examples/rails-rest/controller.rb +43 -0
- data/examples/rails-rest/migration.rb +7 -0
- data/examples/rails-rest/model.rb +23 -0
- data/examples/rails-rest/view__form.html.erb +34 -0
- data/examples/rails-rest/view_edit.html.erb +6 -0
- data/examples/rails-rest/view_index.html.erb +25 -0
- data/examples/rails-rest/view_new.html.erb +5 -0
- data/examples/rails-rest/view_show.html.erb +19 -0
- data/examples/traffic_light.rb +9 -0
- data/examples/vehicle.rb +33 -0
- data/gemfiles/active_model_3.0.0.gemfile +7 -0
- data/gemfiles/active_model_3.0.0.gemfile.lock +35 -0
- data/gemfiles/active_model_3.0.5.gemfile +7 -0
- data/gemfiles/active_model_3.0.5.gemfile.lock +35 -0
- data/gemfiles/active_model_3.1.1.gemfile +7 -0
- data/gemfiles/active_model_3.1.1.gemfile.lock +36 -0
- data/gemfiles/active_model_3.2.1.gemfile +7 -0
- data/gemfiles/active_model_3.2.12.gemfile +7 -0
- data/gemfiles/active_model_3.2.12.gemfile.lock +36 -0
- data/gemfiles/active_model_3.2.13.rc1.gemfile +7 -0
- data/gemfiles/active_model_3.2.13.rc1.gemfile.lock +36 -0
- data/gemfiles/active_model_4.0.0.gemfile +9 -0
- data/gemfiles/active_model_4.0.0.gemfile.lock +78 -0
- data/gemfiles/active_record_2.0.0.gemfile +9 -0
- data/gemfiles/active_record_2.0.0.gemfile.lock +39 -0
- data/gemfiles/active_record_2.0.5.gemfile +9 -0
- data/gemfiles/active_record_2.0.5.gemfile.lock +39 -0
- data/gemfiles/active_record_2.1.0.gemfile +9 -0
- data/gemfiles/active_record_2.1.0.gemfile.lock +39 -0
- data/gemfiles/active_record_2.1.2.gemfile +9 -0
- data/gemfiles/active_record_2.1.2.gemfile.lock +39 -0
- data/gemfiles/active_record_2.2.3.gemfile +9 -0
- data/gemfiles/active_record_2.2.3.gemfile.lock +39 -0
- data/gemfiles/active_record_2.3.12.gemfile +9 -0
- data/gemfiles/active_record_2.3.12.gemfile.lock +39 -0
- data/gemfiles/active_record_2.3.5.gemfile +9 -0
- data/gemfiles/active_record_2.3.5.gemfile.lock +39 -0
- data/gemfiles/active_record_3.0.0.gemfile +9 -0
- data/gemfiles/active_record_3.0.0.gemfile.lock +51 -0
- data/gemfiles/active_record_3.0.5.gemfile +9 -0
- data/gemfiles/active_record_3.0.5.gemfile.lock +50 -0
- data/gemfiles/active_record_3.1.1.gemfile +9 -0
- data/gemfiles/active_record_3.1.1.gemfile.lock +51 -0
- data/gemfiles/active_record_3.2.12.gemfile +9 -0
- data/gemfiles/active_record_3.2.12.gemfile.lock +51 -0
- data/gemfiles/active_record_3.2.13.rc1.gemfile +9 -0
- data/gemfiles/active_record_3.2.13.rc1.gemfile.lock +51 -0
- data/gemfiles/active_record_4.0.0.gemfile +11 -0
- data/gemfiles/active_record_4.0.0.gemfile.lock +83 -0
- data/gemfiles/data_mapper_0.10.2.gemfile +13 -0
- data/gemfiles/data_mapper_0.10.2.gemfile.lock +56 -0
- data/gemfiles/data_mapper_0.9.11.gemfile +13 -0
- data/gemfiles/data_mapper_0.9.11.gemfile.lock +71 -0
- data/gemfiles/data_mapper_0.9.4.gemfile +12 -0
- data/gemfiles/data_mapper_0.9.4.gemfile.lock +70 -0
- data/gemfiles/data_mapper_0.9.7.gemfile +13 -0
- data/gemfiles/data_mapper_0.9.7.gemfile.lock +67 -0
- data/gemfiles/data_mapper_1.0.0.gemfile +12 -0
- data/gemfiles/data_mapper_1.0.0.gemfile.lock +63 -0
- data/gemfiles/data_mapper_1.0.1.gemfile +12 -0
- data/gemfiles/data_mapper_1.0.1.gemfile.lock +63 -0
- data/gemfiles/data_mapper_1.0.2.gemfile +12 -0
- data/gemfiles/data_mapper_1.0.2.gemfile.lock +63 -0
- data/gemfiles/data_mapper_1.1.0.gemfile +12 -0
- data/gemfiles/data_mapper_1.1.0.gemfile.lock +61 -0
- data/gemfiles/data_mapper_1.2.0.gemfile +12 -0
- data/gemfiles/data_mapper_1.2.0.gemfile.lock +61 -0
- data/gemfiles/default.gemfile +7 -0
- data/gemfiles/default.gemfile.lock +27 -0
- data/gemfiles/graphviz_0.9.17.gemfile +7 -0
- data/gemfiles/graphviz_0.9.17.gemfile.lock +29 -0
- data/gemfiles/graphviz_0.9.21.gemfile +7 -0
- data/gemfiles/graphviz_0.9.21.gemfile.lock +29 -0
- data/gemfiles/graphviz_1.0.0.gemfile +7 -0
- data/gemfiles/graphviz_1.0.0.gemfile.lock +29 -0
- data/gemfiles/graphviz_1.0.3.gemfile +7 -0
- data/gemfiles/graphviz_1.0.3.gemfile.lock +29 -0
- data/gemfiles/graphviz_1.0.8.gemfile +7 -0
- data/gemfiles/graphviz_1.0.8.gemfile.lock +29 -0
- data/gemfiles/mongo_mapper_0.10.0.gemfile +8 -0
- data/gemfiles/mongo_mapper_0.10.0.gemfile.lock +47 -0
- data/gemfiles/mongo_mapper_0.11.2.gemfile +9 -0
- data/gemfiles/mongo_mapper_0.11.2.gemfile.lock +48 -0
- data/gemfiles/mongo_mapper_0.12.0.gemfile +9 -0
- data/gemfiles/mongo_mapper_0.12.0.gemfile.lock +48 -0
- data/gemfiles/mongo_mapper_0.5.5.gemfile +8 -0
- data/gemfiles/mongo_mapper_0.5.5.gemfile.lock +36 -0
- data/gemfiles/mongo_mapper_0.5.8.gemfile +8 -0
- data/gemfiles/mongo_mapper_0.5.8.gemfile.lock +36 -0
- data/gemfiles/mongo_mapper_0.6.0.gemfile +8 -0
- data/gemfiles/mongo_mapper_0.6.0.gemfile.lock +36 -0
- data/gemfiles/mongo_mapper_0.6.10.gemfile +8 -0
- data/gemfiles/mongo_mapper_0.6.10.gemfile.lock +36 -0
- data/gemfiles/mongo_mapper_0.7.0.gemfile +8 -0
- data/gemfiles/mongo_mapper_0.7.0.gemfile.lock +36 -0
- data/gemfiles/mongo_mapper_0.7.5.gemfile +8 -0
- data/gemfiles/mongo_mapper_0.7.5.gemfile.lock +39 -0
- data/gemfiles/mongo_mapper_0.8.0.gemfile +10 -0
- data/gemfiles/mongo_mapper_0.8.0.gemfile.lock +43 -0
- data/gemfiles/mongo_mapper_0.8.3.gemfile +10 -0
- data/gemfiles/mongo_mapper_0.8.3.gemfile.lock +43 -0
- data/gemfiles/mongo_mapper_0.8.4.gemfile +8 -0
- data/gemfiles/mongo_mapper_0.8.4.gemfile.lock +42 -0
- data/gemfiles/mongo_mapper_0.8.6.gemfile +8 -0
- data/gemfiles/mongo_mapper_0.8.6.gemfile.lock +42 -0
- data/gemfiles/mongo_mapper_0.9.0.gemfile +7 -0
- data/gemfiles/mongo_mapper_0.9.0.gemfile.lock +45 -0
- data/gemfiles/mongoid_2.0.0.gemfile +9 -0
- data/gemfiles/mongoid_2.0.0.gemfile.lock +49 -0
- data/gemfiles/mongoid_2.1.4.gemfile +9 -0
- data/gemfiles/mongoid_2.1.4.gemfile.lock +47 -0
- data/gemfiles/mongoid_2.2.4.gemfile +9 -0
- data/gemfiles/mongoid_2.2.4.gemfile.lock +47 -0
- data/gemfiles/mongoid_2.3.3.gemfile +9 -0
- data/gemfiles/mongoid_2.3.3.gemfile.lock +47 -0
- data/gemfiles/mongoid_2.4.0.gemfile +9 -0
- data/gemfiles/mongoid_2.4.0.gemfile.lock +47 -0
- data/gemfiles/mongoid_2.4.10.gemfile +9 -0
- data/gemfiles/mongoid_2.4.10.gemfile.lock +47 -0
- data/gemfiles/mongoid_2.5.2.gemfile +9 -0
- data/gemfiles/mongoid_2.5.2.gemfile.lock +47 -0
- data/gemfiles/mongoid_2.6.0.gemfile +9 -0
- data/gemfiles/mongoid_2.6.0.gemfile.lock +47 -0
- data/gemfiles/mongoid_3.0.0.gemfile +8 -0
- data/gemfiles/mongoid_3.0.0.gemfile.lock +45 -0
- data/gemfiles/mongoid_3.0.22.gemfile +8 -0
- data/gemfiles/mongoid_3.0.22.gemfile.lock +45 -0
- data/gemfiles/mongoid_3.1.0.gemfile +8 -0
- data/gemfiles/mongoid_3.1.0.gemfile.lock +45 -0
- data/gemfiles/sequel_2.11.0.gemfile +9 -0
- data/gemfiles/sequel_2.11.0.gemfile.lock +33 -0
- data/gemfiles/sequel_2.12.0.gemfile +9 -0
- data/gemfiles/sequel_2.12.0.gemfile.lock +33 -0
- data/gemfiles/sequel_2.8.0.gemfile +9 -0
- data/gemfiles/sequel_2.8.0.gemfile.lock +33 -0
- data/gemfiles/sequel_3.0.0.gemfile +9 -0
- data/gemfiles/sequel_3.0.0.gemfile.lock +33 -0
- data/gemfiles/sequel_3.10.0.gemfile +9 -0
- data/gemfiles/sequel_3.10.0.gemfile.lock +33 -0
- data/gemfiles/sequel_3.13.0.gemfile +9 -0
- data/gemfiles/sequel_3.13.0.gemfile.lock +33 -0
- data/gemfiles/sequel_3.14.0.gemfile +9 -0
- data/gemfiles/sequel_3.14.0.gemfile.lock +33 -0
- data/gemfiles/sequel_3.23.0.gemfile +9 -0
- data/gemfiles/sequel_3.23.0.gemfile.lock +33 -0
- data/gemfiles/sequel_3.24.0.gemfile +9 -0
- data/gemfiles/sequel_3.24.0.gemfile.lock +33 -0
- data/gemfiles/sequel_3.29.0.gemfile +9 -0
- data/gemfiles/sequel_3.29.0.gemfile.lock +33 -0
- data/gemfiles/sequel_3.34.0.gemfile +9 -0
- data/gemfiles/sequel_3.34.0.gemfile.lock +33 -0
- data/gemfiles/sequel_3.35.0.gemfile +9 -0
- data/gemfiles/sequel_3.35.0.gemfile.lock +33 -0
- data/gemfiles/sequel_3.4.0.gemfile +9 -0
- data/gemfiles/sequel_3.4.0.gemfile.lock +33 -0
- data/gemfiles/sequel_3.44.0.gemfile +9 -0
- data/gemfiles/sequel_3.44.0.gemfile.lock +33 -0
- data/init.rb +1 -0
- data/lib/state_machine.rb +8 -0
- data/lib/state_machine/assertions.rb +36 -0
- data/lib/state_machine/branch.rb +225 -0
- data/lib/state_machine/callback.rb +236 -0
- data/lib/state_machine/core.rb +12 -0
- data/lib/state_machine/core_ext.rb +2 -0
- data/lib/state_machine/core_ext/class/state_machine.rb +5 -0
- data/lib/state_machine/error.rb +13 -0
- data/lib/state_machine/eval_helpers.rb +87 -0
- data/lib/state_machine/event.rb +257 -0
- data/lib/state_machine/event_collection.rb +141 -0
- data/lib/state_machine/extensions.rb +149 -0
- data/lib/state_machine/graph.rb +92 -0
- data/lib/state_machine/helper_module.rb +17 -0
- data/lib/state_machine/initializers.rb +4 -0
- data/lib/state_machine/initializers/merb.rb +1 -0
- data/lib/state_machine/initializers/rails.rb +25 -0
- data/lib/state_machine/integrations.rb +121 -0
- data/lib/state_machine/integrations/active_model.rb +585 -0
- data/lib/state_machine/integrations/active_model/locale.rb +11 -0
- data/lib/state_machine/integrations/active_model/observer.rb +33 -0
- data/lib/state_machine/integrations/active_model/observer_update.rb +42 -0
- data/lib/state_machine/integrations/active_model/versions.rb +31 -0
- data/lib/state_machine/integrations/active_record.rb +552 -0
- data/lib/state_machine/integrations/active_record/locale.rb +20 -0
- data/lib/state_machine/integrations/active_record/versions.rb +123 -0
- data/lib/state_machine/integrations/base.rb +100 -0
- data/lib/state_machine/integrations/data_mapper.rb +511 -0
- data/lib/state_machine/integrations/data_mapper/observer.rb +210 -0
- data/lib/state_machine/integrations/data_mapper/versions.rb +85 -0
- data/lib/state_machine/integrations/mongo_mapper.rb +389 -0
- data/lib/state_machine/integrations/mongo_mapper/locale.rb +4 -0
- data/lib/state_machine/integrations/mongo_mapper/versions.rb +89 -0
- data/lib/state_machine/integrations/mongoid.rb +465 -0
- data/lib/state_machine/integrations/mongoid/locale.rb +4 -0
- data/lib/state_machine/integrations/mongoid/versions.rb +81 -0
- data/lib/state_machine/integrations/sequel.rb +486 -0
- data/lib/state_machine/integrations/sequel/versions.rb +95 -0
- data/lib/state_machine/machine.rb +2292 -0
- data/lib/state_machine/machine_collection.rb +86 -0
- data/lib/state_machine/macro_methods.rb +522 -0
- data/lib/state_machine/matcher.rb +123 -0
- data/lib/state_machine/matcher_helpers.rb +54 -0
- data/lib/state_machine/node_collection.rb +222 -0
- data/lib/state_machine/path.rb +120 -0
- data/lib/state_machine/path_collection.rb +90 -0
- data/lib/state_machine/state.rb +297 -0
- data/lib/state_machine/state_collection.rb +112 -0
- data/lib/state_machine/state_context.rb +138 -0
- data/lib/state_machine/transition.rb +470 -0
- data/lib/state_machine/transition_collection.rb +245 -0
- data/lib/state_machine/version.rb +3 -0
- data/lib/state_machine/yard.rb +8 -0
- data/lib/state_machine/yard/handlers.rb +12 -0
- data/lib/state_machine/yard/handlers/base.rb +32 -0
- data/lib/state_machine/yard/handlers/event.rb +25 -0
- data/lib/state_machine/yard/handlers/machine.rb +344 -0
- data/lib/state_machine/yard/handlers/state.rb +25 -0
- data/lib/state_machine/yard/handlers/transition.rb +47 -0
- data/lib/state_machine/yard/templates.rb +3 -0
- data/lib/state_machine/yard/templates/default/class/html/setup.rb +30 -0
- data/lib/state_machine/yard/templates/default/class/html/state_machines.erb +12 -0
- data/lib/tasks/state_machine.rake +1 -0
- data/lib/tasks/state_machine.rb +30 -0
- data/lib/yard-state_machine.rb +2 -0
- data/state_machine.gemspec +22 -0
- data/test/files/en.yml +17 -0
- data/test/files/switch.rb +15 -0
- data/test/functional/state_machine_test.rb +1066 -0
- data/test/test_helper.rb +7 -0
- data/test/unit/assertions_test.rb +40 -0
- data/test/unit/branch_test.rb +969 -0
- data/test/unit/callback_test.rb +704 -0
- data/test/unit/error_test.rb +43 -0
- data/test/unit/eval_helpers_test.rb +270 -0
- data/test/unit/event_collection_test.rb +398 -0
- data/test/unit/event_test.rb +1196 -0
- data/test/unit/graph_test.rb +98 -0
- data/test/unit/helper_module_test.rb +17 -0
- data/test/unit/integrations/active_model_test.rb +1245 -0
- data/test/unit/integrations/active_record_test.rb +2551 -0
- data/test/unit/integrations/base_test.rb +104 -0
- data/test/unit/integrations/data_mapper_test.rb +2194 -0
- data/test/unit/integrations/mongo_mapper_test.rb +2026 -0
- data/test/unit/integrations/mongoid_test.rb +2309 -0
- data/test/unit/integrations/sequel_test.rb +1896 -0
- data/test/unit/integrations_test.rb +83 -0
- data/test/unit/invalid_event_test.rb +20 -0
- data/test/unit/invalid_parallel_transition_test.rb +18 -0
- data/test/unit/invalid_transition_test.rb +115 -0
- data/test/unit/machine_collection_test.rb +603 -0
- data/test/unit/machine_test.rb +3431 -0
- data/test/unit/matcher_helpers_test.rb +37 -0
- data/test/unit/matcher_test.rb +155 -0
- data/test/unit/node_collection_test.rb +362 -0
- data/test/unit/path_collection_test.rb +266 -0
- data/test/unit/path_test.rb +485 -0
- data/test/unit/state_collection_test.rb +352 -0
- data/test/unit/state_context_test.rb +441 -0
- data/test/unit/state_machine_test.rb +31 -0
- data/test/unit/state_test.rb +1101 -0
- data/test/unit/transition_collection_test.rb +2168 -0
- data/test/unit/transition_test.rb +1558 -0
- metadata +435 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class IntegrationMatcherTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
superclass = Class.new
|
6
|
+
self.class.const_set('Vehicle', superclass)
|
7
|
+
|
8
|
+
@klass = Class.new(superclass)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_should_return_nil_if_no_match_found
|
12
|
+
assert_nil StateMachine::Integrations.match(@klass)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_return_integration_class_if_match_found
|
16
|
+
integration = Module.new do
|
17
|
+
include StateMachine::Integrations::Base
|
18
|
+
|
19
|
+
def self.matching_ancestors
|
20
|
+
['IntegrationMatcherTest::Vehicle']
|
21
|
+
end
|
22
|
+
end
|
23
|
+
StateMachine::Integrations.const_set('Custom', integration)
|
24
|
+
|
25
|
+
assert_equal integration, StateMachine::Integrations.match(@klass)
|
26
|
+
ensure
|
27
|
+
StateMachine::Integrations.send(:remove_const, 'Custom')
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_should_return_nil_if_no_match_found_with_ancestors
|
31
|
+
assert_nil StateMachine::Integrations.match_ancestors(['IntegrationMatcherTest::Fake'])
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_should_return_integration_class_if_match_found_with_ancestors
|
35
|
+
integration = Module.new do
|
36
|
+
include StateMachine::Integrations::Base
|
37
|
+
|
38
|
+
def self.matching_ancestors
|
39
|
+
['IntegrationMatcherTest::Vehicle']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
StateMachine::Integrations.const_set('Custom', integration)
|
43
|
+
|
44
|
+
assert_equal integration, StateMachine::Integrations.match_ancestors(['IntegrationMatcherTest::Fake', 'IntegrationMatcherTest::Vehicle'])
|
45
|
+
ensure
|
46
|
+
StateMachine::Integrations.send(:remove_const, 'Custom')
|
47
|
+
end
|
48
|
+
|
49
|
+
def teardown
|
50
|
+
self.class.send(:remove_const, 'Vehicle')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class IntegrationFinderTest < Test::Unit::TestCase
|
55
|
+
def test_should_find_base
|
56
|
+
assert_equal StateMachine::Integrations::Base, StateMachine::Integrations.find_by_name(:base)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_should_find_active_model
|
60
|
+
assert_equal StateMachine::Integrations::ActiveModel, StateMachine::Integrations.find_by_name(:active_model)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_find_active_record
|
64
|
+
assert_equal StateMachine::Integrations::ActiveRecord, StateMachine::Integrations.find_by_name(:active_record)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_should_find_data_mapper
|
68
|
+
assert_equal StateMachine::Integrations::DataMapper, StateMachine::Integrations.find_by_name(:data_mapper)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_should_find_mongo_mapper
|
72
|
+
assert_equal StateMachine::Integrations::MongoMapper, StateMachine::Integrations.find_by_name(:mongo_mapper)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_should_find_sequel
|
76
|
+
assert_equal StateMachine::Integrations::Sequel, StateMachine::Integrations.find_by_name(:sequel)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_should_raise_an_exception_if_invalid
|
80
|
+
exception = assert_raise(StateMachine::IntegrationNotFound) { StateMachine::Integrations.find_by_name(:invalid) }
|
81
|
+
assert_equal ':invalid is an invalid integration', exception.message
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class InvalidEventTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@object = Object.new
|
6
|
+
@invalid_event = StateMachine::InvalidEvent.new(@object, :invalid)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_should_have_an_object
|
10
|
+
assert_equal @object, @invalid_event.object
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_should_have_an_event
|
14
|
+
assert_equal :invalid, @invalid_event.event
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_should_generate_a_message
|
18
|
+
assert_equal ':invalid is an unknown state machine event', @invalid_event.message
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class InvalidParallelTransitionTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@object = Object.new
|
6
|
+
@events = [:ignite, :disable_alarm]
|
7
|
+
|
8
|
+
@invalid_transition = StateMachine::InvalidParallelTransition.new(@object, @events)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_should_have_an_object
|
12
|
+
assert_equal @object, @invalid_transition.object
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_have_events
|
16
|
+
assert_equal @events, @invalid_transition.events
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class InvalidTransitionTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@klass = Class.new
|
6
|
+
@machine = StateMachine::Machine.new(@klass)
|
7
|
+
@state = @machine.state :parked
|
8
|
+
@machine.event :ignite
|
9
|
+
|
10
|
+
@object = @klass.new
|
11
|
+
@object.state = 'parked'
|
12
|
+
|
13
|
+
@invalid_transition = StateMachine::InvalidTransition.new(@object, @machine, :ignite)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_should_have_an_object
|
17
|
+
assert_equal @object, @invalid_transition.object
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_should_have_a_machine
|
21
|
+
assert_equal @machine, @invalid_transition.machine
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_should_have_an_event
|
25
|
+
assert_equal :ignite, @invalid_transition.event
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_should_have_a_qualified_event
|
29
|
+
assert_equal :ignite, @invalid_transition.qualified_event
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_should_have_a_from_value
|
33
|
+
assert_equal 'parked', @invalid_transition.from
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_have_a_from_name
|
37
|
+
assert_equal :parked, @invalid_transition.from_name
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_should_have_a_qualified_from_name
|
41
|
+
assert_equal :parked, @invalid_transition.qualified_from_name
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_should_generate_a_message
|
45
|
+
assert_equal 'Cannot transition state via :ignite from :parked', @invalid_transition.message
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class InvalidTransitionWithNamespaceTest < Test::Unit::TestCase
|
50
|
+
def setup
|
51
|
+
@klass = Class.new
|
52
|
+
@machine = StateMachine::Machine.new(@klass, :namespace => 'alarm')
|
53
|
+
@state = @machine.state :active
|
54
|
+
@machine.event :disable
|
55
|
+
|
56
|
+
@object = @klass.new
|
57
|
+
@object.state = 'active'
|
58
|
+
|
59
|
+
@invalid_transition = StateMachine::InvalidTransition.new(@object, @machine, :disable)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_should_have_an_event
|
63
|
+
assert_equal :disable, @invalid_transition.event
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_should_have_a_qualified_event
|
67
|
+
assert_equal :disable_alarm, @invalid_transition.qualified_event
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_should_have_a_from_name
|
71
|
+
assert_equal :active, @invalid_transition.from_name
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_should_have_a_qualified_from_name
|
75
|
+
assert_equal :alarm_active, @invalid_transition.qualified_from_name
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class InvalidTransitionWithIntegrationTest < Test::Unit::TestCase
|
80
|
+
def setup
|
81
|
+
StateMachine::Integrations.const_set('Custom', Module.new do
|
82
|
+
include StateMachine::Integrations::Base
|
83
|
+
|
84
|
+
def errors_for(object)
|
85
|
+
object.errors
|
86
|
+
end
|
87
|
+
end)
|
88
|
+
|
89
|
+
@klass = Class.new do
|
90
|
+
attr_accessor :errors
|
91
|
+
end
|
92
|
+
@machine = StateMachine::Machine.new(@klass, :integration => :custom)
|
93
|
+
@machine.state :parked
|
94
|
+
@machine.event :ignite
|
95
|
+
|
96
|
+
@object = @klass.new
|
97
|
+
@object.state = 'parked'
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_should_generate_a_message_without_reasons_if_empty
|
101
|
+
@object.errors = ''
|
102
|
+
invalid_transition = StateMachine::InvalidTransition.new(@object, @machine, :ignite)
|
103
|
+
assert_equal 'Cannot transition state via :ignite from :parked', invalid_transition.message
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_should_generate_a_message_with_error_reasons_if_errors_found
|
107
|
+
@object.errors = 'Id is invalid, Name is invalid'
|
108
|
+
invalid_transition = StateMachine::InvalidTransition.new(@object, @machine, :ignite)
|
109
|
+
assert_equal 'Cannot transition state via :ignite from :parked (Reason(s): Id is invalid, Name is invalid)', invalid_transition.message
|
110
|
+
end
|
111
|
+
|
112
|
+
def teardown
|
113
|
+
StateMachine::Integrations.send(:remove_const, 'Custom')
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,603 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class MachineCollectionByDefaultTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@machines = StateMachine::MachineCollection.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_should_not_have_any_machines
|
9
|
+
assert @machines.empty?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class MachineCollectionStateInitializationTest < Test::Unit::TestCase
|
14
|
+
def setup
|
15
|
+
@machines = StateMachine::MachineCollection.new
|
16
|
+
|
17
|
+
@klass = Class.new
|
18
|
+
|
19
|
+
@machines[:state] = StateMachine::Machine.new(@klass, :state, :initial => :parked)
|
20
|
+
@machines[:alarm_state] = StateMachine::Machine.new(@klass, :alarm_state, :initial => lambda {|object| :active})
|
21
|
+
@machines[:alarm_state].state :active, :value => lambda {'active'}
|
22
|
+
|
23
|
+
# Prevent the auto-initialization hook from firing
|
24
|
+
@klass.class_eval do
|
25
|
+
def initialize
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
@object = @klass.new
|
30
|
+
@object.state = nil
|
31
|
+
@object.alarm_state = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_should_raise_exception_if_invalid_option_specified
|
35
|
+
assert_raise(ArgumentError) {@machines.initialize_states(@object, :invalid => true)}
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_should_only_initialize_static_states_prior_to_block
|
39
|
+
@machines.initialize_states(@object) do
|
40
|
+
@state_in_block = @object.state
|
41
|
+
@alarm_state_in_block = @object.alarm_state
|
42
|
+
end
|
43
|
+
|
44
|
+
assert_equal 'parked', @state_in_block
|
45
|
+
assert_nil @alarm_state_in_block
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_should_only_initialize_dynamic_states_after_block
|
49
|
+
@machines.initialize_states(@object) do
|
50
|
+
@alarm_state_in_block = @object.alarm_state
|
51
|
+
end
|
52
|
+
|
53
|
+
assert_nil @alarm_state_in_block
|
54
|
+
assert_equal 'active', @object.alarm_state
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_should_initialize_all_states_without_block
|
58
|
+
@machines.initialize_states(@object)
|
59
|
+
|
60
|
+
assert_equal 'parked', @object.state
|
61
|
+
assert_equal 'active', @object.alarm_state
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_should_skip_static_states_if_disabled
|
65
|
+
@machines.initialize_states(@object, :static => false)
|
66
|
+
assert_nil @object.state
|
67
|
+
assert_equal 'active', @object.alarm_state
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_should_not_initialize_existing_static_states_by_default
|
71
|
+
@object.state = 'idling'
|
72
|
+
@machines.initialize_states(@object)
|
73
|
+
assert_equal 'idling', @object.state
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_should_initialize_existing_static_states_if_forced
|
77
|
+
@object.state = 'idling'
|
78
|
+
@machines.initialize_states(@object, :static => :force)
|
79
|
+
assert_equal 'parked', @object.state
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_should_not_initialize_existing_static_states_if_not_forced
|
83
|
+
@object.state = 'idling'
|
84
|
+
@machines.initialize_states(@object, :static => true)
|
85
|
+
assert_equal 'idling', @object.state
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_should_skip_dynamic_states_if_disabled
|
89
|
+
@machines.initialize_states(@object, :dynamic => false)
|
90
|
+
assert_equal 'parked', @object.state
|
91
|
+
assert_nil @object.alarm_state
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_should_not_initialize_existing_dynamic_states_by_default
|
95
|
+
@object.alarm_state = 'inactive'
|
96
|
+
@machines.initialize_states(@object)
|
97
|
+
assert_equal 'inactive', @object.alarm_state
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_should_initialize_existing_dynamic_states_if_forced
|
101
|
+
@object.alarm_state = 'inactive'
|
102
|
+
@machines.initialize_states(@object, :dynamic => :force)
|
103
|
+
assert_equal 'active', @object.alarm_state
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_should_not_initialize_existing_dynamic_states_if_not_forced
|
107
|
+
@object.alarm_state = 'inactive'
|
108
|
+
@machines.initialize_states(@object, :dynamic => true)
|
109
|
+
assert_equal 'inactive', @object.alarm_state
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class MachineCollectionFireTest < Test::Unit::TestCase
|
114
|
+
def setup
|
115
|
+
@machines = StateMachine::MachineCollection.new
|
116
|
+
|
117
|
+
@klass = Class.new do
|
118
|
+
attr_reader :saved
|
119
|
+
|
120
|
+
def save
|
121
|
+
@saved = true
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# First machine
|
126
|
+
@machines[:state] = @state = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
127
|
+
@state.event :ignite do
|
128
|
+
transition :parked => :idling
|
129
|
+
end
|
130
|
+
@state.event :park do
|
131
|
+
transition :idling => :parked
|
132
|
+
end
|
133
|
+
|
134
|
+
# Second machine
|
135
|
+
@machines[:alarm_state] = @alarm_state = StateMachine::Machine.new(@klass, :alarm_state, :initial => :active, :action => :save, :namespace => 'alarm')
|
136
|
+
@alarm_state.event :enable do
|
137
|
+
transition :off => :active
|
138
|
+
end
|
139
|
+
@alarm_state.event :disable do
|
140
|
+
transition :active => :off
|
141
|
+
end
|
142
|
+
|
143
|
+
@object = @klass.new
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_should_raise_exception_if_invalid_event_specified
|
147
|
+
exception = assert_raise(StateMachine::InvalidEvent) { @machines.fire_events(@object, :invalid) }
|
148
|
+
assert_equal :invalid, exception.event
|
149
|
+
|
150
|
+
exception = assert_raise(StateMachine::InvalidEvent) { @machines.fire_events(@object, :ignite, :invalid) }
|
151
|
+
assert_equal :invalid, exception.event
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_should_fail_if_any_event_cannot_transition
|
155
|
+
assert !@machines.fire_events(@object, :park, :disable_alarm)
|
156
|
+
assert_equal 'parked', @object.state
|
157
|
+
assert_equal 'active', @object.alarm_state
|
158
|
+
assert !@object.saved
|
159
|
+
|
160
|
+
assert !@machines.fire_events(@object, :ignite, :enable_alarm)
|
161
|
+
assert_equal 'parked', @object.state
|
162
|
+
assert_equal 'active', @object.alarm_state
|
163
|
+
assert !@object.saved
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_should_run_failure_callbacks_if_any_event_cannot_transition
|
167
|
+
@state_failure_run = @alarm_state_failure_run = false
|
168
|
+
|
169
|
+
@machines[:state].after_failure {@state_failure_run = true}
|
170
|
+
@machines[:alarm_state].after_failure {@alarm_state_failure_run = true}
|
171
|
+
|
172
|
+
assert !@machines.fire_events(@object, :park, :disable_alarm)
|
173
|
+
assert @state_failure_run
|
174
|
+
assert !@alarm_state_failure_run
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_should_be_successful_if_all_events_transition
|
178
|
+
assert @machines.fire_events(@object, :ignite, :disable_alarm)
|
179
|
+
assert_equal 'idling', @object.state
|
180
|
+
assert_equal 'off', @object.alarm_state
|
181
|
+
assert @object.saved
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_should_not_save_if_skipping_action
|
185
|
+
assert @machines.fire_events(@object, :ignite, :disable_alarm, false)
|
186
|
+
assert_equal 'idling', @object.state
|
187
|
+
assert_equal 'off', @object.alarm_state
|
188
|
+
assert !@object.saved
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
class MachineCollectionFireWithTransactionsTest < Test::Unit::TestCase
|
193
|
+
def setup
|
194
|
+
@machines = StateMachine::MachineCollection.new
|
195
|
+
|
196
|
+
@klass = Class.new do
|
197
|
+
attr_accessor :allow_save
|
198
|
+
|
199
|
+
def save
|
200
|
+
@allow_save
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
StateMachine::Integrations.const_set('Custom', Module.new do
|
205
|
+
include StateMachine::Integrations::Base
|
206
|
+
|
207
|
+
attr_reader :rolled_back
|
208
|
+
|
209
|
+
def transaction(object)
|
210
|
+
@rolled_back = yield
|
211
|
+
end
|
212
|
+
end)
|
213
|
+
|
214
|
+
# First machine
|
215
|
+
@machines[:state] = @state = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save, :integration => :custom)
|
216
|
+
@state.event :ignite do
|
217
|
+
transition :parked => :idling
|
218
|
+
end
|
219
|
+
|
220
|
+
# Second machine
|
221
|
+
@machines[:alarm_state] = @alarm_state = StateMachine::Machine.new(@klass, :alarm_state, :initial => :active, :action => :save, :namespace => 'alarm', :integration => :custom)
|
222
|
+
@alarm_state.event :disable do
|
223
|
+
transition :active => :off
|
224
|
+
end
|
225
|
+
|
226
|
+
@object = @klass.new
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_should_not_rollback_if_successful
|
230
|
+
@object.allow_save = true
|
231
|
+
|
232
|
+
assert @machines.fire_events(@object, :ignite, :disable_alarm)
|
233
|
+
assert_equal true, @state.rolled_back
|
234
|
+
assert_nil @alarm_state.rolled_back
|
235
|
+
assert_equal 'idling', @object.state
|
236
|
+
assert_equal 'off', @object.alarm_state
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_should_rollback_if_not_successful
|
240
|
+
@object.allow_save = false
|
241
|
+
|
242
|
+
assert !@machines.fire_events(@object, :ignite, :disable_alarm)
|
243
|
+
assert_equal false, @state.rolled_back
|
244
|
+
assert_nil @alarm_state.rolled_back
|
245
|
+
assert_equal 'parked', @object.state
|
246
|
+
assert_equal 'active', @object.alarm_state
|
247
|
+
end
|
248
|
+
|
249
|
+
def test_should_run_failure_callbacks_if_not_successful
|
250
|
+
@object.allow_save = false
|
251
|
+
@state_failure_run = @alarm_state_failure_run = false
|
252
|
+
|
253
|
+
@machines[:state].after_failure {@state_failure_run = true}
|
254
|
+
@machines[:alarm_state].after_failure {@alarm_state_failure_run = true}
|
255
|
+
|
256
|
+
assert !@machines.fire_events(@object, :ignite, :disable_alarm)
|
257
|
+
assert @state_failure_run
|
258
|
+
assert @alarm_state_failure_run
|
259
|
+
end
|
260
|
+
|
261
|
+
def teardown
|
262
|
+
StateMachine::Integrations.send(:remove_const, 'Custom')
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
class MachineCollectionFireWithValidationsTest < Test::Unit::TestCase
|
267
|
+
def setup
|
268
|
+
StateMachine::Integrations.const_set('Custom', Module.new do
|
269
|
+
include StateMachine::Integrations::Base
|
270
|
+
|
271
|
+
def invalidate(object, attribute, message, values = [])
|
272
|
+
(object.errors ||= []) << generate_message(message, values)
|
273
|
+
end
|
274
|
+
|
275
|
+
def reset(object)
|
276
|
+
object.errors = []
|
277
|
+
end
|
278
|
+
end)
|
279
|
+
|
280
|
+
@klass = Class.new do
|
281
|
+
attr_accessor :errors
|
282
|
+
|
283
|
+
def initialize
|
284
|
+
@errors = []
|
285
|
+
super
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
@machines = StateMachine::MachineCollection.new
|
290
|
+
@machines[:state] = @state = StateMachine::Machine.new(@klass, :state, :initial => :parked, :integration => :custom)
|
291
|
+
@state.event :ignite do
|
292
|
+
transition :parked => :idling
|
293
|
+
end
|
294
|
+
|
295
|
+
@machines[:alarm_state] = @alarm_state = StateMachine::Machine.new(@klass, :alarm_state, :initial => :active, :namespace => 'alarm', :integration => :custom)
|
296
|
+
@alarm_state.event :disable do
|
297
|
+
transition :active => :off
|
298
|
+
end
|
299
|
+
|
300
|
+
@object = @klass.new
|
301
|
+
end
|
302
|
+
|
303
|
+
def test_should_not_invalidate_if_transitions_exist
|
304
|
+
assert @machines.fire_events(@object, :ignite, :disable_alarm)
|
305
|
+
assert_equal [], @object.errors
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_should_invalidate_if_no_transitions_exist
|
309
|
+
@object.state = 'idling'
|
310
|
+
@object.alarm_state = 'off'
|
311
|
+
|
312
|
+
assert !@machines.fire_events(@object, :ignite, :disable_alarm)
|
313
|
+
assert_equal ['cannot transition via "ignite"', 'cannot transition via "disable"'], @object.errors
|
314
|
+
end
|
315
|
+
|
316
|
+
def test_should_run_failure_callbacks_if_no_transitions_exist
|
317
|
+
@object.state = 'idling'
|
318
|
+
@object.alarm_state = 'off'
|
319
|
+
@state_failure_run = @alarm_state_failure_run = false
|
320
|
+
|
321
|
+
@machines[:state].after_failure {@state_failure_run = true}
|
322
|
+
@machines[:alarm_state].after_failure {@alarm_state_failure_run = true}
|
323
|
+
|
324
|
+
assert !@machines.fire_events(@object, :ignite, :disable_alarm)
|
325
|
+
assert @state_failure_run
|
326
|
+
assert @alarm_state_failure_run
|
327
|
+
end
|
328
|
+
|
329
|
+
def teardown
|
330
|
+
StateMachine::Integrations.send(:remove_const, 'Custom')
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
class MachineCollectionTransitionsWithoutEventsTest < Test::Unit::TestCase
|
335
|
+
def setup
|
336
|
+
@klass = Class.new
|
337
|
+
|
338
|
+
@machines = StateMachine::MachineCollection.new
|
339
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
340
|
+
@machine.event :ignite do
|
341
|
+
transition :parked => :idling
|
342
|
+
end
|
343
|
+
|
344
|
+
@object = @klass.new
|
345
|
+
@object.state_event = nil
|
346
|
+
@transitions = @machines.transitions(@object, :save)
|
347
|
+
end
|
348
|
+
|
349
|
+
def test_should_be_empty
|
350
|
+
assert @transitions.empty?
|
351
|
+
end
|
352
|
+
|
353
|
+
def test_should_perform
|
354
|
+
assert_equal true, @transitions.perform
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
class MachineCollectionTransitionsWithBlankEventsTest < Test::Unit::TestCase
|
359
|
+
def setup
|
360
|
+
@klass = Class.new
|
361
|
+
|
362
|
+
@machines = StateMachine::MachineCollection.new
|
363
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
364
|
+
@machine.event :ignite do
|
365
|
+
transition :parked => :idling
|
366
|
+
end
|
367
|
+
|
368
|
+
@object = @klass.new
|
369
|
+
@object.state_event = ''
|
370
|
+
@transitions = @machines.transitions(@object, :save)
|
371
|
+
end
|
372
|
+
|
373
|
+
def test_should_be_empty
|
374
|
+
assert @transitions.empty?
|
375
|
+
end
|
376
|
+
|
377
|
+
def test_should_perform
|
378
|
+
assert_equal true, @transitions.perform
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
class MachineCollectionTransitionsWithInvalidEventsTest < Test::Unit::TestCase
|
383
|
+
def setup
|
384
|
+
@klass = Class.new
|
385
|
+
|
386
|
+
@machines = StateMachine::MachineCollection.new
|
387
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
388
|
+
@machine.event :ignite do
|
389
|
+
transition :parked => :idling
|
390
|
+
end
|
391
|
+
|
392
|
+
@object = @klass.new
|
393
|
+
@object.state_event = 'invalid'
|
394
|
+
@transitions = @machines.transitions(@object, :save)
|
395
|
+
end
|
396
|
+
|
397
|
+
def test_should_be_empty
|
398
|
+
assert @transitions.empty?
|
399
|
+
end
|
400
|
+
|
401
|
+
def test_should_not_perform
|
402
|
+
assert_equal false, @transitions.perform
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
class MachineCollectionTransitionsWithoutTransitionTest < Test::Unit::TestCase
|
407
|
+
def setup
|
408
|
+
@klass = Class.new
|
409
|
+
|
410
|
+
@machines = StateMachine::MachineCollection.new
|
411
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
412
|
+
@machine.event :ignite do
|
413
|
+
transition :parked => :idling
|
414
|
+
end
|
415
|
+
|
416
|
+
@object = @klass.new
|
417
|
+
@object.state = 'idling'
|
418
|
+
@object.state_event = 'ignite'
|
419
|
+
@transitions = @machines.transitions(@object, :save)
|
420
|
+
end
|
421
|
+
|
422
|
+
def test_should_be_empty
|
423
|
+
assert @transitions.empty?
|
424
|
+
end
|
425
|
+
|
426
|
+
def test_should_not_perform
|
427
|
+
assert_equal false, @transitions.perform
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
class MachineCollectionTransitionsWithTransitionTest < Test::Unit::TestCase
|
432
|
+
def setup
|
433
|
+
@klass = Class.new
|
434
|
+
|
435
|
+
@machines = StateMachine::MachineCollection.new
|
436
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
437
|
+
@machine.event :ignite do
|
438
|
+
transition :parked => :idling
|
439
|
+
end
|
440
|
+
|
441
|
+
@object = @klass.new
|
442
|
+
@object.state_event = 'ignite'
|
443
|
+
@transitions = @machines.transitions(@object, :save)
|
444
|
+
end
|
445
|
+
|
446
|
+
def test_should_not_be_empty
|
447
|
+
assert_equal 1, @transitions.length
|
448
|
+
end
|
449
|
+
|
450
|
+
def test_should_perform
|
451
|
+
assert_equal true, @transitions.perform
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
class MachineCollectionTransitionsWithSameActionsTest < Test::Unit::TestCase
|
456
|
+
def setup
|
457
|
+
@klass = Class.new
|
458
|
+
|
459
|
+
@machines = StateMachine::MachineCollection.new
|
460
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
461
|
+
@machine.event :ignite do
|
462
|
+
transition :parked => :idling
|
463
|
+
end
|
464
|
+
@machines[:status] = @machine = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :save)
|
465
|
+
@machine.event :shift_up do
|
466
|
+
transition :first_gear => :second_gear
|
467
|
+
end
|
468
|
+
|
469
|
+
@object = @klass.new
|
470
|
+
@object.state_event = 'ignite'
|
471
|
+
@object.status_event = 'shift_up'
|
472
|
+
@transitions = @machines.transitions(@object, :save)
|
473
|
+
end
|
474
|
+
|
475
|
+
def test_should_not_be_empty
|
476
|
+
assert_equal 2, @transitions.length
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_should_perform
|
480
|
+
assert_equal true, @transitions.perform
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
class MachineCollectionTransitionsWithDifferentActionsTest < Test::Unit::TestCase
|
485
|
+
def setup
|
486
|
+
@klass = Class.new
|
487
|
+
|
488
|
+
@machines = StateMachine::MachineCollection.new
|
489
|
+
@machines[:state] = @state = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
490
|
+
@state.event :ignite do
|
491
|
+
transition :parked => :idling
|
492
|
+
end
|
493
|
+
@machines[:status] = @status = StateMachine::Machine.new(@klass, :status, :initial => :first_gear, :action => :persist)
|
494
|
+
@status.event :shift_up do
|
495
|
+
transition :first_gear => :second_gear
|
496
|
+
end
|
497
|
+
|
498
|
+
@object = @klass.new
|
499
|
+
@object.state_event = 'ignite'
|
500
|
+
@object.status_event = 'shift_up'
|
501
|
+
@transitions = @machines.transitions(@object, :save)
|
502
|
+
end
|
503
|
+
|
504
|
+
def test_should_only_select_matching_actions
|
505
|
+
assert_equal 1, @transitions.length
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
class MachineCollectionTransitionsWithExisitingTransitionsTest < Test::Unit::TestCase
|
510
|
+
def setup
|
511
|
+
@klass = Class.new
|
512
|
+
|
513
|
+
@machines = StateMachine::MachineCollection.new
|
514
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
515
|
+
@machine.event :ignite do
|
516
|
+
transition :parked => :idling
|
517
|
+
end
|
518
|
+
|
519
|
+
@object = @klass.new
|
520
|
+
@object.send(:state_event_transition=, StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling))
|
521
|
+
@transitions = @machines.transitions(@object, :save)
|
522
|
+
end
|
523
|
+
|
524
|
+
def test_should_not_be_empty
|
525
|
+
assert_equal 1, @transitions.length
|
526
|
+
end
|
527
|
+
|
528
|
+
def test_should_perform
|
529
|
+
assert_equal true, @transitions.perform
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
class MachineCollectionTransitionsWithCustomOptionsTest < Test::Unit::TestCase
|
534
|
+
def setup
|
535
|
+
@klass = Class.new
|
536
|
+
|
537
|
+
@machines = StateMachine::MachineCollection.new
|
538
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
539
|
+
@machine.event :ignite do
|
540
|
+
transition :parked => :idling
|
541
|
+
end
|
542
|
+
|
543
|
+
@object = @klass.new
|
544
|
+
@transitions = @machines.transitions(@object, :save, :after => false)
|
545
|
+
end
|
546
|
+
|
547
|
+
def test_should_use_custom_options
|
548
|
+
assert @transitions.skip_after
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
class MachineCollectionFireAttributesWithValidationsTest < Test::Unit::TestCase
|
553
|
+
def setup
|
554
|
+
@klass = Class.new do
|
555
|
+
attr_accessor :errors
|
556
|
+
|
557
|
+
def initialize
|
558
|
+
@errors = []
|
559
|
+
super
|
560
|
+
end
|
561
|
+
end
|
562
|
+
|
563
|
+
@machines = StateMachine::MachineCollection.new
|
564
|
+
@machines[:state] = @machine = StateMachine::Machine.new(@klass, :state, :initial => :parked, :action => :save)
|
565
|
+
@machine.event :ignite do
|
566
|
+
transition :parked => :idling
|
567
|
+
end
|
568
|
+
|
569
|
+
class << @machine
|
570
|
+
def invalidate(object, attribute, message, values = [])
|
571
|
+
(object.errors ||= []) << generate_message(message, values)
|
572
|
+
end
|
573
|
+
|
574
|
+
def reset(object)
|
575
|
+
object.errors = []
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
@object = @klass.new
|
580
|
+
end
|
581
|
+
|
582
|
+
def test_should_invalidate_if_event_is_invalid
|
583
|
+
@object.state_event = 'invalid'
|
584
|
+
@machines.transitions(@object, :save)
|
585
|
+
|
586
|
+
assert !@object.errors.empty?
|
587
|
+
end
|
588
|
+
|
589
|
+
def test_should_invalidate_if_no_transition_exists
|
590
|
+
@object.state = 'idling'
|
591
|
+
@object.state_event = 'ignite'
|
592
|
+
@machines.transitions(@object, :save)
|
593
|
+
|
594
|
+
assert !@object.errors.empty?
|
595
|
+
end
|
596
|
+
|
597
|
+
def test_should_not_invalidate_if_transition_exists
|
598
|
+
@object.state_event = 'ignite'
|
599
|
+
@machines.transitions(@object, :save)
|
600
|
+
|
601
|
+
assert @object.errors.empty?
|
602
|
+
end
|
603
|
+
end
|