/* Ċ Ġ* ĠCopyright Ġ 2 0 1 6 - 2 0 1 7 ĠJetBrains Ġs . r . o . Ċ Ġ* Ċ Ġ* Ġ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 Ġkotlinx . coroutines . experimental . future Ċ Ċ import Ġguide . test . ignore Lost Threads Ċ import Ġkotlinx . coroutines . experimental .* Ċ import Ġorg . hamcrest . core . Is Equal Ċ import Ġorg . junit . Assert .* Ċ import Ġorg . junit . Before Ċ import Ġorg . junit . Test Ċ import Ġjava . util . concurrent . Comp letableFuture Ċ import Ġjava . util . concurrent . Completion Stage Ċ import Ġjava . util . concurrent . ExecutionException Ċ import Ġjava . util . concurrent . atomic . Atomic Integer Ċ import Ġkotlin . coroutines . experimental . Coroutine Context Ċ Ċ class ĠFuture Test Ġ: ĠTest Base () Ġ{ ĊĠĠĠ Ġ@ Before ĊĠĠĠ Ġfun Ġsetup () Ġ{ ĊĠĠĠĠĠĠĠ Ġignore Lost Threads (" Fork Join Pool . common Pool - worker - ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Simple Await () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġfuture Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCompletableFuture . supply Async Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" O " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. await () Ġ+ Ġ" K " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠassertThat ( future . get (), ĠIs Equal (" OK ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Completed Future () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġto Await Ġ= ĠCompletableFuture < String >() ĊĠĠĠĠĠĠĠ Ġto Await . complete (" O ") ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġfuture Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġto Await . await () Ġ+ Ġ" K " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠassertThat ( future . get (), ĠIs Equal (" OK ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Completed Completion Stage () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcomplet able Ġ= ĠCompletableFuture < String >() ĊĠĠĠĠĠĠĠ Ġcomplet able . complete (" O ") ĊĠĠĠĠĠĠĠ Ġval Ġto Await : ĠCompletion Stage < String > Ġ= Ġcomplet able ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġfuture Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġto Await . await () Ġ+ Ġ" K " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠassertThat ( future . get (), ĠIs Equal (" OK ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest WaitFor Future () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġto Await Ġ= ĠCompletableFuture < String >() ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġfuture Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġto Await . await () Ġ+ Ġ" K " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠassertFalse ( future . is Done ) ĊĠĠĠĠĠĠĠ Ġto Await . complete (" O ") ĊĠĠĠĠĠĠĠ ĠassertThat ( future . get (), ĠIs Equal (" OK ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest WaitFor Completion Stage () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcomplet able Ġ= ĠCompletableFuture < String >() ĊĠĠĠĠĠĠĠ Ġval Ġto Await : ĠCompletion Stage < String > Ġ= Ġcomplet able ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġfuture Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġto Await . await () Ġ+ Ġ" K " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠassertFalse ( future . is Done ) ĊĠĠĠĠĠĠĠ Ġcomplet able . complete (" O ") ĊĠĠĠĠĠĠĠ ĠassertThat ( future . get (), ĠIs Equal (" OK ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Completed Future Exception ally () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġto Await Ġ= ĠCompletableFuture < String >() ĊĠĠĠĠĠĠĠ Ġto Await . complete Exception ally ( RuntimeException (" O ")) ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġfuture < String > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Await . await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠRuntimeException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . message !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ+ Ġ" K " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠassertThat ( future . get (), ĠIs Equal (" OK ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Completed Completion Stage Exception ally () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcomplet able Ġ= ĠCompletableFuture < String >() ĊĠĠĠĠĠĠĠ Ġval Ġto Await : ĠCompletion Stage < String > Ġ= Ġcomplet able ĊĠĠĠĠĠĠĠ Ġcomplet able . complete Exception ally ( RuntimeException (" O ")) ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġfuture < String > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Await . await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠRuntimeException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . message !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ+ Ġ" K " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠassertThat ( future . get (), ĠIs Equal (" OK ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest WaitFor Future With Exception () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġto Await Ġ= ĠCompletableFuture < String >() ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġfuture < String > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Await . await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠRuntimeException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . message !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ+ Ġ" K " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠassertFalse ( future . is Done ) ĊĠĠĠĠĠĠĠ Ġto Await . complete Exception ally ( RuntimeException (" O ")) ĊĠĠĠĠĠĠĠ ĠassertThat ( future . get (), ĠIs Equal (" OK ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest WaitFor Completion Stage With Exception () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcomplet able Ġ= ĠCompletableFuture < String >() ĊĠĠĠĠĠĠĠ Ġval Ġto Await : ĠCompletion Stage < String > Ġ= Ġcomplet able ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġfuture < String > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Await . await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠRuntimeException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . message !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ+ Ġ" K " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠassertFalse ( future . is Done ) ĊĠĠĠĠĠĠĠ Ġcomplet able . complete Exception ally ( RuntimeException (" O ")) ĊĠĠĠĠĠĠĠ ĠassertThat ( future . get (), ĠIs Equal (" OK ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Exception Inside Coroutine () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġfuture Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Comp letableFuture . supply Async Ġ{ Ġtrue Ġ}. await ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" OK ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" fail " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfuture . get () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfail ("' get ' Ġshould 've Ġthrow Ġan Ġexception ") ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠExecution Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertTrue ( e . cause Ġis ĠIllegalStateException ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( e . cause !!. message , ĠIs Equal (" OK ")) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Completed Deferred As Comp letableFuture () Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠ Ġexpect ( 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġdeferred Ġ= Ġasync ( coroutine Context , ĠCor outine Start . UN DISPATCH ED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexpect ( 2 ) Ġ// Ġcompleted Ġright Ġaway ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" OK " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġexpect ( 3 ) ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġdeferred . as Comp letableFuture () ĊĠĠĠĠĠĠĠ ĠassertThat ( future . await (), ĠIs Equal (" OK ")) ĊĠĠĠĠĠĠĠ Ġfinish ( 4 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest WaitFor Deferred As Comp letableFuture () Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠ Ġexpect ( 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġdeferred Ġ= Ġasync ( coroutine Context ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexpect ( 3 ) Ġ// Ġwill Ġcomplete Ġlater ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" OK " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġexpect ( 2 ) ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġdeferred . as Comp letableFuture () ĊĠĠĠĠĠĠĠ ĠassertThat ( future . await (), ĠIs Equal (" OK ")) Ġ// Ġawait Ġyields Ġmain Ġthread Ġto Ġdeferred Ġcoroutine ĊĠĠĠĠĠĠĠ Ġfinish ( 4 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest C ancellable Await Future () Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠ Ġexpect ( 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġto Await Ġ= ĠCompletableFuture < String >() ĊĠĠĠĠĠĠĠ Ġval Ġjob Ġ= Ġlaunch ( coroutine Context , ĠCor outine Start . UN DISPATCH ED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexpect ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Await . await () Ġ// Ġsus p ends ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠC ancellation Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexpect ( 5 ) Ġ// Ġshould Ġthrow Ġcancellation Ġexception ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġexpect ( 3 ) ĊĠĠĠĠĠĠĠ Ġjob . cancel () Ġ// Ġcancel Ġthe Ġjob ĊĠĠĠĠĠĠĠ Ġto Await . complete (" fail ") Ġ// Ġtoo Ġlate , Ġthe Ġwaiting Ġjob Ġwas Ġalready Ġcancelled ĊĠĠĠĠĠĠĠ Ġexpect ( 4 ) Ġ// Ġjob Ġprocessing Ġof Ġcancellation Ġwas Ġscheduled , Ġnot Ġexecuted Ġyet ĊĠĠĠĠĠĠĠ Ġyield () Ġ// Ġyield Ġmain Ġthread Ġto Ġjob ĊĠĠĠĠĠĠĠ Ġfinish ( 6 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Non C ancellable Await Completion Stage () Ġ= Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠ Ġexpect ( 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġcomplet able Ġ= ĠCompletableFuture < String >() ĊĠĠĠĠĠĠĠ Ġval Ġto Await : ĠCompletion Stage < String > Ġ= Ġcomplet able ĊĠĠĠĠĠĠĠ Ġval Ġjob Ġ= Ġlaunch ( coroutine Context , ĠCor outine Start . UN DISPATCH ED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexpect ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertThat ( to Await . await (), ĠIs Equal (" OK ")) Ġ// Ġsus p ends ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexpect ( 5 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġexpect ( 3 ) ĊĠĠĠĠĠĠĠ Ġjob . cancel () Ġ// Ġcancel Ġthe Ġjob ĊĠĠĠĠĠĠĠ Ġcomplet able . complete (" OK ") Ġ// Ġok , Ġbecause Ġawait Ġon Ġcompletion Ġstage Ġis Ġnot Ġcancell able ĊĠĠĠĠĠĠĠ Ġexpect ( 4 ) Ġ// Ġjob Ġprocessing Ġof Ġwas Ġscheduled , Ġnot Ġexecuted Ġyet ĊĠĠĠĠĠĠĠ Ġyield () Ġ// Ġyield Ġmain Ġthread Ġto Ġjob ĊĠĠĠĠĠĠĠ Ġfinish ( 6 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Test ĊĠĠĠ Ġfun Ġtest Continuation Wrapped () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdepth Ġ= ĠAtomicInteger () ĊĠĠĠĠĠĠĠ Ġval Ġfuture Ġ= Ġfuture ( wrap Continuation Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdepth . and Increment ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdepth . and De crement ĊĠĠĠĠĠĠĠ Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals (" Part Ġbefore Ġfirst Ġsus pension Ġmust Ġbe Ġwrapped ", Ġ 1 , Ġdepth . get ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCompletableFuture . supply Async Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( depth . get () Ġ> Ġ 0 ) Ġ; ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals (" Part Ġinside Ġsus pension Ġpoint Ġshould Ġnot Ġbe Ġwrapped ", Ġ 0 , Ġdepth . get ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" OK " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. await () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals (" Part Ġafter Ġfirst Ġsus pension Ġshould Ġbe Ġwrapped ", Ġ 1 , Ġdepth . get ()) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCompletableFuture . supply Async Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( depth . get () Ġ> Ġ 0 ) Ġ; ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠassertEquals (" Part Ġinside Ġsus pension Ġpoint Ġshould Ġnot Ġbe Ġwrapped ", Ġ 0 , Ġdepth . get ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ignored " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠassertThat ( future . get (), ĠIs Equal (" OK ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġwrap Continuation ( wrapper : Ġ(() Ġ-> ĠUnit ) Ġ-> ĠUnit ): ĠCor outine Dispatcher Ġ= Ġobject Ġ: ĠCor outine Dispatcher () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġdispatch ( context : ĠCor outine Context , Ġblock : ĠRunnable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrapper Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblock . run () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ