statum 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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
  - - ">="