finite_machine 0.11.3 → 0.12.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 +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
|