All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.TestDispatcher.kt Maven / Gradle / Ivy

There is a newer version: 1.9.0
Show newest version
package kotlinx.coroutines.test

import kotlinx.coroutines.*
import kotlin.coroutines.*
import kotlin.jvm.*
import kotlin.time.*

/**
 * A test dispatcher that can interface with a [TestCoroutineScheduler].
 *
 * The available implementations are:
 * - [StandardTestDispatcher] is a dispatcher that places new tasks into a queue.
 * - [UnconfinedTestDispatcher] is a dispatcher that behaves like [Dispatchers.Unconfined] while allowing to control
 *   the virtual time.
 */
@Suppress("INVISIBLE_REFERENCE")
public abstract class TestDispatcher internal constructor() : CoroutineDispatcher(), Delay, DelayWithTimeoutDiagnostics {
    /** The scheduler that this dispatcher is linked to. */
    public abstract val scheduler: TestCoroutineScheduler

    /** Notifies the dispatcher that it should process a single event marked with [marker] happening at time [time]. */
    internal fun processEvent(marker: Any) {
        check(marker is Runnable)
        marker.run()
    }

    /** @suppress */
    override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation) {
        val timedRunnable = CancellableContinuationRunnable(continuation, this)
        val handle = scheduler.registerEvent(
            this,
            timeMillis,
            timedRunnable,
            continuation.context,
            ::cancellableRunnableIsCancelled
        )
        continuation.disposeOnCancellation(handle)
    }

    /** @suppress */
    override fun invokeOnTimeout(timeMillis: Long, block: Runnable, context: CoroutineContext): DisposableHandle =
        scheduler.registerEvent(this, timeMillis, block, context) { false }

    /** @suppress */
    @Suppress("CANNOT_OVERRIDE_INVISIBLE_MEMBER")
    @Deprecated("Is only needed internally", level = DeprecationLevel.HIDDEN)
    public override fun timeoutMessage(timeout: Duration): String =
        "Timed out after $timeout of _virtual_ (kotlinx.coroutines.test) time. " +
            "To use the real time, wrap 'withTimeout' in 'withContext(Dispatchers.Default.limitedParallelism(1))'"
}

/**
 * This class exists to allow cleanup code to avoid throwing for cancelled continuations scheduled
 * in the future.
 */
private class CancellableContinuationRunnable(
    @JvmField val continuation: CancellableContinuation,
    private val dispatcher: CoroutineDispatcher
) : Runnable {
    override fun run() = with(dispatcher) { with(continuation) { resumeUndispatched(Unit) } }
}

private fun cancellableRunnableIsCancelled(runnable: CancellableContinuationRunnable): Boolean =
    !runnable.continuation.isActive




© 2015 - 2024 Weber Informatics LLC | Privacy Policy