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.
Files changed (106) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +34 -0
  3. data/README.md +564 -569
  4. data/Rakefile +5 -1
  5. data/benchmarks/memory_profile.rb +11 -0
  6. data/benchmarks/memory_usage.rb +16 -9
  7. data/finite_machine.gemspec +10 -3
  8. data/lib/finite_machine.rb +34 -46
  9. data/lib/finite_machine/async_call.rb +5 -21
  10. data/lib/finite_machine/callable.rb +4 -4
  11. data/lib/finite_machine/catchable.rb +4 -2
  12. data/lib/finite_machine/choice_merger.rb +19 -19
  13. data/lib/finite_machine/const.rb +16 -0
  14. data/lib/finite_machine/definition.rb +2 -2
  15. data/lib/finite_machine/dsl.rb +66 -149
  16. data/lib/finite_machine/env.rb +4 -2
  17. data/lib/finite_machine/event_definition.rb +7 -15
  18. data/lib/finite_machine/{events_chain.rb → events_map.rb} +39 -51
  19. data/lib/finite_machine/hook_event.rb +60 -61
  20. data/lib/finite_machine/hooks.rb +44 -36
  21. data/lib/finite_machine/listener.rb +2 -2
  22. data/lib/finite_machine/logger.rb +5 -4
  23. data/lib/finite_machine/message_queue.rb +39 -30
  24. data/lib/finite_machine/observer.rb +55 -37
  25. data/lib/finite_machine/safety.rb +12 -10
  26. data/lib/finite_machine/state_definition.rb +3 -5
  27. data/lib/finite_machine/state_machine.rb +83 -64
  28. data/lib/finite_machine/state_parser.rb +51 -79
  29. data/lib/finite_machine/subscribers.rb +1 -1
  30. data/lib/finite_machine/threadable.rb +3 -1
  31. data/lib/finite_machine/transition.rb +30 -31
  32. data/lib/finite_machine/transition_builder.rb +23 -32
  33. data/lib/finite_machine/transition_event.rb +12 -11
  34. data/lib/finite_machine/two_phase_lock.rb +3 -1
  35. data/lib/finite_machine/undefined_transition.rb +5 -6
  36. data/lib/finite_machine/version.rb +2 -2
  37. data/spec/integration/system_spec.rb +36 -38
  38. data/spec/performance/benchmark_spec.rb +13 -21
  39. data/spec/unit/alias_target_spec.rb +22 -41
  40. data/spec/unit/async_callbacks_spec.rb +8 -13
  41. data/spec/unit/auto_methods_spec.rb +44 -0
  42. data/spec/unit/callable/call_spec.rb +1 -3
  43. data/spec/unit/callbacks_spec.rb +372 -463
  44. data/spec/unit/can_spec.rb +13 -23
  45. data/spec/unit/cancel_callbacks_spec.rb +46 -0
  46. data/spec/unit/choice_spec.rb +105 -141
  47. data/spec/unit/define_spec.rb +31 -31
  48. data/spec/unit/definition_spec.rb +24 -41
  49. data/spec/unit/event_names_spec.rb +6 -10
  50. data/spec/unit/events_map/add_spec.rb +23 -0
  51. data/spec/unit/events_map/choice_transition_spec.rb +25 -0
  52. data/spec/unit/events_map/clear_spec.rb +13 -0
  53. data/spec/unit/events_map/events_spec.rb +16 -0
  54. data/spec/unit/events_map/inspect_spec.rb +22 -0
  55. data/spec/unit/{events_chain → events_map}/match_transition_spec.rb +12 -14
  56. data/spec/unit/{events_chain → events_map}/move_to_spec.rb +14 -17
  57. data/spec/unit/events_map/states_for_spec.rb +17 -0
  58. data/spec/unit/events_spec.rb +91 -160
  59. data/spec/unit/handlers_spec.rb +34 -66
  60. data/spec/unit/hook_event/any_state_or_event_spec.rb +13 -0
  61. data/spec/unit/hook_event/build_spec.rb +1 -3
  62. data/spec/unit/hook_event/eql_spec.rb +1 -3
  63. data/spec/unit/hook_event/initialize_spec.rb +2 -4
  64. data/spec/unit/hook_event/notify_spec.rb +2 -4
  65. data/spec/unit/hooks/clear_spec.rb +1 -1
  66. data/spec/unit/hooks/{call_spec.rb → find_spec.rb} +4 -9
  67. data/spec/unit/hooks/inspect_spec.rb +16 -8
  68. data/spec/unit/hooks/register_spec.rb +4 -9
  69. data/spec/unit/if_unless_spec.rb +76 -115
  70. data/spec/unit/initial_spec.rb +50 -82
  71. data/spec/unit/inspect_spec.rb +14 -9
  72. data/spec/unit/is_spec.rb +12 -18
  73. data/spec/unit/log_transitions_spec.rb +4 -10
  74. data/spec/unit/logger_spec.rb +1 -3
  75. data/spec/unit/{event_queue_spec.rb → message_queue_spec.rb} +15 -8
  76. data/spec/unit/new_spec.rb +50 -0
  77. data/spec/unit/respond_to_spec.rb +2 -6
  78. data/spec/unit/state_parser/parse_spec.rb +9 -12
  79. data/spec/unit/states_spec.rb +12 -18
  80. data/spec/unit/subscribers_spec.rb +1 -3
  81. data/spec/unit/target_spec.rb +60 -93
  82. data/spec/unit/terminated_spec.rb +15 -25
  83. data/spec/unit/transition/check_conditions_spec.rb +16 -15
  84. data/spec/unit/transition/inspect_spec.rb +6 -6
  85. data/spec/unit/transition/matches_spec.rb +5 -7
  86. data/spec/unit/transition/states_spec.rb +5 -7
  87. data/spec/unit/transition/to_state_spec.rb +5 -13
  88. data/spec/unit/trigger_spec.rb +5 -9
  89. data/spec/unit/undefined_transition/eql_spec.rb +1 -3
  90. metadata +86 -49
  91. data/.gitignore +0 -18
  92. data/.rspec +0 -5
  93. data/.travis.yml +0 -27
  94. data/Gemfile +0 -16
  95. data/assets/finite_machine_logo.png +0 -0
  96. data/lib/finite_machine/async_proxy.rb +0 -55
  97. data/spec/unit/async_events_spec.rb +0 -107
  98. data/spec/unit/events_chain/add_spec.rb +0 -25
  99. data/spec/unit/events_chain/cancel_transitions_spec.rb +0 -22
  100. data/spec/unit/events_chain/choice_transition_spec.rb +0 -28
  101. data/spec/unit/events_chain/clear_spec.rb +0 -15
  102. data/spec/unit/events_chain/events_spec.rb +0 -18
  103. data/spec/unit/events_chain/inspect_spec.rb +0 -24
  104. data/spec/unit/events_chain/states_for_spec.rb +0 -17
  105. data/spec/unit/hook_event/infer_default_name_spec.rb +0 -13
  106. data/spec/unit/state_parser/inspect_spec.rb +0 -25
@@ -1,6 +1,4 @@
1
- # encoding: utf-8
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.define do
19
- events {
20
- event :slow, :green => :yellow
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.define do
30
- events {
31
- event :init, :none => :green
32
- event :slow, :green => :yellow
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.define do
38
+ fsm = FiniteMachine.new do
45
39
  initial :green
46
40
 
47
- events {
48
- event :slow, :green => :yellow
49
- event :stop, :yellow => :red
50
- }
51
- callbacks {
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.define initial: :green do
62
- events {
63
- event :slow, :green => :yellow
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.define do
60
+ fsm = FiniteMachine.new do
72
61
  initial :green, defer: true
73
62
 
74
- events {
75
- event :slow, :green => :yellow
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.define do
74
+ FiniteMachine.new do
88
75
  initial defer: true
89
76
 
90
- events {
91
- event :slow, :green => :yellow
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.define do
84
+ fsm = FiniteMachine.new do
100
85
  initial :green, event: :start
101
86
 
102
- events {
103
- event :slow, :green => :none
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.define do
99
+ fsm = FiniteMachine.new do
117
100
  initial :green, event: :start, defer: true
118
101
 
119
- events {
120
- event :slow, :green => :yellow
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.define do
113
+ fsm = FiniteMachine.new do
133
114
  initial logger.level
134
115
 
135
- events {
136
- event :slow, :green => :none
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.define do
123
+ fsm = FiniteMachine.new do
145
124
  initial 1
146
- events {
147
- event :a, 1 => 2
148
- event :b, 2 => 3
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.define do
137
+ fsm = FiniteMachine.new do
160
138
  initial :green
161
139
 
162
- events {
163
- event :slow, :green => :yellow
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.define do
151
+ fsm = FiniteMachine.new do
176
152
  initial :green, defer: true
177
153
 
178
- events {
179
- event :slow, :green => :yellow
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.define do
166
+ fsm = FiniteMachine.new do
193
167
  initial :green, silent: false
194
168
 
195
- events {
196
- event :slow, :green => :yellow
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.define do
179
+ fsm = FiniteMachine.new do
209
180
  initial :green, silent: false, defer: true
210
181
 
211
- events {
212
- event :slow, :green => :yellow
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
@@ -1,17 +1,22 @@
1
- # encoding: utf-8
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.define do
5
+ fsm = FiniteMachine.new do
8
6
  initial :green
9
7
 
10
- events {
11
- event :slow, :green => :yellow
12
- event :stop, :yellow => :red
13
- }
8
+ event :slow, :green => :yellow
9
+ event :stop, :yellow => :red
14
10
  end
15
- expect(fsm.inspect).to match(/^<#FiniteMachine::StateMachine:0x#{fsm.object_id.to_s(16)} @states=\[:none, :green, :yellow, :red\], @events=\[:init, :slow, :stop\], @transitions=\[{:none=>:green}, {:green=>:yellow}, {:yellow=>:red}\]>$/)
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
@@ -1,19 +1,15 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
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.define do
6
+ fsm = FiniteMachine.new do
9
7
  initial :green
10
8
 
11
- events {
12
- event :slow, :green => :yellow
13
- event :stop, :yellow => :red
14
- event :ready, :red => :yellow
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.define do
31
+ fsm = FiniteMachine.new do
36
32
  initial :green
37
33
 
38
- events {
39
- event :slow, :green => :yellow
40
- event :stop, :yellow => :red
41
- event :ready, :red => :yellow
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
- # encoding: utf-8
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.define log_transitions: true do
9
+ fsm = FiniteMachine.new log_transitions: true do
14
10
  initial :green
15
11
 
16
- events {
17
- event :slow, :green => :yellow
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
@@ -1,6 +1,4 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
1
+ # frozen_string_literal: true
4
2
 
5
3
  RSpec.describe FiniteMachine::Logger do
6
4
  let(:message) { 'error' }
@@ -1,55 +1,62 @@
1
- # encoding: utf-8
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.01)
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 << event2 << event3
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.alive?).to be(true)
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