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
@@ -1,245 +0,0 @@
1
- module EnumStateMachine
2
- # Represents a collection of transitions in a state machine
3
- class TransitionCollection < Array
4
- include Assertions
5
-
6
- # Whether to skip running the action for each transition's machine
7
- attr_reader :skip_actions
8
-
9
- # Whether to skip running the after callbacks
10
- attr_reader :skip_after
11
-
12
- # Whether transitions should wrapped around a transaction block
13
- attr_reader :use_transaction
14
-
15
- # Creates a new collection of transitions that can be run in parallel. Each
16
- # transition *must* be for a different attribute.
17
- #
18
- # Configuration options:
19
- # * <tt>:actions</tt> - Whether to run the action configured for each transition
20
- # * <tt>:after</tt> - Whether to run after callbacks
21
- # * <tt>:transaction</tt> - Whether to wrap transitions within a transaction
22
- def initialize(transitions = [], options = {})
23
- super(transitions)
24
-
25
- # Determine the validity of the transitions as a whole
26
- @valid = all?
27
- reject! {|transition| !transition}
28
-
29
- attributes = map {|transition| transition.attribute}.uniq
30
- raise ArgumentError, 'Cannot perform multiple transitions in parallel for the same state machine attribute' if attributes.length != length
31
-
32
- assert_valid_keys(options, :actions, :after, :transaction)
33
- options = {:actions => true, :after => true, :transaction => true}.merge(options)
34
- @skip_actions = !options[:actions]
35
- @skip_after = !options[:after]
36
- @use_transaction = options[:transaction]
37
- end
38
-
39
- # Runs each of the collection's transitions in parallel.
40
- #
41
- # All transitions will run through the following steps:
42
- # 1. Before callbacks
43
- # 2. Persist state
44
- # 3. Invoke action
45
- # 4. After callbacks (if configured)
46
- # 5. Rollback (if action is unsuccessful)
47
- #
48
- # If a block is passed to this method, that block will be called instead
49
- # of invoking each transition's action.
50
- def perform(&block)
51
- reset
52
-
53
- if valid?
54
- if use_event_attributes? && !block_given?
55
- each do |transition|
56
- transition.transient = true
57
- transition.machine.write(object, :event_transition, transition)
58
- end
59
-
60
- run_actions
61
- else
62
- within_transaction do
63
- catch(:halt) { run_callbacks(&block) }
64
- rollback unless success?
65
- end
66
- end
67
- end
68
-
69
- if actions.length == 1 && results.include?(actions.first)
70
- results[actions.first]
71
- else
72
- success?
73
- end
74
- end
75
-
76
- protected
77
- attr_reader :results #:nodoc:
78
-
79
- private
80
- # Is this a valid set of transitions? If the collection was creating with
81
- # any +false+ values for transitions, then the the collection will be
82
- # marked as invalid.
83
- def valid?
84
- @valid
85
- end
86
-
87
- # Did each transition perform successfully? This will only be true if the
88
- # following requirements are met:
89
- # * No +before+ callbacks halt
90
- # * All actions run successfully (always true if skipping actions)
91
- def success?
92
- @success
93
- end
94
-
95
- # Gets the object being transitioned
96
- def object
97
- first.object
98
- end
99
-
100
- # Gets the list of actions to run. If configured to skip actions, then
101
- # this will return an empty collection.
102
- def actions
103
- empty? ? [nil] : map {|transition| transition.action}.uniq
104
- end
105
-
106
- # Determines whether an event attribute be used to trigger the transitions
107
- # in this collection or whether the transitions be run directly *outside*
108
- # of the action.
109
- def use_event_attributes?
110
- !skip_actions && !skip_after && actions.all? && actions.length == 1 && first.machine.action_hook?
111
- end
112
-
113
- # Resets any information tracked from previous attempts to perform the
114
- # collection
115
- def reset
116
- @results = {}
117
- @success = false
118
- end
119
-
120
- # Runs each transition's callbacks recursively. Once all before callbacks
121
- # have been executed, the transitions will then be persisted and the
122
- # configured actions will be run.
123
- #
124
- # If any transition fails to run its callbacks, :halt will be thrown.
125
- def run_callbacks(index = 0, &block)
126
- if transition = self[index]
127
- throw :halt unless transition.run_callbacks(:after => !skip_after) do
128
- run_callbacks(index + 1, &block)
129
- {:result => results[transition.action], :success => success?}
130
- end
131
- else
132
- persist
133
- run_actions(&block)
134
- end
135
- end
136
-
137
- # Transitions the current value of the object's states to those specified by
138
- # each transition
139
- def persist
140
- each {|transition| transition.persist}
141
- end
142
-
143
- # Runs the actions for each transition. If a block is given method, then it
144
- # will be called instead of invoking each transition's action.
145
- #
146
- # The results of the actions will be used to determine #success?.
147
- def run_actions
148
- catch_exceptions do
149
- @success = if block_given?
150
- result = yield
151
- actions.each {|action| results[action] = result}
152
- !!result
153
- else
154
- actions.compact.each {|action| !skip_actions && results[action] = object.send(action)}
155
- results.values.all?
156
- end
157
- end
158
- end
159
-
160
- # Rolls back changes made to the object's states via each transition
161
- def rollback
162
- each {|transition| transition.rollback}
163
- end
164
-
165
- # Wraps the given block with a rescue handler so that any exceptions that
166
- # occur will automatically result in the transition rolling back any changes
167
- # that were made to the object involved.
168
- def catch_exceptions
169
- begin
170
- yield
171
- rescue Exception
172
- rollback
173
- raise
174
- end
175
- end
176
-
177
- # Runs a block within a transaction for the object being transitioned. If
178
- # transactions are disabled, then this is a no-op.
179
- def within_transaction
180
- if use_transaction && !empty?
181
- first.within_transaction do
182
- yield
183
- success?
184
- end
185
- else
186
- yield
187
- end
188
- end
189
- end
190
-
191
- # Represents a collection of transitions that were generated from attribute-
192
- # based events
193
- class AttributeTransitionCollection < TransitionCollection
194
- def initialize(transitions = [], options = {}) #:nodoc:
195
- super(transitions, {:transaction => false, :actions => false}.merge(options))
196
- end
197
-
198
- private
199
- # Hooks into running transition callbacks so that event / event transition
200
- # attributes can be properly updated
201
- def run_callbacks(index = 0)
202
- if index == 0
203
- # Clears any traces of the event attribute to prevent it from being
204
- # evaluated multiple times if actions are nested
205
- each do |transition|
206
- transition.machine.write(object, :event, nil)
207
- transition.machine.write(object, :event_transition, nil)
208
- end
209
-
210
- # Rollback only if exceptions occur during before callbacks
211
- begin
212
- super
213
- rescue Exception
214
- rollback unless @before_run
215
- raise
216
- end
217
-
218
- # Persists transitions on the object if partial transition was successful.
219
- # This allows us to reference them later to complete the transition with
220
- # after callbacks.
221
- each {|transition| transition.machine.write(object, :event_transition, transition)} if skip_after && success?
222
- else
223
- super
224
- end
225
- end
226
-
227
- # Tracks that before callbacks have now completed
228
- def persist
229
- @before_run = true
230
- super
231
- end
232
-
233
- # Resets callback tracking
234
- def reset
235
- super
236
- @before_run = false
237
- end
238
-
239
- # Resets the event attribute so it can be re-evaluated if attempted again
240
- def rollback
241
- super
242
- each {|transition| transition.machine.write(object, :event, transition.event) unless transition.transient?}
243
- end
244
- end
245
- end
@@ -1,3 +0,0 @@
1
- module EnumStateMachine
2
- VERSION = '0.0.1'
3
- end
@@ -1,8 +0,0 @@
1
- module EnumStateMachine
2
- # YARD plugin for automated documentation
3
- module YARD
4
- end
5
- end
6
-
7
- require 'enum_state_machine/yard/handlers'
8
- require 'enum_state_machine/yard/templates'
@@ -1,12 +0,0 @@
1
- module EnumStateMachine
2
- module YARD
3
- # YARD custom handlers for integrating the state_machine DSL with the
4
- # YARD documentation system
5
- module Handlers
6
- end
7
- end
8
- end
9
-
10
- Dir["#{File.dirname(__FILE__)}/handlers/*.rb"].sort.each do |path|
11
- require "enum_state_machine/yard/handlers/#{File.basename(path)}"
12
- end
@@ -1,32 +0,0 @@
1
- module EnumStateMachine
2
- module YARD
3
- module Handlers
4
- # Handles and processes nodes
5
- class Base < ::YARD::Handlers::Ruby::Base
6
- private
7
- # Extracts the value from the node as either a string or symbol
8
- def extract_node_name(ast)
9
- case ast.type
10
- when :symbol_literal
11
- ast.jump(:ident).source.to_sym
12
- when :string_literal
13
- ast.jump(:tstring_content).source
14
- else
15
- nil
16
- end
17
- end
18
-
19
- # Extracts the values from the node as either strings or symbols.
20
- # If the node isn't an array, it'll be converted to an array.
21
- def extract_node_names(ast, convert_to_array = true)
22
- if [nil, :array].include?(ast.type)
23
- ast.children.map {|child| extract_node_name(child)}
24
- else
25
- node_name = extract_node_name(ast)
26
- convert_to_array ? [node_name] : node_name
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,25 +0,0 @@
1
- module EnumStateMachine
2
- module YARD
3
- module Handlers
4
- # Handles and processes #event
5
- class Event < Base
6
- handles method_call(:event)
7
-
8
- def process
9
- if owner.is_a?(EnumStateMachine::Machine)
10
- handler = self
11
- statement = self.statement
12
- names = extract_node_names(statement.parameters(false))
13
-
14
- names.each do |name|
15
- owner.event(name) do
16
- # Parse the block
17
- handler.parse_block(statement.last.last, :owner => self)
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,344 +0,0 @@
1
- require 'tempfile'
2
-
3
- module EnumStateMachine
4
- module YARD
5
- module Handlers
6
- # Handles and processes #state_machine
7
- class Machine < Base
8
- handles method_call(:state_machine)
9
- namespace_only
10
-
11
- # The generated state machine
12
- attr_reader :machine
13
-
14
- def process
15
- # Cross-file storage for state machines
16
- globals.state_machines ||= Hash.new {|h, k| h[k] = {}}
17
- namespace['state_machines'] ||= {}
18
-
19
- # Create new machine
20
- klass = inherited_machine ? Class.new(inherited_machine.owner_class) : Class.new { extend EnumStateMachine::MacroMethods }
21
- @machine = klass.state_machine(name, options) {}
22
-
23
- # Track the state machine
24
- globals.state_machines[namespace.name][name] = machine
25
- namespace['state_machines'][name] = {:name => name, :description => statement.docstring}
26
-
27
- # Parse the block
28
- parse_block(statement.last.last, :owner => machine)
29
-
30
- # Draw the machine for reference in the template
31
- file = Tempfile.new(['enum_state_machine', '.png'])
32
- begin
33
- if machine.draw(:name => File.basename(file.path, '.png'), :path => File.dirname(file.path), :orientation => 'landscape')
34
- namespace['state_machines'][name][:image] = file.read
35
- end
36
- ensure
37
- # Clean up tempfile
38
- file.close
39
- file.unlink
40
- end
41
-
42
- # Define auto-generated methods
43
- define_macro_methods
44
- define_state_methods
45
- define_event_methods
46
- end
47
-
48
- protected
49
- # Extracts the machine name's
50
- def name
51
- @name ||= begin
52
- ast = statement.parameters.first
53
- if ast && [:symbol_literal, :string_literal].include?(ast.type)
54
- extract_node_name(ast)
55
- else
56
- :state
57
- end
58
- end
59
- end
60
-
61
- # Extracts the machine options. Note that this will only extract a
62
- # subset of the options supported.
63
- def options
64
- @options ||= begin
65
- options = {}
66
- ast = statement.parameters(false).last
67
-
68
- if !inherited_machine && ast && ![:symbol_literal, :string_literal].include?(ast.type)
69
- ast.children.each do |assoc|
70
- # Only extract important options
71
- key = extract_node_name(assoc[0])
72
- next unless [:initial, :attribute, :namespace, :action].include?(key)
73
-
74
- value = extract_node_name(assoc[1])
75
- options[key] = value
76
- end
77
- end
78
-
79
- options
80
- end
81
- end
82
-
83
- # Gets the machine that was inherited from a superclass. This also
84
- # ensures each ancestor has been loaded prior to looking up their definitions.
85
- def inherited_machine
86
- @inherited_machine ||= begin
87
- namespace.inheritance_tree.each do |ancestor|
88
- begin
89
- ensure_loaded!(ancestor)
90
- rescue ::YARD::Handlers::NamespaceMissingError
91
- # Ignore: just means that we can't access an ancestor
92
- end
93
- end
94
-
95
- # Find the first ancestor that has the machine
96
- loaded_superclasses.detect do |superclass|
97
- if superclass != namespace
98
- machine = globals.state_machines[superclass.name][name]
99
- break machine if machine
100
- end
101
- end
102
- end
103
- end
104
-
105
- # Gets members of this class's superclasses have already been loaded
106
- # by YARD
107
- def loaded_superclasses
108
- namespace.inheritance_tree.select {|ancestor| ancestor.is_a?(::YARD::CodeObjects::ClassObject)}
109
- end
110
-
111
- # Gets a list of all attributes for the current class, including those
112
- # that are inherited
113
- def instance_attributes
114
- attributes = {}
115
- loaded_superclasses.each {|superclass| attributes.merge!(superclass.instance_attributes)}
116
- attributes
117
- end
118
-
119
- # Gets the type of ORM integration being used based on the list of
120
- # ancestors (including mixins)
121
- def integration
122
- @integration ||= Integrations.match_ancestors(namespace.inheritance_tree(true).map {|ancestor| ancestor.path})
123
- end
124
-
125
- # Gets the class type being used to define states. Default is "Symbol".
126
- def state_type
127
- @state_type ||= machine.states.any? ? machine.states.map {|state| state.name}.compact.first.class.to_s : 'Symbol'
128
- end
129
-
130
- # Gets the class type being used to define events. Default is "Symbol".
131
- def event_type
132
- @event_type ||= machine.events.any? ? machine.events.first.name.class.to_s : 'Symbol'
133
- end
134
-
135
- # Defines auto-generated macro methods for the given machine
136
- def define_macro_methods
137
- return if inherited_machine
138
-
139
- # Human state name lookup
140
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, "human_#{machine.attribute(:name)}", :class))
141
- m.docstring = [
142
- "Gets the humanized name for the given state.",
143
- "@param [#{state_type}] state The state to look up",
144
- "@return [String] The human state name"
145
- ]
146
- m.parameters = ["state"]
147
-
148
- # Human event name lookup
149
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, "human_#{machine.attribute(:event_name)}", :class))
150
- m.docstring = [
151
- "Gets the humanized name for the given event.",
152
- "@param [#{event_type}] event The event to look up",
153
- "@return [String] The human event name"
154
- ]
155
- m.parameters = ["event"]
156
-
157
- # Only register attributes when the accessor isn't explicitly defined
158
- # by the class / superclass *and* isn't defined by inference from the
159
- # ORM being used
160
- unless integration || instance_attributes.include?(machine.attribute.to_sym)
161
- attribute = machine.attribute
162
- namespace.attributes[:instance][attribute] = {}
163
-
164
- # Machine attribute getter
165
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, attribute))
166
- namespace.attributes[:instance][attribute][:read] = m
167
- m.docstring = [
168
- "Gets the current attribute value for the machine",
169
- "@return The attribute value"
170
- ]
171
-
172
- # Machine attribute setter
173
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, "#{attribute}="))
174
- namespace.attributes[:instance][attribute][:write] = m
175
- m.docstring = [
176
- "Sets the current value for the machine",
177
- "@param new_#{attribute} The new value to set"
178
- ]
179
- m.parameters = ["new_#{attribute}"]
180
- end
181
-
182
- if integration && integration.defaults[:action] && !options.include?(:action) || options[:action]
183
- attribute = "#{machine.name}_event"
184
- namespace.attributes[:instance][attribute] = {}
185
-
186
- # Machine event attribute getter
187
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, attribute))
188
- namespace.attributes[:instance][attribute][:read] = m
189
- m.docstring = [
190
- "Gets the current event attribute value for the machine",
191
- "@return The event attribute value"
192
- ]
193
-
194
- # Machine event attribute setter
195
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, "#{attribute}="))
196
- namespace.attributes[:instance][attribute][:write] = m
197
- m.docstring = [
198
- "Sets the current value for the machine",
199
- "@param new_#{attribute} The new value to set"
200
- ]
201
- m.parameters = ["new_#{attribute}"]
202
- end
203
-
204
- # Presence query
205
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, "#{machine.name}?"))
206
- m.docstring = [
207
- "Checks the given state name against the current state.",
208
- "@param [#{state_type}] state_name The name of the state to check",
209
- "@return [Boolean] True if they are the same state, otherwise false",
210
- "@raise [IndexError] If the state name is invalid"
211
- ]
212
- m.parameters = ["state_name"]
213
-
214
- # Internal state name
215
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, machine.attribute(:name)))
216
- m.docstring = [
217
- "Gets the internal name of the state for the current value.",
218
- "@return [#{state_type}] The internal name of the state"
219
- ]
220
-
221
- # Human state name
222
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, "human_#{machine.attribute(:name)}"))
223
- m.docstring = [
224
- "Gets the human-readable name of the state for the current value.",
225
- "@return [String] The human-readable state name"
226
- ]
227
-
228
- # Available events
229
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, machine.attribute(:events)))
230
- m.docstring = [
231
- "Gets the list of events that can be fired on the current #{machine.name} (uses the *unqualified* event names)",
232
- "@param [Hash] requirements The transition requirements to test against",
233
- "@option requirements [#{state_type}] :from (the current state) One or more initial states",
234
- "@option requirements [#{state_type}] :to One or more target states",
235
- "@option requirements [#{event_type}] :on One or more events that fire the transition",
236
- "@option requirements [Boolean] :guard Whether to guard transitions with conditionals",
237
- "@return [Array<#{event_type}>] The list of event names"
238
- ]
239
- m.parameters = [["requirements", "{}"]]
240
-
241
- # Available transitions
242
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, machine.attribute(:transitions)))
243
- m.docstring = [
244
- "Gets the list of transitions that can be made for the current #{machine.name}",
245
- "@param [Hash] requirements The transition requirements to test against",
246
- "@option requirements [#{state_type}] :from (the current state) One or more initial states",
247
- "@option requirements [#{state_type}] :to One or more target states",
248
- "@option requirements [#{event_type}] :on One or more events that fire the transition",
249
- "@option requirements [Boolean] :guard Whether to guard transitions with conditionals",
250
- "@return [Array<EnumStateMachine::Transition>] The available transitions"
251
- ]
252
- m.parameters = [["requirements", "{}"]]
253
-
254
- # Available transition paths
255
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, machine.attribute(:paths)))
256
- m.docstring = [
257
- "Gets the list of sequences of transitions that can be run for the current #{machine.name}",
258
- "@param [Hash] requirements The transition requirements to test against",
259
- "@option requirements [#{state_type}] :from (the current state) The initial state",
260
- "@option requirements [#{state_type}] :to The target state",
261
- "@option requirements [Boolean] :deep Whether to enable deep searches for the target state",
262
- "@option requirements [Boolean] :guard Whether to guard transitions with conditionals",
263
- "@return [EnumStateMachine::PathCollection] The collection of paths"
264
- ]
265
- m.parameters = [["requirements", "{}"]]
266
-
267
- # Generic event fire
268
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, "fire_#{machine.attribute(:event)}"))
269
- m.docstring = [
270
- "Fires an arbitrary #{machine.name} event with the given argument list",
271
- "@param [#{event_type}] event The name of the event to fire",
272
- "@param args Optional arguments to include in the transition",
273
- "@return [Boolean] +true+ if the event succeeds, otherwise +false+"
274
- ]
275
- m.parameters = ["event", "*args"]
276
- end
277
-
278
- # Defines auto-generated event methods for the given machine
279
- def define_event_methods
280
- machine.events.each do |event|
281
- next if inherited_machine && inherited_machine.events[event.name]
282
-
283
- # Event query
284
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, "can_#{event.qualified_name}?"))
285
- m.docstring = [
286
- "Checks whether #{event.name.inspect} can be fired.",
287
- "@param [Hash] requirements The transition requirements to test against",
288
- "@option requirements [#{state_type}] :from (the current state) One or more initial states",
289
- "@option requirements [#{state_type}] :to One or more target states",
290
- "@option requirements [Boolean] :guard Whether to guard transitions with conditionals",
291
- "@return [Boolean] +true+ if #{event.name.inspect} can be fired, otherwise +false+"
292
- ]
293
- m.parameters = [["requirements", "{}"]]
294
-
295
- # Event transition
296
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, "#{event.qualified_name}_transition"))
297
- m.docstring = [
298
- "Gets the next transition that would be performed if #{event.name.inspect} were to be fired.",
299
- "@param [Hash] requirements The transition requirements to test against",
300
- "@option requirements [#{state_type}] :from (the current state) One or more initial states",
301
- "@option requirements [#{state_type}] :to One or more target states",
302
- "@option requirements [Boolean] :guard Whether to guard transitions with conditionals",
303
- "@return [EnumStateMachine::Transition] The transition that would be performed or +nil+"
304
- ]
305
- m.parameters = [["requirements", "{}"]]
306
-
307
- # Fire event
308
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, event.qualified_name))
309
- m.docstring = [
310
- "Fires the #{event.name.inspect} event.",
311
- "@param [Array] args Optional arguments to include in transition callbacks",
312
- "@return [Boolean] +true+ if the transition succeeds, otherwise +false+"
313
- ]
314
- m.parameters = ["*args"]
315
-
316
- # Fire event (raises exception)
317
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, "#{event.qualified_name}!"))
318
- m.docstring = [
319
- "Fires the #{event.name.inspect} event, raising an exception if it fails.",
320
- "@param [Array] args Optional arguments to include in transition callbacks",
321
- "@return [Boolean] +true+ if the transition succeeds",
322
- "@raise [EnumStateMachine::InvalidTransition] If the transition fails"
323
- ]
324
- m.parameters = ["*args"]
325
- end
326
- end
327
-
328
- # Defines auto-generated state methods for the given machine
329
- def define_state_methods
330
- machine.states.each do |state|
331
- next if inherited_machine && inherited_machine.states[state.name] || !state.name
332
-
333
- # State query
334
- register(m = ::YARD::CodeObjects::MethodObject.new(namespace, "#{state.qualified_name}?"))
335
- m.docstring = [
336
- "Checks whether #{state.name.inspect} is the current state.",
337
- "@return [Boolean] +true+ if this is the current state, otherwise +false+"
338
- ]
339
- end
340
- end
341
- end
342
- end
343
- end
344
- end