mirror of
https://github.com/mamoe/mirai.git
synced 2025-04-25 13:03:35 +08:00
[core/testFramework] Add assertNoCoroutineSuspension
This commit is contained in:
parent
9995a2136c
commit
0ea5503f3b
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2019-2023 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.utils.testFramework
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFails
|
||||
import kotlin.test.fail
|
||||
|
||||
suspend inline fun <R> assertNoCoroutineSuspension(
|
||||
crossinline block: suspend () -> R,
|
||||
): R {
|
||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||
return withContext(Dispatchers.Default.limitedParallelism(1)) {
|
||||
val job = launch(start = CoroutineStart.UNDISPATCHED) {
|
||||
yield()
|
||||
fail("Expected no coroutine suspension")
|
||||
}
|
||||
val ret = block()
|
||||
job.cancel()
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
suspend inline fun <R> assertCoroutineSuspends(
|
||||
crossinline block: suspend () -> R,
|
||||
): R {
|
||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||
|
||||
return withContext(Dispatchers.Default.limitedParallelism(1)) {
|
||||
val job = launch(start = CoroutineStart.UNDISPATCHED) {
|
||||
yield() // goto block
|
||||
}
|
||||
val ret = block()
|
||||
kotlin.test.assertTrue("Expected coroutine suspension") { job.isCompleted }
|
||||
job.cancel()
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
class AssertCoroutineSuspensionTest {
|
||||
@Test
|
||||
fun `assertNoCoroutineSuspension no suspension`() = runTest {
|
||||
assertNoCoroutineSuspension {}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `assertNoCoroutineSuspension suspend cancellable`() = runTest {
|
||||
assertFails {
|
||||
assertNoCoroutineSuspension {
|
||||
suspendCancellableCoroutine<Unit> { }
|
||||
}
|
||||
}.run {
|
||||
assertEquals("Expected no coroutine suspension", message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `assertCoroutineSuspends suspend`() = runTest {
|
||||
assertCoroutineSuspends {
|
||||
suspendCancellableCoroutine {
|
||||
// resume after suspendCancellableCoroutine returns to create a suspension
|
||||
launch(start = CoroutineStart.UNDISPATCHED) {
|
||||
yield()
|
||||
it.resume(Unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `assertCoroutineSuspends no suspension`() = runTest {
|
||||
assertFails {
|
||||
assertCoroutineSuspends {}
|
||||
}.run {
|
||||
assertEquals("Expected coroutine suspension", message)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user