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/can_spec.rb
CHANGED
@@ -25,34 +25,34 @@ describe FiniteMachine, 'can?' do
|
|
25
25
|
|
26
26
|
expect(fsm.current).to eql(:green)
|
27
27
|
|
28
|
-
expect(fsm.can?(:slow)).to
|
29
|
-
expect(fsm.cannot?(:stop)).to
|
30
|
-
expect(fsm.can?(:ready)).to
|
31
|
-
expect(fsm.can?(:go)).to
|
28
|
+
expect(fsm.can?(:slow)).to be(true)
|
29
|
+
expect(fsm.cannot?(:stop)).to be(true)
|
30
|
+
expect(fsm.can?(:ready)).to be(false)
|
31
|
+
expect(fsm.can?(:go)).to be(false)
|
32
32
|
|
33
33
|
fsm.slow
|
34
34
|
expect(fsm.current).to eql(:yellow)
|
35
35
|
|
36
|
-
expect(fsm.can?(:slow)).to
|
37
|
-
expect(fsm.can?(:stop)).to
|
38
|
-
expect(fsm.can?(:ready)).to
|
39
|
-
expect(fsm.can?(:go)).to
|
36
|
+
expect(fsm.can?(:slow)).to be(false)
|
37
|
+
expect(fsm.can?(:stop)).to be(true)
|
38
|
+
expect(fsm.can?(:ready)).to be(false)
|
39
|
+
expect(fsm.can?(:go)).to be(true)
|
40
40
|
|
41
41
|
fsm.stop
|
42
42
|
expect(fsm.current).to eql(:red)
|
43
43
|
|
44
|
-
expect(fsm.can?(:slow)).to
|
45
|
-
expect(fsm.can?(:stop)).to
|
46
|
-
expect(fsm.can?(:ready)).to
|
47
|
-
expect(fsm.can?(:go)).to
|
44
|
+
expect(fsm.can?(:slow)).to be(false)
|
45
|
+
expect(fsm.can?(:stop)).to be(false)
|
46
|
+
expect(fsm.can?(:ready)).to be(true)
|
47
|
+
expect(fsm.can?(:go)).to be(false)
|
48
48
|
|
49
49
|
fsm.ready
|
50
50
|
expect(fsm.current).to eql(:yellow)
|
51
51
|
|
52
|
-
expect(fsm.can?(:slow)).to
|
53
|
-
expect(fsm.can?(:stop)).to
|
54
|
-
expect(fsm.can?(:ready)).to
|
55
|
-
expect(fsm.can?(:go)).to
|
52
|
+
expect(fsm.can?(:slow)).to be(false)
|
53
|
+
expect(fsm.can?(:stop)).to be(true)
|
54
|
+
expect(fsm.can?(:ready)).to be(false)
|
55
|
+
expect(fsm.can?(:go)).to be(true)
|
56
56
|
end
|
57
57
|
|
58
58
|
context 'with conditionl transition' do
|
@@ -66,13 +66,13 @@ describe FiniteMachine, 'can?' do
|
|
66
66
|
}
|
67
67
|
end
|
68
68
|
expect(fsm.current).to eq(:green)
|
69
|
-
expect(fsm.can?(:slow)).to
|
70
|
-
expect(fsm.can?(:stop)).to
|
69
|
+
expect(fsm.can?(:slow)).to be(true)
|
70
|
+
expect(fsm.can?(:stop)).to be(false)
|
71
71
|
|
72
72
|
fsm.slow
|
73
73
|
expect(fsm.current).to eq(:yellow)
|
74
|
-
expect(fsm.can?(:stop, false)).to
|
75
|
-
expect(fsm.can?(:stop, true)).to
|
74
|
+
expect(fsm.can?(:stop, false)).to be(false)
|
75
|
+
expect(fsm.can?(:stop, true)).to be(true)
|
76
76
|
end
|
77
77
|
|
78
78
|
it "checks against target and grouped events" do
|
@@ -90,9 +90,9 @@ describe FiniteMachine, 'can?' do
|
|
90
90
|
end
|
91
91
|
expect(fsm.current).to eq(:initial)
|
92
92
|
|
93
|
-
expect(fsm.can?(:bump)).to
|
93
|
+
expect(fsm.can?(:bump)).to be(true)
|
94
94
|
fsm.bump
|
95
|
-
expect(fsm.can?(:bump)).to
|
95
|
+
expect(fsm.can?(:bump)).to be(false)
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe FiniteMachine::Event, 'eql?' do
|
6
|
+
let(:machine) { double(:machine) }
|
7
|
+
let(:name) { :green }
|
8
|
+
let(:options) { {} }
|
9
|
+
let(:object) { described_class }
|
10
|
+
|
11
|
+
subject(:event) { object.new(machine, options) }
|
12
|
+
|
13
|
+
context 'with the same object' do
|
14
|
+
let(:other) { event }
|
15
|
+
|
16
|
+
it "equals" do
|
17
|
+
expect(event).to eql(other)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with an equivalent object' do
|
22
|
+
let(:other) { event.dup }
|
23
|
+
|
24
|
+
it "equals" do
|
25
|
+
expect(event).to eql(other)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with an object having different name" do
|
30
|
+
let(:other_name) { :red }
|
31
|
+
let(:other) { object.new(machine, {name: other_name}) }
|
32
|
+
|
33
|
+
it "doesn't equal" do
|
34
|
+
expect(event).to_not eql(other)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe FiniteMachine::Event, 'new' do
|
6
|
+
let(:machine) { double(:machine) }
|
7
|
+
let(:name) { :green }
|
8
|
+
let(:options) { {} }
|
9
|
+
let(:object) { described_class }
|
10
|
+
|
11
|
+
subject(:event) { object.new(machine, options) }
|
12
|
+
|
13
|
+
context "by default" do
|
14
|
+
it "sets name to :none" do
|
15
|
+
expect(event.name).to eql(:none)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "sets silent to false"do
|
19
|
+
expect(event.silent).to eql(false)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "with custom data" do
|
24
|
+
let(:options) { {silent: true, name: name} }
|
25
|
+
|
26
|
+
it "sets name to :green" do
|
27
|
+
expect(event.name).to eql(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "sets silent to true"do
|
31
|
+
expect(event.silent).to eql(true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "freezes object" do
|
36
|
+
expect { event.name = :red }.to raise_error(RuntimeError)
|
37
|
+
end
|
38
|
+
end
|
@@ -12,7 +12,7 @@ describe FiniteMachine::Event, '#inspect' do
|
|
12
12
|
it "adds multiple transitions" do
|
13
13
|
transition = double(:transition)
|
14
14
|
event << transition
|
15
|
-
expect(event.inspect).to eq("<#FiniteMachine::Event @name=test, @transitions=[#{transition.inspect}]>")
|
15
|
+
expect(event.inspect).to eq("<#FiniteMachine::Event @name=test, @silent=false, @transitions=[#{transition.inspect}]>")
|
16
16
|
end
|
17
17
|
|
18
18
|
it "prints event name" do
|
@@ -40,12 +40,12 @@ describe FiniteMachine::EventQueue do
|
|
40
40
|
event1 = double(:event1, dispatch: true)
|
41
41
|
event2 = double(:event2, dispatch: true)
|
42
42
|
event3 = double(:event3, dispatch: true)
|
43
|
-
expect(event_queue.alive?).to
|
43
|
+
expect(event_queue.alive?).to be(true)
|
44
44
|
event_queue << event1
|
45
45
|
event_queue << event2
|
46
46
|
event_queue.shutdown
|
47
47
|
event_queue << event3
|
48
48
|
sleep 0.001
|
49
|
-
expect(event_queue.alive?).to
|
49
|
+
expect(event_queue.alive?).to be(false)
|
50
50
|
end
|
51
51
|
end
|
@@ -12,9 +12,9 @@ describe FiniteMachine::EventsChain, '#clear' do
|
|
12
12
|
it "clears chain events" do
|
13
13
|
event = double(:event)
|
14
14
|
chain.add(:validated, event)
|
15
|
-
expect(chain.empty?).to
|
15
|
+
expect(chain.empty?).to be(false)
|
16
16
|
|
17
17
|
chain.clear
|
18
|
-
expect(chain.empty?).to
|
18
|
+
expect(chain.empty?).to be(true)
|
19
19
|
end
|
20
20
|
end
|
data/spec/unit/events_spec.rb
CHANGED
@@ -64,16 +64,16 @@ describe FiniteMachine, 'events' do
|
|
64
64
|
|
65
65
|
expect(fsm.current).to eql(:green)
|
66
66
|
|
67
|
-
expect(fsm.can?(:noop)).to
|
68
|
-
expect(fsm.can?(:slow)).to
|
67
|
+
expect(fsm.can?(:noop)).to be true
|
68
|
+
expect(fsm.can?(:slow)).to be true
|
69
69
|
|
70
70
|
fsm.noop
|
71
71
|
expect(fsm.current).to eql(:green)
|
72
72
|
fsm.slow
|
73
73
|
expect(fsm.current).to eql(:yellow)
|
74
74
|
|
75
|
-
expect(fsm.cannot?(:noop)).to
|
76
|
-
expect(fsm.cannot?(:slow)).to
|
75
|
+
expect(fsm.cannot?(:noop)).to be true
|
76
|
+
expect(fsm.cannot?(:slow)).to be true
|
77
77
|
end
|
78
78
|
|
79
79
|
it "permits event from any state with :any 'from'" do
|
@@ -171,7 +171,7 @@ describe FiniteMachine, 'events' do
|
|
171
171
|
}
|
172
172
|
end
|
173
173
|
expect(fsm.current).to eql(:green)
|
174
|
-
expect(fsm.can?(:stop)).to
|
174
|
+
expect(fsm.can?(:stop)).to be false
|
175
175
|
fsm.stop!
|
176
176
|
expect(fsm.current).to eql(:red)
|
177
177
|
end
|
@@ -191,10 +191,10 @@ describe FiniteMachine, 'events' do
|
|
191
191
|
|
192
192
|
expect(fsm.current).to eql(:green)
|
193
193
|
|
194
|
-
expect(fsm.can?(:slow)).to
|
195
|
-
expect(fsm.can?(:stop)).to
|
196
|
-
expect(fsm.cannot?(:ready)).to
|
197
|
-
expect(fsm.cannot?(:go)).to
|
194
|
+
expect(fsm.can?(:slow)).to be true
|
195
|
+
expect(fsm.can?(:stop)).to be true
|
196
|
+
expect(fsm.cannot?(:ready)).to be true
|
197
|
+
expect(fsm.cannot?(:go)).to be true
|
198
198
|
|
199
199
|
fsm.slow; expect(fsm.current).to eql(:yellow)
|
200
200
|
fsm.stop; expect(fsm.current).to eql(:red)
|
@@ -219,10 +219,10 @@ describe FiniteMachine, 'events' do
|
|
219
219
|
|
220
220
|
expect(fsm.current).to eql(:green)
|
221
221
|
|
222
|
-
expect(fsm.can?(:slow)).to
|
223
|
-
expect(fsm.can?(:stop)).to
|
224
|
-
expect(fsm.cannot?(:ready)).to
|
225
|
-
expect(fsm.cannot?(:go)).to
|
222
|
+
expect(fsm.can?(:slow)).to be true
|
223
|
+
expect(fsm.can?(:stop)).to be true
|
224
|
+
expect(fsm.cannot?(:ready)).to be true
|
225
|
+
expect(fsm.cannot?(:go)).to be true
|
226
226
|
|
227
227
|
fsm.slow; expect(fsm.current).to eql(:yellow)
|
228
228
|
fsm.stop; expect(fsm.current).to eql(:red)
|
@@ -247,7 +247,7 @@ describe FiniteMachine, 'events' do
|
|
247
247
|
end
|
248
248
|
|
249
249
|
expect(fsm.current).to eql(:green)
|
250
|
-
expect(fsm.can?(:stop)).to
|
250
|
+
expect(fsm.can?(:stop)).to be true
|
251
251
|
fsm.stop
|
252
252
|
expect(fsm.current).to eql(:yellow)
|
253
253
|
fsm.stop
|
@@ -272,12 +272,9 @@ describe FiniteMachine, 'events' do
|
|
272
272
|
end
|
273
273
|
|
274
274
|
expect(fsm.current).to eq(:initial)
|
275
|
-
fsm.bump
|
276
|
-
expect(fsm.current).to eq(:
|
277
|
-
fsm.bump
|
278
|
-
expect(fsm.current).to eq(:medium)
|
279
|
-
fsm.bump
|
280
|
-
expect(fsm.current).to eq(:high)
|
275
|
+
fsm.bump; expect(fsm.current).to eq(:low)
|
276
|
+
fsm.bump; expect(fsm.current).to eq(:medium)
|
277
|
+
fsm.bump; expect(fsm.current).to eq(:high)
|
281
278
|
end
|
282
279
|
|
283
280
|
it "returns values for events" do
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe FiniteMachine::HookEvent, 'eql?' do
|
6
|
+
let(:name) { :green }
|
7
|
+
let(:transition) { double(:transition) }
|
8
|
+
let(:data) { [:foo, :bar] }
|
9
|
+
let(:object) { described_class }
|
10
|
+
|
11
|
+
subject(:hook) { object.new(name, transition, *data) }
|
12
|
+
|
13
|
+
context 'with the same object' do
|
14
|
+
let(:other) { hook }
|
15
|
+
|
16
|
+
it "equals" do
|
17
|
+
expect(hook).to eql(other)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with an equivalent object' do
|
22
|
+
let(:other) { hook.dup }
|
23
|
+
|
24
|
+
it "equals" do
|
25
|
+
expect(hook).to eql(other)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with an object having different name" do
|
30
|
+
let(:other_name) { :red }
|
31
|
+
let(:other) { object.new(other_name, transition, *data) }
|
32
|
+
|
33
|
+
it "doesn't equal" do
|
34
|
+
expect(hook).not_to eql(other)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe FiniteMachine::HookEvent, 'new' do
|
6
|
+
let(:name) { :green }
|
7
|
+
let(:transition) { double(:transition) }
|
8
|
+
let(:data) { [:foo, :bar] }
|
9
|
+
let(:object) { described_class }
|
10
|
+
|
11
|
+
subject(:hook) { object.new(name, transition, *data) }
|
12
|
+
|
13
|
+
it "exposes readers" do
|
14
|
+
expect(hook.name).to eql(name)
|
15
|
+
expect(hook.data).to eql(data)
|
16
|
+
expect(hook.type).to eql(object)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "freezes object" do
|
20
|
+
expect { hook.name = :red }.to raise_error(RuntimeError)
|
21
|
+
end
|
22
|
+
end
|
data/spec/unit/if_unless_spec.rb
CHANGED
@@ -139,13 +139,13 @@ describe FiniteMachine, ':if, :unless' do
|
|
139
139
|
}
|
140
140
|
end
|
141
141
|
car.turn_engine_off
|
142
|
-
expect(car.engine_on?).to
|
142
|
+
expect(car.engine_on?).to be false
|
143
143
|
expect(fsm.current).to eql(:neutral)
|
144
144
|
fsm.start
|
145
145
|
expect(fsm.current).to eql(:neutral)
|
146
146
|
|
147
147
|
car.turn_engine_on
|
148
|
-
expect(car.engine_on?).to
|
148
|
+
expect(car.engine_on?).to be true
|
149
149
|
expect(fsm.current).to eql(:neutral)
|
150
150
|
fsm.start
|
151
151
|
expect(fsm.current).to eql(:one)
|
@@ -189,13 +189,13 @@ describe FiniteMachine, ':if, :unless' do
|
|
189
189
|
}
|
190
190
|
end
|
191
191
|
car.turn_engine_off
|
192
|
-
expect(car.engine_on?).to
|
192
|
+
expect(car.engine_on?).to be false
|
193
193
|
expect(fsm.current).to eql(:neutral)
|
194
194
|
fsm.start
|
195
195
|
expect(fsm.current).to eql(:neutral)
|
196
196
|
|
197
197
|
car.turn_engine_on
|
198
|
-
expect(car.engine_on?).to
|
198
|
+
expect(car.engine_on?).to be true
|
199
199
|
expect(fsm.current).to eql(:neutral)
|
200
200
|
fsm.start
|
201
201
|
expect(fsm.current).to eql(:one)
|
@@ -217,13 +217,13 @@ describe FiniteMachine, ':if, :unless' do
|
|
217
217
|
}
|
218
218
|
end
|
219
219
|
car.turn_engine_off
|
220
|
-
expect(car.engine_on?).to
|
220
|
+
expect(car.engine_on?).to be false
|
221
221
|
expect(fsm.current).to eql(:neutral)
|
222
222
|
fsm.start
|
223
223
|
expect(fsm.current).to eql(:neutral)
|
224
224
|
|
225
225
|
car.turn_engine_on
|
226
|
-
expect(car.engine_on?).to
|
226
|
+
expect(car.engine_on?).to be true
|
227
227
|
expect(fsm.current).to eql(:neutral)
|
228
228
|
fsm.start
|
229
229
|
expect(fsm.current).to eql(:one)
|
@@ -69,7 +69,7 @@ describe FiniteMachine, 'initialize' do
|
|
69
69
|
|
70
70
|
it "allows to specify deferred inital state" do
|
71
71
|
fsm = FiniteMachine.define do
|
72
|
-
initial
|
72
|
+
initial :green, defer: true
|
73
73
|
|
74
74
|
events {
|
75
75
|
event :slow, :green => :yellow
|
@@ -97,7 +97,7 @@ describe FiniteMachine, 'initialize' do
|
|
97
97
|
|
98
98
|
it "allows to specify inital start event" do
|
99
99
|
fsm = FiniteMachine.define do
|
100
|
-
initial
|
100
|
+
initial :green, event: :start
|
101
101
|
|
102
102
|
events {
|
103
103
|
event :slow, :green => :none
|
@@ -114,7 +114,7 @@ describe FiniteMachine, 'initialize' do
|
|
114
114
|
|
115
115
|
it "allows to specify deferred inital start event" do
|
116
116
|
fsm = FiniteMachine.define do
|
117
|
-
initial
|
117
|
+
initial :green, event: :start, defer: true
|
118
118
|
|
119
119
|
events {
|
120
120
|
event :slow, :green => :yellow
|
@@ -173,7 +173,7 @@ describe FiniteMachine, 'initialize' do
|
|
173
173
|
|
174
174
|
it "allows to retrieve initial state for deferred" do
|
175
175
|
fsm = FiniteMachine.define do
|
176
|
-
initial
|
176
|
+
initial :green, defer: true
|
177
177
|
|
178
178
|
events {
|
179
179
|
event :slow, :green => :yellow
|
@@ -190,7 +190,7 @@ describe FiniteMachine, 'initialize' do
|
|
190
190
|
it "allows to trigger callbacks on initial with :silent option" do
|
191
191
|
called = []
|
192
192
|
fsm = FiniteMachine.define do
|
193
|
-
initial
|
193
|
+
initial :green, silent: false
|
194
194
|
|
195
195
|
events {
|
196
196
|
event :slow, :green => :yellow
|
@@ -206,7 +206,7 @@ describe FiniteMachine, 'initialize' do
|
|
206
206
|
it "allows to trigger callbacks on deferred initial state" do
|
207
207
|
called = []
|
208
208
|
fsm = FiniteMachine.define do
|
209
|
-
initial
|
209
|
+
initial :green, silent: false, defer: true
|
210
210
|
|
211
211
|
events {
|
212
212
|
event :slow, :green => :yellow
|