File: TestDispatcher.kt

package info (click to toggle)
kotlin 1.3.31%2Bds1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 109,908 kB
  • sloc: java: 454,756; xml: 18,599; javascript: 10,452; sh: 513; python: 97; makefile: 69; ansic: 4
file content (50 lines) | stat: -rw-r--r-- 1,456 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*
 * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
 * that can be found in the license/LICENSE.txt file.
 */

package test.coroutines

import java.io.Closeable
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlin.coroutines.*
import kotlin.test.assertEquals

class TestDispatcher(
    private val name: String
) : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor, Closeable {
    private lateinit var thread: Thread

    val executor: ExecutorService = Executors.newSingleThreadExecutor { runnable ->
        Thread(runnable, name).also { thread = it }
    }

    fun assertThread() {
        assertEquals(thread, Thread.currentThread())
    }

    override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> =
        DispatchedContinuation(continuation)

    override fun close() {
        executor.shutdown()
    }

    suspend fun yield() = suspendCoroutine<Unit> { cont ->
        executor.execute {
            assertThread()
            cont.resume(Unit)
        }
    }

    inner class DispatchedContinuation<T>(val delegate: Continuation<T>) : Continuation<T> {
        override val context: CoroutineContext = delegate.context

        override fun resumeWith(result: Result<T>) {
            executor.execute {
                delegate.resumeWith(result)
            }
        }
    }
}