/* Ċ ĠCopyright Ġ 2 0 2 0 ĠSpl endo ĠConsult ing ĠB . V . ĠThe ĠNe therlands ĊĊĠĠĠ Ġ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 . spl endo . kal uga . test Ċ Ċ import Ġco . touch lab . state ly . ensure Never Frozen Ċ import Ġco . touch lab . state ly . freeze Ċ import Ġcom . spl endo . kal uga . base . run Blocking Ċ import Ġkotlinx . coroutines . Cancellation Exception Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . yield Ċ Ċ open Ġclass ĠSimple UIT hread Test Ġ: ĠUIT hread Test < Simple UIT hread Test . Simple TestContext >() Ġ{ ĊĠĠĠ Ġclass ĠSimple TestContext ( coroutine Scope : ĠCor outine Scope ) Ġ: ĠTest Context , ĠCor outine Scope Ġby Ġcoroutine Scope ĊĊĠĠĠ Ġoverride Ġval Ġcreate TestContext : Ġsuspend Ġ( Coroutine Scope ) Ġ-> ĠSimple TestContext Ġ= Ġ{ ĠSimple TestContext ( it ) Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠThis Ġclass Ġallows Ġa Ġtest Ġblock Ġto Ġbe Ġrun Ġon Ġthe ĠUI Ġthread Ġinside Ġa Ġcustom Ġcontext Ċ Ġ* Ġthat Ġis Ġalso Ġcreated Ġin Ġthe ĠUI ĠThread . Ċ Ġ* Ċ Ġ* ĠWhile Ġnormally ĠiOS Ġtests Ġalready Ġrun Ġon Ġthe ĠUI Ġthread , Ġthis Ġprevents Ġthe ĠMain Ġdispatcher Ġfrom Ġworking Ġas Ġlong Ġas Ġthat ĠThread Ġis Ġblocked , Ċ Ġ* Ġso Ġthis Ġclass Ġis Ġmostly Ġused Ġin Ġconjunction Ġwith Ġthe Ġ[ com . spl endo . kal uga . test . main Background ] Ġentry Ġpoint . Ċ Ġ* Ċ Ġ* ĠIt Ġis Ġuseful Ġfor ĠKotlin ĠNative Ġclasses Ġthat Ġonly Ġwork Ġwhen Ġcreated Ġon Ġthe ĠUI Ġthread , Ċ Ġ* Ġas Ġit Ġe ases Ġdealing Ġwith Ġim mut ability Ġand Ġallows Ġa Ġshared Ġcontext . Ċ Ġ* Ċ Ġ*/ Ċ abstract Ġclass ĠUIT hread Test < TC Ġ: ĠUIT hread Test . TestContext >( allow Free zing : ĠBoolean Ġ= Ġfalse ) Ġ: ĠBaseTest () Ġ{ ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! allow Free zing ) Ġensure Never Frozen () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinterface ĠTest Context Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġdispose () Ġ{} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠEmpty TestContext Ġprivate Ġconstructor () Ġ: ĠTest Context Ġ{ ĊĠĠĠĠĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠINSTANCE Ġ= ĠEmpty TestContext () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġabstract Ġval Ġcreate TestContext : Ġsuspend Ġ( scope : ĠCor outine Scope ) Ġ-> ĠTC ĊĊĠĠĠ Ġprivate Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcancellation Exception Ġ= ĠC ancellation Exception (" Scope Ġcanceled Ġby Ġtest On UIT hread Ġbecause Ġcancel Scope After Test Ġwas Ġset Ġto Ġtrue .") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRun Ġyour Ġtest Ġblock Ġon Ġthe ĠUI Ġthread Ġand Ġinside Ġthe ĠTest Context . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠOptionally Ġwith Ġ[ cancel Scope After Test ] Ġyou Ġcan Ġrun Ġyour Ġtest Ġblock Ġinside Ġa Ġseparately Ġlaunched Ġjob , Ġwhich ĊĠĠĠĠ Ġ* Ġis Ġcanceled Ġafter Ġyour Ġblock Ġis Ġrun . ĠThe Ġscope Ġwaits Ġtill Ġthis Ġis Ġcompleted Ġby Ġjoining . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThis Ġcan Ġbe Ġhandy Ġfor Ġtesting Ġclasses Ġthat Ġrely Ġon Ġscopes Ġthat Ġeventually Ġget Ġcanceled , ĊĠĠĠĠ Ġ* Ġe . g . Ġbecause Ġthey Ġare Ġcanceled Ġautomatically Ġby Ġa Ġlifecycle Ġevent . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġblock Ġtest Ġblock Ġto Ġbe Ġrun Ġon Ġthe ĠUI Ġthread Ġand Ġin Ġthe Ġtest Ġcontext . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġcancel Scope After Test Ġwhether Ġto Ġcancel Ġthe Ġcor outines cope Ġyour Ġblock Ġran Ġin Ġafter Ġit 's Ġdone . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġtest On UIT hread ( cancel Scope After Test : ĠBoolean Ġ= Ġfalse , Ġblock : Ġsuspend ĠTC . () Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcreate TestContext Ġ= Ġcreate TestContext ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtest : Ġsuspend Ġ( Coroutine Scope ) Ġ-> ĠUnit Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtest Context Ġ= Ġcreate TestContext ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġyield () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock ( test Context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtest Context . dispose () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate TestContext . freeze () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtest . freeze () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cancel Scope After Test ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtest Blocking And Cancel Scope ( Dispatch ers . Main ) Ġ{ Ġtest ( this ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Blocking ( Dispatch ers . Main ) Ġ{ Ġtest ( this ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( c : ĠC ancellation Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! cancel Scope After Test Ġ|| Ġc Ġ!== Ġcancellation Exception ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġc ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ