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,352 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class StateCollectionByDefaultTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@machine = StateMachine::Machine.new(Class.new)
|
6
|
+
@states = StateMachine::StateCollection.new(@machine)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_should_not_have_any_nodes
|
10
|
+
assert_equal 0, @states.length
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_should_have_a_machine
|
14
|
+
assert_equal @machine, @states.machine
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_should_be_empty_by_priority
|
18
|
+
assert_equal [], @states.by_priority
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class StateCollectionTest < Test::Unit::TestCase
|
23
|
+
def setup
|
24
|
+
@klass = Class.new
|
25
|
+
@machine = StateMachine::Machine.new(@klass)
|
26
|
+
@states = StateMachine::StateCollection.new(@machine)
|
27
|
+
|
28
|
+
@states << @nil = StateMachine::State.new(@machine, nil)
|
29
|
+
@states << @parked = StateMachine::State.new(@machine, :parked)
|
30
|
+
@states << @idling = StateMachine::State.new(@machine, :idling)
|
31
|
+
@machine.states.concat(@states)
|
32
|
+
|
33
|
+
@object = @klass.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_index_by_name
|
37
|
+
assert_equal @parked, @states[:parked, :name]
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_should_index_by_name_by_default
|
41
|
+
assert_equal @parked, @states[:parked]
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_should_index_by_string_name
|
45
|
+
assert_equal @parked, @states['parked']
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_should_index_by_qualified_name
|
49
|
+
assert_equal @parked, @states[:parked, :qualified_name]
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_should_index_by_string_qualified_name
|
53
|
+
assert_equal @parked, @states['parked', :qualified_name]
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_should_index_by_value
|
57
|
+
assert_equal @parked, @states['parked', :value]
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_should_not_match_if_value_does_not_match
|
61
|
+
assert !@states.matches?(@object, :parked)
|
62
|
+
assert !@states.matches?(@object, :idling)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_should_match_if_value_matches
|
66
|
+
assert @states.matches?(@object, nil)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_raise_exception_if_matching_invalid_state
|
70
|
+
assert_raise(IndexError) { @states.matches?(@object, :invalid) }
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_should_find_state_for_object_if_value_is_known
|
74
|
+
@object.state = 'parked'
|
75
|
+
assert_equal @parked, @states.match(@object)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_should_find_bang_state_for_object_if_value_is_known
|
79
|
+
@object.state = 'parked'
|
80
|
+
assert_equal @parked, @states.match!(@object)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_should_not_find_state_for_object_with_unknown_value
|
84
|
+
@object.state = 'invalid'
|
85
|
+
assert_nil @states.match(@object)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_should_raise_exception_if_finding_bang_state_for_object_with_unknown_value
|
89
|
+
@object.state = 'invalid'
|
90
|
+
exception = assert_raise(ArgumentError) { @states.match!(@object) }
|
91
|
+
assert_equal '"invalid" is not a known state value', exception.message
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class StateCollectionStringTest < Test::Unit::TestCase
|
96
|
+
def setup
|
97
|
+
@klass = Class.new
|
98
|
+
@machine = StateMachine::Machine.new(@klass)
|
99
|
+
@states = StateMachine::StateCollection.new(@machine)
|
100
|
+
|
101
|
+
@states << @nil = StateMachine::State.new(@machine, nil)
|
102
|
+
@states << @parked = StateMachine::State.new(@machine, 'parked')
|
103
|
+
@machine.states.concat(@states)
|
104
|
+
|
105
|
+
@object = @klass.new
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_should_index_by_name
|
109
|
+
assert_equal @parked, @states['parked', :name]
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_should_index_by_name_by_default
|
113
|
+
assert_equal @parked, @states['parked']
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_should_index_by_symbol_name
|
117
|
+
assert_equal @parked, @states[:parked]
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_should_index_by_qualified_name
|
121
|
+
assert_equal @parked, @states['parked', :qualified_name]
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_should_index_by_symbol_qualified_name
|
125
|
+
assert_equal @parked, @states[:parked, :qualified_name]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
class StateCollectionWithNamespaceTest < Test::Unit::TestCase
|
130
|
+
def setup
|
131
|
+
@klass = Class.new
|
132
|
+
@machine = StateMachine::Machine.new(@klass, :namespace => 'vehicle')
|
133
|
+
@states = StateMachine::StateCollection.new(@machine)
|
134
|
+
|
135
|
+
@states << @state = StateMachine::State.new(@machine, :parked)
|
136
|
+
@machine.states.concat(@states)
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_should_index_by_name
|
140
|
+
assert_equal @state, @states[:parked, :name]
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_should_index_by_qualified_name
|
144
|
+
assert_equal @state, @states[:vehicle_parked, :qualified_name]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class StateCollectionWithCustomStateValuesTest < Test::Unit::TestCase
|
149
|
+
def setup
|
150
|
+
@klass = Class.new
|
151
|
+
@machine = StateMachine::Machine.new(@klass)
|
152
|
+
@states = StateMachine::StateCollection.new(@machine)
|
153
|
+
|
154
|
+
@states << @state = StateMachine::State.new(@machine, :parked, :value => 1)
|
155
|
+
@machine.states.concat(@states)
|
156
|
+
|
157
|
+
@object = @klass.new
|
158
|
+
@object.state = 1
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_should_match_if_value_matches
|
162
|
+
assert @states.matches?(@object, :parked)
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_should_not_match_if_value_does_not_match
|
166
|
+
@object.state = 2
|
167
|
+
assert !@states.matches?(@object, :parked)
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_should_find_state_for_object_if_value_is_known
|
171
|
+
assert_equal @state, @states.match(@object)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
class StateCollectionWithStateMatchersTest < Test::Unit::TestCase
|
176
|
+
def setup
|
177
|
+
@klass = Class.new
|
178
|
+
@machine = StateMachine::Machine.new(@klass)
|
179
|
+
@states = StateMachine::StateCollection.new(@machine)
|
180
|
+
|
181
|
+
@states << @state = StateMachine::State.new(@machine, :parked, :if => lambda {|value| !value.nil?})
|
182
|
+
@machine.states.concat(@states)
|
183
|
+
|
184
|
+
@object = @klass.new
|
185
|
+
@object.state = 1
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_should_match_if_value_matches
|
189
|
+
assert @states.matches?(@object, :parked)
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_should_not_match_if_value_does_not_match
|
193
|
+
@object.state = nil
|
194
|
+
assert !@states.matches?(@object, :parked)
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_should_find_state_for_object_if_value_is_known
|
198
|
+
assert_equal @state, @states.match(@object)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
class StateCollectionWithInitialStateTest < Test::Unit::TestCase
|
203
|
+
def setup
|
204
|
+
@machine = StateMachine::Machine.new(Class.new)
|
205
|
+
@states = StateMachine::StateCollection.new(@machine)
|
206
|
+
|
207
|
+
@states << @parked = StateMachine::State.new(@machine, :parked)
|
208
|
+
@states << @idling = StateMachine::State.new(@machine, :idling)
|
209
|
+
@machine.states.concat(@states)
|
210
|
+
|
211
|
+
@parked.initial = true
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_should_order_state_before_transition_states
|
215
|
+
@machine.event :ignite do
|
216
|
+
transition :to => :idling
|
217
|
+
end
|
218
|
+
assert_equal [@parked, @idling], @states.by_priority
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_should_order_state_before_states_with_behaviors
|
222
|
+
@idling.context do
|
223
|
+
def speed
|
224
|
+
0
|
225
|
+
end
|
226
|
+
end
|
227
|
+
assert_equal [@parked, @idling], @states.by_priority
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_should_order_state_before_other_states
|
231
|
+
assert_equal [@parked, @idling], @states.by_priority
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_should_order_state_before_callback_states
|
235
|
+
@machine.before_transition :from => :idling, :do => lambda {}
|
236
|
+
assert_equal [@parked, @idling], @states.by_priority
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
class StateCollectionWithStateBehaviorsTest < Test::Unit::TestCase
|
241
|
+
def setup
|
242
|
+
@machine = StateMachine::Machine.new(Class.new)
|
243
|
+
@states = StateMachine::StateCollection.new(@machine)
|
244
|
+
|
245
|
+
@states << @parked = StateMachine::State.new(@machine, :parked)
|
246
|
+
@states << @idling = StateMachine::State.new(@machine, :idling)
|
247
|
+
@machine.states.concat(@states)
|
248
|
+
|
249
|
+
@idling.context do
|
250
|
+
def speed
|
251
|
+
0
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def test_should_order_states_after_initial_state
|
257
|
+
@parked.initial = true
|
258
|
+
assert_equal [@parked, @idling], @states.by_priority
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_should_order_states_after_transition_states
|
262
|
+
@machine.event :ignite do
|
263
|
+
transition :from => :parked
|
264
|
+
end
|
265
|
+
assert_equal [@parked, @idling], @states.by_priority
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_should_order_states_before_other_states
|
269
|
+
assert_equal [@idling, @parked], @states.by_priority
|
270
|
+
end
|
271
|
+
|
272
|
+
def test_should_order_state_before_callback_states
|
273
|
+
@machine.before_transition :from => :parked, :do => lambda {}
|
274
|
+
assert_equal [@idling, @parked], @states.by_priority
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
class StateCollectionWithEventTransitionsTest < Test::Unit::TestCase
|
279
|
+
def setup
|
280
|
+
@machine = StateMachine::Machine.new(Class.new)
|
281
|
+
@states = StateMachine::StateCollection.new(@machine)
|
282
|
+
|
283
|
+
@states << @parked = StateMachine::State.new(@machine, :parked)
|
284
|
+
@states << @idling = StateMachine::State.new(@machine, :idling)
|
285
|
+
@machine.states.concat(@states)
|
286
|
+
|
287
|
+
@machine.event :ignite do
|
288
|
+
transition :to => :idling
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def test_should_order_states_after_initial_state
|
293
|
+
@parked.initial = true
|
294
|
+
assert_equal [@parked, @idling], @states.by_priority
|
295
|
+
end
|
296
|
+
|
297
|
+
def test_should_order_states_before_states_with_behaviors
|
298
|
+
@parked.context do
|
299
|
+
def speed
|
300
|
+
0
|
301
|
+
end
|
302
|
+
end
|
303
|
+
assert_equal [@idling, @parked], @states.by_priority
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_should_order_states_before_other_states
|
307
|
+
assert_equal [@idling, @parked], @states.by_priority
|
308
|
+
end
|
309
|
+
|
310
|
+
def test_should_order_state_before_callback_states
|
311
|
+
@machine.before_transition :from => :parked, :do => lambda {}
|
312
|
+
assert_equal [@idling, @parked], @states.by_priority
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
class StateCollectionWithTransitionCallbacksTest < Test::Unit::TestCase
|
317
|
+
def setup
|
318
|
+
@machine = StateMachine::Machine.new(Class.new)
|
319
|
+
@states = StateMachine::StateCollection.new(@machine)
|
320
|
+
|
321
|
+
@states << @parked = StateMachine::State.new(@machine, :parked)
|
322
|
+
@states << @idling = StateMachine::State.new(@machine, :idling)
|
323
|
+
@machine.states.concat(@states)
|
324
|
+
|
325
|
+
@machine.before_transition :to => :idling, :do => lambda {}
|
326
|
+
end
|
327
|
+
|
328
|
+
def test_should_order_states_after_initial_state
|
329
|
+
@parked.initial = true
|
330
|
+
assert_equal [@parked, @idling], @states.by_priority
|
331
|
+
end
|
332
|
+
|
333
|
+
def test_should_order_states_after_transition_states
|
334
|
+
@machine.event :ignite do
|
335
|
+
transition :from => :parked
|
336
|
+
end
|
337
|
+
assert_equal [@parked, @idling], @states.by_priority
|
338
|
+
end
|
339
|
+
|
340
|
+
def test_should_order_states_after_states_with_behaviors
|
341
|
+
@parked.context do
|
342
|
+
def speed
|
343
|
+
0
|
344
|
+
end
|
345
|
+
end
|
346
|
+
assert_equal [@parked, @idling], @states.by_priority
|
347
|
+
end
|
348
|
+
|
349
|
+
def test_should_order_states_after_other_states
|
350
|
+
assert_equal [@parked, @idling], @states.by_priority
|
351
|
+
end
|
352
|
+
end
|
@@ -0,0 +1,441 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class Validateable
|
4
|
+
class << self
|
5
|
+
def validate(*args, &block)
|
6
|
+
args << block if block_given?
|
7
|
+
args
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class StateContextTest < Test::Unit::TestCase
|
13
|
+
def setup
|
14
|
+
@klass = Class.new(Validateable)
|
15
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
16
|
+
@state = @machine.state :parked
|
17
|
+
|
18
|
+
@state_context = StateMachine::StateContext.new(@state)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_have_a_machine
|
22
|
+
assert_equal @machine, @state_context.machine
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_should_have_a_state
|
26
|
+
assert_equal @state, @state_context.state
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class StateContextTransitionTest < Test::Unit::TestCase
|
31
|
+
def setup
|
32
|
+
@klass = Class.new
|
33
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
34
|
+
@state = @machine.state :parked
|
35
|
+
|
36
|
+
@state_context = StateMachine::StateContext.new(@state)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_should_not_allow_except_to
|
40
|
+
exception = assert_raise(ArgumentError) { @state_context.transition(:except_to => :idling) }
|
41
|
+
assert_equal 'Invalid key(s): except_to', exception.message
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_should_not_allow_except_from
|
45
|
+
exception = assert_raise(ArgumentError) { @state_context.transition(:except_from => :idling) }
|
46
|
+
assert_equal 'Invalid key(s): except_from', exception.message
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_should_not_allow_implicit_transitions
|
50
|
+
exception = assert_raise(ArgumentError) { @state_context.transition(:parked => :idling) }
|
51
|
+
assert_equal 'Invalid key(s): parked', exception.message
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_should_not_allow_except_on
|
55
|
+
exception = assert_raise(ArgumentError) { @state_context.transition(:except_on => :park) }
|
56
|
+
assert_equal 'Invalid key(s): except_on', exception.message
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_should_require_on_event
|
60
|
+
exception = assert_raise(ArgumentError) { @state_context.transition(:to => :idling) }
|
61
|
+
assert_equal 'Must specify :on event', exception.message
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_should_not_allow_missing_from_and_to
|
65
|
+
exception = assert_raise(ArgumentError) { @state_context.transition(:on => :ignite) }
|
66
|
+
assert_equal 'Must specify either :to or :from state', exception.message
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_should_not_allow_from_and_to
|
70
|
+
exception = assert_raise(ArgumentError) { @state_context.transition(:on => :ignite, :from => :parked, :to => :idling) }
|
71
|
+
assert_equal 'Must specify either :to or :from state', exception.message
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_should_allow_to_state_if_missing_from_state
|
75
|
+
assert_nothing_raised { @state_context.transition(:on => :park, :from => :parked) }
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_should_allow_from_state_if_missing_to_state
|
79
|
+
assert_nothing_raised { @state_context.transition(:on => :ignite, :to => :idling) }
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_should_automatically_set_to_option_with_from_state
|
83
|
+
branch = @state_context.transition(:from => :idling, :on => :park)
|
84
|
+
assert_instance_of StateMachine::Branch, branch
|
85
|
+
|
86
|
+
state_requirements = branch.state_requirements
|
87
|
+
assert_equal 1, state_requirements.length
|
88
|
+
|
89
|
+
from_requirement = state_requirements[0][:to]
|
90
|
+
assert_instance_of StateMachine::WhitelistMatcher, from_requirement
|
91
|
+
assert_equal [:parked], from_requirement.values
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_should_automatically_set_from_option_with_to_state
|
95
|
+
branch = @state_context.transition(:to => :idling, :on => :ignite)
|
96
|
+
assert_instance_of StateMachine::Branch, branch
|
97
|
+
|
98
|
+
state_requirements = branch.state_requirements
|
99
|
+
assert_equal 1, state_requirements.length
|
100
|
+
|
101
|
+
from_requirement = state_requirements[0][:from]
|
102
|
+
assert_instance_of StateMachine::WhitelistMatcher, from_requirement
|
103
|
+
assert_equal [:parked], from_requirement.values
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_should_allow_if_condition
|
107
|
+
assert_nothing_raised {@state_context.transition(:to => :idling, :on => :park, :if => :seatbelt_on?)}
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_should_allow_unless_condition
|
111
|
+
assert_nothing_raised {@state_context.transition(:to => :idling, :on => :park, :unless => :seatbelt_off?)}
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_should_include_all_transition_states_in_machine_states
|
115
|
+
@state_context.transition(:to => :idling, :on => :ignite)
|
116
|
+
|
117
|
+
assert_equal [:parked, :idling], @machine.states.map {|state| state.name}
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_should_include_all_transition_events_in_machine_events
|
121
|
+
@state_context.transition(:to => :idling, :on => :ignite)
|
122
|
+
|
123
|
+
assert_equal [:ignite], @machine.events.map {|event| event.name}
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_should_allow_multiple_events
|
127
|
+
@state_context.transition(:to => :idling, :on => [:ignite, :shift_up])
|
128
|
+
|
129
|
+
assert_equal [:ignite, :shift_up], @machine.events.map {|event| event.name}
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class StateContextWithMatchingTransitionTest < Test::Unit::TestCase
|
134
|
+
def setup
|
135
|
+
@klass = Class.new
|
136
|
+
@machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
137
|
+
@state = @machine.state :parked
|
138
|
+
|
139
|
+
@state_context = StateMachine::StateContext.new(@state)
|
140
|
+
@state_context.transition(:to => :idling, :on => :ignite)
|
141
|
+
|
142
|
+
@event = @machine.event(:ignite)
|
143
|
+
@object = @klass.new
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_should_be_able_to_fire
|
147
|
+
assert @event.can_fire?(@object)
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_should_have_a_transition
|
151
|
+
transition = @event.transition_for(@object)
|
152
|
+
assert_not_nil transition
|
153
|
+
assert_equal 'parked', transition.from
|
154
|
+
assert_equal 'idling', transition.to
|
155
|
+
assert_equal :ignite, transition.event
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
class StateContextProxyTest < Test::Unit::TestCase
|
160
|
+
def setup
|
161
|
+
@klass = Class.new(Validateable)
|
162
|
+
machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
163
|
+
state = machine.state :parked
|
164
|
+
|
165
|
+
@state_context = StateMachine::StateContext.new(state)
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_should_call_class_with_same_arguments
|
169
|
+
options = {}
|
170
|
+
validation = @state_context.validate(:name, options)
|
171
|
+
|
172
|
+
assert_equal [:name, options], validation
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_should_pass_block_through_to_class
|
176
|
+
options = {}
|
177
|
+
proxy_block = lambda {}
|
178
|
+
validation = @state_context.validate(:name, options, &proxy_block)
|
179
|
+
|
180
|
+
assert_equal [:name, options, proxy_block], validation
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
class StateContextProxyWithoutConditionsTest < Test::Unit::TestCase
|
185
|
+
def setup
|
186
|
+
@klass = Class.new(Validateable)
|
187
|
+
machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
188
|
+
state = machine.state :parked
|
189
|
+
|
190
|
+
@state_context = StateMachine::StateContext.new(state)
|
191
|
+
@object = @klass.new
|
192
|
+
|
193
|
+
@options = @state_context.validate[0]
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_should_have_options_configuration
|
197
|
+
assert_instance_of Hash, @options
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_should_have_if_option
|
201
|
+
assert_not_nil @options[:if]
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_should_be_false_if_state_is_different
|
205
|
+
@object.state = nil
|
206
|
+
assert !@options[:if].call(@object)
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_should_be_true_if_state_matches
|
210
|
+
assert @options[:if].call(@object)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
class StateContextProxyWithIfConditionTest < Test::Unit::TestCase
|
215
|
+
def setup
|
216
|
+
@klass = Class.new(Validateable)
|
217
|
+
machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
218
|
+
state = machine.state :parked
|
219
|
+
|
220
|
+
@state_context = StateMachine::StateContext.new(state)
|
221
|
+
@object = @klass.new
|
222
|
+
|
223
|
+
@condition_result = nil
|
224
|
+
@options = @state_context.validate(:if => lambda {@condition_result})[0]
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_should_have_if_option
|
228
|
+
assert_not_nil @options[:if]
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_should_be_false_if_state_is_different
|
232
|
+
@object.state = nil
|
233
|
+
assert !@options[:if].call(@object)
|
234
|
+
end
|
235
|
+
|
236
|
+
def test_should_be_false_if_original_condition_is_false
|
237
|
+
@condition_result = false
|
238
|
+
assert !@options[:if].call(@object)
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_should_be_true_if_state_matches_and_original_condition_is_true
|
242
|
+
@condition_result = true
|
243
|
+
assert @options[:if].call(@object)
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_should_evaluate_symbol_condition
|
247
|
+
@klass.class_eval do
|
248
|
+
attr_accessor :callback
|
249
|
+
end
|
250
|
+
|
251
|
+
options = @state_context.validate(:if => :callback)[0]
|
252
|
+
|
253
|
+
object = @klass.new
|
254
|
+
object.callback = false
|
255
|
+
assert !options[:if].call(object)
|
256
|
+
|
257
|
+
object.callback = true
|
258
|
+
assert options[:if].call(object)
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_should_evaluate_string_condition
|
262
|
+
@klass.class_eval do
|
263
|
+
attr_accessor :callback
|
264
|
+
end
|
265
|
+
|
266
|
+
options = @state_context.validate(:if => '@callback')[0]
|
267
|
+
|
268
|
+
object = @klass.new
|
269
|
+
object.callback = false
|
270
|
+
assert !options[:if].call(object)
|
271
|
+
|
272
|
+
object.callback = true
|
273
|
+
assert options[:if].call(object)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
class StateContextProxyWithMultipleIfConditionsTest < Test::Unit::TestCase
|
278
|
+
def setup
|
279
|
+
@klass = Class.new(Validateable)
|
280
|
+
machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
281
|
+
state = machine.state :parked
|
282
|
+
|
283
|
+
@state_context = StateMachine::StateContext.new(state)
|
284
|
+
@object = @klass.new
|
285
|
+
|
286
|
+
@first_condition_result = nil
|
287
|
+
@second_condition_result = nil
|
288
|
+
@options = @state_context.validate(:if => [lambda {@first_condition_result}, lambda {@second_condition_result}])[0]
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_should_be_true_if_all_conditions_are_true
|
292
|
+
@first_condition_result = true
|
293
|
+
@second_condition_result = true
|
294
|
+
assert @options[:if].call(@object)
|
295
|
+
end
|
296
|
+
|
297
|
+
def test_should_be_false_if_any_condition_is_false
|
298
|
+
@first_condition_result = true
|
299
|
+
@second_condition_result = false
|
300
|
+
assert !@options[:if].call(@object)
|
301
|
+
|
302
|
+
@first_condition_result = false
|
303
|
+
@second_condition_result = true
|
304
|
+
assert !@options[:if].call(@object)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
class StateContextProxyWithUnlessConditionTest < Test::Unit::TestCase
|
309
|
+
def setup
|
310
|
+
@klass = Class.new(Validateable)
|
311
|
+
machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
312
|
+
state = machine.state :parked
|
313
|
+
|
314
|
+
@state_context = StateMachine::StateContext.new(state)
|
315
|
+
@object = @klass.new
|
316
|
+
|
317
|
+
@condition_result = nil
|
318
|
+
@options = @state_context.validate(:unless => lambda {@condition_result})[0]
|
319
|
+
end
|
320
|
+
|
321
|
+
def test_should_have_if_option
|
322
|
+
assert_not_nil @options[:if]
|
323
|
+
end
|
324
|
+
|
325
|
+
def test_should_be_false_if_state_is_different
|
326
|
+
@object.state = nil
|
327
|
+
assert !@options[:if].call(@object)
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_should_be_false_if_original_condition_is_true
|
331
|
+
@condition_result = true
|
332
|
+
assert !@options[:if].call(@object)
|
333
|
+
end
|
334
|
+
|
335
|
+
def test_should_be_true_if_state_matches_and_original_condition_is_false
|
336
|
+
@condition_result = false
|
337
|
+
assert @options[:if].call(@object)
|
338
|
+
end
|
339
|
+
|
340
|
+
def test_should_evaluate_symbol_condition
|
341
|
+
@klass.class_eval do
|
342
|
+
attr_accessor :callback
|
343
|
+
end
|
344
|
+
|
345
|
+
options = @state_context.validate(:unless => :callback)[0]
|
346
|
+
|
347
|
+
object = @klass.new
|
348
|
+
object.callback = true
|
349
|
+
assert !options[:if].call(object)
|
350
|
+
|
351
|
+
object.callback = false
|
352
|
+
assert options[:if].call(object)
|
353
|
+
end
|
354
|
+
|
355
|
+
def test_should_evaluate_string_condition
|
356
|
+
@klass.class_eval do
|
357
|
+
attr_accessor :callback
|
358
|
+
end
|
359
|
+
|
360
|
+
options = @state_context.validate(:unless => '@callback')[0]
|
361
|
+
|
362
|
+
object = @klass.new
|
363
|
+
object.callback = true
|
364
|
+
assert !options[:if].call(object)
|
365
|
+
|
366
|
+
object.callback = false
|
367
|
+
assert options[:if].call(object)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
class StateContextProxyWithMultipleUnlessConditionsTest < Test::Unit::TestCase
|
372
|
+
def setup
|
373
|
+
@klass = Class.new(Validateable)
|
374
|
+
machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
375
|
+
state = machine.state :parked
|
376
|
+
|
377
|
+
@state_context = StateMachine::StateContext.new(state)
|
378
|
+
@object = @klass.new
|
379
|
+
|
380
|
+
@first_condition_result = nil
|
381
|
+
@second_condition_result = nil
|
382
|
+
@options = @state_context.validate(:unless => [lambda {@first_condition_result}, lambda {@second_condition_result}])[0]
|
383
|
+
end
|
384
|
+
|
385
|
+
def test_should_be_true_if_all_conditions_are_false
|
386
|
+
@first_condition_result = false
|
387
|
+
@second_condition_result = false
|
388
|
+
assert @options[:if].call(@object)
|
389
|
+
end
|
390
|
+
|
391
|
+
def test_should_be_false_if_any_condition_is_true
|
392
|
+
@first_condition_result = true
|
393
|
+
@second_condition_result = false
|
394
|
+
assert !@options[:if].call(@object)
|
395
|
+
|
396
|
+
@first_condition_result = false
|
397
|
+
@second_condition_result = true
|
398
|
+
assert !@options[:if].call(@object)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
class StateContextProxyWithIfAndUnlessConditionsTest < Test::Unit::TestCase
|
403
|
+
def setup
|
404
|
+
@klass = Class.new(Validateable)
|
405
|
+
machine = StateMachine::Machine.new(@klass, :initial => :parked)
|
406
|
+
state = machine.state :parked
|
407
|
+
|
408
|
+
@state_context = StateMachine::StateContext.new(state)
|
409
|
+
@object = @klass.new
|
410
|
+
|
411
|
+
@if_condition_result = nil
|
412
|
+
@unless_condition_result = nil
|
413
|
+
@options = @state_context.validate(:if => lambda {@if_condition_result}, :unless => lambda {@unless_condition_result})[0]
|
414
|
+
end
|
415
|
+
|
416
|
+
def test_should_be_false_if_if_condition_is_false
|
417
|
+
@if_condition_result = false
|
418
|
+
@unless_condition_result = false
|
419
|
+
assert !@options[:if].call(@object)
|
420
|
+
|
421
|
+
@if_condition_result = false
|
422
|
+
@unless_condition_result = true
|
423
|
+
assert !@options[:if].call(@object)
|
424
|
+
end
|
425
|
+
|
426
|
+
def test_should_be_false_if_unless_condition_is_true
|
427
|
+
@if_condition_result = false
|
428
|
+
@unless_condition_result = true
|
429
|
+
assert !@options[:if].call(@object)
|
430
|
+
|
431
|
+
@if_condition_result = true
|
432
|
+
@unless_condition_result = true
|
433
|
+
assert !@options[:if].call(@object)
|
434
|
+
end
|
435
|
+
|
436
|
+
def test_should_be_true_if_if_condition_is_true_and_unless_condition_is_false
|
437
|
+
@if_condition_result = true
|
438
|
+
@unless_condition_result = false
|
439
|
+
assert @options[:if].call(@object)
|
440
|
+
end
|
441
|
+
end
|