Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dkhalanskyjb committed Dec 16, 2022
1 parent 7c627da commit c4345c5
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 16 deletions.
27 changes: 25 additions & 2 deletions kotlinx-coroutines-test/common/test/Helpers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,32 @@ inline fun <T> assertRunsFast(timeout: Duration, block: () -> T): T {
inline fun <T> assertRunsFast(block: () -> T): T = assertRunsFast(2.seconds, block)

/**
* Passes [test] as an argument to [block], but as a function returning not a [TestResult] but [Unit].
* Runs [test], and then invokes [block], passing to it the lambda that functionally behaves
* the same way [test] does.
*/
expect fun testResultMap(block: (() -> Unit) -> Unit, test: () -> TestResult): TestResult
fun testResultMap(block: (() -> Unit) -> Unit, test: () -> TestResult): TestResult = testResultChain(
block = test,
after = {
block { it.getOrThrow() }
createTestResult { }
}
)

/**
* Chains together [block] and [after], passing the result of [block] to [after].
*/
expect fun testResultChain(block: () -> TestResult, after: (Result<Unit>) -> TestResult): TestResult

fun testResultChain(vararg chained: (Result<Unit>) -> TestResult): TestResult =
if (chained.isEmpty()) {
createTestResult { }
} else {
testResultChain(block = {
chained[0](Result.success(Unit))
}) {
testResultChain(*chained.drop(1).toTypedArray())
}
}

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

Expand Down
56 changes: 56 additions & 0 deletions kotlinx-coroutines-test/common/test/TestScopeTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,62 @@ class TestScopeTest {
}
}

/**
* Tests that the [TestScope] exception reporting mechanism will report the exceptions that happen between
* different tests.
*
* This test must be ran manually, because such exceptions still go through the global exception handler
* (as there's no guarantee that another test will happen), and the global exception handler will
* log the exceptions or, on Native, crash the test suite.
*/
@Test
@Ignore
fun testReportingStrayUncaughtExceptionsBetweenTests() {
val thrown = TestException("x")
testResultChain({
// register a handler for uncaught exceptions
runTest { }
}, {
GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) {
throw thrown
}
runTest {
fail("unreached")
}
}, {
// this `runTest` will not report the exception
runTest {
when (val exception = it.exceptionOrNull()) {
is UncaughtExceptionsBeforeTest -> {
assertEquals(1, exception.suppressedExceptions.size)
assertSame(exception.suppressedExceptions[0], thrown)
}
else -> fail("unexpected exception: $exception")
}
}
})
}

/**
* Tests that the uncaught exceptions that happen during the test are reported.
*/
@Test
fun testReportingStrayUncaughtExceptionsDuringTest(): TestResult {
val thrown = TestException("x")
return testResultChain({ _ ->
runTest {
val job = launch(Dispatchers.Default + NonCancellable) {
throw thrown
}
job.join()
}
}, {
runTest {
assertEquals(thrown, it.exceptionOrNull())
}
})
}

companion object {
internal val invalidContexts = listOf(
Dispatchers.Default, // not a [TestDispatcher]
Expand Down
13 changes: 5 additions & 8 deletions kotlinx-coroutines-test/js/test/Helpers.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
/*
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
* Copyright 2016-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.coroutines.test

import kotlin.test.*

actual fun testResultMap(block: (() -> Unit) -> Unit, test: () -> TestResult): TestResult =
test().then(
actual fun testResultChain(block: () -> TestResult, after: (Result<Unit>) -> TestResult): TestResult =
block().then(
{
block {
}
after(Result.success(Unit))
}, {
block {
throw it
}
after(Result.failure(it))
})

actual typealias NoJs = Ignore
9 changes: 6 additions & 3 deletions kotlinx-coroutines-test/jvm/test/HelpersJvm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
*/
package kotlinx.coroutines.test

actual fun testResultMap(block: (() -> Unit) -> Unit, test: () -> TestResult) {
block {
test()
actual fun testResultChain(block: () -> TestResult, after: (Result<Unit>) -> TestResult): TestResult {
try {
block()
after(Result.success(Unit))
} catch (e: Throwable) {
after(Result.failure(e))
}
}
9 changes: 6 additions & 3 deletions kotlinx-coroutines-test/native/test/Helpers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ package kotlinx.coroutines.test

import kotlin.test.*

actual fun testResultMap(block: (() -> Unit) -> Unit, test: () -> TestResult) {
block {
test()
actual fun testResultChain(block: () -> TestResult, after: (Result<Unit>) -> TestResult): TestResult {
try {
block()
after(Result.success(Unit))
} catch (e: Throwable) {
after(Result.failure(e))
}
}

Expand Down

0 comments on commit c4345c5

Please sign in to comment.