1 /*
2  * Copyright 2016-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 package kotlinx.coroutines
6 
7 import kotlin.coroutines.*
8 import kotlin.test.*
9 
10 class ImmediateYieldTest : TestBase() {
11 
12     // See https://github.com/Kotlin/kotlinx.coroutines/issues/1474
13     @Test
<lambda>null14     fun testImmediateYield() = runTest {
15         expect(1)
16         launch(ImmediateDispatcher(coroutineContext[ContinuationInterceptor])) {
17             expect(2)
18             yield()
19             expect(4)
20         }
21         expect(3) // after yield
22         yield() // yield back
23         finish(5)
24     }
25 
26     // imitate immediate dispatcher
27     private class ImmediateDispatcher(job: ContinuationInterceptor?) : CoroutineDispatcher() {
28         val delegate: CoroutineDispatcher = job as CoroutineDispatcher
29 
isDispatchNeedednull30         override fun isDispatchNeeded(context: CoroutineContext): Boolean = false
31 
32         override fun dispatch(context: CoroutineContext, block: Runnable) =
33             delegate.dispatch(context, block)
34     }
35 
36     @Test
37     fun testWrappedUnconfinedDispatcherYield() = runTest {
38         expect(1)
39         launch(wrapperDispatcher(Dispatchers.Unconfined)) {
40             expect(2)
41             yield() // Would not work with wrapped unconfined dispatcher
42             expect(3)
43         }
44         finish(4) // after launch
45     }
46 
47     @Test
<lambda>null48     fun testWrappedUnconfinedDispatcherYieldStackOverflow() = runTest {
49         expect(1)
50         withContext(wrapperDispatcher(Dispatchers.Unconfined)) {
51             repeat(100_000) {
52                 yield()
53             }
54         }
55         finish(2)
56     }
57 }