
commonMain.io.kotest.properties.shrinking.shrink.kt Maven / Gradle / Ivy
package io.kotest.properties.shrinking
import io.kotest.assertions.show.show
import io.kotest.properties.Gen
import io.kotest.properties.PropertyContext
import io.kotest.properties.PropertyFailureInput
import io.kotest.properties.PropertyTesting
import io.kotest.properties.propertyAssertionError
fun shrink(t: T, gen: Gen, test: (T) -> Unit): T = shrink2(t, gen.shrinker(), test)
fun shrink2(t: T, shrinker: Shrinker?, test: (T) -> Unit): T {
return when (shrinker) {
null -> t
else -> shrink(t, shrinker, test)
}
}
fun shrink(t: T, shrinker: Shrinker, test: (T) -> Unit): T {
val sb = StringBuilder()
sb.append("Attempting to shrink failed arg ${t.show().value}\n")
var candidate = t
val tested = HashSet()
var count = 0
while (true) {
val candidates = shrinker.shrink(candidate).filterNot { tested.contains(it) }
if (candidates.isEmpty()) {
sb.append("Shrink result => ${candidate.show().value}\n")
if (PropertyTesting.shouldPrintShrinkSteps) {
println(sb)
}
return candidate
} else {
val next = candidates.firstOrNull {
tested.add(it)
count++
try {
test(it)
sb.append("Shrink #$count: ${it.show().value} pass\n")
false
} catch (t: Throwable) {
sb.append("Shrink #$count: ${it.show().value} fail\n")
true
}
}
if (next == null) {
sb.append("Shrink result => ${candidate.show().value}\n")
if (PropertyTesting.shouldPrintShrinkSteps) {
println(sb)
}
return candidate
} else {
candidate = next
}
}
}
}
fun shrinkInputs(a: A,
b: B,
c: C,
d: D,
gena: Gen,
genb: Gen,
genc: Gen,
gend: Gen,
context: PropertyContext,
fn: PropertyContext.(a: A, b: B, c: C, d: D) -> Unit,
e: AssertionError) {
val smallestA = shrink(a, gena) { context.fn(it, b, c, d) }
val smallestB = shrink(b, genb) { context.fn(smallestA, it, c, d) }
val smallestC = shrink(c, genc) { context.fn(smallestA, smallestB, it, d) }
val smallestD = shrink(d, gend) { context.fn(smallestA, smallestB, smallestC, it) }
val inputs = listOf(
PropertyFailureInput(a, smallestA),
PropertyFailureInput(b, smallestB),
PropertyFailureInput(c, smallestC),
PropertyFailureInput(d, smallestD)
)
throw propertyAssertionError(e, context.attempts(), inputs)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy