From 5509e9068283295a33c92a9ae9d9b56c85cc2dcf Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Wed, 27 Oct 2021 10:29:25 +0300 Subject: [PATCH] Fixes --- kotlinx-coroutines-test/README.md | 5 ++--- .../api/kotlinx-coroutines-test.api | 8 -------- .../common/src/DelayController.kt | 11 ++--------- kotlinx-coroutines-test/common/src/TestBuilders.kt | 2 +- .../common/src/TestCoroutineScheduler.kt | 7 ++++--- .../common/src/TestCoroutineScope.kt | 12 ++++++++---- kotlinx-coroutines-test/common/src/TestDispatcher.kt | 1 - 7 files changed, 17 insertions(+), 29 deletions(-) diff --git a/kotlinx-coroutines-test/README.md b/kotlinx-coroutines-test/README.md index 43ae18f532..5130da1167 100644 --- a/kotlinx-coroutines-test/README.md +++ b/kotlinx-coroutines-test/README.md @@ -114,7 +114,7 @@ suspend fun bar() {} ``` `runBlockingTest` will auto-progress virtual time until all coroutines are completed before returning. If any coroutines -are not able to complete, an [UncompletedCoroutinesError] will be thrown. +are not able to complete, an `AssertionError` will be thrown. *Note:* The default eager behavior of [runBlockingTest] will ignore [CoroutineStart] parameters. @@ -148,7 +148,7 @@ suspend fun CoroutineScope.foo() { *Note:* `runBlockingTest` will always attempt to auto-progress time until all coroutines are completed just before exiting. This is a convenience to avoid having to call [advanceUntilIdle][DelayController.advanceUntilIdle] as the last line of many common test cases. -If any coroutines cannot complete by advancing time, an [UncompletedCoroutinesError] is thrown. +If any coroutines cannot complete by advancing time, an `AssertionError` is thrown. ### Testing `withTimeout` using `runBlockingTest` @@ -447,7 +447,6 @@ If you have any suggestions for improvements to this experimental API please sha [setMain]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/set-main.html [runBlockingTest]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/run-blocking-test.html -[UncompletedCoroutinesError]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/-uncompleted-coroutines-error/index.html [DelayController]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/-delay-controller/index.html [DelayController.advanceUntilIdle]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/-delay-controller/advance-until-idle.html [DelayController.pauseDispatcher]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/-delay-controller/pause-dispatcher.html diff --git a/kotlinx-coroutines-test/api/kotlinx-coroutines-test.api b/kotlinx-coroutines-test/api/kotlinx-coroutines-test.api index 3198253b0f..0aebee5275 100644 --- a/kotlinx-coroutines-test/api/kotlinx-coroutines-test.api +++ b/kotlinx-coroutines-test/api/kotlinx-coroutines-test.api @@ -58,10 +58,6 @@ public abstract interface class kotlinx/coroutines/test/TestCoroutineScope : kot public abstract fun getTestScheduler ()Lkotlinx/coroutines/test/TestCoroutineScheduler; } -public final class kotlinx/coroutines/test/TestCoroutineScope$DefaultImpls { - public static fun getTestScheduler (Lkotlinx/coroutines/test/TestCoroutineScope;)Lkotlinx/coroutines/test/TestCoroutineScheduler; -} - public final class kotlinx/coroutines/test/TestCoroutineScopeKt { public static final fun TestCoroutineScope (Lkotlin/coroutines/CoroutineContext;)Lkotlinx/coroutines/test/TestCoroutineScope; public static synthetic fun TestCoroutineScope$default (Lkotlin/coroutines/CoroutineContext;ILjava/lang/Object;)Lkotlinx/coroutines/test/TestCoroutineScope; @@ -92,7 +88,3 @@ public abstract interface class kotlinx/coroutines/test/UncaughtExceptionCaptor public abstract fun getUncaughtExceptions ()Ljava/util/List; } -public final class kotlinx/coroutines/test/UncompletedCoroutinesError : java/lang/AssertionError { - public fun (Ljava/lang/String;)V -} - diff --git a/kotlinx-coroutines-test/common/src/DelayController.kt b/kotlinx-coroutines-test/common/src/DelayController.kt index b86955db31..5d8686da6b 100644 --- a/kotlinx-coroutines-test/common/src/DelayController.kt +++ b/kotlinx-coroutines-test/common/src/DelayController.kt @@ -84,11 +84,11 @@ public interface DelayController { /** * Call after test code completes to ensure that the dispatcher is properly cleaned up. * - * @throws UncompletedCoroutinesError if any pending tasks are active, however it will not throw for suspended + * @throws AssertionError if any pending tasks are active, however it will not throw for suspended * coroutines. */ @ExperimentalCoroutinesApi - @Throws(UncompletedCoroutinesError::class) + @Throws(AssertionError::class) public fun cleanupTestCoroutines() /** @@ -123,13 +123,6 @@ public interface DelayController { public fun resumeDispatcher() } -/** - * Thrown when a test has completed and there are tasks that are not completed or cancelled. - */ -// todo: maybe convert into non-public class in 1.3.0 (need use-cases for a public exception type) -@ExperimentalCoroutinesApi -public class UncompletedCoroutinesError(message: String): AssertionError(message) - internal interface SchedulerAsDelayController: DelayController { public val scheduler: TestCoroutineScheduler diff --git a/kotlinx-coroutines-test/common/src/TestBuilders.kt b/kotlinx-coroutines-test/common/src/TestBuilders.kt index ebe22050f1..f66f962be7 100644 --- a/kotlinx-coroutines-test/common/src/TestBuilders.kt +++ b/kotlinx-coroutines-test/common/src/TestBuilders.kt @@ -34,7 +34,7 @@ import kotlin.coroutines.* * * Unhandled exceptions thrown by coroutines in the test will be re-thrown at the end of the test. * - * @throws UncompletedCoroutinesError If the [testBody] does not complete (or cancel) all coroutines that it launches + * @throws AssertionError If the [testBody] does not complete (or cancel) all coroutines that it launches * (including coroutines suspended on join/await). * * @param context additional context elements. If [context] contains [CoroutineDispatcher] or [CoroutineExceptionHandler], diff --git a/kotlinx-coroutines-test/common/src/TestCoroutineScheduler.kt b/kotlinx-coroutines-test/common/src/TestCoroutineScheduler.kt index 0d0716999c..2f5e1fd216 100644 --- a/kotlinx-coroutines-test/common/src/TestCoroutineScheduler.kt +++ b/kotlinx-coroutines-test/common/src/TestCoroutineScheduler.kt @@ -24,10 +24,11 @@ import kotlin.jvm.* */ @ExperimentalCoroutinesApi // TODO: maybe make this a `TimeSource`? -public class TestCoroutineScheduler: AbstractCoroutineContextElement(TestCoroutineScheduler), CoroutineContext.Element { +public class TestCoroutineScheduler : AbstractCoroutineContextElement(TestCoroutineScheduler), + CoroutineContext.Element { /** @suppress */ - public companion object Key: CoroutineContext.Key + public companion object Key : CoroutineContext.Key /** This heap stores the knowledge about which dispatchers are interested in which moments of virtual time. */ // TODO: all the synchronization is done via a separate lock, so a non-thread-safe priority queue can be used. @@ -55,7 +56,7 @@ public class TestCoroutineScheduler: AbstractCoroutineContextElement(TestCorouti dispatcher: TestDispatcher, timeDeltaMillis: Long, marker: T, - isCancelled : (T) -> Boolean + isCancelled: (T) -> Boolean ): DisposableHandle { require(timeDeltaMillis >= 0) { "Attempted scheduling an event earlier in time (with the time delta $timeDeltaMillis)" } val count = count.getAndIncrement() diff --git a/kotlinx-coroutines-test/common/src/TestCoroutineScope.kt b/kotlinx-coroutines-test/common/src/TestCoroutineScope.kt index fae427aa62..e4e92bd486 100644 --- a/kotlinx-coroutines-test/common/src/TestCoroutineScope.kt +++ b/kotlinx-coroutines-test/common/src/TestCoroutineScope.kt @@ -11,13 +11,13 @@ import kotlin.coroutines.* * A scope which provides detailed control over the execution of coroutines for tests. */ @ExperimentalCoroutinesApi -public interface TestCoroutineScope: CoroutineScope, UncaughtExceptionCaptor { +public sealed interface TestCoroutineScope: CoroutineScope, UncaughtExceptionCaptor { /** * Call after the test completes. * Calls [UncaughtExceptionCaptor.cleanupTestCoroutinesCaptor] and [DelayController.cleanupTestCoroutines]. * * @throws Throwable the first uncaught exception, if there are any uncaught exceptions. - * @throws UncompletedCoroutinesError if any pending tasks are active, however it will not throw for suspended + * @throws AssertionError if any pending tasks are active, however it will not throw for suspended * coroutines. */ @ExperimentalCoroutinesApi @@ -28,8 +28,6 @@ public interface TestCoroutineScope: CoroutineScope, UncaughtExceptionCaptor { */ @ExperimentalCoroutinesApi public val testScheduler: TestCoroutineScheduler - get() = coroutineContext[TestCoroutineScheduler] - ?: throw UnsupportedOperationException("This scope does not have a TestCoroutineScheduler linked to it") } private class TestCoroutineScopeImpl ( @@ -158,3 +156,9 @@ public fun TestCoroutineScope.resumeDispatcher() { private val TestCoroutineScope.delayControllerForPausing: DelayController get() = coroutineContext.delayController ?: throw IllegalStateException("This scope isn't able to pause its dispatchers") + +/** + * Thrown when a test has completed and there are tasks that are not completed or cancelled. + */ +@ExperimentalCoroutinesApi +internal class UncompletedCoroutinesError(message: String): AssertionError(message) diff --git a/kotlinx-coroutines-test/common/src/TestDispatcher.kt b/kotlinx-coroutines-test/common/src/TestDispatcher.kt index 549eddc34f..b37f10bfda 100644 --- a/kotlinx-coroutines-test/common/src/TestDispatcher.kt +++ b/kotlinx-coroutines-test/common/src/TestDispatcher.kt @@ -18,7 +18,6 @@ public abstract class TestDispatcher: CoroutineDispatcher(), Delay { public abstract val scheduler: TestCoroutineScheduler /** Notifies the dispatcher that it should process a single event marked with [marker] happening at time [time]. */ - @ExperimentalCoroutinesApi internal abstract fun processEvent(time: Long, marker: Any) /** @suppress */