11require (" busted" )
22
33local machine = require (" statemachine" )
4+ local _ = require (" luassert.match" )._
45
56describe (" Lua state machine framework" , function ()
67 describe (" A stop light" , function ()
@@ -68,11 +69,13 @@ describe("Lua state machine framework", function()
6869
6970 fsm :warn ()
7071
71- assert .spy (fsm .onbeforewarn ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
72- assert .spy (fsm .onleavegreen ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
73- assert .spy (fsm .onenteryellow ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
74- assert .spy (fsm .onafterwarn ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
75- assert .spy (fsm .onstatechange ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
72+ assert .spy (fsm .onbeforewarn ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
73+ assert .spy (fsm .onleavegreen ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
74+
75+ assert .spy (fsm .onenteryellow ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
76+ assert .spy (fsm .onafterwarn ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
77+ assert .spy (fsm .onstatechange ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
78+
7679 assert .spy (fsm .onyellow ).was_not_called ()
7780 assert .spy (fsm .onwarn ).was_not_called ()
7881 end )
@@ -89,11 +92,12 @@ describe("Lua state machine framework", function()
8992
9093 fsm :warn ()
9194
92- assert .spy (fsm .onbeforewarn ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
93- assert .spy (fsm .onleavegreen ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
94- assert .spy (fsm .onenteryellow ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
95- assert .spy (fsm .onafterwarn ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
96- assert .spy (fsm .onstatechange ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
95+ assert .spy (fsm .onbeforewarn ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
96+ assert .spy (fsm .onleavegreen ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
97+
98+ assert .spy (fsm .onenteryellow ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
99+ assert .spy (fsm .onafterwarn ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
100+ assert .spy (fsm .onstatechange ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
97101
98102 assert .spy (fsm .onyellow ).was_not_called ()
99103 assert .spy (fsm .onwarn ).was_not_called ()
@@ -108,11 +112,12 @@ describe("Lua state machine framework", function()
108112
109113 fsm :warn (' bar' )
110114
111- assert .spy (fsm .onbeforewarn ).was_called_with (fsm , ' warn' , ' green' , ' yellow' , ' bar' )
112- assert .spy (fsm .onleavegreen ).was_called_with (fsm , ' warn' , ' green' , ' yellow' , ' bar' )
113- assert .spy (fsm .onenteryellow ).was_called_with (fsm , ' warn' , ' green' , ' yellow' , ' bar' )
114- assert .spy (fsm .onafterwarn ).was_called_with (fsm , ' warn' , ' green' , ' yellow' , ' bar' )
115- assert .spy (fsm .onstatechange ).was_called_with (fsm , ' warn' , ' green' , ' yellow' , ' bar' )
115+ assert .spy (fsm .onbeforewarn ).was_called_with (_ , ' warn' , ' green' , ' yellow' , ' bar' )
116+ assert .spy (fsm .onleavegreen ).was_called_with (_ , ' warn' , ' green' , ' yellow' , ' bar' )
117+
118+ assert .spy (fsm .onenteryellow ).was_called_with (_ , ' warn' , ' green' , ' yellow' , ' bar' )
119+ assert .spy (fsm .onafterwarn ).was_called_with (_ , ' warn' , ' green' , ' yellow' , ' bar' )
120+ assert .spy (fsm .onstatechange ).was_called_with (_ , ' warn' , ' green' , ' yellow' , ' bar' )
116121 end )
117122
118123 it (" should fire short handlers as a fallback" , function ()
@@ -121,8 +126,8 @@ describe("Lua state machine framework", function()
121126
122127 fsm :warn ()
123128
124- assert .spy (fsm .onyellow ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
125- assert .spy (fsm .onwarn ).was_called_with (fsm , ' warn' , ' green' , ' yellow' )
129+ assert .spy (fsm .onyellow ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
130+ assert .spy (fsm .onwarn ).was_called_with (_ , ' warn' , ' green' , ' yellow' )
126131 end )
127132
128133 it (" should cancel the warn event from onleavegreen" , function ()
@@ -147,6 +152,124 @@ describe("Lua state machine framework", function()
147152 assert .are_equal (fsm .current , ' green' )
148153 end )
149154
155+ it (" pauses when async is passed" , function ()
156+ fsm .onleavegreen = function (self , name , from , to )
157+ return fsm .ASYNC
158+ end
159+ fsm .onenteryellow = function (self , name , from , to )
160+ return fsm .ASYNC
161+ end
162+
163+ local result = fsm :warn ()
164+ assert .is_true (result )
165+ assert .are_equal (fsm .current , ' green' )
166+ assert .are_equal (fsm .currentTransitioningEvent , ' warn' )
167+ assert .are_equal (fsm .asyncState , ' warnWaitingOnLeave' )
168+
169+ result = fsm :transition (fsm .currentTransitioningEvent )
170+ assert .is_true (result )
171+ assert .are_equal (fsm .current , ' yellow' )
172+ assert .are_equal (fsm .currentTransitioningEvent , ' warn' )
173+ assert .are_equal (fsm .asyncState , ' warnWaitingOnEnter' )
174+
175+ result = fsm :transition (fsm .currentTransitioningEvent )
176+ assert .is_true (result )
177+ assert .are_equal (fsm .current , ' yellow' )
178+ assert .is_nil (fsm .currentTransitioningEvent )
179+ assert .are_equal (fsm .asyncState , fsm .NONE )
180+ end )
181+
182+ it (" should accept additional arguments to async handlers" , function ()
183+ fsm .onbeforewarn = stub .new ()
184+ fsm .onleavegreen = spy .new (function (self , name , from , to , arg )
185+ return fsm .ASYNC
186+ end )
187+ fsm .onenteryellow = spy .new (function (self , name , from , to , arg )
188+ return fsm .ASYNC
189+ end )
190+ fsm .onafterwarn = stub .new ()
191+ fsm .onstatechange = stub .new ()
192+
193+ fsm :warn (' bar' )
194+ assert .spy (fsm .onbeforewarn ).was_called_with (_ , ' warn' , ' green' , ' yellow' , ' bar' )
195+ assert .spy (fsm .onleavegreen ).was_called_with (_ , ' warn' , ' green' , ' yellow' , ' bar' )
196+
197+ fsm :transition (fsm .currentTransitioningEvent )
198+ assert .spy (fsm .onenteryellow ).was_called_with (_ , ' warn' , ' green' , ' yellow' , ' bar' )
199+
200+ fsm :transition (fsm .currentTransitioningEvent )
201+ assert .spy (fsm .onafterwarn ).was_called_with (_ , ' warn' , ' green' , ' yellow' , ' bar' )
202+ assert .spy (fsm .onstatechange ).was_called_with (_ , ' warn' , ' green' , ' yellow' , ' bar' )
203+ end )
204+
205+ it (" should properly transition when another event happens during leave async" , function ()
206+ local tempStoplight = {}
207+ for _ , event in ipairs (stoplight ) do
208+ table.insert (tempStoplight , event )
209+ end
210+ table.insert (tempStoplight , { name = " panic" , from = " green" , to = " red" })
211+
212+ local fsm = machine .create ({
213+ initial = ' green' ,
214+ events = tempStoplight
215+ })
216+
217+ fsm .onleavegreen = function (self , name , from , to )
218+ return fsm .ASYNC
219+ end
220+
221+ fsm :warn ()
222+
223+ local result = fsm :panic ()
224+ local transitionResult = fsm :transition (fsm .currentTransitioningEvent )
225+
226+ assert .is_true (result )
227+ assert .is_true (transitionResult )
228+ assert .is_nil (fsm .currentTransitioningEvent )
229+ assert .are_equal (fsm .asyncState , fsm .NONE )
230+ assert .are_equal (fsm .current , ' red' )
231+ end )
232+
233+ it (" should properly transition when another event happens during enter async" , function ()
234+ fsm .onenteryellow = function (self , name , from , to )
235+ return fsm .ASYNC
236+ end
237+
238+ fsm :warn ()
239+
240+ local result = fsm :panic ()
241+
242+ assert .is_true (result )
243+ assert .is_nil (fsm .currentTransitioningEvent )
244+ assert .are_equal (fsm .asyncState , fsm .NONE )
245+ assert .are_equal (fsm .current , ' red' )
246+ end )
247+
248+ it (" should properly cancel the transition if asked" , function ()
249+ fsm .onleavegreen = function (self , name , from , to )
250+ return fsm .ASYNC
251+ end
252+
253+ fsm :warn ()
254+ fsm :cancelTransition (fsm .currentTransitioningEvent )
255+
256+ assert .is_nil (fsm .currentTransitioningEvent )
257+ assert .are_equal (fsm .asyncState , fsm .NONE )
258+ assert .are_equal (fsm .current , ' green' )
259+
260+ fsm .onleavegreen = nil
261+ fsm .onenteryellow = function (self , name , from , to )
262+ return fsm .ASYNC
263+ end
264+
265+ fsm :warn ()
266+ fsm :cancelTransition (fsm .currentTransitioningEvent )
267+
268+ assert .is_nil (fsm .currentTransitioningEvent )
269+ assert .are_equal (fsm .asyncState , fsm .NONE )
270+ assert .are_equal (fsm .current , ' yellow' )
271+ end )
272+
150273 it (" todot generates dot file (graphviz)" , function ()
151274 assert .has_no_error (function ()
152275 fsm :todot (' stoplight.dot' )
0 commit comments