finite_machine 0.11.3 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +34 -0
- data/README.md +564 -569
- data/Rakefile +5 -1
- data/benchmarks/memory_profile.rb +11 -0
- data/benchmarks/memory_usage.rb +16 -9
- data/finite_machine.gemspec +10 -3
- data/lib/finite_machine.rb +34 -46
- data/lib/finite_machine/async_call.rb +5 -21
- data/lib/finite_machine/callable.rb +4 -4
- data/lib/finite_machine/catchable.rb +4 -2
- data/lib/finite_machine/choice_merger.rb +19 -19
- data/lib/finite_machine/const.rb +16 -0
- data/lib/finite_machine/definition.rb +2 -2
- data/lib/finite_machine/dsl.rb +66 -149
- data/lib/finite_machine/env.rb +4 -2
- data/lib/finite_machine/event_definition.rb +7 -15
- data/lib/finite_machine/{events_chain.rb → events_map.rb} +39 -51
- data/lib/finite_machine/hook_event.rb +60 -61
- data/lib/finite_machine/hooks.rb +44 -36
- data/lib/finite_machine/listener.rb +2 -2
- data/lib/finite_machine/logger.rb +5 -4
- data/lib/finite_machine/message_queue.rb +39 -30
- data/lib/finite_machine/observer.rb +55 -37
- data/lib/finite_machine/safety.rb +12 -10
- data/lib/finite_machine/state_definition.rb +3 -5
- data/lib/finite_machine/state_machine.rb +83 -64
- data/lib/finite_machine/state_parser.rb +51 -79
- data/lib/finite_machine/subscribers.rb +1 -1
- data/lib/finite_machine/threadable.rb +3 -1
- data/lib/finite_machine/transition.rb +30 -31
- data/lib/finite_machine/transition_builder.rb +23 -32
- data/lib/finite_machine/transition_event.rb +12 -11
- data/lib/finite_machine/two_phase_lock.rb +3 -1
- data/lib/finite_machine/undefined_transition.rb +5 -6
- data/lib/finite_machine/version.rb +2 -2
- data/spec/integration/system_spec.rb +36 -38
- data/spec/performance/benchmark_spec.rb +13 -21
- data/spec/unit/alias_target_spec.rb +22 -41
- data/spec/unit/async_callbacks_spec.rb +8 -13
- data/spec/unit/auto_methods_spec.rb +44 -0
- data/spec/unit/callable/call_spec.rb +1 -3
- data/spec/unit/callbacks_spec.rb +372 -463
- data/spec/unit/can_spec.rb +13 -23
- data/spec/unit/cancel_callbacks_spec.rb +46 -0
- data/spec/unit/choice_spec.rb +105 -141
- data/spec/unit/define_spec.rb +31 -31
- data/spec/unit/definition_spec.rb +24 -41
- data/spec/unit/event_names_spec.rb +6 -10
- data/spec/unit/events_map/add_spec.rb +23 -0
- data/spec/unit/events_map/choice_transition_spec.rb +25 -0
- data/spec/unit/events_map/clear_spec.rb +13 -0
- data/spec/unit/events_map/events_spec.rb +16 -0
- data/spec/unit/events_map/inspect_spec.rb +22 -0
- data/spec/unit/{events_chain → events_map}/match_transition_spec.rb +12 -14
- data/spec/unit/{events_chain → events_map}/move_to_spec.rb +14 -17
- data/spec/unit/events_map/states_for_spec.rb +17 -0
- data/spec/unit/events_spec.rb +91 -160
- data/spec/unit/handlers_spec.rb +34 -66
- data/spec/unit/hook_event/any_state_or_event_spec.rb +13 -0
- data/spec/unit/hook_event/build_spec.rb +1 -3
- data/spec/unit/hook_event/eql_spec.rb +1 -3
- data/spec/unit/hook_event/initialize_spec.rb +2 -4
- data/spec/unit/hook_event/notify_spec.rb +2 -4
- data/spec/unit/hooks/clear_spec.rb +1 -1
- data/spec/unit/hooks/{call_spec.rb → find_spec.rb} +4 -9
- data/spec/unit/hooks/inspect_spec.rb +16 -8
- data/spec/unit/hooks/register_spec.rb +4 -9
- data/spec/unit/if_unless_spec.rb +76 -115
- data/spec/unit/initial_spec.rb +50 -82
- data/spec/unit/inspect_spec.rb +14 -9
- data/spec/unit/is_spec.rb +12 -18
- data/spec/unit/log_transitions_spec.rb +4 -10
- data/spec/unit/logger_spec.rb +1 -3
- data/spec/unit/{event_queue_spec.rb → message_queue_spec.rb} +15 -8
- data/spec/unit/new_spec.rb +50 -0
- data/spec/unit/respond_to_spec.rb +2 -6
- data/spec/unit/state_parser/parse_spec.rb +9 -12
- data/spec/unit/states_spec.rb +12 -18
- data/spec/unit/subscribers_spec.rb +1 -3
- data/spec/unit/target_spec.rb +60 -93
- data/spec/unit/terminated_spec.rb +15 -25
- data/spec/unit/transition/check_conditions_spec.rb +16 -15
- data/spec/unit/transition/inspect_spec.rb +6 -6
- data/spec/unit/transition/matches_spec.rb +5 -7
- data/spec/unit/transition/states_spec.rb +5 -7
- data/spec/unit/transition/to_state_spec.rb +5 -13
- data/spec/unit/trigger_spec.rb +5 -9
- data/spec/unit/undefined_transition/eql_spec.rb +1 -3
- metadata +86 -49
- data/.gitignore +0 -18
- data/.rspec +0 -5
- data/.travis.yml +0 -27
- data/Gemfile +0 -16
- data/assets/finite_machine_logo.png +0 -0
- data/lib/finite_machine/async_proxy.rb +0 -55
- data/spec/unit/async_events_spec.rb +0 -107
- data/spec/unit/events_chain/add_spec.rb +0 -25
- data/spec/unit/events_chain/cancel_transitions_spec.rb +0 -22
- data/spec/unit/events_chain/choice_transition_spec.rb +0 -28
- data/spec/unit/events_chain/clear_spec.rb +0 -15
- data/spec/unit/events_chain/events_spec.rb +0 -18
- data/spec/unit/events_chain/inspect_spec.rb +0 -24
- data/spec/unit/events_chain/states_for_spec.rb +0 -17
- data/spec/unit/hook_event/infer_default_name_spec.rb +0 -13
- data/spec/unit/state_parser/inspect_spec.rb +0 -25
data/spec/unit/initial_spec.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
require 'spec_helper'
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
3
|
RSpec.describe FiniteMachine, 'initial' do
|
6
4
|
|
@@ -15,23 +13,19 @@ RSpec.describe FiniteMachine, 'initial' do
|
|
15
13
|
}
|
16
14
|
|
17
15
|
it "defaults initial state to :none" do
|
18
|
-
fsm = FiniteMachine.
|
19
|
-
|
20
|
-
|
21
|
-
event :stop, :yellow => :red
|
22
|
-
}
|
16
|
+
fsm = FiniteMachine.new do
|
17
|
+
event :slow, :green => :yellow
|
18
|
+
event :stop, :yellow => :red
|
23
19
|
end
|
24
20
|
|
25
21
|
expect(fsm.current).to eql(:none)
|
26
22
|
end
|
27
23
|
|
28
24
|
it "requires initial state transition from :none" do
|
29
|
-
fsm = FiniteMachine.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
event :stop, :yellow => :red
|
34
|
-
}
|
25
|
+
fsm = FiniteMachine.new do
|
26
|
+
event :init, :none => :green
|
27
|
+
event :slow, :green => :yellow
|
28
|
+
event :stop, :yellow => :red
|
35
29
|
end
|
36
30
|
|
37
31
|
expect(fsm.current).to eql(:none)
|
@@ -41,40 +35,33 @@ RSpec.describe FiniteMachine, 'initial' do
|
|
41
35
|
|
42
36
|
it "allows to specify inital state" do
|
43
37
|
called = []
|
44
|
-
fsm = FiniteMachine.
|
38
|
+
fsm = FiniteMachine.new do
|
45
39
|
initial :green
|
46
40
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
on_exit :none do |event| called << 'on_exit_none' end
|
53
|
-
on_enter :green do |event| called << 'on_enter_green' end
|
54
|
-
}
|
41
|
+
event :slow, :green => :yellow
|
42
|
+
event :stop, :yellow => :red
|
43
|
+
|
44
|
+
on_exit :none do |event| called << 'on_exit_none' end
|
45
|
+
on_enter :green do |event| called << 'on_enter_green' end
|
55
46
|
end
|
56
47
|
expect(fsm.current).to eql(:green)
|
57
48
|
expect(called).to be_empty
|
58
49
|
end
|
59
50
|
|
60
51
|
it "allows to specify initial state through parameter" do
|
61
|
-
fsm = FiniteMachine.
|
62
|
-
|
63
|
-
|
64
|
-
event :stop, :yellow => :red
|
65
|
-
}
|
52
|
+
fsm = FiniteMachine.new initial: :green do
|
53
|
+
event :slow, :green => :yellow
|
54
|
+
event :stop, :yellow => :red
|
66
55
|
end
|
67
56
|
expect(fsm.current).to eql(:green)
|
68
57
|
end
|
69
58
|
|
70
59
|
it "allows to specify deferred inital state" do
|
71
|
-
fsm = FiniteMachine.
|
60
|
+
fsm = FiniteMachine.new do
|
72
61
|
initial :green, defer: true
|
73
62
|
|
74
|
-
|
75
|
-
|
76
|
-
event :stop, :yellow => :red
|
77
|
-
}
|
63
|
+
event :slow, :green => :yellow
|
64
|
+
event :stop, :yellow => :red
|
78
65
|
end
|
79
66
|
|
80
67
|
expect(fsm.current).to eql(:none)
|
@@ -84,25 +71,21 @@ RSpec.describe FiniteMachine, 'initial' do
|
|
84
71
|
|
85
72
|
it "raises error when specyfying initial without state name" do
|
86
73
|
expect {
|
87
|
-
FiniteMachine.
|
74
|
+
FiniteMachine.new do
|
88
75
|
initial defer: true
|
89
76
|
|
90
|
-
|
91
|
-
|
92
|
-
event :stop, :yellow => :red
|
93
|
-
}
|
77
|
+
event :slow, :green => :yellow
|
78
|
+
event :stop, :yellow => :red
|
94
79
|
end
|
95
80
|
}.to raise_error(FiniteMachine::MissingInitialStateError)
|
96
81
|
end
|
97
82
|
|
98
83
|
it "allows to specify inital start event" do
|
99
|
-
fsm = FiniteMachine.
|
84
|
+
fsm = FiniteMachine.new do
|
100
85
|
initial :green, event: :start
|
101
86
|
|
102
|
-
|
103
|
-
|
104
|
-
event :stop, :yellow => :red
|
105
|
-
}
|
87
|
+
event :slow, :green => :none
|
88
|
+
event :stop, :yellow => :red
|
106
89
|
end
|
107
90
|
|
108
91
|
expect(fsm.current).to eql(:green)
|
@@ -113,13 +96,11 @@ RSpec.describe FiniteMachine, 'initial' do
|
|
113
96
|
end
|
114
97
|
|
115
98
|
it "allows to specify deferred inital start event" do
|
116
|
-
fsm = FiniteMachine.
|
99
|
+
fsm = FiniteMachine.new do
|
117
100
|
initial :green, event: :start, defer: true
|
118
101
|
|
119
|
-
|
120
|
-
|
121
|
-
event :stop, :yellow => :red
|
122
|
-
}
|
102
|
+
event :slow, :green => :yellow
|
103
|
+
event :stop, :yellow => :red
|
123
104
|
end
|
124
105
|
|
125
106
|
expect(fsm.current).to eql(:none)
|
@@ -129,24 +110,21 @@ RSpec.describe FiniteMachine, 'initial' do
|
|
129
110
|
|
130
111
|
it "evaluates initial state" do
|
131
112
|
logger = DummyLogger.new
|
132
|
-
fsm = FiniteMachine.
|
113
|
+
fsm = FiniteMachine.new do
|
133
114
|
initial logger.level
|
134
115
|
|
135
|
-
|
136
|
-
|
137
|
-
event :stop, :yellow => :red
|
138
|
-
}
|
116
|
+
event :slow, :green => :none
|
117
|
+
event :stop, :yellow => :red
|
139
118
|
end
|
140
119
|
expect(fsm.current).to eql(:pending)
|
141
120
|
end
|
142
121
|
|
143
122
|
it "doesn't care about state type" do
|
144
|
-
fsm = FiniteMachine.
|
123
|
+
fsm = FiniteMachine.new do
|
145
124
|
initial 1
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
}
|
125
|
+
|
126
|
+
event :a, 1 => 2
|
127
|
+
event :b, 2 => 3
|
150
128
|
end
|
151
129
|
expect(fsm.current).to eql(1)
|
152
130
|
fsm.a
|
@@ -156,13 +134,11 @@ RSpec.describe FiniteMachine, 'initial' do
|
|
156
134
|
end
|
157
135
|
|
158
136
|
it "allows to retrieve initial state" do
|
159
|
-
fsm = FiniteMachine.
|
137
|
+
fsm = FiniteMachine.new do
|
160
138
|
initial :green
|
161
139
|
|
162
|
-
|
163
|
-
|
164
|
-
event :stop, :yellow => :red
|
165
|
-
}
|
140
|
+
event :slow, :green => :yellow
|
141
|
+
event :stop, :yellow => :red
|
166
142
|
end
|
167
143
|
expect(fsm.current).to eq(:green)
|
168
144
|
expect(fsm.initial_state).to eq(:green)
|
@@ -172,13 +148,11 @@ RSpec.describe FiniteMachine, 'initial' do
|
|
172
148
|
end
|
173
149
|
|
174
150
|
it "allows to retrieve initial state for deferred" do
|
175
|
-
fsm = FiniteMachine.
|
151
|
+
fsm = FiniteMachine.new do
|
176
152
|
initial :green, defer: true
|
177
153
|
|
178
|
-
|
179
|
-
|
180
|
-
event :stop, :yellow => :red
|
181
|
-
}
|
154
|
+
event :slow, :green => :yellow
|
155
|
+
event :stop, :yellow => :red
|
182
156
|
end
|
183
157
|
expect(fsm.current).to eq(:none)
|
184
158
|
expect(fsm.initial_state).to eq(:none)
|
@@ -189,15 +163,12 @@ RSpec.describe FiniteMachine, 'initial' do
|
|
189
163
|
|
190
164
|
it "allows to trigger callbacks on initial with :silent option" do
|
191
165
|
called = []
|
192
|
-
fsm = FiniteMachine.
|
166
|
+
fsm = FiniteMachine.new do
|
193
167
|
initial :green, silent: false
|
194
168
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
callbacks {
|
199
|
-
on_enter :green do |event| called << 'on_enter_green' end
|
200
|
-
}
|
169
|
+
event :slow, :green => :yellow
|
170
|
+
|
171
|
+
on_enter :green do |event| called << 'on_enter_green' end
|
201
172
|
end
|
202
173
|
expect(fsm.current).to eq(:green)
|
203
174
|
expect(called).to eq(['on_enter_green'])
|
@@ -205,15 +176,12 @@ RSpec.describe FiniteMachine, 'initial' do
|
|
205
176
|
|
206
177
|
it "allows to trigger callbacks on deferred initial state" do
|
207
178
|
called = []
|
208
|
-
fsm = FiniteMachine.
|
179
|
+
fsm = FiniteMachine.new do
|
209
180
|
initial :green, silent: false, defer: true
|
210
181
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
callbacks {
|
215
|
-
on_enter :green do |event| called << 'on_enter_green' end
|
216
|
-
}
|
182
|
+
event :slow, :green => :yellow
|
183
|
+
|
184
|
+
on_enter :green do |event| called << 'on_enter_green' end
|
217
185
|
end
|
218
186
|
expect(fsm.current).to eq(:none)
|
219
187
|
fsm.init
|
data/spec/unit/inspect_spec.rb
CHANGED
@@ -1,17 +1,22 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
require 'spec_helper'
|
1
|
+
# frozen_string_literal
|
4
2
|
|
5
3
|
RSpec.describe FiniteMachine, '#inspect' do
|
6
4
|
it "print useful information about state machine" do
|
7
|
-
fsm = FiniteMachine.
|
5
|
+
fsm = FiniteMachine.new do
|
8
6
|
initial :green
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
event :stop, :yellow => :red
|
13
|
-
}
|
8
|
+
event :slow, :green => :yellow
|
9
|
+
event :stop, :yellow => :red
|
14
10
|
end
|
15
|
-
|
11
|
+
inspected = fsm.inspect
|
12
|
+
expect(inspected).to match(/^<#FiniteMachine::StateMachine:0x#{fsm.object_id.to_s(16)} @states=\[.*\], @events=\[.*\], @transitions=\[.*\]>$/)
|
13
|
+
|
14
|
+
event_names = eval inspected[/events=\[(.*?)\]/]
|
15
|
+
states = eval inspected[/states=\[(.*?)\]/]
|
16
|
+
transitions = eval inspected[/transitions=\[(.*?)\]/]
|
17
|
+
|
18
|
+
expect(event_names).to match_array([:init, :slow, :stop])
|
19
|
+
expect(states).to match_array([:none, :green, :yellow, :red])
|
20
|
+
expect(transitions).to match_array([{:none => :green}, {:green => :yellow}, {:yellow => :red}])
|
16
21
|
end
|
17
22
|
end
|
data/spec/unit/is_spec.rb
CHANGED
@@ -1,19 +1,15 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
RSpec.describe FiniteMachine, 'is?' do
|
3
|
+
RSpec.describe FiniteMachine, '#is?' do
|
6
4
|
|
7
5
|
it "allows to check if state is reachable" do
|
8
|
-
fsm = FiniteMachine.
|
6
|
+
fsm = FiniteMachine.new do
|
9
7
|
initial :green
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
event :go, :yellow => :green
|
16
|
-
}
|
9
|
+
event :slow, :green => :yellow
|
10
|
+
event :stop, :yellow => :red
|
11
|
+
event :ready, :red => :yellow
|
12
|
+
event :go, :yellow => :green
|
17
13
|
end
|
18
14
|
|
19
15
|
expect(fsm.current).to eql(:green)
|
@@ -32,15 +28,13 @@ RSpec.describe FiniteMachine, 'is?' do
|
|
32
28
|
end
|
33
29
|
|
34
30
|
it "defines helper methods to check current state" do
|
35
|
-
fsm = FiniteMachine.
|
31
|
+
fsm = FiniteMachine.new do
|
36
32
|
initial :green
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
event :go, :yellow => :green
|
43
|
-
}
|
34
|
+
event :slow, :green => :yellow
|
35
|
+
event :stop, :yellow => :red
|
36
|
+
event :ready, :red => :yellow
|
37
|
+
event :go, :yellow => :green
|
44
38
|
end
|
45
39
|
expect(fsm.current).to eql(:green)
|
46
40
|
|
@@ -1,8 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe FiniteMachine, 'log_transitions' do
|
1
|
+
RSpec.describe FiniteMachine, ':log_transitions' do
|
6
2
|
let(:output) { StringIO.new('', 'w+')}
|
7
3
|
|
8
4
|
before { FiniteMachine.logger = ::Logger.new(output) }
|
@@ -10,13 +6,11 @@ RSpec.describe FiniteMachine, 'log_transitions' do
|
|
10
6
|
after { FiniteMachine.logger = ::Logger.new($stderr) }
|
11
7
|
|
12
8
|
it "logs transitions" do
|
13
|
-
fsm = FiniteMachine.
|
9
|
+
fsm = FiniteMachine.new log_transitions: true do
|
14
10
|
initial :green
|
15
11
|
|
16
|
-
|
17
|
-
|
18
|
-
event :stop, :yellow => :red
|
19
|
-
}
|
12
|
+
event :slow, :green => :yellow
|
13
|
+
event :stop, :yellow => :red
|
20
14
|
end
|
21
15
|
|
22
16
|
fsm.slow
|
data/spec/unit/logger_spec.rb
CHANGED
@@ -1,55 +1,62 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe FiniteMachine::MessageQueue do
|
4
|
-
|
5
|
-
subject(:event_queue) { described_class.new }
|
6
|
-
|
7
4
|
it "dispatches all events" do
|
5
|
+
event_queue = FiniteMachine::MessageQueue.new
|
8
6
|
event_queue.start
|
9
7
|
called = []
|
10
8
|
event1 = double(:event1, dispatch: called << 'event1_dispatched')
|
11
9
|
event2 = double(:event2, dispatch: called << 'event2_dispatched')
|
10
|
+
|
12
11
|
expect(event_queue.size).to be_zero
|
12
|
+
|
13
13
|
event_queue << event1
|
14
14
|
event_queue << event2
|
15
15
|
event_queue.join(0.001)
|
16
|
+
|
16
17
|
expect(called).to match_array(['event1_dispatched', 'event2_dispatched'])
|
18
|
+
event_queue.shutdown
|
17
19
|
end
|
18
20
|
|
19
21
|
it "logs error" do
|
22
|
+
event_queue = FiniteMachine::MessageQueue.new
|
20
23
|
event_queue.start
|
21
24
|
event = spy(:event)
|
22
25
|
allow(event).to receive(:dispatch) { raise }
|
23
26
|
expect(FiniteMachine::Logger).to receive(:error)
|
24
27
|
event_queue << event
|
25
|
-
event_queue.join(0.
|
28
|
+
event_queue.join(0.02)
|
26
29
|
expect(event_queue).to be_empty
|
27
30
|
end
|
28
31
|
|
29
32
|
it "notifies listeners" do
|
33
|
+
event_queue = FiniteMachine::MessageQueue.new
|
30
34
|
event_queue.start
|
31
35
|
called = []
|
32
36
|
event1 = double(:event1, dispatch: true)
|
33
37
|
event2 = double(:event2, dispatch: true)
|
34
38
|
event3 = double(:event3, dispatch: true)
|
35
39
|
event_queue.subscribe(:listener1) { |event| called << event }
|
36
|
-
event_queue << event1
|
40
|
+
event_queue << event1
|
41
|
+
event_queue << event2
|
42
|
+
event_queue << event3
|
37
43
|
event_queue.join(0.02)
|
38
44
|
event_queue.shutdown
|
39
45
|
expect(called).to match_array([event1, event2, event3])
|
40
46
|
end
|
41
47
|
|
42
48
|
it "allows to shutdown event queue" do
|
49
|
+
event_queue = FiniteMachine::MessageQueue.new
|
43
50
|
event_queue.start
|
44
51
|
event1 = double(:event1, dispatch: true)
|
45
52
|
event2 = double(:event2, dispatch: true)
|
46
53
|
event3 = double(:event3, dispatch: true)
|
47
|
-
expect(event_queue.
|
54
|
+
expect(event_queue.running?).to be(true)
|
48
55
|
event_queue << event1
|
49
56
|
event_queue << event2
|
50
57
|
event_queue.shutdown
|
51
58
|
event_queue << event3
|
59
|
+
expect(event_queue.running?).to be(false)
|
52
60
|
event_queue.join(0.001)
|
53
|
-
expect(event_queue.alive?).to be(false)
|
54
61
|
end
|
55
62
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe FiniteMachine, '.new' do
|
4
|
+
context 'with block' do
|
5
|
+
it "creates system state machine" do
|
6
|
+
fsm = FiniteMachine.new do
|
7
|
+
initial :green
|
8
|
+
|
9
|
+
event :slow, :green => :yellow
|
10
|
+
event :stop, :yellow => :red
|
11
|
+
event :ready, :red => :yellow
|
12
|
+
event :go, :yellow => :green
|
13
|
+
end
|
14
|
+
|
15
|
+
expect(fsm.current).to eql(:green)
|
16
|
+
|
17
|
+
fsm.slow
|
18
|
+
expect(fsm.current).to eql(:yellow)
|
19
|
+
fsm.stop
|
20
|
+
expect(fsm.current).to eql(:red)
|
21
|
+
fsm.ready
|
22
|
+
expect(fsm.current).to eql(:yellow)
|
23
|
+
fsm.go
|
24
|
+
expect(fsm.current).to eql(:green)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'without block' do
|
29
|
+
it "creates state machine" do
|
30
|
+
called = []
|
31
|
+
fsm = FiniteMachine.new
|
32
|
+
fsm.initial(:green)
|
33
|
+
fsm.event(:slow, :green => :yellow)
|
34
|
+
fsm.event(:stop, :yellow => :red)
|
35
|
+
fsm.event(:ready,:red => :yellow)
|
36
|
+
fsm.event(:go, :yellow => :green)
|
37
|
+
fsm.on_enter(:yellow) { |event| called << 'on_enter_yellow' }
|
38
|
+
fsm.handle(FiniteMachine::InvalidStateError) { |exception|
|
39
|
+
called << 'error_handler'
|
40
|
+
}
|
41
|
+
fsm.init
|
42
|
+
expect(fsm.current).to eql(:green)
|
43
|
+
fsm.slow
|
44
|
+
expect(fsm.current).to eql(:yellow)
|
45
|
+
fsm.ready
|
46
|
+
expect(fsm.current).to eql(:yellow)
|
47
|
+
expect(called).to match_array(['on_enter_yellow', 'error_handler'])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|