• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright 2016-2018 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 org.junit.*
8 import java.util.concurrent.*
9 import kotlin.coroutines.*
10 import kotlin.test.assertEquals
11 
12 class DelayJvmTest : TestBase() {
13     /**
14      * Test that delay works properly in contexts with custom [ContinuationInterceptor]
15      */
16     @Test
17     fun testDelayInArbitraryContext() = runBlocking {
18         var thread: Thread? = null
19         val pool = Executors.newFixedThreadPool(1) { runnable ->
20             Thread(runnable).also { thread = it }
21         }
22         val context = CustomInterceptor(pool)
23         val c = async(context) {
24             assertEquals(thread, Thread.currentThread())
25             delay(100)
26             assertEquals(thread, Thread.currentThread())
27             42
28         }
29         assertEquals(42, c.await())
30         pool.shutdown()
31     }
32 
33     @Test
34     fun testDelayWithoutDispatcher() = runBlocking(CoroutineName("testNoDispatcher.main")) {
35         // launch w/o a specified dispatcher
36         val c = async(CoroutineName("testNoDispatcher.inner")) {
37             delay(100)
38             42
39         }
40         assertEquals(42, c.await())
41     }
42 
43     @Test
44     fun testNegativeDelay() = runBlocking {
45         expect(1)
46         val job = async {
47             expect(3)
48             delay(0)
49             expect(4)
50         }
51 
52         delay(-1)
53         expect(2)
54         job.await()
55         finish(5)
56     }
57 
58     class CustomInterceptor(val pool: Executor) : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor {
59         override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> =
60             Wrapper(pool, continuation)
61     }
62 
63     class Wrapper<T>(val pool: Executor, private val cont: Continuation<T>) : Continuation<T> {
64         override val context: CoroutineContext
65             get() = cont.context
66 
67         override fun resumeWith(result: Result<T>) {
68             pool.execute { cont.resumeWith(result) }
69         }
70     }
71 }