<lambda>null1 package kotlinx.coroutines.testing
2
3 import kotlinx.coroutines.*
4 import kotlin.test.*
5 import kotlin.js.*
6
7 actual typealias NoJs = Ignore
8
9 actual val VERBOSE = false
10
11 actual val isStressTest: Boolean = false
12 actual val stressTestMultiplier: Int = 1
13 actual val stressTestMultiplierSqrt: Int = 1
14
15 @JsName("Promise")
16 external class MyPromise {
17 fun then(onFulfilled: ((Unit) -> Unit), onRejected: ((Throwable) -> Unit)): MyPromise
18 fun then(onFulfilled: ((Unit) -> Unit)): MyPromise
19 }
20
21 /** Always a `Promise<Unit>` */
22 public actual typealias TestResult = MyPromise
23
lastResortReportExceptionnull24 internal actual fun lastResortReportException(error: Throwable) {
25 println(error)
26 console.log(error)
27 }
28
29 actual open class TestBase(
30 private val errorCatching: ErrorCatching.Impl
31 ): OrderedExecutionTestBase(), ErrorCatching by errorCatching {
32 private var lastTestPromise: Promise<*>? = null
33
34 actual constructor(): this(errorCatching = ErrorCatching.Impl())
35
printlnnull36 actual fun println(message: Any?) {
37 kotlin.io.println(message)
38 }
39
runTestnull40 actual fun runTest(
41 expected: ((Throwable) -> Boolean)?,
42 unhandled: List<(Throwable) -> Boolean>,
43 block: suspend CoroutineScope.() -> Unit
44 ): TestResult {
45 var exCount = 0
46 var ex: Throwable? = null
47 /*
48 * This is an additional sanity check against `runTest` mis-usage on JS.
49 * The only way to write an async test on JS is to return Promise from the test function.
50 * _Just_ launching promise and returning `Unit` won't suffice as the underlying test framework
51 * won't be able to detect an asynchronous failure in a timely manner.
52 * We cannot detect such situations, but we can detect the most common erroneous pattern
53 * in our code base, an attempt to use multiple `runTest` in the same `@Test` method,
54 * which typically is a premise to the same error:
55 * ```
56 * @Test
57 * fun incorrectTestForJs() { // <- promise is not returned
58 * for (parameter in parameters) {
59 * runTest {
60 * runTestForParameter(parameter)
61 * }
62 * }
63 * }
64 * ```
65 */
66 if (lastTestPromise != null) {
67 error("Attempt to run multiple asynchronous test within one @Test method")
68 }
69 val result = GlobalScope.promise(block = block, context = CoroutineExceptionHandler { _, e ->
70 if (e is CancellationException) return@CoroutineExceptionHandler // are ignored
71 exCount++
72 when {
73 exCount > unhandled.size ->
74 error("Too many unhandled exceptions $exCount, expected ${unhandled.size}, got: $e", e)
75 !unhandled[exCount - 1](e) ->
76 error("Unhandled exception was unexpected: $e", e)
77 }
78 }).catch { e ->
79 ex = e
80 if (expected != null) {
81 if (!expected(e)) {
82 console.log(e)
83 error("Unexpected exception $e", e)
84 }
85 } else
86 throw e
87 }.finally {
88 if (ex == null && expected != null) error("Exception was expected but none produced")
89 if (exCount < unhandled.size)
90 error("Too few unhandled exceptions $exCount, expected ${unhandled.size}")
91 errorCatching.close()
92 checkFinishCall()
93 }
94 lastTestPromise = result
95 @Suppress("CAST_NEVER_SUCCEEDS")
96 return result as MyPromise
97 }
98 }
99
100 actual val isNative = false
101
102 actual val isBoundByJsTestTimeout = true
103
104 actual val isJavaAndWindows: Boolean get() = false
105
106 actual val usesSharedEventLoop: Boolean = false
107