end_state 0.1.0 → 0.2.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 +4 -4
- data/Gemfile +1 -0
- data/README.md +18 -2
- data/Rakefile +8 -0
- data/lib/end_state/finalizer.rb +1 -0
- data/lib/end_state/graph.rb +21 -0
- data/lib/end_state/guard.rb +1 -0
- data/lib/end_state/messages.rb +11 -0
- data/lib/end_state/state_machine.rb +2 -1
- data/lib/end_state/version.rb +1 -1
- data/lib/end_state.rb +6 -0
- data/lib/tasks/end_state.rake +14 -0
- data/spec/end_state/finalizer_spec.rb +28 -0
- data/spec/end_state/guard_spec.rb +28 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04263dcaee90aaa630e9e16fd1648a71717b5c49
|
4
|
+
data.tar.gz: 1e5cba77cd2f71faa5792ba9374f7c14c941dda9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9e25308af4b71252f6e3709949077ffe7dee67312aea2eff0e310848b8f1215c2fa84f6259901ceee0a0560ee6e5dd6b6064c81720c87fc19cb1ce5a9962dd2
|
7
|
+
data.tar.gz: 4d9db32fc84ae115f6f6ae02e0a901f1f366351bc6291ae6c535f5633b12347fab002fb67322f627bb152f8084ff4c1e7adf773221fd4150b2f0fd01b5a7f979
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -77,7 +77,12 @@ These will only be called during the check performed during the transition and w
|
|
77
77
|
These hooks can be useful for things like logging.
|
78
78
|
|
79
79
|
The wrapped object has an array `failure_messages` available for tracking reasons for invalid transitions. You may shovel
|
80
|
-
a reason (string) into this if you want to provide information on why your guard failed.
|
80
|
+
a reason (string) into this if you want to provide information on why your guard failed. You can also use the helper method in
|
81
|
+
the `Guard` class called `add_error` which takes a string.
|
82
|
+
|
83
|
+
The wrapped object has an array `success_messages` available for tracking reasons for valid transitions. You may shovel
|
84
|
+
a reason (string) into this if you want to provide information on why your guard passed. You can also use the helper method in
|
85
|
+
the `Guard` class called `add_success` which takes a string.
|
81
86
|
|
82
87
|
```ruby
|
83
88
|
class EasyGuard < EndState::Guard
|
@@ -121,7 +126,12 @@ set up a little differently and you have access to:
|
|
121
126
|
* `params` - A hash of params passed when calling transition on the machine.
|
122
127
|
|
123
128
|
The wrapped object has an array `failure_messages` available for tracking reasons for invalid transitions. You may shovel
|
124
|
-
a reason (string) into this if you want to provide information on why your finalizer failed.
|
129
|
+
a reason (string) into this if you want to provide information on why your finalizer failed. You can also use the helper method in
|
130
|
+
the `Finalizer` class called `add_error` which takes a string.
|
131
|
+
|
132
|
+
The wrapped object has an array `success_messages` available for tracking reasons for valid transitions. You may shovel
|
133
|
+
a reason (string) into this if you want to provide information on why your finalizer succeeded. You can also use the helper method in
|
134
|
+
the `Finalizer` class called `add_success` which takes a string.
|
125
135
|
|
126
136
|
```ruby
|
127
137
|
class WrapUp < EndState::Finalizer
|
@@ -195,6 +205,12 @@ transition to the new state.
|
|
195
205
|
You also have the option to use `transition!` which will instead raise an error for failures. If your guards and/or finalizers
|
196
206
|
add to the `failure_messages` array then they will be included in the error message.
|
197
207
|
|
208
|
+
## Graphing
|
209
|
+
|
210
|
+
If you install `GraphViz` and the gem `ruby-graphviz` you can create images representing your state machines.
|
211
|
+
|
212
|
+
`EndState::Graph.new(MyMachine).draw.output png: 'my_machine.png'`
|
213
|
+
|
198
214
|
## Testing
|
199
215
|
|
200
216
|
Included is a custom RSpec matcher for testing your machines.
|
data/Rakefile
CHANGED
data/lib/end_state/finalizer.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
module EndState
|
2
|
+
class Graph < GraphViz
|
3
|
+
attr_reader :machine, :nodes
|
4
|
+
|
5
|
+
def initialize(machine)
|
6
|
+
@machine = machine
|
7
|
+
@nodes = {}
|
8
|
+
super machine.name.to_sym
|
9
|
+
end
|
10
|
+
|
11
|
+
def draw
|
12
|
+
machine.transitions.keys.each do |t|
|
13
|
+
left, right = t.to_a.flatten
|
14
|
+
nodes[left] ||= add_node(left.to_s)
|
15
|
+
nodes[right] ||= add_node(right.to_s)
|
16
|
+
add_edge nodes[left], nodes[right]
|
17
|
+
end
|
18
|
+
self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/end_state/guard.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module EndState
|
2
2
|
class StateMachine < SimpleDelegator
|
3
|
-
attr_accessor :failure_messages
|
3
|
+
attr_accessor :failure_messages, :success_messages
|
4
4
|
|
5
5
|
def self.transition(state_map)
|
6
6
|
initial_states = Array(state_map.keys.first)
|
@@ -59,6 +59,7 @@ module EndState
|
|
59
59
|
|
60
60
|
def transition(state, params = {}, mode = :soft)
|
61
61
|
@failure_messages = []
|
62
|
+
@success_messages = []
|
62
63
|
previous_state = self.state
|
63
64
|
transition = self.class.transitions[{ previous_state => state }]
|
64
65
|
return block_transistion(transition, state, mode) unless transition
|
data/lib/end_state/version.rb
CHANGED
data/lib/end_state.rb
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
require 'delegate'
|
2
2
|
require 'end_state/version'
|
3
3
|
require 'end_state/errors'
|
4
|
+
require 'end_state/messages'
|
4
5
|
require 'end_state/guard'
|
5
6
|
require 'end_state/finalizer'
|
6
7
|
require 'end_state/finalizers'
|
7
8
|
require 'end_state/transition'
|
8
9
|
require 'end_state/action'
|
9
10
|
require 'end_state/state_machine'
|
11
|
+
begin
|
12
|
+
require 'graphviz'
|
13
|
+
require 'end_state/graph'
|
14
|
+
rescue LoadError
|
15
|
+
end
|
10
16
|
|
11
17
|
module EndState
|
12
18
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
namespace :end_state do
|
2
|
+
desc 'Draw the statemachine using GraphViz (options: machine=MyMachine, format=png, output=machine.png'
|
3
|
+
task :draw do
|
4
|
+
options = {}
|
5
|
+
options[:machine] = ENV['machine']
|
6
|
+
options[:format] = ENV['format'] || :png
|
7
|
+
options[:output] = ENV['output'] || "#{options[:machine].to_s}.#{options[:format].to_s}"
|
8
|
+
if options[:machine]
|
9
|
+
EndState::Graph.new(Object.const_get(options[:machine])).draw.output options[:format] => options[:output]
|
10
|
+
else
|
11
|
+
puts 'A machine is required'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module EndState
|
4
|
+
describe Finalizer do
|
5
|
+
subject(:finalizer) { Finalizer.new(object, state, params) }
|
6
|
+
let(:object) { Struct.new('Machine', :failure_messages, :success_messages, :state).new }
|
7
|
+
let(:state) { :a }
|
8
|
+
let(:params) { {} }
|
9
|
+
before do
|
10
|
+
object.failure_messages = []
|
11
|
+
object.success_messages = []
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#add_error' do
|
15
|
+
it 'adds an error' do
|
16
|
+
finalizer.add_error('error')
|
17
|
+
expect(object.failure_messages).to eq ['error']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#add_success' do
|
22
|
+
it 'adds an success' do
|
23
|
+
finalizer.add_error('success')
|
24
|
+
expect(object.failure_messages).to eq ['success']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module EndState
|
4
|
+
describe Guard do
|
5
|
+
subject(:guard) { Guard.new(object, state, params) }
|
6
|
+
let(:object) { Struct.new('Machine', :failure_messages, :success_messages, :state).new }
|
7
|
+
let(:state) { :a }
|
8
|
+
let(:params) { {} }
|
9
|
+
before do
|
10
|
+
object.failure_messages = []
|
11
|
+
object.success_messages = []
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#add_error' do
|
15
|
+
it 'adds an error' do
|
16
|
+
guard.add_error('error')
|
17
|
+
expect(object.failure_messages).to eq ['error']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#add_success' do
|
22
|
+
it 'adds an success' do
|
23
|
+
guard.add_error('success')
|
24
|
+
expect(object.failure_messages).to eq ['success']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: end_state
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- alexpeachey
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -91,13 +91,18 @@ files:
|
|
91
91
|
- lib/end_state/finalizer.rb
|
92
92
|
- lib/end_state/finalizers.rb
|
93
93
|
- lib/end_state/finalizers/persistence.rb
|
94
|
+
- lib/end_state/graph.rb
|
94
95
|
- lib/end_state/guard.rb
|
96
|
+
- lib/end_state/messages.rb
|
95
97
|
- lib/end_state/state_machine.rb
|
96
98
|
- lib/end_state/transition.rb
|
97
99
|
- lib/end_state/version.rb
|
98
100
|
- lib/end_state_matchers.rb
|
101
|
+
- lib/tasks/end_state.rake
|
99
102
|
- spec/end_state/action_spec.rb
|
103
|
+
- spec/end_state/finalizer_spec.rb
|
100
104
|
- spec/end_state/finalizers/persistence_spec.rb
|
105
|
+
- spec/end_state/guard_spec.rb
|
101
106
|
- spec/end_state/state_machine_spec.rb
|
102
107
|
- spec/end_state/transition_spec.rb
|
103
108
|
- spec/end_state_spec.rb
|
@@ -128,7 +133,9 @@ specification_version: 4
|
|
128
133
|
summary: A State Machine implementation
|
129
134
|
test_files:
|
130
135
|
- spec/end_state/action_spec.rb
|
136
|
+
- spec/end_state/finalizer_spec.rb
|
131
137
|
- spec/end_state/finalizers/persistence_spec.rb
|
138
|
+
- spec/end_state/guard_spec.rb
|
132
139
|
- spec/end_state/state_machine_spec.rb
|
133
140
|
- spec/end_state/transition_spec.rb
|
134
141
|
- spec/end_state_spec.rb
|