@@ -11,6 +11,17 @@ import XCTest
1111
1212class MachineTests : _TestCase
1313{
14+ func testConfigure( )
15+ {
16+ let machine = Machine < MyState , MyEvent > ( state: . State0)
17+
18+ machine. configure {
19+ $0. addRoutes ( event: . Event0, transitions: [ . State0 => . State1 ] )
20+ }
21+
22+ XCTAssertTrue ( machine. canTryEvent ( . Event0) != nil )
23+ }
24+
1425 //--------------------------------------------------
1526 // MARK: - tryEvent a.k.a `<-!`
1627 //--------------------------------------------------
@@ -39,6 +50,9 @@ class MachineTests: _TestCase
3950 ] )
4051 }
4152
53+ // initial
54+ XCTAssertEqual ( machine. state, MyState . State0)
55+
4256 // tryEvent
4357 machine <-! . Event0
4458 XCTAssertEqual ( machine. state, MyState . State1)
@@ -52,7 +66,36 @@ class MachineTests: _TestCase
5266 XCTAssertEqual ( machine. state, MyState . State2, " Event0 doesn't have 2 => Any " )
5367 }
5468
55- func testTryEvent_customOperator( )
69+ func testTryEvent_userInfo( )
70+ {
71+ var userInfo : Any ? = nil
72+
73+ let machine = Machine < MyState , MyEvent > ( state: . State0) { machine in
74+ // add 0 => 1 => 2
75+ machine. addRoutes ( event: . Event0, transitions: [
76+ . State0 => . State1,
77+ . State1 => . State2,
78+ ] , handler: { context in
79+ userInfo = context. userInfo
80+ } )
81+ }
82+
83+ // initial
84+ XCTAssertEqual ( machine. state, MyState . State0)
85+ XCTAssertNil ( userInfo)
86+
87+ // tryEvent
88+ machine <-! ( . Event0, " gogogo " )
89+ XCTAssertEqual ( machine. state, MyState . State1)
90+ XCTAssertTrue ( userInfo as! String == " gogogo " )
91+
92+ // tryEvent
93+ machine <-! ( . Event0, " done " )
94+ XCTAssertEqual ( machine. state, MyState . State2)
95+ XCTAssertTrue ( userInfo as! String == " done " )
96+ }
97+
98+ func testTryEvent_twice( )
5699 {
57100 let machine = Machine < MyState , MyEvent > ( state: . State0) { machine in
58101 // add 0 => 1
@@ -231,6 +274,33 @@ class MachineTests: _TestCase
231274 XCTAssertEqual ( invokeCount, 0 , " Handler should NOT be performed " )
232275 }
233276
277+ func testRemoveRoute_handler( )
278+ {
279+ var invokeCount = 0
280+
281+ let machine = Machine < MyState , MyEvent > ( state: . State0) { machine in
282+
283+ // add 0 => 1 => 2
284+ let routeDisposable = machine. addRoutes ( event: . Event0, transitions: [
285+ . State0 => . State1,
286+ . State1 => . State2,
287+ ] , handler: { context in
288+ invokeCount++
289+ return
290+ } )
291+
292+ // removeRoute
293+ routeDisposable. dispose ( )
294+
295+ }
296+
297+ // tryEvent
298+ machine <-! . Event0
299+ XCTAssertEqual ( machine. state, MyState . State0, " Route should be removed. " )
300+
301+ XCTAssertEqual ( invokeCount, 0 , " Handler should NOT be performed " )
302+ }
303+
234304 //--------------------------------------------------
235305 // MARK: - add/removeHandler
236306 //--------------------------------------------------
@@ -265,6 +335,26 @@ class MachineTests: _TestCase
265335 XCTAssertEqual ( invokeCount, 2 )
266336 }
267337
338+ func testAddErrorHandler( )
339+ {
340+ var invokeCount = 0
341+
342+ let machine = Machine < MyState , MyEvent > ( state: . State0) { machine in
343+ machine. addRoutes ( event: . Event0, transitions: [ . State0 => . State1 ] )
344+ machine. addErrorHandler { event, fromState, toState, userInfo in
345+ invokeCount++
346+ }
347+ }
348+
349+ XCTAssertEqual ( invokeCount, 0 )
350+
351+ // tryEvent (fails)
352+ machine <-! . Event1
353+
354+ XCTAssertEqual ( invokeCount, 1 , " Error handler should be called. " )
355+
356+ }
357+
268358 func testRemoveHandler( )
269359 {
270360 var invokeCount = 0
@@ -366,4 +456,85 @@ class MachineTests: _TestCase
366456
367457 }
368458
459+ func testAddRouteMapping_handler( )
460+ {
461+ var invokeCount1 = 0
462+ var invokeCount2 = 0
463+ var disposables = [ Disposable] ( )
464+
465+ let machine = Machine < StrState , StrEvent > ( state: . Str( " initial " ) ) { machine in
466+
467+ let d = machine. addRouteMapping ( { event, fromState, userInfo -> StrState ? in
468+ // no route for no-event
469+ guard let event = event else { return nil }
470+
471+ switch ( event, fromState) {
472+ case ( . Str( " gogogo " ) , . Str( " initial " ) ) :
473+ return . Str( " Phase 1 " )
474+ default :
475+ return nil
476+ }
477+ } , handler: { context in
478+ invokeCount1++
479+ } )
480+
481+ disposables += [ d]
482+
483+ let d2 = machine. addRouteMapping ( { event, fromState, userInfo -> StrState ? in
484+ // no route for no-event
485+ guard let event = event else { return nil }
486+
487+ switch ( event, fromState) {
488+ case ( . Str( " finish " ) , . Str( " Phase 1 " ) ) :
489+ return . Str( " end " )
490+ default :
491+ return nil
492+ }
493+ } , handler: { context in
494+ invokeCount2++
495+ } )
496+
497+ disposables += [ d2]
498+
499+ }
500+
501+ // initial
502+ XCTAssertEqual ( machine. state, StrState . Str ( " initial " ) )
503+
504+ // tryEvent (fails)
505+ machine <-! . Str( " go? " )
506+ XCTAssertEqual ( machine. state, StrState . Str ( " initial " ) , " No change. " )
507+ XCTAssertEqual ( invokeCount1, 0 )
508+ XCTAssertEqual ( invokeCount2, 0 )
509+
510+ // tryEvent
511+ machine <-! . Str( " gogogo " )
512+ XCTAssertEqual ( machine. state, StrState . Str ( " Phase 1 " ) )
513+ XCTAssertEqual ( invokeCount1, 1 )
514+ XCTAssertEqual ( invokeCount2, 0 )
515+
516+ // tryEvent (fails)
517+ machine <-! . Str( " gogogo " )
518+ XCTAssertEqual ( machine. state, StrState . Str ( " Phase 1 " ) , " No change. " )
519+ XCTAssertEqual ( invokeCount1, 1 )
520+ XCTAssertEqual ( invokeCount2, 0 )
521+
522+ // tryEvent
523+ machine <-! . Str( " finish " )
524+ XCTAssertEqual ( machine. state, StrState . Str ( " end " ) )
525+ XCTAssertEqual ( invokeCount1, 1 )
526+ XCTAssertEqual ( invokeCount2, 1 )
527+
528+ // hasRoute (before dispose)
529+ XCTAssertEqual ( machine. hasRoute ( event: . Str( " gogogo " ) , transition: . Str( " initial " ) => . Str( " Phase 1 " ) ) , true )
530+ XCTAssertEqual ( machine. hasRoute ( event: . Str( " finish " ) , transition: . Str( " Phase 1 " ) => . Str( " end " ) ) , true )
531+
532+ disposables. forEach { $0. dispose ( ) }
533+
534+ // hasRoute (after dispose)
535+ XCTAssertEqual ( machine. hasRoute ( event: . Str( " gogogo " ) , transition: . Str( " initial " ) => . Str( " Phase 1 " ) ) , false , " Routes & handlers should be disposed. " )
536+ XCTAssertEqual ( machine. hasRoute ( event: . Str( " finish " ) , transition: . Str( " Phase 1 " ) => . Str( " end " ) ) , false , " Routes & handlers should be disposed. " )
537+
538+ }
539+
369540}
0 commit comments