enum_state_machine 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +12 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. metadata +83 -130
  6. data/.rvmrc +0 -1
  7. data/enum_state_machine.gemspec +0 -25
  8. data/lib/enum_state_machine.rb +0 -9
  9. data/lib/enum_state_machine/assertions.rb +0 -36
  10. data/lib/enum_state_machine/branch.rb +0 -225
  11. data/lib/enum_state_machine/callback.rb +0 -232
  12. data/lib/enum_state_machine/core.rb +0 -12
  13. data/lib/enum_state_machine/core_ext.rb +0 -2
  14. data/lib/enum_state_machine/core_ext/class/state_machine.rb +0 -5
  15. data/lib/enum_state_machine/error.rb +0 -13
  16. data/lib/enum_state_machine/eval_helpers.rb +0 -87
  17. data/lib/enum_state_machine/event.rb +0 -257
  18. data/lib/enum_state_machine/event_collection.rb +0 -141
  19. data/lib/enum_state_machine/extensions.rb +0 -149
  20. data/lib/enum_state_machine/graph.rb +0 -92
  21. data/lib/enum_state_machine/helper_module.rb +0 -17
  22. data/lib/enum_state_machine/initializers.rb +0 -4
  23. data/lib/enum_state_machine/initializers/rails.rb +0 -22
  24. data/lib/enum_state_machine/integrations.rb +0 -97
  25. data/lib/enum_state_machine/integrations/active_model.rb +0 -585
  26. data/lib/enum_state_machine/integrations/active_model/locale.rb +0 -11
  27. data/lib/enum_state_machine/integrations/active_model/observer.rb +0 -33
  28. data/lib/enum_state_machine/integrations/active_model/observer_update.rb +0 -42
  29. data/lib/enum_state_machine/integrations/active_model/versions.rb +0 -31
  30. data/lib/enum_state_machine/integrations/active_record.rb +0 -548
  31. data/lib/enum_state_machine/integrations/active_record/locale.rb +0 -20
  32. data/lib/enum_state_machine/integrations/active_record/versions.rb +0 -123
  33. data/lib/enum_state_machine/integrations/base.rb +0 -100
  34. data/lib/enum_state_machine/machine.rb +0 -2292
  35. data/lib/enum_state_machine/machine_collection.rb +0 -86
  36. data/lib/enum_state_machine/macro_methods.rb +0 -518
  37. data/lib/enum_state_machine/matcher.rb +0 -123
  38. data/lib/enum_state_machine/matcher_helpers.rb +0 -54
  39. data/lib/enum_state_machine/node_collection.rb +0 -222
  40. data/lib/enum_state_machine/path.rb +0 -120
  41. data/lib/enum_state_machine/path_collection.rb +0 -90
  42. data/lib/enum_state_machine/state.rb +0 -297
  43. data/lib/enum_state_machine/state_collection.rb +0 -112
  44. data/lib/enum_state_machine/state_context.rb +0 -138
  45. data/lib/enum_state_machine/state_enum.rb +0 -23
  46. data/lib/enum_state_machine/transition.rb +0 -470
  47. data/lib/enum_state_machine/transition_collection.rb +0 -245
  48. data/lib/enum_state_machine/version.rb +0 -3
  49. data/lib/enum_state_machine/yard.rb +0 -8
  50. data/lib/enum_state_machine/yard/handlers.rb +0 -12
  51. data/lib/enum_state_machine/yard/handlers/base.rb +0 -32
  52. data/lib/enum_state_machine/yard/handlers/event.rb +0 -25
  53. data/lib/enum_state_machine/yard/handlers/machine.rb +0 -344
  54. data/lib/enum_state_machine/yard/handlers/state.rb +0 -25
  55. data/lib/enum_state_machine/yard/handlers/transition.rb +0 -47
  56. data/lib/enum_state_machine/yard/templates.rb +0 -3
  57. data/lib/enum_state_machine/yard/templates/default/class/html/setup.rb +0 -30
  58. data/lib/enum_state_machine/yard/templates/default/class/html/state_machines.erb +0 -12
  59. data/lib/tasks/enum_state_machine.rake +0 -1
  60. data/lib/tasks/enum_state_machine.rb +0 -24
  61. data/lib/yard-enum_state_machine.rb +0 -2
  62. data/test/functional/state_machine_test.rb +0 -1066
  63. data/test/unit/integrations/active_model_test.rb +0 -1245
  64. data/test/unit/integrations/active_record_test.rb +0 -2551
  65. data/test/unit/integrations/base_test.rb +0 -104
  66. data/test/unit/integrations_test.rb +0 -71
  67. data/test/unit/invalid_event_test.rb +0 -20
  68. data/test/unit/invalid_parallel_transition_test.rb +0 -18
  69. data/test/unit/invalid_transition_test.rb +0 -115
  70. data/test/unit/machine_collection_test.rb +0 -603
  71. data/test/unit/machine_test.rb +0 -3395
  72. data/test/unit/state_machine_test.rb +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d195b0469b462e5fdb5257d7c552159dd81b9584
4
- data.tar.gz: 9823967bda0300a02fad53e1b4db6e70b39f2cc6
3
+ metadata.gz: d0a9a300870e2fe8f7dad7efadeb2f0412090d9f
4
+ data.tar.gz: 4e4302f4aa155d84292e840b73845b1a3225bbc7
5
5
  SHA512:
6
- metadata.gz: 0f8186afaf20c300450f3c494d069772b3fd2ba9282db5f386f651d3ac118d9a504eaa45662d66a4e5a2b9d61e26daeaf046547a2ffea7272dc0cbb7023d99bc
7
- data.tar.gz: 1c6b94a1e170edeaa89af462f41df0b1665adf12d23730825b325cab3262f7a5f7ca45562c0bd2092aa27d43589d3353558786bed07f3f49d4c3d542ffa1b7aa
6
+ metadata.gz: e7d269d54907828b2b4f1569c649acb83988b99df821d8eaab07cca000857febefbb1b9afdf96d7614a5a0b8bc003ccf24c5824756e6f17123a22d1b20b7bdca
7
+ data.tar.gz: 55c85d9036a2ba634dfdb46ffdb662a23815098098ac0edb2e0088d2c73a58e12e52ac7bb2862f5423d684087ff1f41ab7a51e2804ded514bfff18e5ec31ce0c
data/.gitignore CHANGED
@@ -7,3 +7,15 @@ coverage/
7
7
  /doc/
8
8
  test/*.log
9
9
  /Gemfile.lock
10
+
11
+ # jeweler generated
12
+ pkg
13
+
14
+ # exclude everything in tmp
15
+ tmp/*
16
+ # except the metric_fu directory
17
+ !tmp/metric_fu/
18
+ # but exclude everything *in* the metric_fu directory
19
+ tmp/metric_fu/*
20
+ # except for the _data directory to track metrical outputs
21
+ !tmp/metric_fu/_data/
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ enum_state_machine
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0.0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enum_state_machine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - The HornsAndHooves Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-02 00:00:00.000000000 Z
11
+ date: 2015-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: power_enum
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 4.0.13
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 4.0.13
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - ~>
67
81
  - !ruby/object:Gem::Version
68
82
  version: 0.5.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  description: Adds support for creating enum state machines for attributes on any
70
98
  Ruby class
71
99
  email:
@@ -77,111 +105,46 @@ extra_rdoc_files:
77
105
  - CHANGELOG.md
78
106
  - LICENSE
79
107
  files:
80
- - .rvmrc
81
108
  - .gitignore
82
- - test/functional/state_machine_test.rb
83
- - test/unit/machine_collection_test.rb
84
- - test/unit/invalid_parallel_transition_test.rb
85
- - test/unit/integrations/base_test.rb
86
- - test/unit/integrations/active_model_test.rb
87
- - test/unit/integrations/active_record_test.rb
88
- - test/unit/path_test.rb
89
- - test/unit/helper_module_test.rb
90
- - test/unit/state_machine_test.rb
91
- - test/unit/matcher_test.rb
92
- - test/unit/eval_helpers_test.rb
93
- - test/unit/state_test.rb
94
- - test/unit/assertions_test.rb
95
- - test/unit/graph_test.rb
96
- - test/unit/error_test.rb
97
- - test/unit/path_collection_test.rb
98
- - test/unit/invalid_transition_test.rb
99
- - test/unit/matcher_helpers_test.rb
100
- - test/unit/transition_test.rb
101
- - test/unit/state_enum_test.rb
102
- - test/unit/node_collection_test.rb
103
- - test/unit/callback_test.rb
104
- - test/unit/invalid_event_test.rb
105
- - test/unit/integrations_test.rb
106
- - test/unit/event_collection_test.rb
107
- - test/unit/event_test.rb
108
- - test/unit/transition_collection_test.rb
109
- - test/unit/state_context_test.rb
110
- - test/unit/state_collection_test.rb
111
- - test/unit/branch_test.rb
112
- - test/unit/machine_test.rb
113
- - test/test_helper.rb
114
- - test/files/en.yml
115
- - test/files/switch.rb
109
+ - .ruby-gemset
110
+ - .ruby-version
111
+ - Appraisals
116
112
  - CHANGELOG.md
113
+ - Gemfile
114
+ - LICENSE
117
115
  - README.md
118
- - enum_state_machine.gemspec
119
- - gemfiles/default.gemfile
116
+ - Rakefile
117
+ - gemfiles/active_model_4.0.4.gemfile
120
118
  - gemfiles/active_model_4.0.4.gemfile.lock
121
119
  - gemfiles/active_record_4.0.4.gemfile
122
- - gemfiles/active_model_4.0.4.gemfile
123
- - gemfiles/graphviz_1.0.9.gemfile.lock
124
- - gemfiles/default.gemfile.lock
125
120
  - gemfiles/active_record_4.0.4.gemfile.lock
121
+ - gemfiles/default.gemfile
122
+ - gemfiles/default.gemfile.lock
126
123
  - gemfiles/graphviz_1.0.9.gemfile
127
- - Gemfile
128
- - Rakefile
129
- - LICENSE
130
- - lib/yard-enum_state_machine.rb
131
- - lib/tasks/enum_state_machine.rake
132
- - lib/tasks/enum_state_machine.rb
133
- - lib/enum_state_machine/callback.rb
134
- - lib/enum_state_machine/yard.rb
135
- - lib/enum_state_machine/state_context.rb
136
- - lib/enum_state_machine/integrations/active_record.rb
137
- - lib/enum_state_machine/integrations/active_record/locale.rb
138
- - lib/enum_state_machine/integrations/active_record/versions.rb
139
- - lib/enum_state_machine/integrations/active_model/locale.rb
140
- - lib/enum_state_machine/integrations/active_model/versions.rb
141
- - lib/enum_state_machine/integrations/active_model/observer_update.rb
142
- - lib/enum_state_machine/integrations/active_model/observer.rb
143
- - lib/enum_state_machine/integrations/active_model.rb
144
- - lib/enum_state_machine/integrations/base.rb
145
- - lib/enum_state_machine/matcher_helpers.rb
146
- - lib/enum_state_machine/graph.rb
147
- - lib/enum_state_machine/yard/templates/default/class/html/setup.rb
148
- - lib/enum_state_machine/yard/templates/default/class/html/state_machines.erb
149
- - lib/enum_state_machine/yard/handlers.rb
150
- - lib/enum_state_machine/yard/templates.rb
151
- - lib/enum_state_machine/yard/handlers/transition.rb
152
- - lib/enum_state_machine/yard/handlers/event.rb
153
- - lib/enum_state_machine/yard/handlers/machine.rb
154
- - lib/enum_state_machine/yard/handlers/state.rb
155
- - lib/enum_state_machine/yard/handlers/base.rb
156
- - lib/enum_state_machine/transition.rb
157
- - lib/enum_state_machine/event.rb
158
- - lib/enum_state_machine/state_enum.rb
159
- - lib/enum_state_machine/core.rb
160
- - lib/enum_state_machine/machine_collection.rb
161
- - lib/enum_state_machine/state_collection.rb
162
- - lib/enum_state_machine/path_collection.rb
163
- - lib/enum_state_machine/eval_helpers.rb
164
- - lib/enum_state_machine/event_collection.rb
165
- - lib/enum_state_machine/error.rb
166
- - lib/enum_state_machine/matcher.rb
167
- - lib/enum_state_machine/extensions.rb
168
- - lib/enum_state_machine/core_ext.rb
169
- - lib/enum_state_machine/assertions.rb
170
- - lib/enum_state_machine/integrations.rb
171
- - lib/enum_state_machine/version.rb
172
- - lib/enum_state_machine/core_ext/class/state_machine.rb
173
- - lib/enum_state_machine/machine.rb
174
- - lib/enum_state_machine/node_collection.rb
175
- - lib/enum_state_machine/state.rb
176
- - lib/enum_state_machine/macro_methods.rb
177
- - lib/enum_state_machine/initializers/rails.rb
178
- - lib/enum_state_machine/helper_module.rb
179
- - lib/enum_state_machine/branch.rb
180
- - lib/enum_state_machine/transition_collection.rb
181
- - lib/enum_state_machine/path.rb
182
- - lib/enum_state_machine/initializers.rb
183
- - lib/enum_state_machine.rb
184
- - Appraisals
124
+ - gemfiles/graphviz_1.0.9.gemfile.lock
125
+ - test/files/en.yml
126
+ - test/files/switch.rb
127
+ - test/test_helper.rb
128
+ - test/unit/assertions_test.rb
129
+ - test/unit/branch_test.rb
130
+ - test/unit/callback_test.rb
131
+ - test/unit/error_test.rb
132
+ - test/unit/eval_helpers_test.rb
133
+ - test/unit/event_collection_test.rb
134
+ - test/unit/event_test.rb
135
+ - test/unit/graph_test.rb
136
+ - test/unit/helper_module_test.rb
137
+ - test/unit/matcher_helpers_test.rb
138
+ - test/unit/matcher_test.rb
139
+ - test/unit/node_collection_test.rb
140
+ - test/unit/path_collection_test.rb
141
+ - test/unit/path_test.rb
142
+ - test/unit/state_collection_test.rb
143
+ - test/unit/state_context_test.rb
144
+ - test/unit/state_enum_test.rb
145
+ - test/unit/state_test.rb
146
+ - test/unit/transition_collection_test.rb
147
+ - test/unit/transition_test.rb
185
148
  homepage: https://github.com/HornsAndHooves/enum_state_machine
186
149
  licenses:
187
150
  - MIT
@@ -208,42 +171,32 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
171
  version: '0'
209
172
  requirements: []
210
173
  rubyforge_project:
211
- rubygems_version: 2.1.11
174
+ rubygems_version: 2.4.5
212
175
  signing_key:
213
176
  specification_version: 4
214
177
  summary: Enum State machines for attributes
215
178
  test_files:
216
- - test/functional/state_machine_test.rb
217
- - test/unit/machine_collection_test.rb
218
- - test/unit/invalid_parallel_transition_test.rb
219
- - test/unit/integrations/base_test.rb
220
- - test/unit/integrations/active_model_test.rb
221
- - test/unit/integrations/active_record_test.rb
222
- - test/unit/path_test.rb
223
- - test/unit/helper_module_test.rb
224
- - test/unit/state_machine_test.rb
225
- - test/unit/matcher_test.rb
226
- - test/unit/eval_helpers_test.rb
227
- - test/unit/state_test.rb
179
+ - test/files/en.yml
180
+ - test/files/switch.rb
181
+ - test/test_helper.rb
228
182
  - test/unit/assertions_test.rb
229
- - test/unit/graph_test.rb
230
- - test/unit/error_test.rb
231
- - test/unit/path_collection_test.rb
232
- - test/unit/invalid_transition_test.rb
233
- - test/unit/matcher_helpers_test.rb
234
- - test/unit/transition_test.rb
235
- - test/unit/state_enum_test.rb
236
- - test/unit/node_collection_test.rb
183
+ - test/unit/branch_test.rb
237
184
  - test/unit/callback_test.rb
238
- - test/unit/invalid_event_test.rb
239
- - test/unit/integrations_test.rb
185
+ - test/unit/error_test.rb
186
+ - test/unit/eval_helpers_test.rb
240
187
  - test/unit/event_collection_test.rb
241
188
  - test/unit/event_test.rb
242
- - test/unit/transition_collection_test.rb
243
- - test/unit/state_context_test.rb
189
+ - test/unit/graph_test.rb
190
+ - test/unit/helper_module_test.rb
191
+ - test/unit/matcher_helpers_test.rb
192
+ - test/unit/matcher_test.rb
193
+ - test/unit/node_collection_test.rb
194
+ - test/unit/path_collection_test.rb
195
+ - test/unit/path_test.rb
244
196
  - test/unit/state_collection_test.rb
245
- - test/unit/branch_test.rb
246
- - test/unit/machine_test.rb
247
- - test/test_helper.rb
248
- - test/files/en.yml
249
- - test/files/switch.rb
197
+ - test/unit/state_context_test.rb
198
+ - test/unit/state_enum_test.rb
199
+ - test/unit/state_test.rb
200
+ - test/unit/transition_collection_test.rb
201
+ - test/unit/transition_test.rb
202
+ has_rdoc:
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm use 2.0.0@enum_state_machine --create
@@ -1,25 +0,0 @@
1
- $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
- require 'enum_state_machine/version'
3
-
4
- Gem::Specification.new do |s|
5
- s.name = "enum_state_machine"
6
- s.version = EnumStateMachine::VERSION
7
- s.authors = ["The HornsAndHooves Team"]
8
- s.email = ["arthur.shagall@gmail.com"]
9
- s.homepage = "https://github.com/HornsAndHooves/enum_state_machine"
10
- s.description = "Adds support for creating enum state machines for attributes on any Ruby class"
11
- s.summary = "Enum State machines for attributes"
12
- s.require_paths = ["lib"]
13
- ignores = File.read(".gitignore").split.map {|i| i.sub(/\/$/, "/*").sub(/^[^\/]/, "**/\\0")}
14
- s.files = (Dir[".*"] + Dir["**/*"]).select {|f| File.file?(f) && !ignores.any? {|i| File.fnmatch(i, "/#{f}")}}
15
- s.test_files = s.files.grep(/^test\//)
16
- s.rdoc_options = %w(--line-numbers --inline-source --title enum_state_machine --main README.md)
17
- s.extra_rdoc_files = %w(README.md CHANGELOG.md LICENSE)
18
- s.license = 'MIT'
19
-
20
- s.add_dependency("power_enum", "~> 2.4")
21
-
22
- s.add_development_dependency("rake")
23
- s.add_development_dependency("simplecov")
24
- s.add_development_dependency("appraisal", "~> 0.5.0")
25
- end
@@ -1,9 +0,0 @@
1
- # By default, requiring "enum_state_machine" means that both the core implementation
2
- # *and* extensions to the Ruby core (Class in particular) will be pulled in.
3
- #
4
- # If you want to skip the Ruby core extensions, simply require "enum_state_machine/core"
5
- # and extend EnumStateMachine::MacroMethods in your class. See the README for more
6
- # information.
7
- require 'enum_state_machine/core'
8
- require 'enum_state_machine/core_ext'
9
- require 'enum_state_machine/state_enum'
@@ -1,36 +0,0 @@
1
- module EnumStateMachine
2
- # Provides a set of helper methods for making assertions about the content
3
- # of various objects
4
- module Assertions
5
- # Validates that the given hash *only* includes the specified valid keys.
6
- # If any invalid keys are found, an ArgumentError will be raised.
7
- #
8
- # == Examples
9
- #
10
- # options = {:name => 'John Smith', :age => 30}
11
- #
12
- # assert_valid_keys(options, :name) # => ArgumentError: Invalid key(s): age
13
- # assert_valid_keys(options, 'name', 'age') # => ArgumentError: Invalid key(s): age, name
14
- # assert_valid_keys(options, :name, :age) # => nil
15
- def assert_valid_keys(hash, *valid_keys)
16
- invalid_keys = hash.keys - valid_keys
17
- raise ArgumentError, "Invalid key(s): #{invalid_keys.join(', ')}" unless invalid_keys.empty?
18
- end
19
-
20
- # Validates that the given hash only includes at *most* one of a set of
21
- # exclusive keys. If more than one key is found, an ArgumentError will be
22
- # raised.
23
- #
24
- # == Examples
25
- #
26
- # options = {:only => :on, :except => :off}
27
- # assert_exclusive_keys(options, :only) # => nil
28
- # assert_exclusive_keys(options, :except) # => nil
29
- # assert_exclusive_keys(options, :only, :except) # => ArgumentError: Conflicting keys: only, except
30
- # assert_exclusive_keys(options, :only, :except, :with) # => ArgumentError: Conflicting keys: only, except
31
- def assert_exclusive_keys(hash, *exclusive_keys)
32
- conflicting_keys = exclusive_keys & hash.keys
33
- raise ArgumentError, "Conflicting keys: #{conflicting_keys.join(', ')}" unless conflicting_keys.length <= 1
34
- end
35
- end
36
- end
@@ -1,225 +0,0 @@
1
- require 'enum_state_machine/matcher'
2
- require 'enum_state_machine/eval_helpers'
3
- require 'enum_state_machine/assertions'
4
-
5
- module EnumStateMachine
6
- # Represents a set of requirements that must be met in order for a transition
7
- # or callback to occur. Branches verify that the event, from state, and to
8
- # state of the transition match, in addition to if/unless conditionals for
9
- # an object's state.
10
- class Branch
11
- include Assertions
12
- include EvalHelpers
13
-
14
- # The condition that must be met on an object
15
- attr_reader :if_condition
16
-
17
- # The condition that must *not* be met on an object
18
- attr_reader :unless_condition
19
-
20
- # The requirement for verifying the event being matched
21
- attr_reader :event_requirement
22
-
23
- # One or more requirements for verifying the states being matched. All
24
- # requirements contain a mapping of {:from => matcher, :to => matcher}.
25
- attr_reader :state_requirements
26
-
27
- # A list of all of the states known to this branch. This will pull states
28
- # from the following options (in the same order):
29
- # * +from+ / +except_from+
30
- # * +to+ / +except_to+
31
- attr_reader :known_states
32
-
33
- # Creates a new branch
34
- def initialize(options = {}) #:nodoc:
35
- # Build conditionals
36
- @if_condition = options.delete(:if)
37
- @unless_condition = options.delete(:unless)
38
-
39
- # Build event requirement
40
- @event_requirement = build_matcher(options, :on, :except_on)
41
-
42
- if (options.keys - [:from, :to, :on, :except_from, :except_to, :except_on]).empty?
43
- # Explicit from/to requirements specified
44
- @state_requirements = [{:from => build_matcher(options, :from, :except_from), :to => build_matcher(options, :to, :except_to)}]
45
- else
46
- # Separate out the event requirement
47
- options.delete(:on)
48
- options.delete(:except_on)
49
-
50
- # Implicit from/to requirements specified
51
- @state_requirements = options.collect do |from, to|
52
- from = WhitelistMatcher.new(from) unless from.is_a?(Matcher)
53
- to = WhitelistMatcher.new(to) unless to.is_a?(Matcher)
54
- {:from => from, :to => to}
55
- end
56
- end
57
-
58
- # Track known states. The order that requirements are iterated is based
59
- # on the priority in which tracked states should be added.
60
- @known_states = []
61
- @state_requirements.each do |state_requirement|
62
- [:from, :to].each {|option| @known_states |= state_requirement[option].values}
63
- end
64
- end
65
-
66
- # Determines whether the given object / query matches the requirements
67
- # configured for this branch. In addition to matching the event, from state,
68
- # and to state, this will also check whether the configured :if/:unless
69
- # conditions pass on the given object.
70
- #
71
- # == Examples
72
- #
73
- # branch = EnumStateMachine::Branch.new(:parked => :idling, :on => :ignite)
74
- #
75
- # # Successful
76
- # branch.matches?(object, :on => :ignite) # => true
77
- # branch.matches?(object, :from => nil) # => true
78
- # branch.matches?(object, :from => :parked) # => true
79
- # branch.matches?(object, :to => :idling) # => true
80
- # branch.matches?(object, :from => :parked, :to => :idling) # => true
81
- # branch.matches?(object, :on => :ignite, :from => :parked, :to => :idling) # => true
82
- #
83
- # # Unsuccessful
84
- # branch.matches?(object, :on => :park) # => false
85
- # branch.matches?(object, :from => :idling) # => false
86
- # branch.matches?(object, :to => :first_gear) # => false
87
- # branch.matches?(object, :from => :parked, :to => :first_gear) # => false
88
- # branch.matches?(object, :on => :park, :from => :parked, :to => :idling) # => false
89
- def matches?(object, query = {})
90
- !match(object, query).nil?
91
- end
92
-
93
- # Attempts to match the given object / query against the set of requirements
94
- # configured for this branch. In addition to matching the event, from state,
95
- # and to state, this will also check whether the configured :if/:unless
96
- # conditions pass on the given object.
97
- #
98
- # If a match is found, then the event/state requirements that the query
99
- # passed successfully will be returned. Otherwise, nil is returned if there
100
- # was no match.
101
- #
102
- # Query options:
103
- # * <tt>:from</tt> - One or more states being transitioned from. If none
104
- # are specified, then this will always match.
105
- # * <tt>:to</tt> - One or more states being transitioned to. If none are
106
- # specified, then this will always match.
107
- # * <tt>:on</tt> - One or more events that fired the transition. If none
108
- # are specified, then this will always match.
109
- # * <tt>:guard</tt> - Whether to guard matches with the if/unless
110
- # conditionals defined for this branch. Default is true.
111
- #
112
- # == Examples
113
- #
114
- # branch = EnumStateMachine::Branch.new(:parked => :idling, :on => :ignite)
115
- #
116
- # branch.match(object, :on => :ignite) # => {:to => ..., :from => ..., :on => ...}
117
- # branch.match(object, :on => :park) # => nil
118
- def match(object, query = {})
119
- assert_valid_keys(query, :from, :to, :on, :guard)
120
-
121
- if (match = match_query(query)) && matches_conditions?(object, query)
122
- match
123
- end
124
- end
125
-
126
- # Draws a representation of this branch on the given graph. This will draw
127
- # an edge between every state this branch matches *from* to either the
128
- # configured to state or, if none specified, then a loopback to the from
129
- # state.
130
- #
131
- # For example, if the following from states are configured:
132
- # * +idling+
133
- # * +first_gear+
134
- # * +backing_up+
135
- #
136
- # ...and the to state is +parked+, then the following edges will be created:
137
- # * +idling+ -> +parked+
138
- # * +first_gear+ -> +parked+
139
- # * +backing_up+ -> +parked+
140
- #
141
- # Each edge will be labeled with the name of the event that would cause the
142
- # transition.
143
- def draw(graph, event, valid_states)
144
- state_requirements.each do |state_requirement|
145
- # From states determined based on the known valid states
146
- from_states = state_requirement[:from].filter(valid_states)
147
-
148
- # If a to state is not specified, then it's a loopback and each from
149
- # state maps back to itself
150
- if state_requirement[:to].values.empty?
151
- loopback = true
152
- else
153
- to_state = state_requirement[:to].values.first
154
- to_state = to_state ? to_state.to_s : 'nil'
155
- loopback = false
156
- end
157
-
158
- # Generate an edge between each from and to state
159
- from_states.each do |from_state|
160
- from_state = from_state ? from_state.to_s : 'nil'
161
- graph.add_edges(from_state, loopback ? from_state : to_state, :label => event.to_s)
162
- end
163
- end
164
-
165
- true
166
- end
167
-
168
- protected
169
- # Builds a matcher strategy to use for the given options. If neither a
170
- # whitelist nor a blacklist option is specified, then an AllMatcher is
171
- # built.
172
- def build_matcher(options, whitelist_option, blacklist_option)
173
- assert_exclusive_keys(options, whitelist_option, blacklist_option)
174
-
175
- if options.include?(whitelist_option)
176
- value = options[whitelist_option]
177
- value.is_a?(Matcher) ? value : WhitelistMatcher.new(options[whitelist_option])
178
- elsif options.include?(blacklist_option)
179
- value = options[blacklist_option]
180
- raise ArgumentError, ":#{blacklist_option} option cannot use matchers; use :#{whitelist_option} instead" if value.is_a?(Matcher)
181
- BlacklistMatcher.new(value)
182
- else
183
- AllMatcher.instance
184
- end
185
- end
186
-
187
- # Verifies that all configured requirements (event and state) match the
188
- # given query. If a match is found, then a hash containing the
189
- # event/state requirements that passed will be returned; otherwise, nil.
190
- def match_query(query)
191
- query ||= {}
192
-
193
- if match_event(query) && (state_requirement = match_states(query))
194
- state_requirement.merge(:on => event_requirement)
195
- end
196
- end
197
-
198
- # Verifies that the event requirement matches the given query
199
- def match_event(query)
200
- matches_requirement?(query, :on, event_requirement)
201
- end
202
-
203
- # Verifies that the state requirements match the given query. If a
204
- # matching requirement is found, then it is returned.
205
- def match_states(query)
206
- state_requirements.detect do |state_requirement|
207
- [:from, :to].all? {|option| matches_requirement?(query, option, state_requirement[option])}
208
- end
209
- end
210
-
211
- # Verifies that an option in the given query matches the values required
212
- # for that option
213
- def matches_requirement?(query, option, requirement)
214
- !query.include?(option) || requirement.matches?(query[option], query)
215
- end
216
-
217
- # Verifies that the conditionals for this branch evaluate to true for the
218
- # given object
219
- def matches_conditions?(object, query)
220
- query[:guard] == false ||
221
- Array(if_condition).all? {|condition| evaluate_method(object, condition)} &&
222
- !Array(unless_condition).any? {|condition| evaluate_method(object, condition)}
223
- end
224
- end
225
- end