package Ġcom . t inder Ċ Ċ import Ġkotlin . test . Test Ċ import Ġkotlin . test . assertEquals Ċ import Ġkotlin . test . assert Fails With Ċ Ċ internal Ġclass ĠState Machine Test Ġ{ ĊĊĠĠĠ Ġclass ĠMat ter StateMachine Ġ{ ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġlogger Ġ= ĠLogger Mock () ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġstate Machine Ġ= ĠState Machine . create < State , ĠEvent , ĠSide Effect > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠinitialState ( State . Solid ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate < State . Solid > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . On Mel ted > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . Liquid , ĠSide Effect . Log Mel ted ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate < State . Liquid > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . On Frozen > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . Solid , ĠSide Effect . Log Frozen ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . On V apor ized > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . Gas , ĠSide Effect . Log V apor ized ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate < State . Gas > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . On Con dense d > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . Liquid , ĠSide Effect . Log Con dense d ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Transition Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalid Transition Ġ= Ġit Ġas ? ĠState Machine . Transition . Valid Ġ?: Ġreturn @ on Transition ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( valid Transition . side Effect ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSide Effect . Log Mel ted Ġ-> Ġlogger . log ( ON _ ME LT ED _ MESSAGE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSide Effect . Log Frozen Ġ-> Ġlogger . log ( ON _ F RO Z EN _ MESSAGE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSide Effect . Log V apor ized Ġ-> Ġlogger . log ( ON _ V AP ORIZ ED _ MESSAGE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSide Effect . Log Con dense d Ġ-> Ġlogger . log ( ON _ COND ENSE D _ MESSAGE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun ĠinitialState _ shouldBe Solid () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Solid , Ġstate Machine . state ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġgiven State Is Solid _ on Mel ted _ should Transition To Liquid State And Log () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGiven ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Machine Ġ= Ġgiven State Is ( State . Solid ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( Event . On Mel ted ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Liquid , Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( State . Solid , ĠEvent . On Mel ted , ĠState . Liquid , ĠSide Effect . Log Mel ted ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( ON _ ME LT ED _ MESSAGE , Ġlogger . last Message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġgiven State Is Liquid _ on F ro ze _ should Transition ToS olid State And Log () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGiven ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Machine Ġ= Ġgiven State Is ( State . Liquid ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( Event . On Frozen ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Solid , Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( State . Liquid , ĠEvent . On Frozen , ĠState . Solid , ĠSide Effect . Log Frozen ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( ON _ F RO Z EN _ MESSAGE , Ġlogger . last Message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġgiven State Is Liquid _ on V apor ized _ should Transition To Gas State And Log () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGiven ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Machine Ġ= Ġgiven State Is ( State . Liquid ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( Event . On V apor ized ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Gas , Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( State . Liquid , ĠEvent . On V apor ized , ĠState . Gas , ĠSide Effect . Log V apor ized ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( ON _ V AP ORIZ ED _ MESSAGE , Ġlogger . last Message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġgiven State Is Gas _ on Con dense d _ should Transition To Liquid State And Log () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGiven ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Machine Ġ= Ġgiven State Is ( State . Gas ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( Event . On Con dense d ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Liquid , Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( State . Gas , ĠEvent . On Con dense d , ĠState . Liquid , ĠSide Effect . Log Con dense d ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( ON _ COND ENSE D _ MESSAGE , Ġlogger . last Message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġgiven State Is ( state : ĠState ): ĠState Machine < State , ĠEvent , ĠSide Effect > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġstate Machine . with Ġ{ ĠinitialState ( state ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconst Ġval ĠON _ ME LT ED _ MESSAGE Ġ= Ġ" I Ġme lt ed " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconst Ġval ĠON _ F RO Z EN _ MESSAGE Ġ= Ġ" I Ġf ro ze " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconst Ġval ĠON _ V AP ORIZ ED _ MESSAGE Ġ= Ġ" I Ġv apor ized " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconst Ġval ĠON _ COND ENSE D _ MESSAGE Ġ= Ġ" I Ġcond ensed " ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsealed Ġclass ĠState Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠSolid Ġ: ĠState () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠLi quid Ġ: ĠState () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠG as Ġ: ĠState () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsealed Ġclass ĠEvent Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠOn Mel ted Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠOn Frozen Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠOn V apor ized Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠOn Con dense d Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsealed Ġclass ĠSide Effect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠLog Mel ted Ġ: ĠSide Effect () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠLog Frozen Ġ: ĠSide Effect () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠLog V apor ized Ġ: ĠSide Effect () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠLog Con dense d Ġ: ĠSide Effect () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Utility Ġclass Ġto Ġmock Ġlogger Ġdue Ġto ĠKotlin ĠMulti platform Ġlimitations ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclass ĠLogger Mock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlateinit Ġvar Ġlast Message : ĠString ; ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġlog ( message : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlast Message Ġ= Ġmessage ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠTurn st ile StateMachine Ġ{ ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġstate Machine Ġ= ĠState Machine . create < State , ĠEvent , ĠCommand > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠinitialState ( State . Locked ( credit Ġ= Ġ 0 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate < State . Locked > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . Insert Coin > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Credit Ġ= Ġcredit Ġ+ Ġit . value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Credit Ġ>= ĠF ARE _ PRICE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . Unlock ed , ĠCommand . Open Do ors ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . Locked ( new Credit )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . Ad mit Person > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdont Transition ( Command . Sound Alarm ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . Machine Did Fail > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . Broken ( this ), ĠCommand . Order Repair ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate < State . Unlock ed > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . Ad mit Person > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . Locked ( credit Ġ= Ġ 0 ), ĠCommand . Close Do ors ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate < State . Broken > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . Machine Repair Did Complete > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( old State ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun ĠinitialState _ shouldBe Locked () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Locked ( credit Ġ= Ġ 0 ), Ġstate Machine . state ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġgiven State Is Locked _ when Insert Coin _ and Credit LessThan F air Price _ should Transition To Locked State () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( Event . Insert Coin ( 1 0 )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Locked ( credit Ġ= Ġ 1 0 ), Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Locked ( credit Ġ= Ġ 0 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEvent . Insert Coin ( 1 0 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Locked ( credit Ġ= Ġ 1 0 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġgiven State Is Locked _ when Insert Coin _ and Credit Equals F air Price _ should Transition To Unlock ed State And Open Do ors () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGiven ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Machine Ġ= Ġgiven State Is ( State . Locked ( credit Ġ= Ġ 3 5 )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( Event . Insert Coin ( 1 5 )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Unlock ed , Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Locked ( credit Ġ= Ġ 3 5 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEvent . Insert Coin ( 1 5 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Unlock ed , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCommand . Open Do ors ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġgiven State Is Locked _ when Insert Coin _ and Credit More Than F air Price _ should Transition To Unlock ed State And Open Do ors () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGiven ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Machine Ġ= Ġgiven State Is ( State . Locked ( credit Ġ= Ġ 3 5 )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( Event . Insert Coin ( 2 0 )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Unlock ed , Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Locked ( credit Ġ= Ġ 3 5 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEvent . Insert Coin ( 2 0 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Unlock ed , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCommand . Open Do ors ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġgiven State Is Locked _ when Ad mit Person _ should Transition To Locked State And Sound Alarm () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGiven ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Machine Ġ= Ġgiven State Is ( State . Locked ( credit Ġ= Ġ 3 5 )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( Event . Ad mit Person ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Locked ( credit Ġ= Ġ 3 5 ), Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Locked ( credit Ġ= Ġ 3 5 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEvent . Ad mit Person , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Locked ( credit Ġ= Ġ 3 5 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCommand . Sound Alarm ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġgiven State Is Locked _ when Machine Did Fail _ should Transition To Broken State And Order Repair () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGiven ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Machine Ġ= Ġgiven State Is ( State . Locked ( credit Ġ= Ġ 1 5 )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition To Broken Ġ= Ġstate Machine . transition ( Event . Machine Did Fail ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Broken ( old State Ġ= ĠState . Locked ( credit Ġ= Ġ 1 5 )), Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Locked ( credit Ġ= Ġ 1 5 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEvent . Machine Did Fail , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Broken ( old State Ġ= ĠState . Locked ( credit Ġ= Ġ 1 5 )), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCommand . Order Repair ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To Broken ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġgiven State Is Unlock ed _ when Ad mit Person _ should Transition To Locked State And Close Do ors () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGiven ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Machine Ġ= Ġgiven State Is ( State . Unlock ed ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( Event . Ad mit Person ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Locked ( credit Ġ= Ġ 0 ), Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Unlock ed , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEvent . Ad mit Person , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Locked ( credit Ġ= Ġ 0 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCommand . Close Do ors ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠ Ġfun Ġgiven State Is Broken _ when Machine Repair Did Complete _ should Transition To Locked State () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGiven ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Machine Ġ= Ġgiven State Is ( State . Broken ( old State Ġ= ĠState . Locked ( credit Ġ= Ġ 1 5 ))) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( Event . Machine Repair Did Complete ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . Locked ( credit Ġ= Ġ 1 5 ), Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Broken ( old State Ġ= ĠState . Locked ( credit Ġ= Ġ 1 5 )), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEvent . Machine Repair Did Complete , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠState . Locked ( credit Ġ= Ġ 1 5 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġgiven State Is ( state : ĠState ): ĠState Machine < State , ĠEvent , ĠCommand > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġstate Machine . with Ġ{ ĠinitialState ( state ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠF ARE _ PRICE Ġ= Ġ 5 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsealed Ġclass ĠState Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠLocked ( val Ġcredit : ĠInt ) Ġ: ĠState () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠUn locked Ġ: ĠState () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠBroken ( val Ġold State : ĠState ) Ġ: ĠState () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsealed Ġclass ĠEvent Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠInsert Coin ( val Ġvalue : ĠInt ) Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠAd mit Person Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠMachine Did Fail Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠMachine Repair Did Complete Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsealed Ġclass ĠCommand Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠSound Alarm Ġ: ĠCommand () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠClose Do ors Ġ: ĠCommand () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠOpen Do ors Ġ: ĠCommand () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠOrder Repair Ġ: ĠCommand () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠObject StateMachine Ġ{ ĊĊĠĠĠĠĠĠĠ Ġclass ĠWith InitialState Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon Transition Listener 1 Ġ= ĠTransition Listener Mock <( StateMachine . Transition < State , ĠEvent , ĠSide Effect >) >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon Transition Listener 2 Ġ= ĠTransition Listener Mock <( StateMachine . Transition < State , ĠEvent , ĠSide Effect >) >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon State A Exit Listener 1 Ġ= ĠState Listener Mock < State , ĠEvent >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon State A Exit Listener 2 Ġ= ĠState Listener Mock < State , ĠEvent >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon State C Enter Listener 1 Ġ= ĠState Listener Mock < State , ĠEvent >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon State C Enter Listener 2 Ġ= ĠState Listener Mock < State , ĠEvent >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġstate Machine Ġ= ĠState Machine . create < State , ĠEvent , ĠSide Effect > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠinitialState ( State . A ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate < State . A > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Exit ( on State A Exit Listener 1 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Exit ( on State A Exit Listener 2 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . E 1 > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . B ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . E 2 > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . C ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . E 4 > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . D ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate < State . B > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . E 3 > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( State . C , ĠSide Effect . SE 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate < State . C > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon < Event . E 4 > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdont Transition () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Enter ( on State C Enter Listener 1 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Enter ( on State C Enter Listener 2 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Transition ( on Transition Listener 1 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Transition ( on Transition Listener 2 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġstate _ should Return InitialState () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġstate Machine . state ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . A , Ġstate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Valid Event _ should Return Transition () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition From State A To State B Ġ= Ġstate Machine . transition ( Event . E 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( State . A , ĠEvent . E 1 , ĠState . B , Ġnull ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition From State A To State B ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition From State B To State C Ġ= Ġstate Machine . transition ( Event . E 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( State . B , ĠEvent . E 3 , ĠState . C , ĠSide Effect . SE 1 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition From State B To State C ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Valid Event _ should Create AndSet New State () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( Event . E 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . B , Ġstate Machine . state ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( Event . E 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( State . C , Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Valid Event _ should Trigger On State ChangeListener () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( Event . E 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( State . A , ĠEvent . E 1 , ĠState . B , Ġnull ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Transition Listener 1 . call ers . last ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( Event . E 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( State . B , ĠEvent . E 3 , ĠState . C , ĠSide Effect . SE 1 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Transition Listener 2 . call ers . last ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( Event . E 4 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( State . C , ĠEvent . E 4 , ĠState . C , Ġnull ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Transition Listener 2 . call ers . last ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Valid Event _ should Trigger On Enter Listeners () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( Event . E 2 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( listOf ( State . C , ĠEvent . E 2 ), Ġon State C Enter Listener 1 . call ers . last ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( listOf ( State . C , ĠEvent . E 2 ), Ġon State C Enter Listener 2 . call ers . last ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Valid Event _ should Trigger On Exit Listeners () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( Event . E 2 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( listOf ( State . A , ĠEvent . E 2 ), Ġon State A Exit Listener 1 . call ers . last ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( listOf ( State . A , ĠEvent . E 2 ), Ġon State A Exit Listener 2 . call ers . last ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Invalid Event _ should Return Invalid Transition () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfrom State Ġ= Ġstate Machine . state ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( Event . E 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Invalid < State , ĠEvent , ĠSide Effect >( State . A , ĠEvent . E 3 ), Ġtransition ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( from State , Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Un declared State _ should Throw IllegalStateException () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassert Fails With < IllegalStateException > Ġ{ Ġstate Machine . transition ( Event . E 4 ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġclass ĠWithout InitialState Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġcreate _ given No InitialState _ should Throw IllegalArgumentException () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassert Fails With < IllegalArgumentException > Ġ{ ĠState Machine . create < State , ĠEvent , ĠSide Effect > Ġ{} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġsealed Ġclass ĠState Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠA Ġ: ĠState () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠB Ġ: ĠState () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠC Ġ: ĠState () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠD Ġ: ĠState () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġsealed Ġclass ĠEvent Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠE 1 Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠE 2 Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠE 3 Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠE 4 Ġ: ĠEvent () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġsealed Ġclass ĠSide Effect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠSE 1 Ġ: ĠSide Effect () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠSE 2 Ġ: ĠSide Effect () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠSE 3 Ġ: ĠSide Effect () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠConstant StateMachine Ġ{ ĊĊĠĠĠĠĠĠĠ Ġclass ĠWith InitialState Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon Transition Listener 1 Ġ= ĠTransition Listener Mock <( StateMachine . Transition < String , ĠInt , ĠString >) >(); ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon Transition Listener 2 Ġ= ĠTransition Listener Mock <( StateMachine . Transition < String , ĠInt , ĠString >) >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon State C Enter Listener 1 Ġ= ĠState Listener Mock < String , ĠInt >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon State C Enter Listener 2 Ġ= ĠState Listener Mock < String , ĠInt >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon State A Exit Listener 1 Ġ= ĠState Listener Mock < String , ĠInt >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġon State A Exit Listener 2 Ġ= ĠState Listener Mock < String , ĠInt >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġstate Machine Ġ= ĠState Machine . create < String , ĠInt , ĠString > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠinitialState ( STATE _ A ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate ( STATE _ A ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Exit ( on State A Exit Listener 1 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Exit ( on State A Exit Listener 2 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon ( EVENT _ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( STATE _ B ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon ( EVENT _ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( STATE _ C ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon ( EVENT _ 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( STATE _ D ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate ( STATE _ B ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon ( EVENT _ 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( STATE _ C , ĠS IDE _ EFFECT _ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate ( STATE _ C ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Enter ( on State C Enter Listener 1 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Enter ( on State C Enter Listener 2 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Transition ( on Transition Listener 1 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Transition ( on Transition Listener 2 :: invoke ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġstate _ should Return InitialState () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġstate Machine . state ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( STATE _ A , Ġstate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Valid Event _ should Return True () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition From State A To State B Ġ= Ġstate Machine . transition ( EVENT _ 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( STATE _ A , ĠEVENT _ 1 , ĠSTATE _ B , Ġnull ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition From State A To State B ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition From State B To State C Ġ= Ġstate Machine . transition ( EVENT _ 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( STATE _ B , ĠEVENT _ 3 , ĠSTATE _ C , ĠS IDE _ EFFECT _ 1 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition From State B To State C ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Valid Event _ should Create AndSet New State () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( EVENT _ 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( STATE _ B , Ġstate Machine . state ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( EVENT _ 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( STATE _ C , Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Valid Event _ should Trigger On State ChangeListener () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( EVENT _ 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( STATE _ A , ĠEVENT _ 1 , ĠSTATE _ B , Ġnull ), Ġon Transition Listener 1 . call ers . last ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( EVENT _ 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Valid ( STATE _ B , ĠEVENT _ 3 , ĠSTATE _ C , ĠS IDE _ EFFECT _ 1 ), Ġon Transition Listener 2 . call ers . last ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Valid Event _ should Trigger On Enter Listeners () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( EVENT _ 2 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( listOf ( STATE _ C , ĠEVENT _ 2 ), Ġon State C Enter Listener 1 . call ers . last ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( listOf ( STATE _ C , ĠEVENT _ 2 ), Ġon State C Enter Listener 2 . call ers . last ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Valid Event _ should Trigger On Exit Listeners () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Machine . transition ( EVENT _ 2 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( listOf ( STATE _ A , ĠEVENT _ 2 ), Ġon State A Exit Listener 1 . call ers . last ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( listOf ( STATE _ A , ĠEVENT _ 2 ), Ġon State A Exit Listener 2 . call ers . last ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Invalid Event _ should Return Invalid Transition () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWhen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfrom State Ġ= Ġstate Machine . state ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtransition Ġ= Ġstate Machine . transition ( EVENT _ 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( StateMachine . Transition . Invalid < String , ĠInt , ĠString >( STATE _ A , ĠEVENT _ 3 ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals ( from State , Ġstate Machine . state ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Un declared State _ should Throw IllegalStateException () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassert Fails With < IllegalStateException > Ġ{ Ġstate Machine . transition ( EVENT _ 4 ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġclass ĠWithout InitialState Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġcreate _ given No InitialState _ should Throw IllegalArgumentException () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassert Fails With < IllegalArgumentException > Ġ{ ĠState Machine . create < String , ĠInt , ĠString > Ġ{} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġclass ĠWith Missing State Definition Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġstate Machine Ġ= ĠState Machine . create < String , ĠInt , ĠNothing > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠinitialState ( STATE _ A ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate ( STATE _ A ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon ( EVENT _ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtransition To ( STATE _ B ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMissing ĠSTATE _ B Ġdefinition . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Test ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtransition _ given Missing Destination State Definition _ should Throw IllegalStateException With State Name () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThen ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexception Ġ= Ġassert Fails With < IllegalStateException > Ġ{ Ġstate Machine . transition ( EVENT _ 1 ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals (" Missing Ġdefinition Ġfor Ġstate Ġ${ STATE _ B :: class . simple Name } !", Ġexception . message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠSTATE _ A Ġ= Ġ" a " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠSTATE _ B Ġ= Ġ" b " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠSTATE _ C Ġ= Ġ" c " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠSTATE _ D Ġ= Ġ" d " ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠEVENT _ 1 Ġ= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠEVENT _ 2 Ġ= Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠEVENT _ 3 Ġ= Ġ 3 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠEVENT _ 4 Ġ= Ġ 4 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠS IDE _ EFFECT _ 1 Ġ= Ġ" alpha " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġ// Utility Ġclasses Ġto Ġmock Ġlisteners Ġdue Ġto ĠKotlin ĠMulti platform Ġlimitations ĊĠĠĠ Ġprivate Ġclass ĠTransition Listener Mock < T > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcall ers Ġ= Ġmutable ListOf < T >() ĊĠĠĠĠĠĠĠ Ġfun Ġinvoke ( p 1 : ĠT ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcall ers . add ( p 1 ); ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠState Listener Mock < T , ĠK > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcall ers Ġ= Ġmutable ListOf < List <* >>() ĊĠĠĠĠĠĠĠ Ġfun Ġinvoke ( p 1 : ĠT , Ġp 2 : ĠK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcall ers . add ( listOf ( p 1 , Ġp 2 )); ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ