end_state 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|