xref: /aosp_15_r20/external/kotlinx.coroutines/test-utils/jvm/src/Exceptions.kt (revision 7a7160fed73afa6648ef8aa100d4a336fe921d9a)
1 package kotlinx.coroutines.testing.exceptions
2 
3 import kotlinx.coroutines.*
4 import java.io.*
5 import java.util.*
6 import kotlin.contracts.*
7 import kotlin.coroutines.*
8 import kotlin.test.*
9 
checkExceptionnull10 inline fun <reified T : Throwable> checkException(exception: Throwable) {
11     assertIs<T>(exception)
12     assertTrue(exception.suppressed.isEmpty())
13     assertNull(exception.cause)
14 }
15 
checkCyclesnull16 fun checkCycles(t: Throwable) {
17     val sw = StringWriter()
18     t.printStackTrace(PrintWriter(sw))
19     assertFalse(sw.toString().contains("CIRCULAR REFERENCE"))
20 }
21 
22 class CapturingHandler : AbstractCoroutineContextElement(CoroutineExceptionHandler),
23     CoroutineExceptionHandler
24 {
25     private var unhandled: ArrayList<Throwable>? = ArrayList()
26 
<lambda>null27     override fun handleException(context: CoroutineContext, exception: Throwable) = synchronized<Unit>(this) {
28         unhandled!!.add(exception)
29     }
30 
<lambda>null31     fun getException(): Throwable = synchronized(this) {
32         val size = unhandled!!.size
33         assert(size == 1) { "Expected one unhandled exception, but have $size: $unhandled" }
34         return unhandled!![0].also { unhandled = null }
35     }
36 }
37 
captureExceptionsRunnull38 fun captureExceptionsRun(
39     context: CoroutineContext = EmptyCoroutineContext,
40     block: suspend CoroutineScope.() -> Unit
41 ): Throwable {
42     val handler = CapturingHandler()
43     runBlocking(context + handler, block = block)
44     return handler.getException()
45 }
46 
47 @OptIn(ExperimentalContracts::class)
assertCallsExceptionHandlerWithnull48 suspend inline fun <reified E: Throwable> assertCallsExceptionHandlerWith(
49     crossinline operation: suspend (CoroutineExceptionHandler) -> Unit): E {
50     contract {
51         callsInPlace(operation, InvocationKind.EXACTLY_ONCE)
52     }
53     val handler = CapturingHandler()
54     return withContext(handler) {
55         operation(handler)
56         assertIs<E>(handler.getException())
57     }
58 }
59