statum 0.3.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8faf2ca3f2b51f152887aa12e747d8089b3aef9c
4
- data.tar.gz: b1312cb2bdf56cd71d32780faf14dc0699409327
3
+ metadata.gz: 3d044edb13c46dc2a4ece61532eb8268c6dfa91f
4
+ data.tar.gz: 3c51404c5dc3281442ed7f4a7be5a34d2fbb7f57
5
5
  SHA512:
6
- metadata.gz: f469b8e8ecad0b292ca837fdb4289d329b5b9dec87591ea8cfcb32c9f65f3eefb4baacaa423acb5734faec5a4fb04d1aa84da74525183336f7e7b5c2dc18301f
7
- data.tar.gz: bfe730ae1c8ad58cc939464139480278c06ac84f9b1379a23793cf8eed5ad4e7182053618ccac0f16730edd211b801d5e1536b455a3d68ffd78cf63f57fa88ee
6
+ metadata.gz: f8b8b6c598abfe37921b2edb85c1d55624d53074097ea8288b34d2a906c84c6c27369e624d98a4de598c1fadd18d9aa5af61aca9cfe594094242bb0961f0c8c7
7
+ data.tar.gz: 3a4f4e46b868a885e5138265d63a5d5ee5c8f0005e16bda19f2d815293c589f262a4c28f7c84f54b97fdc281f40bcc4604872000066b8122e0f55df2ab1df5c8
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  ![Build Status](https://travis-ci.org/nulldef/statum.svg?branch=master)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/nulldef/statum/badge.svg?branch=master)](https://coveralls.io/github/nulldef/statum?branch=master&v=1)
5
+ [![Gem Version](https://badge.fury.io/rb/statum.svg)](https://badge.fury.io/rb/statum)
5
6
 
6
7
  Finite state machine for your objects
7
8
 
@@ -1,16 +1,25 @@
1
1
  require "statum/version"
2
+ require "statum/class_methods"
3
+ require "statum/instance_methods"
2
4
  require "statum/machine"
3
5
  require "statum/hook"
4
6
  require "statum/event"
5
7
  require "statum/state_definer"
6
8
 
7
9
  module Statum
10
+ # Error for unknown event
8
11
  UnknownEventError = Class.new(ArgumentError)
12
+
13
+ # Error for wrong transition
9
14
  ErrorTransitionError = Class.new(StandardError)
15
+
16
+ # Error for duplicated state machine
10
17
  ExistingMachineError = Class.new(ArgumentError)
11
18
 
19
+ # Variable to store state machines
12
20
  STATE_MACHINES_VARIABLE = '@__statum_machines'.freeze
13
21
 
22
+ # Any state identifier
14
23
  ANY_STATE_NAME = :__statum_any_state
15
24
 
16
25
  class << self
@@ -19,61 +28,4 @@ module Statum
19
28
  base.include(Statum::InstanceMethods)
20
29
  end
21
30
  end
22
-
23
- module ClassMethods
24
- def statum(field, options = {}, &block)
25
- definer = Statum::StateDefiner.new(self, field, options)
26
- definer.instance_eval(&block) if block_given?
27
- add_machine(definer.state_machine)
28
- end
29
-
30
- def state_machines
31
- instance_variable_get(STATE_MACHINES_VARIABLE) || []
32
- end
33
-
34
- private
35
-
36
- def add_machine(machine)
37
- if state_machines.any? { |m| m.name == machine.name }
38
- raise ExistingMachineError, "State machine for #{machine.name} already exists"
39
- end
40
- instance_variable_set(STATE_MACHINES_VARIABLE, state_machines + [machine])
41
- end
42
- end
43
-
44
- module InstanceMethods
45
- def method_missing(meth, *args)
46
- if meth.to_s.end_with?('?') && (machine = find_machine_by_state(meth[0...-1]))
47
- machine.current(self) == meth[0...-1].to_sym
48
- elsif meth.to_s.end_with?('!') && (machine = find_machine_by_event(meth[0...-1]))
49
- machine.fire!(self, meth[0...-1])
50
- else
51
- super
52
- end
53
- end
54
-
55
- def respond_to_missing?(meth, *args)
56
- if meth.to_s.end_with?('?')
57
- !find_machine_by_state(meth[0...-1]).nil?
58
- elsif meth.to_s.end_with?('!')
59
- !find_machine_by_event(meth[0...-1]).nil?
60
- else
61
- super
62
- end
63
- end
64
-
65
- private
66
-
67
- def find_machine_by_event(name)
68
- state_machines.select { |machine| machine.event?(name) }.first
69
- end
70
-
71
- def find_machine_by_state(name)
72
- state_machines.select { |machine| machine.state?(name) }.first
73
- end
74
-
75
- def state_machines
76
- self.class.state_machines
77
- end
78
- end
79
31
  end
@@ -0,0 +1,35 @@
1
+ module Statum
2
+ module ClassMethods
3
+ # Define new state machine
4
+ #
5
+ # @param [Symbol] field Field to store state
6
+ # @param [Hash] options Options
7
+ # @option options [Symbol] initial Initial value
8
+ # @param [Block] block Bloc with DSL
9
+ def statum(field, options = {}, &block)
10
+ definer = Statum::StateDefiner.new(self, field, options)
11
+ definer.instance_eval(&block) if block_given?
12
+ add_machine(definer.state_machine)
13
+ end
14
+
15
+ # Returns defined state machines
16
+ #
17
+ # @return [Array<Statum::Machine>]
18
+ def state_machines
19
+ instance_variable_get(STATE_MACHINES_VARIABLE) || []
20
+ end
21
+
22
+ private
23
+
24
+ # Add new state machine
25
+ #
26
+ # @param [Statum::Machine] machine New state machine
27
+ # @raise Statum::ExistingMachineError
28
+ def add_machine(machine)
29
+ if state_machines.any? { |m| m.name == machine.name }
30
+ raise Statum::ExistingMachineError, "State machine for #{machine.name} already exists"
31
+ end
32
+ instance_variable_set(STATE_MACHINES_VARIABLE, state_machines + [machine])
33
+ end
34
+ end
35
+ end
@@ -3,18 +3,18 @@ module Statum
3
3
  #
4
4
  # @attr [Statum::Hook] before Before hook object
5
5
  # @attr [Statum::Hook] after After hook object
6
- # @attr [Symbol|Array] from From state name (or names)
6
+ # @attr [Symbol, Array] from From state name (or names)
7
7
  # @attr [Symbol] to To state name
8
8
  class Event
9
9
  attr_reader :from, :to, :before, :after
10
10
 
11
11
  # Creates an event class
12
12
  #
13
- # @param [String|Symbol|Array] from From state name
14
- # @param [String|Symbol] to To state name
13
+ # @param [Symbol, Array<Symbol>] from From state name
14
+ # @param [Symbol] to To state name
15
15
  # @param [Hash] options Options for event
16
16
  def initialize(from, to, options = {})
17
- @from = from.is_a?(Array) ? from : from.to_sym
17
+ @from = from.is_a?(Array) ? from.map(&:to_sym) : from.to_sym
18
18
  @to = to.to_sym
19
19
  @before = Statum::Hook.new(options.fetch(:before, nil))
20
20
  @after = Statum::Hook.new(options.fetch(:after, nil))
@@ -22,7 +22,7 @@ module Statum
22
22
 
23
23
  # Returns true if event can be fired from current state
24
24
  #
25
- # @param [String|Symbol] current_state Current state
25
+ # @param [Symbol] current_state Current state
26
26
  #
27
27
  # @return [Boolean]
28
28
  def can_fire?(current_state)
@@ -3,7 +3,7 @@ module Statum
3
3
  class Hook
4
4
  # Creates new Hook instance
5
5
  #
6
- # @param [Symbol|Proc|Lambda] hook Callable object or symbol that represents instance method
6
+ # @param [Symbol, Proc] hook Callable object or symbol that represents instance method
7
7
  def initialize(hook)
8
8
  @hook = hook
9
9
  end
@@ -23,6 +23,11 @@ module Statum
23
23
 
24
24
  private
25
25
 
26
+ # Finds hook on instance
27
+ #
28
+ # @param [Object] instance Instance of class that included Statum
29
+ #
30
+ # @return [Proc]
26
31
  def find_hook(instance)
27
32
  @hook.respond_to?(:call) ? @hook : instance.method(@hook)
28
33
  end
@@ -0,0 +1,37 @@
1
+ module Statum
2
+ module InstanceMethods
3
+ def method_missing(meth, *args)
4
+ if meth.to_s.end_with?('?') && (machine = find_machine_by_state(meth[0...-1]))
5
+ machine.current(self) == meth[0...-1].to_sym
6
+ elsif meth.to_s.end_with?('!') && (machine = find_machine_by_event(meth[0...-1]))
7
+ machine.fire!(self, meth[0...-1])
8
+ else
9
+ super
10
+ end
11
+ end
12
+
13
+ def respond_to_missing?(meth, *args)
14
+ if meth.to_s.end_with?('?')
15
+ !find_machine_by_state(meth[0...-1]).nil?
16
+ elsif meth.to_s.end_with?('!')
17
+ !find_machine_by_event(meth[0...-1]).nil?
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def find_machine_by_event(name)
26
+ state_machines.select { |machine| machine.event?(name) }.first
27
+ end
28
+
29
+ def find_machine_by_state(name)
30
+ state_machines.select { |machine| machine.state?(name) }.first
31
+ end
32
+
33
+ def state_machines
34
+ self.class.state_machines
35
+ end
36
+ end
37
+ end
@@ -1,5 +1,9 @@
1
1
  module Statum
2
2
  # Class for representing event machine
3
+ #
4
+ # @attr_reader [Hash] events Events
5
+ # @attr_reader [Array<Symbol>] states States
6
+ # @attr_reader [Symbol] field State field
3
7
  class Machine
4
8
  attr_reader :events, :states, :field
5
9
 
@@ -9,6 +13,10 @@ module Statum
9
13
  # Creates machine instance
10
14
  #
11
15
  # @param [Hash] options options hash
16
+ # @option options [Symbol] field Field to store state
17
+ # @option options [Symbol] initial Initial state
18
+ # @option options [Array<Symbol>] states States
19
+ # @option options [Hash] events Events
12
20
  def initialize(options)
13
21
  @field = options.delete(:field)
14
22
  @initial = options.delete(:initial)
@@ -18,7 +26,7 @@ module Statum
18
26
 
19
27
  # Checks if state present
20
28
  #
21
- # @param [String|Symbol] name state name
29
+ # @param [Symbol] name state name
22
30
  #
23
31
  # @return [Boolean]
24
32
  def state?(name)
@@ -27,7 +35,7 @@ module Statum
27
35
 
28
36
  # Checks if event present
29
37
  #
30
- # @param [String|Boolean] name event name
38
+ # @param [Symbol] name event name
31
39
  #
32
40
  # @return [Boolean]
33
41
  def event?(name)
@@ -37,7 +45,10 @@ module Statum
37
45
  # Execute an event
38
46
  #
39
47
  # @param [Object] instance Instance of class, that includes Statum
40
- # @param [String|Symbol] name Event name
48
+ # @param [Symbol] name Event name
49
+ #
50
+ # @raise Statum::UnknownEventError
51
+ # @raise Statum::ErrorTransitionError
41
52
  def fire!(instance, name)
42
53
  raise Statum::UnknownEventError, "Event #{name} not found" unless event?(name)
43
54
 
@@ -6,6 +6,7 @@ module Statum
6
6
  # @param [Class] klass Class that includes Statum
7
7
  # @param [String|Symbol] field Field that will be used for storing current state
8
8
  # @param [Hash] options Hash options
9
+ # @option options [Symbol] initial Initial value
9
10
  def initialize(klass, field, options)
10
11
  @klass = klass
11
12
  @field = field.to_sym
@@ -16,7 +17,7 @@ module Statum
16
17
  state(@initial) unless @initial.nil?
17
18
  end
18
19
 
19
- # Returns state maching
20
+ # Returns state machine
20
21
  #
21
22
  # @return [Statum::Machine]
22
23
  def state_machine
@@ -30,7 +31,7 @@ module Statum
30
31
 
31
32
  # Define a new state
32
33
  #
33
- # @param [String|Symbol] name State name
34
+ # @param [Symbol] name State name
34
35
  def state(name)
35
36
  @states << name.to_sym unless @states.include?(name.to_sym)
36
37
  end
@@ -1,3 +1,3 @@
1
1
  module Statum
2
- VERSION = "0.3.0".freeze
2
+ VERSION = "0.3.1".freeze
3
3
  end
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.bindir = "exe"
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
+ spec.required_ruby_version = ">= 2.0"
22
23
 
23
24
  spec.add_development_dependency "bundler", "~> 1.16"
24
25
  spec.add_development_dependency "coveralls", "~> 0.8"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Bespalov
@@ -99,8 +99,10 @@ files:
99
99
  - bin/console
100
100
  - bin/setup
101
101
  - lib/statum.rb
102
+ - lib/statum/class_methods.rb
102
103
  - lib/statum/event.rb
103
104
  - lib/statum/hook.rb
105
+ - lib/statum/instance_methods.rb
104
106
  - lib/statum/machine.rb
105
107
  - lib/statum/state_definer.rb
106
108
  - lib/statum/version.rb
@@ -117,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
117
119
  requirements:
118
120
  - - ">="
119
121
  - !ruby/object:Gem::Version
120
- version: '0'
122
+ version: '2.0'
121
123
  required_rubygems_version: !ruby/object:Gem::Requirement
122
124
  requirements:
123
125
  - - ">="