diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index dde97dd..fe8244b 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -3,6 +3,7 @@ object Versions { const val kotlin = "1.5.10" const val kotlinBenchmark = "0.2.0-dev-20" const val kotlinCoroutines = "1.5.0" + const val kotlinCoroutinesTest = "1.5.0" const val ktor = "1.5.4" const val logback = "1.2.3" const val versionsPlugin = "0.38.0" diff --git a/kotlin-result-coroutines/build.gradle.kts b/kotlin-result-coroutines/build.gradle.kts index 51065df..debe6c1 100644 --- a/kotlin-result-coroutines/build.gradle.kts +++ b/kotlin-result-coroutines/build.gradle.kts @@ -31,6 +31,7 @@ kotlin { dependencies { implementation(kotlin("test-junit")) implementation(kotlin("test")) + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${Versions.kotlinCoroutinesTest}") } } diff --git a/kotlin-result-coroutines/src/jvmTest/kotlin/com/github/michaelbull/result/coroutines/binding/AsyncSuspendableBindingTest.kt b/kotlin-result-coroutines/src/jvmTest/kotlin/com/github/michaelbull/result/coroutines/binding/AsyncSuspendableBindingTest.kt index 3a30494..ef4950b 100644 --- a/kotlin-result-coroutines/src/jvmTest/kotlin/com/github/michaelbull/result/coroutines/binding/AsyncSuspendableBindingTest.kt +++ b/kotlin-result-coroutines/src/jvmTest/kotlin/com/github/michaelbull/result/coroutines/binding/AsyncSuspendableBindingTest.kt @@ -3,19 +3,19 @@ package com.github.michaelbull.result.coroutines.binding import com.github.michaelbull.result.Err import com.github.michaelbull.result.Ok import com.github.michaelbull.result.Result -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.asCoroutineDispatcher +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.async -import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking -import java.util.concurrent.Executors -import kotlin.coroutines.CoroutineContext +import kotlinx.coroutines.test.TestCoroutineDispatcher +import kotlinx.coroutines.test.runBlockingTest import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue +@ExperimentalCoroutinesApi class AsyncSuspendableBindingTest { private sealed class BindingError { @@ -35,7 +35,7 @@ class AsyncSuspendableBindingTest { return Ok(2) } - runBlocking { + runBlockingTest { val result = binding { val x = async { provideX().bind() } val y = async { provideY().bind() } @@ -67,7 +67,7 @@ class AsyncSuspendableBindingTest { return Err(BindingError.BindingErrorB) } - runBlocking { + runBlockingTest { val result = binding { val x = async { provideX().bind() } val y = async { provideY().bind() } @@ -95,18 +95,19 @@ class AsyncSuspendableBindingTest { } suspend fun provideY(): Result { - // as this test uses a new thread for each coroutine, we want to set this delay to a high enough number that - // there isn't any chance of a jvm run actually completing this suspending function in this thread first - // otherwise the assertions might fail. - delay(100) + delay(3) yStateChange = true return Err(BindingError.BindingErrorB) } + val dispatcherA = TestCoroutineDispatcher() + val dispatcherB = TestCoroutineDispatcher() + runBlocking { val result = binding { - val x = async(newThread("ThreadA")) { provideX().bind() } - val y = async(newThread("ThreadB")) { provideY().bind() } + val x = async(dispatcherA) { provideX().bind() } + val y = async(dispatcherB) { provideY().bind() } + dispatcherA.advanceTimeBy(2) x.await() + y.await() } @@ -144,11 +145,17 @@ class AsyncSuspendableBindingTest { return Err(BindingError.BindingErrorB) } + val dispatcherA = TestCoroutineDispatcher() + val dispatcherB = TestCoroutineDispatcher() + val dispatcherC = TestCoroutineDispatcher() + runBlocking { val result = binding { - launch(newThread("Thread A")) { provideX().bind() } - launch(newThread("Thread B")) { provideY().bind() } - launch(newThread("Thread C")) { provideZ().bind() } + launch(dispatcherA) { provideX().bind() } + dispatcherA.advanceTimeBy(20) + launch(dispatcherB) { provideY().bind() } + dispatcherB.advanceTimeBy(20) + launch(dispatcherC) { provideZ().bind() } } assertTrue(result is Err) @@ -161,8 +168,4 @@ class AsyncSuspendableBindingTest { assertFalse(zStateChange) } } - - private fun newThread(name: String): CoroutineContext { - return Executors.newSingleThreadExecutor().asCoroutineDispatcher() + CoroutineName(name) - } }