Create soft assertion sample and fix bugs it exposed
This commit is contained in:
@@ -57,5 +57,11 @@ kotlin {
|
||||
}
|
||||
|
||||
configure<com.bnorm.power.PowerAssertGradleExtension> {
|
||||
functions = listOf("kotlin.assert", "kotlin.test.assertTrue", "kotlin.require")
|
||||
functions = listOf(
|
||||
"kotlin.assert",
|
||||
"kotlin.test.assertTrue",
|
||||
"kotlin.require",
|
||||
"com.bnorm.power.AssertScope.assert",
|
||||
"com.bnorm.power.assert"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.bnorm.power
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
typealias LazyMessage = () -> Any
|
||||
|
||||
interface AssertScope {
|
||||
fun assert(assertion: Boolean, lazyMessage: LazyMessage? = null)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
fun assert(assertion: Boolean, lazyMessage: LazyMessage? = null) {
|
||||
contract { returns() implies assertion }
|
||||
if (!assertion) {
|
||||
throw AssertionError(lazyMessage?.invoke()?.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private class SoftAssertScope : AssertScope {
|
||||
private val assertions = mutableListOf<Throwable>()
|
||||
|
||||
override fun assert(assertion: Boolean, lazyMessage: LazyMessage?) {
|
||||
if (!assertion) {
|
||||
assertions.add(AssertionError(lazyMessage?.invoke()?.toString()))
|
||||
}
|
||||
}
|
||||
|
||||
fun close(exception: Throwable? = null) {
|
||||
if (assertions.isNotEmpty()) {
|
||||
val base = exception ?: AssertionError("Multiple failed assertions")
|
||||
for (assertion in assertions) {
|
||||
base.addSuppressed(assertion)
|
||||
}
|
||||
throw base
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
fun <R> assertSoftly(block: AssertScope.() -> R): R {
|
||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||
|
||||
val scope = SoftAssertScope()
|
||||
val result = runCatching { scope.block() }
|
||||
scope.close(result.exceptionOrNull())
|
||||
return result.getOrThrow()
|
||||
}
|
||||
@@ -29,4 +29,22 @@ class PowerAssertTest {
|
||||
fun require() {
|
||||
require(Person.UNKNOWN.size == 1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun softAssert() {
|
||||
val unknown: List<Person>? = Person.UNKNOWN
|
||||
assert(unknown != null)
|
||||
assert(unknown.size == 2)
|
||||
|
||||
val jane: Person
|
||||
val john: Person
|
||||
assertSoftly {
|
||||
jane = unknown[0]
|
||||
assert(jane.firstName == "Jane")
|
||||
assert(jane.lastName == "Doe") { "bad jane last name" }
|
||||
|
||||
john = unknown[1]
|
||||
assert(john.lastName == "Doe" && john.firstName == "John") { "bad john" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user