finite_machine 0.8.1 → 0.9.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/CHANGELOG.md +11 -0
- data/Gemfile +1 -1
- data/README.md +150 -35
- data/lib/finite_machine.rb +1 -0
- data/lib/finite_machine/catchable.rb +1 -1
- data/lib/finite_machine/definition.rb +61 -0
- data/lib/finite_machine/dsl.rb +45 -10
- data/lib/finite_machine/event.rb +17 -1
- data/lib/finite_machine/hook_event.rb +66 -7
- data/lib/finite_machine/observer.rb +3 -3
- data/lib/finite_machine/state_machine.rb +36 -28
- data/lib/finite_machine/version.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/unit/async_events_spec.rb +1 -1
- data/spec/unit/callbacks_spec.rb +23 -23
- data/spec/unit/can_spec.rb +22 -22
- data/spec/unit/event/eql_spec.rb +37 -0
- data/spec/unit/event/initialize_spec.rb +38 -0
- data/spec/unit/event/inspect_spec.rb +1 -1
- data/spec/unit/event_queue_spec.rb +2 -2
- data/spec/unit/events_chain/check_choice_conditions_spec.rb +2 -2
- data/spec/unit/events_chain/clear_spec.rb +1 -1
- data/spec/unit/events_chain/insert_spec.rb +1 -1
- data/spec/unit/events_spec.rb +17 -20
- data/spec/unit/hook_event/eql_spec.rb +37 -0
- data/spec/unit/hook_event/initialize_spec.rb +22 -0
- data/spec/unit/if_unless_spec.rb +6 -6
- data/spec/unit/initialize_spec.rb +6 -6
- data/spec/unit/is_spec.rb +12 -12
- data/spec/unit/logger_spec.rb +1 -1
- data/spec/unit/respond_to_spec.rb +2 -2
- data/spec/unit/standalone_spec.rb +72 -0
- data/spec/unit/subscribers_spec.rb +2 -2
- data/spec/unit/target_spec.rb +59 -10
- data/spec/unit/{finished_spec.rb → terminated_spec.rb} +38 -8
- metadata +15 -4
data/spec/unit/is_spec.rb
CHANGED
@@ -18,17 +18,17 @@ describe FiniteMachine, 'is?' do
|
|
18
18
|
|
19
19
|
expect(fsm.current).to eql(:green)
|
20
20
|
|
21
|
-
expect(fsm.is?(:green)).to
|
22
|
-
expect(fsm.is?(:yellow)).to
|
23
|
-
expect(fsm.is?([:green, :red])).to
|
24
|
-
expect(fsm.is?([:yellow, :red])).to
|
21
|
+
expect(fsm.is?(:green)).to be true
|
22
|
+
expect(fsm.is?(:yellow)).to be false
|
23
|
+
expect(fsm.is?([:green, :red])).to be true
|
24
|
+
expect(fsm.is?([:yellow, :red])).to be false
|
25
25
|
|
26
26
|
fsm.slow
|
27
27
|
|
28
|
-
expect(fsm.is?(:green)).to
|
29
|
-
expect(fsm.is?(:yellow)).to
|
30
|
-
expect(fsm.is?([:green, :red])).to
|
31
|
-
expect(fsm.is?([:yellow, :red])).to
|
28
|
+
expect(fsm.is?(:green)).to be false
|
29
|
+
expect(fsm.is?(:yellow)).to be true
|
30
|
+
expect(fsm.is?([:green, :red])).to be false
|
31
|
+
expect(fsm.is?([:yellow, :red])).to be true
|
32
32
|
end
|
33
33
|
|
34
34
|
it "defines helper methods to check current state" do
|
@@ -44,12 +44,12 @@ describe FiniteMachine, 'is?' do
|
|
44
44
|
end
|
45
45
|
expect(fsm.current).to eql(:green)
|
46
46
|
|
47
|
-
expect(fsm.green?).to
|
48
|
-
expect(fsm.yellow?).to
|
47
|
+
expect(fsm.green?).to be true
|
48
|
+
expect(fsm.yellow?).to be false
|
49
49
|
|
50
50
|
fsm.slow
|
51
51
|
|
52
|
-
expect(fsm.green?).to
|
53
|
-
expect(fsm.yellow?).to
|
52
|
+
expect(fsm.green?).to be false
|
53
|
+
expect(fsm.yellow?).to be true
|
54
54
|
end
|
55
55
|
end
|
data/spec/unit/logger_spec.rb
CHANGED
@@ -9,7 +9,7 @@ describe FiniteMachine::Logger do
|
|
9
9
|
|
10
10
|
subject(:logger) { described_class }
|
11
11
|
|
12
|
-
before { FiniteMachine.
|
12
|
+
before { allow(FiniteMachine).to receive(:logger) { log } }
|
13
13
|
|
14
14
|
it "debugs message call" do
|
15
15
|
expect(log).to receive(:debug).with(message)
|
@@ -31,7 +31,7 @@ describe FiniteMachine, '#respond_to' do
|
|
31
31
|
expect(fsm).to respond_to(:on_enter_slow)
|
32
32
|
end
|
33
33
|
|
34
|
-
it "
|
35
|
-
expect(fsm).
|
34
|
+
it "doesn't know about target class methods" do
|
35
|
+
expect(fsm).not_to respond_to(:engine_on?)
|
36
36
|
end
|
37
37
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe FiniteMachine::Definition, 'definition' do
|
6
|
+
|
7
|
+
before do
|
8
|
+
class Engine < FiniteMachine::Definition
|
9
|
+
initial :neutral
|
10
|
+
|
11
|
+
events {
|
12
|
+
event :forward, [:reverse, :neutral] => :one
|
13
|
+
event :shift, :one => :two
|
14
|
+
event :shift, :two => :one
|
15
|
+
event :back, [:neutral, :one] => :reverse
|
16
|
+
}
|
17
|
+
|
18
|
+
callbacks {
|
19
|
+
on_enter :reverse do |event|
|
20
|
+
target.turn_reverse_lights_on
|
21
|
+
end
|
22
|
+
|
23
|
+
on_exit :reverse do |event|
|
24
|
+
target.turn_reverse_lights_off
|
25
|
+
end
|
26
|
+
}
|
27
|
+
|
28
|
+
handlers {
|
29
|
+
handle FiniteMachine::InvalidStateError do |exception| end
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "creates unique instances" do
|
35
|
+
engine_a = Engine.new
|
36
|
+
engine_b = Engine.new
|
37
|
+
expect(engine_a).not_to be(engine_b)
|
38
|
+
|
39
|
+
engine_a.forward
|
40
|
+
expect(engine_a.current).to eq(:one)
|
41
|
+
expect(engine_b.current).to eq(:neutral)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "allows to create standalone machine" do
|
45
|
+
Car = Class.new do
|
46
|
+
def turn_reverse_lights_off
|
47
|
+
@reverse_lights = false
|
48
|
+
end
|
49
|
+
|
50
|
+
def turn_reverse_lights_on
|
51
|
+
@reverse_lights = true
|
52
|
+
end
|
53
|
+
|
54
|
+
def reverse_lights?
|
55
|
+
@reverse_lights ||= false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
car = Car.new
|
60
|
+
engine = Engine.new
|
61
|
+
engine.target car
|
62
|
+
expect(engine.current).to eq(:neutral)
|
63
|
+
|
64
|
+
engine.forward
|
65
|
+
expect(engine.current).to eq(:one)
|
66
|
+
expect(car.reverse_lights?).to be false
|
67
|
+
|
68
|
+
engine.back
|
69
|
+
expect(engine.current).to eq(:reverse)
|
70
|
+
expect(car.reverse_lights?).to be true
|
71
|
+
end
|
72
|
+
end
|
@@ -12,7 +12,7 @@ describe FiniteMachine::Subscribers do
|
|
12
12
|
before { subscribers.subscribe(listener) }
|
13
13
|
|
14
14
|
it "checks if any subscribers exist" do
|
15
|
-
expect(subscribers.empty?).to
|
15
|
+
expect(subscribers.empty?).to be(false)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "returns index for the subscriber" do
|
@@ -26,6 +26,6 @@ describe FiniteMachine::Subscribers do
|
|
26
26
|
|
27
27
|
it "resets the subscribers" do
|
28
28
|
subscribers.reset
|
29
|
-
expect(subscribers.empty?).to
|
29
|
+
expect(subscribers.empty?).to be(true)
|
30
30
|
end
|
31
31
|
end
|
data/spec/unit/target_spec.rb
CHANGED
@@ -16,6 +16,10 @@ describe FiniteMachine, '#target' do
|
|
16
16
|
@reverse_lights = true
|
17
17
|
end
|
18
18
|
|
19
|
+
def reverse_lights?
|
20
|
+
@reverse_lights ||= false
|
21
|
+
end
|
22
|
+
|
19
23
|
def engine
|
20
24
|
context = self
|
21
25
|
@engine ||= FiniteMachine.define do
|
@@ -32,25 +36,25 @@ describe FiniteMachine, '#target' do
|
|
32
36
|
|
33
37
|
callbacks {
|
34
38
|
on_enter :reverse do |event|
|
35
|
-
turn_reverse_lights_on
|
39
|
+
target.turn_reverse_lights_on
|
36
40
|
end
|
37
41
|
|
38
42
|
on_exit :reverse do |event|
|
39
|
-
turn_reverse_lights_off
|
43
|
+
target.turn_reverse_lights_off
|
40
44
|
end
|
41
45
|
}
|
42
46
|
end
|
43
47
|
end
|
44
48
|
end
|
45
49
|
car = Car.new
|
46
|
-
expect(car.reverse_lights).to
|
50
|
+
expect(car.reverse_lights?).to be(false)
|
47
51
|
expect(car.engine.current).to eql(:neutral)
|
48
52
|
car.engine.back
|
49
53
|
expect(car.engine.current).to eql(:reverse)
|
50
|
-
expect(car.reverse_lights).to
|
54
|
+
expect(car.reverse_lights?).to be(true)
|
51
55
|
car.engine.forward
|
52
56
|
expect(car.engine.current).to eql(:one)
|
53
|
-
expect(car.reverse_lights).to
|
57
|
+
expect(car.reverse_lights?).to be(false)
|
54
58
|
end
|
55
59
|
|
56
60
|
it "propagates method call" do
|
@@ -112,6 +116,10 @@ describe FiniteMachine, '#target' do
|
|
112
116
|
@reverse_lights = true
|
113
117
|
end
|
114
118
|
|
119
|
+
def reverse_lights?
|
120
|
+
@reverse_lights ||= false
|
121
|
+
end
|
122
|
+
|
115
123
|
def engine
|
116
124
|
self.called ||= []
|
117
125
|
context ||= self
|
@@ -129,12 +137,12 @@ describe FiniteMachine, '#target' do
|
|
129
137
|
|
130
138
|
callbacks {
|
131
139
|
on_enter :reverse do |event|
|
132
|
-
called << 'on_enter_reverse'
|
133
|
-
turn_reverse_lights_on
|
140
|
+
target.called << 'on_enter_reverse'
|
141
|
+
target.turn_reverse_lights_on
|
134
142
|
forward('Piotr!')
|
135
143
|
end
|
136
144
|
on_before :forward do |event, name|
|
137
|
-
called << "on_enter_forward with #{name}"
|
145
|
+
target.called << "on_enter_forward with #{name}"
|
138
146
|
end
|
139
147
|
}
|
140
148
|
end
|
@@ -142,7 +150,7 @@ describe FiniteMachine, '#target' do
|
|
142
150
|
end
|
143
151
|
|
144
152
|
car = Car.new
|
145
|
-
expect(car.reverse_lights).to
|
153
|
+
expect(car.reverse_lights?).to be(false)
|
146
154
|
expect(car.engine.current).to eql(:neutral)
|
147
155
|
car.engine.back
|
148
156
|
expect(car.engine.current).to eql(:one)
|
@@ -158,7 +166,7 @@ describe FiniteMachine, '#target' do
|
|
158
166
|
fsm = FiniteMachine.define do
|
159
167
|
initial :green
|
160
168
|
|
161
|
-
target
|
169
|
+
target context
|
162
170
|
|
163
171
|
events {
|
164
172
|
event :slow, :green => :yellow
|
@@ -174,4 +182,45 @@ describe FiniteMachine, '#target' do
|
|
174
182
|
fsm.slow
|
175
183
|
expect(called).to eq(context)
|
176
184
|
end
|
185
|
+
|
186
|
+
it "allows to differentiate between same named methods" do
|
187
|
+
called = []
|
188
|
+
Car = Class.new do
|
189
|
+
def initialize(called)
|
190
|
+
@called = called
|
191
|
+
end
|
192
|
+
def save
|
193
|
+
@called << 'car save called'
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
car = Car.new(called)
|
198
|
+
fsm = FiniteMachine.define do
|
199
|
+
initial :unsaved
|
200
|
+
|
201
|
+
target car
|
202
|
+
|
203
|
+
events {
|
204
|
+
event :validate, :unsaved => :valid
|
205
|
+
event :save, :valid => :saved
|
206
|
+
}
|
207
|
+
|
208
|
+
callbacks {
|
209
|
+
on_enter :valid do |event|
|
210
|
+
target.save
|
211
|
+
save
|
212
|
+
end
|
213
|
+
on_after :save do |event|
|
214
|
+
called << 'event save called'
|
215
|
+
end
|
216
|
+
}
|
217
|
+
end
|
218
|
+
expect(fsm.current).to eql(:unsaved)
|
219
|
+
fsm.validate
|
220
|
+
expect(fsm.current).to eql(:saved)
|
221
|
+
expect(called).to eq([
|
222
|
+
'car save called',
|
223
|
+
'event save called'
|
224
|
+
])
|
225
|
+
end
|
177
226
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe FiniteMachine, '
|
5
|
+
describe FiniteMachine, 'terminated?' do
|
6
6
|
|
7
7
|
it "allows to specify terminal state" do
|
8
8
|
fsm = FiniteMachine.define do
|
@@ -16,15 +16,15 @@ describe FiniteMachine, 'finished?' do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
expect(fsm.current).to eql(:green)
|
19
|
-
expect(fsm.
|
19
|
+
expect(fsm.terminated?).to be(false)
|
20
20
|
|
21
21
|
fsm.slow
|
22
22
|
expect(fsm.current).to eql(:yellow)
|
23
|
-
expect(fsm.
|
23
|
+
expect(fsm.terminated?).to be(false)
|
24
24
|
|
25
25
|
fsm.stop
|
26
26
|
expect(fsm.current).to eql(:red)
|
27
|
-
expect(fsm.
|
27
|
+
expect(fsm.terminated?).to be(true)
|
28
28
|
end
|
29
29
|
|
30
30
|
it "allows to specify terminal state as parameter" do
|
@@ -38,7 +38,7 @@ describe FiniteMachine, 'finished?' do
|
|
38
38
|
end
|
39
39
|
fsm.slow
|
40
40
|
fsm.stop
|
41
|
-
expect(fsm.
|
41
|
+
expect(fsm.terminated?).to be(true)
|
42
42
|
end
|
43
43
|
|
44
44
|
it "checks without terminal state" do
|
@@ -52,14 +52,44 @@ describe FiniteMachine, 'finished?' do
|
|
52
52
|
end
|
53
53
|
|
54
54
|
expect(fsm.current).to eql(:green)
|
55
|
-
expect(fsm.
|
55
|
+
expect(fsm.terminated?).to be(false)
|
56
56
|
|
57
57
|
fsm.slow
|
58
58
|
expect(fsm.current).to eql(:yellow)
|
59
|
-
expect(fsm.
|
59
|
+
expect(fsm.terminated?).to be(false)
|
60
60
|
|
61
61
|
fsm.stop
|
62
62
|
expect(fsm.current).to eql(:red)
|
63
|
-
expect(fsm.
|
63
|
+
expect(fsm.terminated?).to be(false)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "allows for multiple terminal states" do
|
67
|
+
fsm = FiniteMachine.define do
|
68
|
+
initial :open
|
69
|
+
|
70
|
+
terminal :close, :canceled, :faulty
|
71
|
+
|
72
|
+
events {
|
73
|
+
event :resolve, :open => :close
|
74
|
+
event :decline, :open => :canceled
|
75
|
+
event :error, :open => :faulty
|
76
|
+
}
|
77
|
+
end
|
78
|
+
expect(fsm.current).to eql(:open)
|
79
|
+
expect(fsm.terminated?).to be(false)
|
80
|
+
|
81
|
+
fsm.resolve
|
82
|
+
expect(fsm.current).to eql(:close)
|
83
|
+
expect(fsm.terminated?).to be(true)
|
84
|
+
|
85
|
+
fsm.restore!(:open)
|
86
|
+
fsm.decline
|
87
|
+
expect(fsm.current).to eql(:canceled)
|
88
|
+
expect(fsm.terminated?).to be(true)
|
89
|
+
|
90
|
+
fsm.restore!(:open)
|
91
|
+
fsm.error
|
92
|
+
expect(fsm.current).to eql(:faulty)
|
93
|
+
expect(fsm.terminated?).to be(true)
|
64
94
|
end
|
65
95
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: finite_machine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- lib/finite_machine/callable.rb
|
53
53
|
- lib/finite_machine/catchable.rb
|
54
54
|
- lib/finite_machine/choice_merger.rb
|
55
|
+
- lib/finite_machine/definition.rb
|
55
56
|
- lib/finite_machine/dsl.rb
|
56
57
|
- lib/finite_machine/event.rb
|
57
58
|
- lib/finite_machine/event_builder.rb
|
@@ -79,6 +80,8 @@ files:
|
|
79
80
|
- spec/unit/choice_spec.rb
|
80
81
|
- spec/unit/define_spec.rb
|
81
82
|
- spec/unit/event/add_spec.rb
|
83
|
+
- spec/unit/event/eql_spec.rb
|
84
|
+
- spec/unit/event/initialize_spec.rb
|
82
85
|
- spec/unit/event/inspect_spec.rb
|
83
86
|
- spec/unit/event/next_transition_spec.rb
|
84
87
|
- spec/unit/event_queue_spec.rb
|
@@ -88,8 +91,9 @@ files:
|
|
88
91
|
- spec/unit/events_chain/inspect_spec.rb
|
89
92
|
- spec/unit/events_chain/select_transition_spec.rb
|
90
93
|
- spec/unit/events_spec.rb
|
91
|
-
- spec/unit/finished_spec.rb
|
92
94
|
- spec/unit/handlers_spec.rb
|
95
|
+
- spec/unit/hook_event/eql_spec.rb
|
96
|
+
- spec/unit/hook_event/initialize_spec.rb
|
93
97
|
- spec/unit/hooks/call_spec.rb
|
94
98
|
- spec/unit/hooks/inspect_spec.rb
|
95
99
|
- spec/unit/hooks/register_spec.rb
|
@@ -99,11 +103,13 @@ files:
|
|
99
103
|
- spec/unit/is_spec.rb
|
100
104
|
- spec/unit/logger_spec.rb
|
101
105
|
- spec/unit/respond_to_spec.rb
|
106
|
+
- spec/unit/standalone_spec.rb
|
102
107
|
- spec/unit/state_parser/inspect_spec.rb
|
103
108
|
- spec/unit/state_parser/parse_states_spec.rb
|
104
109
|
- spec/unit/states_spec.rb
|
105
110
|
- spec/unit/subscribers_spec.rb
|
106
111
|
- spec/unit/target_spec.rb
|
112
|
+
- spec/unit/terminated_spec.rb
|
107
113
|
- spec/unit/transition/inspect_spec.rb
|
108
114
|
- spec/unit/transition/parse_states_spec.rb
|
109
115
|
- tasks/console.rake
|
@@ -142,6 +148,8 @@ test_files:
|
|
142
148
|
- spec/unit/choice_spec.rb
|
143
149
|
- spec/unit/define_spec.rb
|
144
150
|
- spec/unit/event/add_spec.rb
|
151
|
+
- spec/unit/event/eql_spec.rb
|
152
|
+
- spec/unit/event/initialize_spec.rb
|
145
153
|
- spec/unit/event/inspect_spec.rb
|
146
154
|
- spec/unit/event/next_transition_spec.rb
|
147
155
|
- spec/unit/event_queue_spec.rb
|
@@ -151,8 +159,9 @@ test_files:
|
|
151
159
|
- spec/unit/events_chain/inspect_spec.rb
|
152
160
|
- spec/unit/events_chain/select_transition_spec.rb
|
153
161
|
- spec/unit/events_spec.rb
|
154
|
-
- spec/unit/finished_spec.rb
|
155
162
|
- spec/unit/handlers_spec.rb
|
163
|
+
- spec/unit/hook_event/eql_spec.rb
|
164
|
+
- spec/unit/hook_event/initialize_spec.rb
|
156
165
|
- spec/unit/hooks/call_spec.rb
|
157
166
|
- spec/unit/hooks/inspect_spec.rb
|
158
167
|
- spec/unit/hooks/register_spec.rb
|
@@ -162,11 +171,13 @@ test_files:
|
|
162
171
|
- spec/unit/is_spec.rb
|
163
172
|
- spec/unit/logger_spec.rb
|
164
173
|
- spec/unit/respond_to_spec.rb
|
174
|
+
- spec/unit/standalone_spec.rb
|
165
175
|
- spec/unit/state_parser/inspect_spec.rb
|
166
176
|
- spec/unit/state_parser/parse_states_spec.rb
|
167
177
|
- spec/unit/states_spec.rb
|
168
178
|
- spec/unit/subscribers_spec.rb
|
169
179
|
- spec/unit/target_spec.rb
|
180
|
+
- spec/unit/terminated_spec.rb
|
170
181
|
- spec/unit/transition/inspect_spec.rb
|
171
182
|
- spec/unit/transition/parse_states_spec.rb
|
172
183
|
has_rdoc:
|