@@ -135,6 +135,61 @@ test("state transition fired during onleavestate hook - with MIXED async and non
135135
136136//-----------------------------------------------------------------------------
137137
138+ test ( "state transitions using onleavestate run-time return value instead of design-time async attribute" , function ( ) {
139+
140+ var fsm = StateMachine . create ( {
141+ initial : 'green' ,
142+ events : [
143+ { name : 'warn' , from : 'green' , to : 'yellow' } ,
144+ { name : 'panic' , from : 'yellow' , to : 'red' } ,
145+ { name : 'calm' , from : 'red' , to : 'yellow' } ,
146+ { name : 'clear' , from : 'yellow' , to : 'green' }
147+ ] } ) ;
148+
149+ // default behavior is synchronous
150+
151+ equals ( fsm . current , 'green' , "initial state should be green" ) ;
152+ fsm . warn ( ) ; equals ( fsm . current , 'yellow' , "warn event should transition from green to yellow" ) ;
153+ fsm . panic ( ) ; equals ( fsm . current , 'red' , "panic event should transition from yellow to red" ) ;
154+ fsm . calm ( ) ; equals ( fsm . current , 'yellow' , "calm event should transition from red to yellow" ) ;
155+ fsm . clear ( ) ; equals ( fsm . current , 'green' , "clear event should transition from yellow to green" ) ;
156+
157+ // but add hooks that return false and it magically becomes asynchronous
158+
159+ fsm . onleavegreen = function ( ) { return false ; }
160+ fsm . onleaveyellow = function ( ) { return false ; }
161+ fsm . onleavered = function ( ) { return false ; }
162+
163+ equals ( fsm . current , 'green' , "initial state should be green" ) ;
164+ fsm . warn ( ) ; equals ( fsm . current , 'green' , "should still be green because we haven't transitioned yet" ) ;
165+ fsm . transition ( ) ; equals ( fsm . current , 'yellow' , "warn event should transition from green to yellow" ) ;
166+ fsm . panic ( ) ; equals ( fsm . current , 'yellow' , "should still be yellow because we haven't transitioned yet" ) ;
167+ fsm . transition ( ) ; equals ( fsm . current , 'red' , "panic event should transition from yellow to red" ) ;
168+ fsm . calm ( ) ; equals ( fsm . current , 'red' , "should still be red because we haven't transitioned yet" ) ;
169+ fsm . transition ( ) ; equals ( fsm . current , 'yellow' , "calm event should transition from red to yellow" ) ;
170+ fsm . clear ( ) ; equals ( fsm . current , 'yellow' , "should still be yellow because we haven't transitioned yet" ) ;
171+ fsm . transition ( ) ; equals ( fsm . current , 'green' , "clear event should transition from yellow to green" ) ;
172+
173+ // this allows you to make on-the-fly decisions about whether async or not ...
174+
175+ fsm . onleavegreen = function ( async ) {
176+ if ( async ) {
177+ setTimeout ( function ( ) { fsm . transition ( ) } , 10 ) ;
178+ return false ;
179+ }
180+ }
181+ fsm . onleaveyellow = fsm . onleavered = null ;
182+
183+ fsm . warn ( false ) ; equals ( fsm . current , 'yellow' , "expected synchronous transition from green to yellow" ) ;
184+ fsm . clear ( ) ; equals ( fsm . current , 'green' , "clear event should transition from yellow to green" ) ;
185+ fsm . warn ( true ) ; equals ( fsm . current , 'green' , "should still be green because we haven't transitioned yet" ) ;
186+ fsm . transition ( ) ; equals ( fsm . current , 'yellow' , "warn event should transition from green to yellow" ) ;
187+
188+ } ) ;
189+
190+ //-----------------------------------------------------------------------------
191+
192+
138193test ( "state transition fired without completing previous transition" , function ( ) {
139194
140195 var fsm = StateMachine . create ( {
0 commit comments