Skip to content

Commit ead5c0b

Browse files
committed
Add tests
1 parent f9b7683 commit ead5c0b

File tree

5 files changed

+98
-16
lines changed

5 files changed

+98
-16
lines changed

kotlinx-coroutines-test/common/test/Helpers.kt

+25-2
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,32 @@ inline fun <T> assertRunsFast(timeout: Duration, block: () -> T): T {
3131
inline fun <T> assertRunsFast(block: () -> T): T = assertRunsFast(2.seconds, block)
3232

3333
/**
34-
* Passes [test] as an argument to [block], but as a function returning not a [TestResult] but [Unit].
34+
* Runs [test], and then invokes [block], passing to it the lambda that functionally behaves
35+
* the same way [test] does.
3536
*/
36-
expect fun testResultMap(block: (() -> Unit) -> Unit, test: () -> TestResult): TestResult
37+
fun testResultMap(block: (() -> Unit) -> Unit, test: () -> TestResult): TestResult = testResultChain(
38+
block = test,
39+
after = {
40+
block { it.getOrThrow() }
41+
createTestResult { }
42+
}
43+
)
44+
45+
/**
46+
* Chains together [block] and [after], passing the result of [block] to [after].
47+
*/
48+
expect fun testResultChain(block: () -> TestResult, after: (Result<Unit>) -> TestResult): TestResult
49+
50+
fun testResultChain(vararg chained: (Result<Unit>) -> TestResult): TestResult =
51+
if (chained.isEmpty()) {
52+
createTestResult { }
53+
} else {
54+
testResultChain(block = {
55+
chained[0](Result.success(Unit))
56+
}) {
57+
testResultChain(*chained.drop(1).toTypedArray())
58+
}
59+
}
3760

3861
class TestException(message: String? = null): Exception(message)
3962

kotlinx-coroutines-test/common/test/TestScopeTest.kt

+56
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,62 @@ class TestScopeTest {
476476
}
477477
}
478478

479+
/**
480+
* Tests that the [TestScope] exception reporting mechanism will report the exceptions that happen between
481+
* different tests.
482+
*
483+
* This test must be ran manually, because such exceptions still go through the global exception handler
484+
* (as there's no guarantee that another test will happen), and the global exception handler will
485+
* log the exceptions or, on Native, crash the test suite.
486+
*/
487+
@Test
488+
@Ignore
489+
fun testReportingStrayUncaughtExceptionsBetweenTests() {
490+
val thrown = TestException("x")
491+
testResultChain({
492+
// register a handler for uncaught exceptions
493+
runTest { }
494+
}, {
495+
GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) {
496+
throw thrown
497+
}
498+
runTest {
499+
fail("unreached")
500+
}
501+
}, {
502+
// this `runTest` will not report the exception
503+
runTest {
504+
when (val exception = it.exceptionOrNull()) {
505+
is UncaughtExceptionsBeforeTest -> {
506+
assertEquals(1, exception.suppressedExceptions.size)
507+
assertSame(exception.suppressedExceptions[0], thrown)
508+
}
509+
else -> fail("unexpected exception: $exception")
510+
}
511+
}
512+
})
513+
}
514+
515+
/**
516+
* Tests that the uncaught exceptions that happen during the test are reported.
517+
*/
518+
@Test
519+
fun testReportingStrayUncaughtExceptionsDuringTest(): TestResult {
520+
val thrown = TestException("x")
521+
return testResultChain({ _ ->
522+
runTest {
523+
val job = launch(Dispatchers.Default + NonCancellable) {
524+
throw thrown
525+
}
526+
job.join()
527+
}
528+
}, {
529+
runTest {
530+
assertEquals(thrown, it.exceptionOrNull())
531+
}
532+
})
533+
}
534+
479535
companion object {
480536
internal val invalidContexts = listOf(
481537
Dispatchers.Default, // not a [TestDispatcher]
+5-8
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
/*
2-
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
2+
* Copyright 2016-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

55
package kotlinx.coroutines.test
66

77
import kotlin.test.*
88

9-
actual fun testResultMap(block: (() -> Unit) -> Unit, test: () -> TestResult): TestResult =
10-
test().then(
9+
actual fun testResultChain(block: () -> TestResult, after: (Result<Unit>) -> TestResult): TestResult =
10+
block().then(
1111
{
12-
block {
13-
}
12+
after(Result.success(Unit))
1413
}, {
15-
block {
16-
throw it
17-
}
14+
after(Result.failure(it))
1815
})
1916

2017
actual typealias NoJs = Ignore

kotlinx-coroutines-test/jvm/test/HelpersJvm.kt

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
*/
44
package kotlinx.coroutines.test
55

6-
actual fun testResultMap(block: (() -> Unit) -> Unit, test: () -> TestResult) {
7-
block {
8-
test()
6+
actual fun testResultChain(block: () -> TestResult, after: (Result<Unit>) -> TestResult): TestResult {
7+
try {
8+
block()
9+
after(Result.success(Unit))
10+
} catch (e: Throwable) {
11+
after(Result.failure(e))
912
}
1013
}

kotlinx-coroutines-test/native/test/Helpers.kt

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ package kotlinx.coroutines.test
55

66
import kotlin.test.*
77

8-
actual fun testResultMap(block: (() -> Unit) -> Unit, test: () -> TestResult) {
9-
block {
10-
test()
8+
actual fun testResultChain(block: () -> TestResult, after: (Result<Unit>) -> TestResult): TestResult {
9+
try {
10+
block()
11+
after(Result.success(Unit))
12+
} catch (e: Throwable) {
13+
after(Result.failure(e))
1114
}
1215
}
1316

0 commit comments

Comments
 (0)