• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package kotlinx.coroutines
2 
3 import kotlinx.coroutines.testing.*
4 import kotlin.coroutines.*
5 import kotlin.test.*
6 
7 /**
8  * When using [suspendCoroutine] from the standard library the continuation must be dispatched atomically,
9  * without checking for cancellation at any point in time.
10  */
11 class DispatchedContinuationTest : TestBase() {
12     private lateinit var cont: Continuation<String>
13 
14     @Test
testCancelThenResumenull15     fun testCancelThenResume() = runTest {
16         expect(1)
17         launch(start = CoroutineStart.UNDISPATCHED) {
18             expect(2)
19             coroutineContext[Job]!!.cancel()
20             // a regular suspendCoroutine will still suspend despite the fact that coroutine was cancelled
21             val value = suspendCoroutine<String> {
22                 expect(3)
23                 cont = it
24             }
25             expect(6)
26             assertEquals("OK", value)
27         }
28         expect(4)
29         cont.resume("OK")
30         expect(5)
31         yield() // to the launched job
32         finish(7)
33     }
34 
35     @Test
<lambda>null36     fun testCancelThenResumeUnconfined() = runTest {
37         expect(1)
38         launch(Dispatchers.Unconfined) {
39             expect(2)
40             coroutineContext[Job]!!.cancel()
41             // a regular suspendCoroutine will still suspend despite the fact that coroutine was cancelled
42             val value = suspendCoroutine<String> {
43                 expect(3)
44                 cont = it
45             }
46             expect(5)
47             assertEquals("OK", value)
48         }
49         expect(4)
50         cont.resume("OK") // immediately resumes -- because unconfined
51         finish(6)
52     }
53 
54     @Test
<lambda>null55     fun testResumeThenCancel() = runTest {
56         expect(1)
57         val job = launch(start = CoroutineStart.UNDISPATCHED) {
58             expect(2)
59             val value = suspendCoroutine<String> {
60                 expect(3)
61                 cont = it
62             }
63             expect(7)
64             assertEquals("OK", value)
65         }
66         expect(4)
67         cont.resume("OK")
68         expect(5)
69         // now cancel the job, which the coroutine is waiting to be dispatched
70         job.cancel()
71         expect(6)
72         yield() // to the launched job
73         finish(8)
74     }
75 }