/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 2 1 ĠAb hi ĠM uk the es war ar Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġcom . ms ab hi . fly wheel Ċ Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . flow . collect Ċ import Ġkotlinx . coroutines . test . Test Coroutine Scope Ċ import Ġkotlinx . coroutines . test . run Blocking Test Ċ import Ġorg . junit . Test Ċ import Ġkotlin . test . assertEquals Ċ import Ġkotlin . test . assertIs Ċ Ċ @ Suppress (" EXPERIMENT AL _ API _ USAGE ") Ċ class ĠState Machine Test Ġ{ ĊĊĠĠĠ Ġinternal Ġsealed Ġclass ĠMaterial State Ġ: ĠState Ġ{ ĊĠĠĠĠĠĠĠ Ġobject ĠSolid Ġ: ĠMaterial State () ĊĠĠĠĠĠĠĠ Ġobject ĠLi quid Ġ: ĠMaterial State () ĊĠĠĠĠĠĠĠ Ġobject ĠG as Ġ: ĠMaterial State () ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠQuant um ( val Ġstates : ĠMutable Map < Int , ĠMaterial State >) Ġ: ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMaterial State () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsealed Ġclass ĠMaterial Action Ġ: ĠAction Ġ{ ĊĠĠĠĠĠĠĠ Ġobject ĠOn Mel ted Ġ: ĠMaterial Action () ĊĠĠĠĠĠĠĠ Ġobject ĠOn Frozen Ġ: ĠMaterial Action () ĊĠĠĠĠĠĠĠ Ġobject ĠOn V apor ized Ġ: ĠMaterial Action () ĊĠĠĠĠĠĠĠ Ġobject ĠOn Con dense d Ġ: ĠMaterial Action () ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠOn Quantum ( val Ġid : ĠInt , Ġval Ġstate : ĠMaterial State ) Ġ: ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMaterial Action () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsealed Ġclass ĠMaterial Side Effect Ġ{ ĊĠĠĠĠĠĠĠ Ġobject ĠLog Mel ted Ġ: ĠMaterial Side Effect () ĊĠĠĠĠĠĠĠ Ġobject ĠLog Frozen Ġ: ĠMaterial Side Effect () ĊĠĠĠĠĠĠĠ Ġobject ĠLog V apor ized Ġ: ĠMaterial Side Effect () ĊĠĠĠĠĠĠĠ Ġobject ĠLog Con dense d Ġ: ĠMaterial Side Effect () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġmaterial Reducer Ġ= ĊĠĠĠĠĠĠĠ Ġreducer For Action < Material Action , ĠMaterial State > Ġ{ Ġaction , Ġstate Ġ-> ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMaterial State . Solid Ġ-> Ġwhen Ġ( action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMaterial Action . On Mel ted Ġ-> ĠMaterial State . Liquid ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreduce Error () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMaterial State . Liquid Ġ-> Ġwhen Ġ( action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMaterial Action . On Frozen Ġ-> ĠMaterial State . Solid ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMaterial Action . On V apor ized Ġ-> ĠMaterial State . Gas ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreduce Error () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMaterial State . Gas Ġ-> Ġwhen Ġ( action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMaterial Action . On Con dense d Ġ-> ĠMaterial State . Liquid ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreduce Error () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMaterial State . Quantum Ġ-> Ġwhen Ġ( action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMaterial Action . On Quantum Ġ-> Ġstate . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . states [ action . id ] Ġ= Ġaction . state ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreduce Error () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġ< S Ġ: ĠState > ĠgetState Reserve ( ĊĠĠĠĠĠĠĠ Ġscope : ĠCor outine Scope , ĊĠĠĠĠĠĠĠ ĠinitialState : ĠS , ĊĠĠĠĠĠĠĠ Ġreduce : ĠReduce < S >, ĊĠĠĠĠĠĠĠ Ġdebug Mode : ĠBoolean , ĊĠĠĠĠĠĠĠ Ġmiddle wares : ĠList < Middleware < S >> ? Ġ= Ġnull , ĊĠĠĠ Ġ): ĠState Reserve < S > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġconfig Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠState Reserve Config ( scope Ġ= Ġscope , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Mode Ġ= Ġdebug Mode , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġenhanced StateMachine Ġ= Ġtrue ) ĊĊĠĠĠĠĠĠĠ Ġreturn ĠState Reserve ( config , ĠInitial State . set ( initialState ), Ġreduce , Ġmiddle wares ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġmaterial StateMachine Test (): ĠUnit Ġ= Ġrun Blocking Test Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġscope Ġ= ĠTest Coroutine Scope ( Supervisor Job ()) ĊĠĠĠĠĠĠĠ Ġval Ġstate Reserve Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠgetState Reserve ( scope Ġ= Ġscope , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠinitialState Ġ= ĠMaterial State . Solid , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Mode Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreduce Ġ= Ġmaterial Reducer ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġsimple Valid Transitions Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġvalid Transitions Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġin Valid Transitions Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġon Exit Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġon Enter Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġval Ġj 0 Ġ= Ġlaunch ( Coroutine Name (" j 0 ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate Reserve . transitions . valid Transitions < Material State . Solid , ĠMaterial State . Liquid >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsimple Valid Transitions ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġj 1 Ġ= Ġlaunch ( Coroutine Name (" j 1 ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate Reserve . transitions . valid Transitions < Material State . Liquid , ĠMaterial State . Gas >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsimple Valid Transitions ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġj 2 Ġ= Ġlaunch ( Coroutine Name (" j 2 ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate Reserve . transitions . valid Transition With Action < Material Action . On Mel ted , ĠMaterial State . Solid , ĠMaterial State . Liquid >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Transitions ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġj 3 Ġ= Ġlaunch ( Coroutine Name (" j 3 ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate Reserve . transitions . valid Transition With Action < Material Action . On V apor ized , ĠMaterial State . Liquid , ĠMaterial State . Gas >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalid Transitions ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġj 4 Ġ= Ġlaunch ( Coroutine Name (" j 4 ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate Reserve . transitions . in Valid Transition < Material State >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Valid Transitions ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġj 5 Ġ= Ġlaunch ( Coroutine Name (" j 5 ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate Reserve . transitions . on Exit < Material State . Solid >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Exit ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġj 6 Ġ= Ġlaunch ( Coroutine Name (" j 6 ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate Reserve . transitions . on Enter < Material State . Liquid >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Enter ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġjobs Ġ= Ġset Of ( j 0 , Ġj 1 , Ġj 2 , Ġj 3 , Ġj 4 , Ġj 5 , Ġj 6 ) ĊĊĠĠĠĠĠĠĠ Ġstate Reserve . dispatch ( Material Action . On Mel ted ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Material State . Liquid , Ġstate Reserve . await State ()) ĊĊĠĠĠĠĠĠĠ Ġstate Reserve . dispatch ( Material Action . On V apor ized ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Material State . Gas , Ġstate Reserve . await State ()) ĊĊĠĠĠĠĠĠĠ Ġ// Invalid Ġtransition ĊĠĠĠĠĠĠĠ Ġstate Reserve . dispatch ( Material Action . On Mel ted ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( Material State . Gas , Ġstate Reserve . await State ()) ĊĊĠĠĠĠĠĠĠ ĠassertEquals ( 2 , Ġsimple Valid Transitions ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 2 , Ġvalid Transitions ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġin Valid Transitions ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġon Exit ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġon Enter ) ĊĠĠĠĠĠĠĠ Ġjobs . forEach Ġ{ Ġit . cancel () Ġ} ĊĠĠĠĠĠĠĠ Ġscope . cancel () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ( expected Ġ= ĠIllegalArgumentException :: class ) ĊĠĠĠ Ġfun Ġstate Mut ability Test (): ĠUnit Ġ= Ġrun Blocking Test Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġscope Ġ= ĠTest Coroutine Scope ( Supervisor Job ()) ĊĠĠĠĠĠĠĠ Ġval Ġstate Reserve Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠgetState Reserve ( scope Ġ= Ġscope , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠinitialState Ġ= ĠMaterial State . Quantum ( mutable Map Of ( 1 Ġto ĠMaterial State . Solid )), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Mode Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreduce Ġ= Ġmaterial Reducer ) ĊĊĠĠĠĠĠĠĠ Ġassert Is < Material State . Quantum >( state Reserve . await State ()) ĊĠĠĠĠĠĠĠ Ġstate Reserve . dispatch ( Material Action . On Quantum ( 1 , ĠMaterial State . Liquid )) ĊĊĠĠĠĠĠĠĠ Ġstate Reserve . terminate () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġinvalid Action For State Test (): ĠUnit Ġ= Ġrun Blocking Test Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġscope Ġ= ĠTest Coroutine Scope ( Supervisor Job ()) ĊĠĠĠĠĠĠĠ Ġval Ġstate Reserve Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠgetState Reserve ( scope Ġ= Ġscope , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠinitialState Ġ= ĠMaterial State . Solid , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Mode Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreduce Ġ= Ġmaterial Reducer ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġin Valid Transitions Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġval Ġj 0 Ġ= Ġlaunch ( Coroutine Name (" j 0 ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate Reserve . transitions . in Valid Transition With Action < Material Action , ĠMaterial State >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. collect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Valid Transitions ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġstate Reserve . dispatch ( Material Action . On Frozen ) ĊĠĠĠĠĠĠĠ ĠassertEquals ( 1 , Ġin Valid Transitions ) ĊĠĠĠĠĠĠĠ Ġj 0 . cancel () ĊĠĠĠĠĠĠĠ Ġstate Reserve . terminate () ĊĠĠĠ Ġ} Ċ }