state_machine_updated_for_ruby_3_2 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +72 -0
- data/.yardopts +5 -0
- data/Appraisals +491 -0
- data/CHANGELOG.md +506 -0
- data/Dockerfile +13 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +1244 -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/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/class/state_machine.rb +5 -0
- data/lib/state_machine/core_ext.rb +2 -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/merb.rb +1 -0
- data/lib/state_machine/initializers/rails.rb +25 -0
- data/lib/state_machine/initializers.rb +4 -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_model.rb +585 -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/active_record.rb +548 -0
- data/lib/state_machine/integrations/base.rb +100 -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/data_mapper.rb +511 -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/mongo_mapper.rb +389 -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/mongoid.rb +461 -0
- data/lib/state_machine/integrations/sequel/versions.rb +95 -0
- data/lib/state_machine/integrations/sequel.rb +486 -0
- data/lib/state_machine/integrations.rb +121 -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/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/handlers.rb +12 -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/state_machine/yard/templates.rb +3 -0
- data/lib/state_machine/yard.rb +8 -0
- data/lib/state_machine.rb +8 -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 +23 -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 +272 -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 +3407 -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 +450 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
module StateMachine
|
|
2
|
+
module Integrations
|
|
3
|
+
# Provides a set of base helpers for managing individual integrations
|
|
4
|
+
module Base
|
|
5
|
+
module ClassMethods
|
|
6
|
+
# The default options to use for state machines using this integration
|
|
7
|
+
attr_reader :defaults
|
|
8
|
+
|
|
9
|
+
# The name of the integration
|
|
10
|
+
def integration_name
|
|
11
|
+
@integration_name ||= begin
|
|
12
|
+
name = self.name.split('::').last
|
|
13
|
+
name.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
|
14
|
+
name.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
|
15
|
+
name.downcase!
|
|
16
|
+
name.to_sym
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Whether this integration is available for the current library. This
|
|
21
|
+
# is only true if the ORM that the integration is for is currently
|
|
22
|
+
# defined.
|
|
23
|
+
def available?
|
|
24
|
+
matching_ancestors.any? && Object.const_defined?(matching_ancestors[0].split('::')[0])
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The list of ancestor names that cause this integration to matched.
|
|
28
|
+
def matching_ancestors
|
|
29
|
+
[]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Whether the integration should be used for the given class.
|
|
33
|
+
def matches?(klass)
|
|
34
|
+
matches_ancestors?(klass.ancestors.map {|ancestor| ancestor.name})
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Whether the integration should be used for the given list of ancestors.
|
|
38
|
+
def matches_ancestors?(ancestors)
|
|
39
|
+
(ancestors & matching_ancestors).any?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Tracks the various version overrides for an integration
|
|
43
|
+
def versions
|
|
44
|
+
@versions ||= []
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Creates a new version override for an integration. When this
|
|
48
|
+
# integration is activated, each version that is marked as active will
|
|
49
|
+
# also extend the integration.
|
|
50
|
+
#
|
|
51
|
+
# == Example
|
|
52
|
+
#
|
|
53
|
+
# module StateMachine
|
|
54
|
+
# module Integrations
|
|
55
|
+
# module ORMLibrary
|
|
56
|
+
# version '0.2.x - 0.3.x' do
|
|
57
|
+
# def self.active?
|
|
58
|
+
# ::ORMLibrary::VERSION >= '0.2.0' && ::ORMLibrary::VERSION < '0.4.0'
|
|
59
|
+
# end
|
|
60
|
+
#
|
|
61
|
+
# def invalidate(object, attribute, message, values = [])
|
|
62
|
+
# # Override here...
|
|
63
|
+
# end
|
|
64
|
+
# end
|
|
65
|
+
# end
|
|
66
|
+
# end
|
|
67
|
+
# end
|
|
68
|
+
#
|
|
69
|
+
# In the above example, a version override is defined for the ORMLibrary
|
|
70
|
+
# integration when the version is between 0.2.x and 0.3.x.
|
|
71
|
+
def version(name, &block)
|
|
72
|
+
versions << mod = Module.new(&block)
|
|
73
|
+
mod
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# The path to the locale file containing translations for this
|
|
77
|
+
# integration. This file will only exist for integrations that actually
|
|
78
|
+
# support i18n.
|
|
79
|
+
def locale_path
|
|
80
|
+
path = "#{File.dirname(__FILE__)}/#{integration_name}/locale.rb"
|
|
81
|
+
path if File.exist?(path)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Extends the given object with any version overrides that are currently
|
|
85
|
+
# active
|
|
86
|
+
def extended(base)
|
|
87
|
+
versions.each do |version|
|
|
88
|
+
base.extend(version) if version.active?
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
extend ClassMethods
|
|
94
|
+
|
|
95
|
+
def self.included(base) #:nodoc:
|
|
96
|
+
base.class_eval { extend ClassMethods }
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
module StateMachine
|
|
2
|
+
module Integrations #:nodoc:
|
|
3
|
+
module DataMapper
|
|
4
|
+
# Adds support for creating before/after/around/failure transition
|
|
5
|
+
# callbacks within a DataMapper observer. These callbacks behave very
|
|
6
|
+
# similar to hooks during save/update/destroy/etc., but with the following
|
|
7
|
+
# modifications:
|
|
8
|
+
# * Each callback can define a set of transition requirements that must be
|
|
9
|
+
# met in order for the callback to get invoked.
|
|
10
|
+
# * An additional transition parameter is available that provides
|
|
11
|
+
# contextual information about the event (see StateMachine::Transition
|
|
12
|
+
# for more information)
|
|
13
|
+
#
|
|
14
|
+
# To define a single observer for multiple state machines:
|
|
15
|
+
#
|
|
16
|
+
# class StateMachineObserver
|
|
17
|
+
# include DataMapper::Observer
|
|
18
|
+
#
|
|
19
|
+
# observe Vehicle, Switch, Project
|
|
20
|
+
#
|
|
21
|
+
# after_transition do |transition|
|
|
22
|
+
# Audit.log(self, transition)
|
|
23
|
+
# end
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# == Requirements
|
|
27
|
+
#
|
|
28
|
+
# To use this feature of the DataMapper integration, the dm-observer library
|
|
29
|
+
# must be available. This can be installed either directly or indirectly
|
|
30
|
+
# through dm-more. When loading DataMapper, be sure to load the dm-observer
|
|
31
|
+
# library as well like so:
|
|
32
|
+
#
|
|
33
|
+
# require 'rubygems'
|
|
34
|
+
# require 'dm-core'
|
|
35
|
+
# require 'dm-observer'
|
|
36
|
+
#
|
|
37
|
+
# If dm-observer is not available, then this feature will be skipped.
|
|
38
|
+
module Observer
|
|
39
|
+
include MatcherHelpers
|
|
40
|
+
|
|
41
|
+
# Creates a callback that will be invoked *before* a transition is
|
|
42
|
+
# performed, so long as the given configuration options match the
|
|
43
|
+
# transition. Each part of the transition (event, to state, from state)
|
|
44
|
+
# must match in order for the callback to get invoked.
|
|
45
|
+
#
|
|
46
|
+
# See StateMachine::Machine#before_transition for more
|
|
47
|
+
# information about the various configuration options available.
|
|
48
|
+
#
|
|
49
|
+
# == Examples
|
|
50
|
+
#
|
|
51
|
+
# class Vehicle
|
|
52
|
+
# include DataMapper::Resource
|
|
53
|
+
#
|
|
54
|
+
# property :id, Serial
|
|
55
|
+
# property :state, :String
|
|
56
|
+
#
|
|
57
|
+
# state_machine :initial => :parked do
|
|
58
|
+
# event :ignite do
|
|
59
|
+
# transition :parked => :idling
|
|
60
|
+
# end
|
|
61
|
+
# end
|
|
62
|
+
# end
|
|
63
|
+
#
|
|
64
|
+
# class VehicleObserver
|
|
65
|
+
# include DataMapper::Observer
|
|
66
|
+
#
|
|
67
|
+
# observe Vehicle
|
|
68
|
+
#
|
|
69
|
+
# before :save do
|
|
70
|
+
# # log message
|
|
71
|
+
# end
|
|
72
|
+
#
|
|
73
|
+
# # Target all state machines
|
|
74
|
+
# before_transition :parked => :idling, :on => :ignite do
|
|
75
|
+
# # put on seatbelt
|
|
76
|
+
# end
|
|
77
|
+
#
|
|
78
|
+
# # Target a specific state machine
|
|
79
|
+
# before_transition :state, any => :idling do
|
|
80
|
+
# # put on seatbelt
|
|
81
|
+
# end
|
|
82
|
+
#
|
|
83
|
+
# # Target all state machines without requirements
|
|
84
|
+
# before_transition do |transition|
|
|
85
|
+
# # log message
|
|
86
|
+
# end
|
|
87
|
+
# end
|
|
88
|
+
#
|
|
89
|
+
# *Note* that in each of the above +before_transition+ callbacks, the
|
|
90
|
+
# callback is executed within the context of the object (i.e. the
|
|
91
|
+
# Vehicle instance being transition). This means that +self+ refers
|
|
92
|
+
# to the vehicle record within each callback block.
|
|
93
|
+
def before_transition(*args, &block)
|
|
94
|
+
add_transition_callback(:before_transition, *args, &block)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Creates a callback that will be invoked *after* a transition is
|
|
98
|
+
# performed so long as the given configuration options match the
|
|
99
|
+
# transition.
|
|
100
|
+
#
|
|
101
|
+
# See +before_transition+ for a description of the possible configurations
|
|
102
|
+
# for defining callbacks.
|
|
103
|
+
def after_transition(*args, &block)
|
|
104
|
+
add_transition_callback(:after_transition, *args, &block)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Creates a callback that will be invoked *around* a transition so long
|
|
108
|
+
# as the given requirements match the transition.
|
|
109
|
+
#
|
|
110
|
+
# == Examples
|
|
111
|
+
#
|
|
112
|
+
# class Vehicle
|
|
113
|
+
# include DataMapper::Resource
|
|
114
|
+
#
|
|
115
|
+
# property :id, Serial
|
|
116
|
+
# property :state, :String
|
|
117
|
+
#
|
|
118
|
+
# state_machine :initial => :parked do
|
|
119
|
+
# event :ignite do
|
|
120
|
+
# transition :parked => :idling
|
|
121
|
+
# end
|
|
122
|
+
# end
|
|
123
|
+
# end
|
|
124
|
+
#
|
|
125
|
+
# class VehicleObserver
|
|
126
|
+
# include DataMapper::Observer
|
|
127
|
+
#
|
|
128
|
+
# observe Vehicle
|
|
129
|
+
#
|
|
130
|
+
# around_transition do |transition, block|
|
|
131
|
+
# # track start time
|
|
132
|
+
# block.call
|
|
133
|
+
# # track end time
|
|
134
|
+
# end
|
|
135
|
+
# end
|
|
136
|
+
#
|
|
137
|
+
# See +before_transition+ for a description of the possible configurations
|
|
138
|
+
# for defining callbacks.
|
|
139
|
+
def around_transition(*args, &block)
|
|
140
|
+
add_transition_callback(:around_transition, *args, &block)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Creates a callback that will be invoked *after* a transition failures to
|
|
144
|
+
# be performed so long as the given requirements match the transition.
|
|
145
|
+
#
|
|
146
|
+
# == Example
|
|
147
|
+
#
|
|
148
|
+
# class Vehicle
|
|
149
|
+
# include DataMapper::Resource
|
|
150
|
+
#
|
|
151
|
+
# property :id, Serial
|
|
152
|
+
# property :state, :String
|
|
153
|
+
#
|
|
154
|
+
# state_machine :initial => :parked do
|
|
155
|
+
# event :ignite do
|
|
156
|
+
# transition :parked => :idling
|
|
157
|
+
# end
|
|
158
|
+
# end
|
|
159
|
+
# end
|
|
160
|
+
#
|
|
161
|
+
# class VehicleObserver
|
|
162
|
+
# after_transition_failure do |transition|
|
|
163
|
+
# # log failure
|
|
164
|
+
# end
|
|
165
|
+
#
|
|
166
|
+
# after_transition_failure :on => :ignite do
|
|
167
|
+
# # log failure
|
|
168
|
+
# end
|
|
169
|
+
# end
|
|
170
|
+
#
|
|
171
|
+
# See +before_transition+ for a description of the possible configurations
|
|
172
|
+
# for defining callbacks. *Note* however that you cannot define the state
|
|
173
|
+
# requirements in these callbacks. You may only define event requirements.
|
|
174
|
+
def after_transition_failure(*args, &block)
|
|
175
|
+
add_transition_callback(:after_failure, *args, &block)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
private
|
|
179
|
+
# Adds the transition callback to a specific machine or all of the
|
|
180
|
+
# state machines for each observed class.
|
|
181
|
+
def add_transition_callback(type, *args, &block)
|
|
182
|
+
if args.any? && !args.first.is_a?(Hash)
|
|
183
|
+
# Specific machine(s) being targeted
|
|
184
|
+
names = args
|
|
185
|
+
args = args.last.is_a?(Hash) ? [args.pop] : []
|
|
186
|
+
else
|
|
187
|
+
# Target all state machines
|
|
188
|
+
names = nil
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Add the transition callback to each class being observed
|
|
192
|
+
observing.each do |klass|
|
|
193
|
+
state_machines =
|
|
194
|
+
if names
|
|
195
|
+
names.map {|name| klass.state_machines.fetch(name)}
|
|
196
|
+
else
|
|
197
|
+
klass.state_machines.values
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
state_machines.each {|machine| machine.send(type, *args, &block)}
|
|
201
|
+
end if observing
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
DataMapper::Observer::ClassMethods.class_eval do
|
|
209
|
+
include StateMachine::Integrations::DataMapper::Observer
|
|
210
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module StateMachine
|
|
2
|
+
module Integrations #:nodoc:
|
|
3
|
+
module DataMapper
|
|
4
|
+
version '0.9.x - 0.10.x' do
|
|
5
|
+
def self.active?
|
|
6
|
+
::DataMapper::VERSION =~ /^0\.\d\./ || ::DataMapper::VERSION =~ /^0\.10\./
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def pluralize(word)
|
|
10
|
+
::Extlib::Inflection.pluralize(word.to_s)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
version '0.9.x' do
|
|
15
|
+
def self.active?
|
|
16
|
+
::DataMapper::VERSION =~ /^0\.9\./
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def define_action_helpers
|
|
20
|
+
if action_hook == :save
|
|
21
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
|
22
|
+
def save(*)
|
|
23
|
+
self.class.state_machines.transitions(self, :save).perform { super }
|
|
24
|
+
end
|
|
25
|
+
end_eval
|
|
26
|
+
|
|
27
|
+
define_validation_hook
|
|
28
|
+
else
|
|
29
|
+
super
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
version '0.9.4 - 0.9.6' do
|
|
35
|
+
def self.active?
|
|
36
|
+
::DataMapper::VERSION =~ /^0\.9\.[4-6]/
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# 0.9.4 - 0.9.6 fails to run after callbacks when validations are
|
|
40
|
+
# enabled because of the way dm-validations integrates
|
|
41
|
+
def define_action_helpers?
|
|
42
|
+
super if action != :save || !supports_validations?
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
version '0.10.x' do
|
|
47
|
+
def self.active?
|
|
48
|
+
::DataMapper::VERSION =~ /^0\.10\./
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def define_action_helpers
|
|
52
|
+
if action_hook == :save
|
|
53
|
+
define_helper :instance, <<-end_eval, __FILE__, __LINE__ + 1
|
|
54
|
+
def save(*)
|
|
55
|
+
self.class.state_machines.transitions(self, :save).perform { super }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def save!(*)
|
|
59
|
+
self.class.state_machines.transitions(self, :save).perform { super }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def save_self(*)
|
|
63
|
+
self.class.state_machines.transitions(self, :save).perform { super }
|
|
64
|
+
end
|
|
65
|
+
end_eval
|
|
66
|
+
|
|
67
|
+
define_validation_hook
|
|
68
|
+
else
|
|
69
|
+
super
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
version '1.0.0' do
|
|
75
|
+
def self.active?
|
|
76
|
+
::DataMapper::VERSION == '1.0.0'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def pluralize(word)
|
|
80
|
+
(defined?(::ActiveSupport::Inflector) ? ::ActiveSupport::Inflector : ::Extlib::Inflection).pluralize(word.to_s)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|