nanomachine 1.0.1 → 1.1.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/.travis.yml +10 -7
- data/CHANGES +4 -0
- data/README.md +2 -0
- data/lib/nanomachine.rb +30 -12
- data/lib/nanomachine/version.rb +1 -1
- data/nanomachine.gemspec +1 -1
- data/spec/nano_machine_spec.rb +26 -4
- data/spec/spec_helper.rb +10 -0
- metadata +25 -21
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8700d4a90a91dab6251130620aa30143dcca6a02
|
4
|
+
data.tar.gz: 146d5b6046e62314bfb7ce7c6ea2678d21204794
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 93d15ec3b077ccdd871d2f23d23ee6b935ea2d776183d6d53e7f956533c7c32d87f92f6230d3fb69212b80d1c9c831215ed570353378d9416bf4991b3cfde0e9
|
7
|
+
data.tar.gz: 5b8edab1a67ff0ed7421ecfa25d2dc71b10aa01cbd821ee5b0bf958b021232ec6e2d91a74301af897313db0812cf075a7fa88896cfc01ff1a64b8b136cd6ba4f
|
data/.travis.yml
CHANGED
data/CHANGES
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Nanomachine
|
2
2
|
|
3
|
+
[](http://travis-ci.org/elabs/nanomachine)
|
4
|
+
|
3
5
|
A really tiny state machine for ruby. No events, only accepted transitions and transition callbacks.
|
4
6
|
|
5
7
|
The difference between Nanomachine, and otherwise known Micromachine (https://rubygems.org/gems/micromachine) is that
|
data/lib/nanomachine.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "nanomachine/version"
|
2
2
|
require "set"
|
3
|
+
require "monitor"
|
3
4
|
|
4
5
|
# A minimal state machine where you transition between states, instead
|
5
6
|
# of transition by input symbols or events.
|
@@ -54,11 +55,7 @@ class Nanomachine
|
|
54
55
|
# @yield [self] yields the machine for easy definition of states
|
55
56
|
# @yieldparam [Nanomachine] self
|
56
57
|
def initialize(initial_state)
|
57
|
-
|
58
|
-
raise InvalidStateError, "initial state cannot be nil"
|
59
|
-
end
|
60
|
-
|
61
|
-
@state = initial_state.to_s
|
58
|
+
@state = to_state(initial_state)
|
62
59
|
@transitions = Hash.new(Set.new)
|
63
60
|
@callbacks = Hash.new { |h, k| h[k] = [] }
|
64
61
|
yield self if block_given?
|
@@ -85,7 +82,7 @@ class Nanomachine
|
|
85
82
|
# @param [#to_s] from
|
86
83
|
# @param [#each] to each target state must respond to #to_s
|
87
84
|
def transition(from, to)
|
88
|
-
transitions[from
|
85
|
+
transitions[to_state(from)] = Set.new(to).map! { |state| to_state(state) }
|
89
86
|
end
|
90
87
|
|
91
88
|
# Define a callback to be executed on transition.
|
@@ -125,10 +122,10 @@ class Nanomachine
|
|
125
122
|
end
|
126
123
|
|
127
124
|
from = options.delete(:from)
|
128
|
-
from &&= from
|
125
|
+
from &&= to_state(from)
|
129
126
|
|
130
127
|
to = options.delete(:to)
|
131
|
-
to &&= to
|
128
|
+
to &&= to_state(to)
|
132
129
|
|
133
130
|
unless options.empty?
|
134
131
|
raise ArgumentError, "unknown options: #{options.keys.join(", ")}"
|
@@ -151,12 +148,12 @@ class Nanomachine
|
|
151
148
|
# @param block passed to callbacks defined with {#on_transition}
|
152
149
|
# @return [String, false] state the machine was in before transition, or false if transition is not allowed
|
153
150
|
def transition_to(other_state, *args, &block)
|
154
|
-
|
155
|
-
|
151
|
+
if transition_to?(other_state)
|
152
|
+
other_state = to_state(other_state)
|
156
153
|
previous_state, @state = @state, other_state
|
157
|
-
[[nil, nil], [previous_state, nil], [nil,
|
154
|
+
[[nil, nil], [previous_state, nil], [nil, other_state], [previous_state, other_state]].each do |combo|
|
158
155
|
@callbacks[combo].each do |callback|
|
159
|
-
callback.call([previous_state,
|
156
|
+
callback.call([previous_state, other_state], *args, &block)
|
160
157
|
end
|
161
158
|
end
|
162
159
|
previous_state
|
@@ -180,4 +177,25 @@ class Nanomachine
|
|
180
177
|
raise InvalidTransitionError, "cannot transition from #{state.inspect} to #{other_state.inspect}"
|
181
178
|
end
|
182
179
|
end
|
180
|
+
|
181
|
+
# Query to see if it's possible to transition to the given state.
|
182
|
+
#
|
183
|
+
# @example
|
184
|
+
# fsm.transition_to?("state") # => true
|
185
|
+
#
|
186
|
+
# @param (see #transition_to)
|
187
|
+
# @return [Boolean]
|
188
|
+
def transition_to?(other_state)
|
189
|
+
transitions[state].include?(to_state(other_state))
|
190
|
+
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
def to_state(state)
|
195
|
+
if state.nil?
|
196
|
+
raise InvalidStateError, "state cannot be nil"
|
197
|
+
else
|
198
|
+
state.to_s
|
199
|
+
end
|
200
|
+
end
|
183
201
|
end
|
data/lib/nanomachine/version.rb
CHANGED
data/nanomachine.gemspec
CHANGED
data/spec/nano_machine_spec.rb
CHANGED
@@ -39,7 +39,7 @@ describe "Nanomachine state machine" do
|
|
39
39
|
|
40
40
|
describe "#initialize" do
|
41
41
|
it "raises an error if given an invalid initial state" do
|
42
|
-
expect { Nanomachine.new(nil) }.to raise_error(Nanomachine::InvalidStateError
|
42
|
+
expect { Nanomachine.new(nil) }.to raise_error(Nanomachine::InvalidStateError)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -76,7 +76,7 @@ describe "Nanomachine state machine" do
|
|
76
76
|
|
77
77
|
it "does not transition when the transition is undefined" do
|
78
78
|
fsm.transition_to("X")
|
79
|
-
expect { fsm.transition_to("A").should
|
79
|
+
expect { fsm.transition_to("A").should be_falsy }.to_not change { fsm.state }
|
80
80
|
end
|
81
81
|
|
82
82
|
it "returns the previous state" do
|
@@ -84,7 +84,11 @@ describe "Nanomachine state machine" do
|
|
84
84
|
end
|
85
85
|
|
86
86
|
it "returns false if transition failed" do
|
87
|
-
fsm.transition_to("D").should
|
87
|
+
fsm.transition_to("D").should be_falsy
|
88
|
+
end
|
89
|
+
|
90
|
+
it "raises a type error if state is nil" do
|
91
|
+
expect { fsm.transition_to(nil) }.to raise_error(Nanomachine::InvalidStateError)
|
88
92
|
end
|
89
93
|
|
90
94
|
context "callbacks" do
|
@@ -144,7 +148,7 @@ describe "Nanomachine state machine" do
|
|
144
148
|
end
|
145
149
|
|
146
150
|
it "executes no callbacks on failed transitions" do
|
147
|
-
fsm.transition_to("D").should
|
151
|
+
fsm.transition_to("D").should be_falsy
|
148
152
|
@callbacks.should be_empty
|
149
153
|
end
|
150
154
|
end
|
@@ -159,5 +163,23 @@ describe "Nanomachine state machine" do
|
|
159
163
|
it "returns the previous state on success" do
|
160
164
|
fsm.transition_to!("B").should eq "A"
|
161
165
|
end
|
166
|
+
|
167
|
+
it "raises a type error if state is nil" do
|
168
|
+
expect { fsm.transition_to!(nil) }.to raise_error(Nanomachine::InvalidStateError)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "#transition_to?" do
|
173
|
+
it "returns false if it cannot transition to the given state" do
|
174
|
+
fsm.transition_to?("D").should be_falsy
|
175
|
+
end
|
176
|
+
|
177
|
+
it "returns true if it can transition to the given state" do
|
178
|
+
fsm.transition_to?("B").should be_truthy
|
179
|
+
end
|
180
|
+
|
181
|
+
it "raises a type error if state is nil" do
|
182
|
+
expect { fsm.transition_to?(nil) }.to raise_error(Nanomachine::InvalidStateError)
|
183
|
+
end
|
162
184
|
end
|
163
185
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nanomachine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
5
|
-
prerelease:
|
4
|
+
version: 1.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Ivan Navarrete
|
@@ -10,30 +9,36 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2015-10-28 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: rake
|
17
|
-
requirement:
|
18
|
-
none: false
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
19
17
|
requirements:
|
20
|
-
- -
|
18
|
+
- - ">="
|
21
19
|
- !ruby/object:Gem::Version
|
22
20
|
version: '0'
|
23
21
|
type: :development
|
24
22
|
prerelease: false
|
25
|
-
version_requirements:
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
26
28
|
- !ruby/object:Gem::Dependency
|
27
29
|
name: rspec
|
28
|
-
requirement:
|
29
|
-
none: false
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
|
-
- - ~>
|
32
|
+
- - "~>"
|
32
33
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
34
|
+
version: '3.0'
|
34
35
|
type: :development
|
35
36
|
prerelease: false
|
36
|
-
version_requirements:
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '3.0'
|
37
42
|
description:
|
38
43
|
email:
|
39
44
|
- crzivn@gmail.com
|
@@ -42,9 +47,9 @@ executables: []
|
|
42
47
|
extensions: []
|
43
48
|
extra_rdoc_files: []
|
44
49
|
files:
|
45
|
-
- .gitignore
|
46
|
-
- .rspec
|
47
|
-
- .travis.yml
|
50
|
+
- ".gitignore"
|
51
|
+
- ".rspec"
|
52
|
+
- ".travis.yml"
|
48
53
|
- CHANGES
|
49
54
|
- Gemfile
|
50
55
|
- README.md
|
@@ -57,27 +62,26 @@ files:
|
|
57
62
|
homepage: https://github.com/elabs/nanomachine
|
58
63
|
licenses:
|
59
64
|
- MIT License
|
65
|
+
metadata: {}
|
60
66
|
post_install_message:
|
61
67
|
rdoc_options: []
|
62
68
|
require_paths:
|
63
69
|
- lib
|
64
70
|
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
71
|
requirements:
|
67
|
-
- -
|
72
|
+
- - ">="
|
68
73
|
- !ruby/object:Gem::Version
|
69
74
|
version: '0'
|
70
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
-
none: false
|
72
76
|
requirements:
|
73
|
-
- -
|
77
|
+
- - ">="
|
74
78
|
- !ruby/object:Gem::Version
|
75
79
|
version: '0'
|
76
80
|
requirements: []
|
77
81
|
rubyforge_project:
|
78
|
-
rubygems_version:
|
82
|
+
rubygems_version: 2.4.5.1
|
79
83
|
signing_key:
|
80
|
-
specification_version:
|
84
|
+
specification_version: 4
|
81
85
|
summary: A really tiny state machine for ruby. No events, only acceptable transitions
|
82
86
|
and transition callbacks.
|
83
87
|
test_files:
|