/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 0 , ĠG y uri ĠG re ll Ġand ĠRx Reactor Ġcontributors . ĠAll Ġrights Ġreserved Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder ĠBSD Ġ 3 - Clause ĠLicense . Ċ Ġ* Ġhttps :// opensource . org / licenses / BSD - 3 - Clause Ċ Ġ*/ Ċ Ċ package Ġcom . gy ur ig re ll . flow reactor Ċ Ċ import Ġcom . gy ur ig re ll . flow reactor . Reactor With Effects Tests . Test Reactor . Action Ċ import Ġcom . gy ur ig re ll . flow reactor . Reactor With Effects Tests . Test Reactor . Effect Ċ import Ġcom . gy ur ig re ll . flow reactor . Reactor With Effects Tests . Test Reactor . State Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Experimental Cor outines Api Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġkotlinx . coroutines . flow . as Flow Ċ import Ġkotlinx . coroutines . flow . flow Ċ import Ġkotlinx . coroutines . flow . launch In Ċ import Ġkotlinx . coroutines . flow . on Each Ċ import Ġkotlinx . coroutines . test . Test Coroutine Scope Ċ import Ġkotlinx . coroutines . test . run Blocking Test Ċ import Ġorg . hamcrest . Core Matchers . equalTo Ċ import Ġorg . hamcrest . Matcher Assert . assertThat Ċ import Ġorg . junit . After Ċ import Ġorg . junit . Test Ċ Ċ /** Ċ Ġ* ĠUnit Ġtests Ġfor Ġ[ Reactor With Effects ] Ċ Ġ*/ Ċ @ Experimental Cor outines Api Ċ class ĠRe actor With Effects Tests Ġ{ ĊĠĠĠ Ġprivate Ġval Ġreactor Scope Ġ= ĠTest Coroutine Scope () ĊĊĠĠĠ Ġ@ After ĊĠĠĠ Ġfun Ġteardown () Ġ{ ĊĠĠĠĠĠĠĠ Ġreactor Scope . cleanup Test Cor outines () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Simple Action Ġupdates ĠState Ġsimple Action Ġto Ġtrue `() Ġ= Ġrun Blocking Test Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠArrange ĊĠĠĠĠĠĠĠ Ġval Ġreactor Ġ= ĠTest Reactor ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġstates Ġ= Ġmutable ListOf < State >() ĊĠĠĠĠĠĠĠ Ġreactor . state . on Each Ġ{ Ġstates . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġeffects Ġ= Ġmutable ListOf < Effect >() ĊĠĠĠĠĠĠĠ Ġreactor . effect . on Each Ġ{ Ġeffects . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAct ĊĠĠĠĠĠĠĠ Ġreactor . action . emit ( Action . Simple Action ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAssert ĊĠĠĠĠĠĠĠ ĠassertThat ( states , ĠequalTo ( listOf ( State ( false ), ĠState ( true )))) ĊĠĠĠĠĠĠĠ ĠassertThat ( effects , ĠequalTo ( emptyList ())) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Action WithValue Ġupdates ĠState Ġaction WithValue Ġto Ġcorrect Ġstring `() Ġ= Ġrun Blocking Test Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠArrange ĊĠĠĠĠĠĠĠ Ġval Ġreactor Ġ= ĠTest Reactor ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġstates Ġ= Ġmutable ListOf < State >() ĊĠĠĠĠĠĠĠ Ġreactor . state . on Each Ġ{ Ġstates . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġeffects Ġ= Ġmutable ListOf < Effect >() ĊĠĠĠĠĠĠĠ Ġreactor . effect . on Each Ġ{ Ġeffects . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġthe Value Ġ= Ġ" I Ġlove Ġapple Ġpie " ĊĊĠĠĠĠĠĠĠ Ġ// ĠAct ĊĠĠĠĠĠĠĠ Ġreactor . action . emit ( Action . Action WithValue ( the Value )) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAssert ĊĠĠĠĠĠĠĠ ĠassertThat ( states , ĠequalTo ( listOf ( State (), ĠState ( false , Ġthe Value )))) ĊĠĠĠĠĠĠĠ ĠassertThat ( effects , ĠequalTo ( emptyList ())) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Action F ires Effect One Ġemits Ġthe Ġeffect Ġ` () Ġ= Ġrun Blocking Test Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠArrange ĊĠĠĠĠĠĠĠ Ġval Ġreactor Ġ= ĠTest Reactor ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġstates Ġ= Ġmutable ListOf < State >() ĊĠĠĠĠĠĠĠ Ġreactor . state . on Each Ġ{ Ġstates . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġeffects Ġ= Ġmutable ListOf < Effect >() ĊĠĠĠĠĠĠĠ Ġreactor . effect . on Each Ġ{ Ġeffects . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAct ĊĠĠĠĠĠĠĠ Ġreactor . action . emit ( Action . Action F ires Effect One ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAssert ĊĠĠĠĠĠĠĠ ĠassertThat ( states , ĠequalTo ( listOf ( State ()))) ĊĠĠĠĠĠĠĠ ĠassertThat ( effects , ĠequalTo ( listOf ( Effect . Effect One ))) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Action F ires Effect One Ġemits Ġthe Ġeffect Ġto Ġmultiple Ġsubscribers `() Ġ= Ġrun Blocking Test Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠArrange ĊĠĠĠĠĠĠĠ Ġval Ġreactor Ġ= ĠTest Reactor ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġstates Ġ= Ġmutable ListOf < State >() ĊĠĠĠĠĠĠĠ Ġreactor . state . on Each Ġ{ Ġstates . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġeffects 1 Ġ= Ġmutable ListOf < Effect >() ĊĠĠĠĠĠĠĠ Ġreactor . effect . on Each Ġ{ Ġeffects 1 . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġeffects 2 Ġ= Ġmutable ListOf < Effect >() ĊĠĠĠĠĠĠĠ Ġreactor . effect . on Each Ġ{ Ġeffects 2 . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAct ĊĠĠĠĠĠĠĠ Ġreactor . action . emit ( Action . Action F ires Effect One ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAssert ĊĠĠĠĠĠĠĠ ĠassertThat ( states , ĠequalTo ( listOf ( State ()))) ĊĠĠĠĠĠĠĠ ĠassertThat ( effects 1 , ĠequalTo ( listOf ( Effect . Effect One ))) ĊĠĠĠĠĠĠĠ ĠassertThat ( effects 2 , ĠequalTo ( listOf ( Effect . Effect One ))) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` Action F ires Effect WithValue Ġemits Ġthe Ġeffect Ġwith Ġthe Ġcorrect Ġvalue `() Ġ= Ġrun Blocking Test Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠArrange ĊĠĠĠĠĠĠĠ Ġval Ġreactor Ġ= ĠTest Reactor ( reactor Scope ) ĊĠĠĠĠĠĠĠ Ġval Ġthe Value Ġ= Ġ" M ill ions Ġof Ġpe aches , Ġpe aches Ġfor Ġme " ĊĊĠĠĠĠĠĠĠ Ġval Ġstates Ġ= Ġmutable ListOf < State >() ĊĠĠĠĠĠĠĠ Ġreactor . state . on Each Ġ{ Ġstates . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġeffects Ġ= Ġmutable ListOf < Effect >() ĊĠĠĠĠĠĠĠ Ġreactor . effect . on Each Ġ{ Ġeffects . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAct ĊĠĠĠĠĠĠĠ Ġreactor . action . emit ( Action . Action F ires Effect WithValue ( the Value )) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAssert ĊĠĠĠĠĠĠĠ ĠassertThat ( states , ĠequalTo ( listOf ( State ()))) ĊĠĠĠĠĠĠĠ ĠassertThat ( effects , ĠequalTo ( listOf ( Effect . Effect WithValue ( the Value )))) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` One Ġaction Ġfires Ġtwo Ġeffects `() Ġ= Ġrun Blocking Test Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠArrange ĊĠĠĠĠĠĠĠ Ġval Ġreactor Ġ= ĠTest Reactor ( reactor Scope ) ĊĠĠĠĠĠĠĠ Ġval Ġthe Value Ġ= Ġ" M ill ions Ġof Ġpe aches , Ġpe aches Ġfor Ġme " ĊĊĠĠĠĠĠĠĠ Ġval Ġstates Ġ= Ġmutable ListOf < State >() ĊĠĠĠĠĠĠĠ Ġreactor . state . on Each Ġ{ Ġstates . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġeffects Ġ= Ġmutable ListOf < Effect >() ĊĠĠĠĠĠĠĠ Ġreactor . effect . on Each Ġ{ Ġeffects . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAct ĊĠĠĠĠĠĠĠ Ġreactor . action . emit ( Action . Action F ires Two Effects ( the Value )) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAssert ĊĠĠĠĠĠĠĠ ĠassertThat ( states , ĠequalTo ( listOf ( State ()))) ĊĠĠĠĠĠĠĠ Ġval Ġexpected Effects Ġ= ĠlistOf ( Effect . Effect One , ĠEffect . Effect WithValue ( the Value )) ĊĠĠĠĠĠĠĠ ĠassertThat ( effects , ĠequalTo ( expected Effects )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` An Ġaction Ġcauses Ġan Ġexception Ġto Ġbe Ġthrown , Ġbut Ġreactor Ġkeeps Ġworking `() Ġ= Ġrun Blocking Test Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠArrange ĊĠĠĠĠĠĠĠ Ġval Ġreactor Ġ= ĠTest Reactor ( reactor Scope ) ĊĠĠĠĠĠĠĠ Ġval Ġthe Exception Ġ= ĠIllegalArgumentException (" Some Ġbad Ġargument ") ĊĊĠĠĠĠĠĠĠ Ġval Ġstates Ġ= Ġmutable ListOf < State >() ĊĠĠĠĠĠĠĠ Ġreactor . state . on Each Ġ{ Ġstates . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġeffects Ġ= Ġmutable ListOf < Effect >() ĊĠĠĠĠĠĠĠ Ġreactor . effect . on Each Ġ{ Ġeffects . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAct ĊĠĠĠĠĠĠĠ Ġreactor . action . emit ( Action . Action Throws ( the Exception )) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAssert ĊĠĠĠĠĠĠĠ ĠassertThat ( states , ĠequalTo ( listOf ( State ()))) ĊĠĠĠĠĠĠĠ ĠassertThat ( effects , ĠequalTo ( emptyList ())) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` A Ġmutation Ġcauses Ġan Ġexception Ġto Ġbe Ġthrown , Ġbut Ġreactor Ġkeeps Ġworking `() Ġ= Ġrun Blocking Test Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠArrange ĊĠĠĠĠĠĠĠ Ġval Ġreactor Ġ= ĠTest Reactor ( reactor Scope ) ĊĠĠĠĠĠĠĠ Ġval Ġthe Exception Ġ= ĠIllegalArgumentException (" Some Ġbad Ġargument ") ĊĊĠĠĠĠĠĠĠ Ġval Ġstates Ġ= Ġmutable ListOf < State >() ĊĠĠĠĠĠĠĠ Ġreactor . state . on Each Ġ{ Ġstates . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġval Ġeffects Ġ= Ġmutable ListOf < Effect >() ĊĠĠĠĠĠĠĠ Ġreactor . effect . on Each Ġ{ Ġeffects . add ( it ) Ġ}. launch In ( reactor Scope ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAct ĊĠĠĠĠĠĠĠ Ġreactor . action . emit ( Action . Mutation Throws ( the Exception )) ĊĊĠĠĠĠĠĠĠ Ġ// ĠAssert ĊĠĠĠĠĠĠĠ ĠassertThat ( states , ĠequalTo ( listOf ( State (), ĠState ()))) ĊĠĠĠĠĠĠĠ ĠassertThat ( effects , ĠequalTo ( emptyList ())) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠTest Reactor ( ĊĠĠĠĠĠĠĠ Ġscope : ĠCor outine Scope , ĊĠĠĠĠĠĠĠ ĠinitialState : ĠState Ġ= ĠState () ĊĠĠĠ Ġ) Ġ: ĠRe actor With Effects < Action , ĠTest Reactor . Mutation , ĠState , ĠEffect >( scope , ĠinitialState ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsealed Ġclass ĠAction Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠSimple Action Ġ: ĠAction () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠAction WithValue ( val Ġthe Value : ĠString ) Ġ: ĠAction () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠAction F ires Effect One Ġ: ĠAction () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠAction F ires Effect WithValue ( val Ġthe Value : ĠString ) Ġ: ĠAction () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠAction F ires Two Effects ( val Ġthe Value : ĠString ) Ġ: ĠAction () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠAction Throws ( val Ġthrowable : ĠThrowable ) Ġ: ĠAction () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠMutation Throws ( val Ġthrowable : ĠThrowable ) Ġ: ĠAction () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġsealed Ġclass ĠMutation Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠSimple Action Mutation Ġ: ĠMutation () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠAction WithValue Mutation ( val Ġthe Value : ĠString ) Ġ: ĠMutation () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠMutation Throws ( val Ġthrowable : ĠThrowable ) Ġ: ĠMutation () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠState ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsimple Action : ĠBoolean Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaction WithValue : ĠString Ġ= Ġ"" ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġsealed Ġclass ĠEffect Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobject ĠEffect One Ġ: ĠEffect () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġclass ĠEffect WithValue ( val Ġthe Value : ĠString ) Ġ: ĠEffect () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġmutate ( action : ĠAction ): ĠFlow < Mutation > Ġ= Ġwhen Ġ( action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAction . Simple Action Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ Ġemit ( Mutation . Simple Action Mutation ) Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAction . Action WithValue Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ Ġemit ( Mutation . Action WithValue Mutation ( action . the Value )) Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAction . Action F ires Effect One Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ Ġemit Effect ( Effect . Effect One ) Ġ} Ġ// ĠNote , Ġflow Ġdoesn 't Ġemit ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAction . Action F ires Effect WithValue Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ Ġemit Effect ( Effect . Effect WithValue ( action . the Value )) Ġ} Ġ// ĠNote , Ġflow Ġdoesn 't Ġemit ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAction . Action F ires Two Effects Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflow Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġeffects Ġ= ĠlistOf ( Effect . Effect One , ĠEffect . Effect WithValue ( action . the Value )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit Effect ( effects . as Flow ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ// ĠNote , Ġflow Ġdoesn 't Ġemit ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAction . Action Throws Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġaction . throwable ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAction . Mutation Throws Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf < Mutation >( Mutation . Mutation Throws ( action . throwable )). as Flow () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġreduce ( state : ĠState , Ġmutation : ĠMutation ): ĠState Ġ= Ġwhen Ġ( mutation ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMutation . Simple Action Mutation Ġ-> Ġstate . copy ( simple Action Ġ= Ġtrue ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMutation . Action WithValue Mutation Ġ-> Ġstate . copy ( action WithValue Ġ= Ġmutation . the Value ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMutation . Mutation Throws Ġ-> Ġthrow Ġmutation . throwable ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ