/* Ċ Ġ* ĠMIT ĠLicense Ċ Ġ* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 0 ĠPin aki ĠA ch ary a Ċ Ġ* Ċ Ġ* ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġcopy Ċ Ġ* Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġto Ġdeal Ċ Ġ* Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġthe Ġrights Ċ Ġ* Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġand / or Ġsell Ċ Ġ* Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ċ Ġ* Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ġall Ċ Ġ* Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ Ġ* Ċ Ġ* ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR Ċ Ġ* ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF ĠMERCHANTABILITY , Ċ Ġ* ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE Ċ Ġ* ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER Ċ Ġ* ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR ĠOTHERWISE , ĠARISING ĠFROM , Ċ Ġ* ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN ĠTHE Ċ Ġ* ĠSOFTWARE . Ċ Ġ* Ċ Ġ*/ Ċ Ċ package Ġdev . pin aki . de si pe . feature . listing Ċ Ċ import Ġandroidx . arch . core . executor . testing . Instant Task Executor Rule Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġdev . pin aki . de si pe . common . connectivity . Connectivity Detector Ċ import Ġdev . pin aki . de si pe . common . coroutine . Dispatcher Provider Ċ import Ġdev . pin aki . de si pe . data . repository . Recipe Repository Ċ import Ġdev . pin aki . de si pe . fake . Fake Recipe Repository Ċ import Ġdev . pin aki . de si pe . get Sample Data Ċ import Ġdev . pin aki . de si pe . testutil . Main Coroutine Rule Ċ import Ġdev . pin aki . de si pe . testutil . getValue Ċ import Ġio . mock k . Mock K Annotations Ċ import Ġio . mock k . co Every Ċ import Ġio . mock k . impl . annotations . Mock K Ċ import Ġkotlinx . coroutines . Experimental Cor outines Api Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġorg . junit . Before Ċ Ċ import Ġorg . junit . Rule Ċ import Ġorg . junit . Test Ċ import Ġjava . lang . Exception Ċ Ċ /** Ċ Ġ* ĠUnit ĠTests Ġfor Ġ[ Recipe Listing ViewModel ] Ċ Ġ* Ġ- Ġgiven Ġa Ġnon - empty Ġlist Ġof Ġrecipe Ġitems , Ġitems Ġare Ġdisplayed Ġsuccessfully Ċ Ġ* Ġ- Ġgiven Ġa Ġnon - empty Ġlist Ġof Ġrecipe Ġitems Ġwhen Ġthe Ġinternet Ġis Ġdisconnected , Ċ Ġ* Ġitems Ġare Ġdisplayed Ġsuccessfully Ċ Ġ* Ġ- Ġwhen Ġthe Ġrecipe Ġlist Ġis Ġempty , Ġand Ġinternet Ġconnection Ġis Ġabsent , Ġoffline Ġmessage Ġis Ġshown Ċ Ġ* Ċ Ġ* Ġ- Ġwhen Ġthe Ġrecipe Ġlist Ġis Ġempty , Ġand Ġinternet Ġconnection Ġis Ġpresent Ċ Ġ* Ġand Ġdata Ġcouldn 't Ġbe Ġloaded Ġfrom Ġthe Ġweb service , Ġerror Ġview Ġis Ġshown Ċ Ġ* Ċ Ġ* Ġ- Ġwhen Ġthe Ġrecipe Ġlist Ġis Ġempty , Ġand Ġinternet Ġconnection Ġis Ġpresent Ġand Ġempty Ġrecipe Ġlist Ċ Ġ* Ġis Ġreturned Ġfrom Ġthe Ġweb service , Ġerror Ġview Ġis Ġshown Ċ Ġ* Ċ Ġ* Ġ- Ġwhen Ġthe Ġrecipe Ġlist Ġis Ġempty , Ġand Ġinternet Ġconnection Ġis Ġpresent Ġand Ġdata Ġis Ġloaded Ċ Ġ* Ġfrom Ġthe Ġweb service , Ġerror Ġview Ġis Ġnot Ġshown ĊĊ Ġ*/ Ċ @ Experimental Cor outines Api Ċ class ĠRecipe Listing ViewModel Test Ġ{ ĊĊĠĠĠ Ġ@ get : Rule ĊĠĠĠ Ġval Ġmain Coroutine Rule Ġ= ĠMain Coroutine Rule () ĊĊĠĠĠ Ġ@ get : Rule ĊĠĠĠ Ġval Ġinstant Task Executor Rule Ġ= ĠInstant Task Executor Rule () ĊĊĠĠĠ Ġlateinit Ġvar ĠviewModel : ĠRecipe Listing ViewModel ĊĊĠĠĠ Ġ@ Mock K ĊĠĠĠ Ġlateinit Ġvar Ġrecipe Repository : ĠRecipe Repository ĊĊĠĠĠ Ġ@ Mock K ĊĠĠĠ Ġlateinit Ġvar Ġconnectivity Detector : ĠConnect ivity Detector ĊĊĠĠĠ Ġ@ Mock K ĊĠĠĠ Ġlateinit Ġvar Ġdispatcher Provider : ĠDispatcher Provider ĊĊĠĠĠ Ġ@ Before ĊĠĠĠ Ġfun ĠsetUp () Ġ{ ĊĠĠĠĠĠĠĠ ĠMock K Annotations . init ( this , Ġrelax Unit Fun Ġ= Ġtrue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` when Ġthe Ġrecipe Ġlist Ġis Ġnon Ġempty , Ġitems Ġare Ġdisplayed Ġsuccessfully `() Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġgiven - Ġrepository Ġreturns Ġnon Ġempty Ġdata ĊĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġrecipe Repository . getAll Recipes () Ġ} Ġreturns ĠMutable LiveData ( get Sample Data ()) ĊĊĠĠĠĠĠĠĠ Ġ// Ġwhen Ġ- Ġview model Ġis Ġinstantiated ĊĠĠĠĠĠĠĠ ĠviewModel Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRecipe Listing ViewModel ( recipe Repository , Ġconnectivity Detector , Ġdispatcher Provider ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġthen Ġ- Ġrecipe Ġlist Ġis Ġdisplayed Ġsuccessfully ĊĠĠĠĠĠĠĠ Ġval Ġrecipe List To Display Ġ= ĠgetValue ( viewModel . all Recipes ) ĊĠĠĠĠĠĠĠ Ġassert ( recipe List To Display . isNotEmpty ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` when Ġthe Ġrecipe Ġlist Ġis Ġnon Ġempty Ġand Ġinternet Ġis Ġdisconnected , Ġitems Ġare Ġdisplayed Ġsuccessfully `() Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġgiven - Ġrepository Ġreturns Ġnon Ġempty Ġdata ĊĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġrecipe Repository . getAll Recipes () Ġ} Ġreturns ĠMutable LiveData ( get Sample Data ()) ĊĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġconnectivity Detector . isConnected () Ġ} Ġreturns Ġfalse ĊĊĠĠĠĠĠĠĠ Ġ// Ġwhen Ġ- Ġview model Ġis Ġinstantiated ĊĠĠĠĠĠĠĠ ĠviewModel Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRecipe Listing ViewModel ( recipe Repository , Ġconnectivity Detector , Ġdispatcher Provider ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġthen Ġ- Ġrecipe Ġlist Ġis Ġdisplayed Ġsuccessfully ĊĠĠĠĠĠĠĠ Ġval Ġrecipe List To Display Ġ= ĠgetValue ( viewModel . all Recipes ) ĊĠĠĠĠĠĠĠ Ġassert ( recipe List To Display . isNotEmpty ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` when Ġthe Ġrecipe Ġlist Ġis Ġempty , Ġand Ġinternet Ġconnection Ġis Ġabsent , Ġoffline Ġmessage Ġis Ġshown `() Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġgiven - Ġrepository Ġreturns Ġempty Ġdata Ġand Ġinternet Ġis Ġabsent ĊĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġrecipe Repository . getAll Recipes () Ġ} Ġreturns ĠMutable LiveData ( ArrayList ()) ĊĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġconnectivity Detector . isConnected () Ġ} Ġreturns Ġfalse ĊĊĠĠĠĠĠĠĠ Ġ// Ġwhen Ġ- Ġview model Ġis Ġinstantiated ĊĠĠĠĠĠĠĠ ĠviewModel Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRecipe Listing ViewModel ( recipe Repository , Ġconnectivity Detector , Ġdispatcher Provider ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġthen Ġ- Ġoffline Ġmessage Ġis Ġshown ĊĠĠĠĠĠĠĠ Ġval Ġrecipe List To Display Ġ= ĠgetValue ( viewModel . all Recipes ) ĊĠĠĠĠĠĠĠ Ġval Ġshow Offline Ġ= ĠgetValue ( viewModel . show Offline ) ĊĠĠĠĠĠĠĠ Ġassert ( recipe List To Display . isEmpty ()) ĊĠĠĠĠĠĠĠ Ġassert ( show Offline ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` when Ġthe Ġrecipe Ġlist Ġis Ġempty Ġ& Ġdata Ġcouldn 't Ġbe Ġloaded Ġfrom Ġthe Ġweb service , Ġerror Ġview Ġis Ġshown `() Ġ= ĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġgiven - Ġrepository Ġreturns Ġempty Ġdata Ġand Ġweb service Ġthrows Ġexception ĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġrecipe Repository . getAll Recipes () Ġ} Ġreturns ĠMutable LiveData ( ArrayList ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġconnectivity Detector . isConnected () Ġ} Ġreturns Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġrecipe Repository . sync Recipes () Ġ} Ġthrows ĠException () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġdispatcher Provider . io () Ġ} Ġreturns Ġmain Coroutine Rule . get Main Dispatcher () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwhen Ġ- Ġview model Ġis Ġinstantiated ĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRecipe Listing ViewModel ( recipe Repository , Ġconnectivity Detector , Ġdispatcher Provider ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthen Ġ- Ġerror Ġmessage Ġis Ġshown ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrecipe List To Display Ġ= ĠgetValue ( viewModel . all Recipes ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshow Loading Ġ= ĠgetValue ( viewModel . show Loading ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshow Error Ġ= ĠgetValue ( viewModel . show Error ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( recipe List To Display . isEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert (! show Loading ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( show Error ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` when Ġthe Ġrecipe Ġlist Ġis Ġempty Ġand Ġempty Ġrecipe Ġlist Ġis Ġreturned Ġfrom Ġthe Ġweb service , Ġerror Ġview Ġis Ġshown `() Ġ= ĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġgiven - Ġrepository Ġreturns Ġempty Ġdata Ġand Ġweb service Ġreturns Ġempty Ġlist ĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġrecipe Repository . getAll Recipes () Ġ} Ġreturns ĠMutable LiveData ( ArrayList ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġconnectivity Detector . isConnected () Ġ} Ġreturns Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġrecipe Repository . sync Recipes () Ġ} Ġreturns ĠArrayList () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġdispatcher Provider . io () Ġ} Ġreturns Ġmain Coroutine Rule . get Main Dispatcher () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwhen Ġ- Ġview model Ġis Ġinstantiated ĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRecipe Listing ViewModel ( recipe Repository , Ġconnectivity Detector , Ġdispatcher Provider ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthen Ġ- Ġerror Ġmessage Ġis Ġshown ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrecipe List To Display Ġ= ĠgetValue ( viewModel . all Recipes ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshow Loading Ġ= ĠgetValue ( viewModel . show Loading ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshow Error Ġ= ĠgetValue ( viewModel . show Error ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( recipe List To Display . isEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert (! show Loading ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( show Error ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġ` when Ġthe Ġrecipe Ġlist Ġis Ġempty , Ġand Ġand Ġdata Ġis Ġloaded Ġfrom Ġthe Ġweb service , Ġerror Ġview Ġis Ġnot Ġshown `() Ġ= ĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġgiven - Ġrepository Ġreturns Ġempty Ġdata Ġand Ġinternet Ġis Ġabsent ĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġconnectivity Detector . isConnected () Ġ} Ġreturns Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġrecipe Repository . sync Recipes () Ġ} Ġreturns ĠArrayList () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġdispatcher Provider . io () Ġ} Ġreturns Ġmain Coroutine Rule . get Main Dispatcher () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwhen Ġ- Ġview model Ġis Ġinstantiated ĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRecipe Listing ViewModel ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFake Recipe Repository ( ArrayList ()), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnectivity Detector , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdispatcher Provider ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġco Every Ġ{ Ġrecipe Repository . getAll Recipes () Ġ} Ġreturns ĠMutable LiveData ( ArrayList ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthen Ġ- Ġerror Ġmessage Ġis Ġnot Ġshown ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrecipe List To Display Ġ= ĠgetValue ( viewModel . all Recipes ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshow Loading Ġ= ĠgetValue ( viewModel . show Loading ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshow Error Ġ= ĠgetValue ( viewModel . show Error ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( recipe List To Display . isNotEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert (! show Loading ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert (! show Error ) ĊĠĠĠĠĠĠĠ Ġ} Ċ }