Skip to content

Commit

Permalink
Fix ParameterizeFailedError count including skipped cases
Browse files Browse the repository at this point in the history
Also expose the number of passing/skipped tests in the `onComplete` API
now that they're being tracked.

When an iteration continued early from a parameter with empty arguments,
that iteration would still count towards the total when reported in a
`ParameterizeFailedError` despite it not finishing.
  • Loading branch information
BenWoodworth committed Sep 18, 2024
1 parent 30adb30 commit 007cd03
Show file tree
Hide file tree
Showing 14 changed files with 151 additions and 29 deletions.
2 changes: 2 additions & 0 deletions api/parameterize.api
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ public final class com/benwoodworth/parameterize/ParameterizeConfiguration$OnCom
public final fun getCompletedEarly ()Z
public final fun getFailureCount ()J
public final fun getIterationCount ()J
public final fun getPassCount ()J
public final fun getRecordedFailures ()Ljava/util/List;
public final fun getSkipCount ()J
public final fun invoke (Lcom/benwoodworth/parameterize/ParameterizeFailedError$Companion;)Lcom/benwoodworth/parameterize/ParameterizeFailedError;
}

Expand Down
4 changes: 4 additions & 0 deletions api/parameterize.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,12 @@ final class com.benwoodworth.parameterize/ParameterizeConfiguration { // com.ben
final fun <get-failureCount>(): kotlin/Long // com.benwoodworth.parameterize/ParameterizeConfiguration.OnCompleteScope.failureCount.<get-failureCount>|<get-failureCount>(){}[0]
final val iterationCount // com.benwoodworth.parameterize/ParameterizeConfiguration.OnCompleteScope.iterationCount|{}iterationCount[0]
final fun <get-iterationCount>(): kotlin/Long // com.benwoodworth.parameterize/ParameterizeConfiguration.OnCompleteScope.iterationCount.<get-iterationCount>|<get-iterationCount>(){}[0]
final val passCount // com.benwoodworth.parameterize/ParameterizeConfiguration.OnCompleteScope.passCount|{}passCount[0]
final fun <get-passCount>(): kotlin/Long // com.benwoodworth.parameterize/ParameterizeConfiguration.OnCompleteScope.passCount.<get-passCount>|<get-passCount>(){}[0]
final val recordedFailures // com.benwoodworth.parameterize/ParameterizeConfiguration.OnCompleteScope.recordedFailures|{}recordedFailures[0]
final fun <get-recordedFailures>(): kotlin.collections/List<com.benwoodworth.parameterize/ParameterizeFailure> // com.benwoodworth.parameterize/ParameterizeConfiguration.OnCompleteScope.recordedFailures.<get-recordedFailures>|<get-recordedFailures>(){}[0]
final val skipCount // com.benwoodworth.parameterize/ParameterizeConfiguration.OnCompleteScope.skipCount|{}skipCount[0]
final fun <get-skipCount>(): kotlin/Long // com.benwoodworth.parameterize/ParameterizeConfiguration.OnCompleteScope.skipCount.<get-skipCount>|<get-skipCount>(){}[0]

final fun (com.benwoodworth.parameterize/ParameterizeFailedError.Companion).invoke(): com.benwoodworth.parameterize/ParameterizeFailedError // com.benwoodworth.parameterize/ParameterizeConfiguration.OnCompleteScope.invoke|invoke@com.benwoodworth.parameterize.ParameterizeFailedError.Companion(){}[0]
}
Expand Down
15 changes: 13 additions & 2 deletions src/commonMain/kotlin/ParameterizeConfiguration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,15 @@ public class ParameterizeConfiguration internal constructor(
/** @see Builder.onComplete */
public class OnCompleteScope internal constructor(
/**
* The total number of iterations completed.
* The total number of iterations, including [skips][skipCount] and [failures][failureCount].
*/
public val iterationCount: Long,

/**
* The number of skipped iterations, from parameters with empty arguments.
*/
public val skipCount: Long,

/**
* The number of failing iterations.
*/
Expand All @@ -235,8 +240,14 @@ public class ParameterizeConfiguration internal constructor(
/** @see OnFailureScope.recordFailure */
public val recordedFailures: List<ParameterizeFailure>
) {
/**
* The number of passing iterations, completed without [failing][failureCount] or [skipping][skipCount].
*/
public val passCount: Long
get() = iterationCount - skipCount - failureCount

/** @see ParameterizeFailedError */
public operator fun ParameterizeFailedError.Companion.invoke(): ParameterizeFailedError =
ParameterizeFailedError(recordedFailures, failureCount, iterationCount, completedEarly)
ParameterizeFailedError(recordedFailures, failureCount, passCount, completedEarly)
}
}
6 changes: 3 additions & 3 deletions src/commonMain/kotlin/ParameterizeFailedError.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import com.benwoodworth.parameterize.ParameterizeConfiguration.OnCompleteScope
public expect class ParameterizeFailedError internal constructor(
recordedFailures: List<ParameterizeFailure>,
failureCount: Long,
iterationCount: Long,
passCount: Long,
completedEarly: Boolean
) : AssertionError {
// TODO: Use context receiver instead of companion + pseudo constructor
Expand All @@ -43,7 +43,7 @@ public expect class ParameterizeFailedError internal constructor(

internal val recordedFailures: List<ParameterizeFailure>
internal val failureCount: Long
internal val iterationCount: Long
internal val passCount: Long
internal val completedEarly: Boolean

/** @suppress */
Expand Down Expand Up @@ -88,7 +88,7 @@ internal inline val ParameterizeFailedError.commonMessage
append("Failed ")
append(failureCount)
append('/')
append(iterationCount)
append(passCount + failureCount)

if (completedEarly) {
append('+')
Expand Down
2 changes: 1 addition & 1 deletion src/commonMain/kotlin/ParameterizeIterator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ internal class ParameterizeIterator(

@PublishedApi
internal fun handleFailure(failure: Throwable): Unit = when {
failure is ParameterizeContinue -> {}
failure is ParameterizeContinue -> parameterizeState.handleContinue()

failure is ParameterizeException && failure.parameterizeState === parameterizeState -> {
afterEach() // Since nextIteration() won't be called again to finalize the iteration
Expand Down
6 changes: 6 additions & 0 deletions src/commonMain/kotlin/ParameterizeState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ internal class ParameterizeState {
private var lastParameterWithNextArgument: ParameterState? = null

private var iterationCount = 0L
private var continueCount = 0L
private var failureCount = 0L
private val recordedFailures = mutableListOf<ParameterizeFailure>()

Expand Down Expand Up @@ -111,6 +112,10 @@ internal class ParameterizeState {
}
}

fun handleContinue() {
continueCount++
}

/**
* Get a list of used arguments for reporting a failure.
*/
Expand Down Expand Up @@ -153,6 +158,7 @@ internal class ParameterizeState {

val scope = OnCompleteScope(
iterationCount,
continueCount,
failureCount,
completedEarly = hasNextArgumentCombination,
recordedFailures,
Expand Down
101 changes: 100 additions & 1 deletion src/commonTest/kotlin/ParameterizeConfigurationSpec_onComplete.kt
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,87 @@ class ParameterizeConfigurationSpec_onComplete {
}
}

@Test
fun iteration_count_should_be_correct_with_skip() {
var expectedIterationCount = 0L

testParameterize(
onComplete = {
assertEquals(expectedIterationCount, iterationCount)
}
) {
val iteration by parameter(0..100)

expectedIterationCount++

if (iteration % 3 == 0 && iteration % 7 == 0) {
val skipWithEmptyParameter by parameterOf<Unit>()
}
}
}

@Test
fun skip_count_should_be_correct() {
var expectedSkipCount = 0L

testParameterize(
onComplete = {
assertEquals(expectedSkipCount, skipCount)
}
) {
val iteration by parameter(0..100)

if (iteration % 3 == 0 && iteration % 7 == 0) {
expectedSkipCount++
val skipWithEmptyParameter by parameterOf<Unit>()
}
}
}

@Test
fun skip_count_should_be_correct_with_break() {
var expectedSkipCount = 0L

testParameterize(
onFailure = {
breakEarly = true
},
onComplete = {
assertEquals(expectedSkipCount, skipCount)
}
) {
val iteration by parameter(0..100)

if (iteration % 3 == 0 && iteration % 7 == 0) {
expectedSkipCount++
val skipWithEmptyParameter by parameterOf<Unit>()
}

if (iteration == 50) {
fail()
}
}
}

@Test
fun pass_count_should_be_correct_with_skip() {
var expectedPassCount = 0L

testParameterize(
onComplete = {
assertEquals(expectedPassCount, passCount)
}
) {
val iteration by parameter(0..100)

if (iteration % 3 == 0 && iteration % 7 == 0) {
val skipWithEmptyParameter by parameterOf<Unit>()
}

expectedPassCount++
}
}

@Test
fun failure_count_should_be_correct() {
var expectedFailureCount = 0L
Expand Down Expand Up @@ -235,17 +316,35 @@ class ParameterizeConfigurationSpec_onComplete {
}
}

@Test
fun pass_count_should_be_correct() {
val scope = OnCompleteScope(
iterationCount = 10,
skipCount = 5,
failureCount = 3,
completedEarly = true,
recordedFailures = emptyList()
)

// Iterations that didn't skip or fail
val expectedPassCount = with(scope) { iterationCount - skipCount - failureCount }

assertEquals(expectedPassCount, scope.passCount)
}

@Test
fun error_constructor_should_build_error_with_correct_values() = testAll(
"base values" to OnCompleteScope(
recordedFailures = emptyList(),
failureCount = 1,
skipCount = 1,
iterationCount = 1,
completedEarly = false
),
"changed values" to OnCompleteScope(
recordedFailures = listOf(ParameterizeFailure(Throwable(), emptyList())),
failureCount = 2,
skipCount = 2,
iterationCount = 2,
completedEarly = true
)
Expand All @@ -256,7 +355,7 @@ class ParameterizeConfigurationSpec_onComplete {

assertEquals(scope.recordedFailures, error.recordedFailures, error::recordedFailures.name)
assertEquals(scope.failureCount, error.failureCount, error::failureCount.name)
assertEquals(scope.iterationCount, error.iterationCount, error::iterationCount.name)
assertEquals(scope.passCount, error.passCount, error::passCount.name)
assertEquals(scope.completedEarly, error.completedEarly, error::completedEarly.name)
}
}
30 changes: 15 additions & 15 deletions src/commonTest/kotlin/ParameterizeFailedErrorSpec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
emptyList(),
failureCount = 3,
iterationCount = 7,
passCount = 4,
completedEarly = false
)

Expand All @@ -53,7 +53,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
emptyList(),
failureCount = 3,
iterationCount = 7,
passCount = 4,
completedEarly = true
)

Expand All @@ -71,7 +71,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
failures.map { ParameterizeFailure(it, emptyList()) },
failureCount = 3,
iterationCount = 7,
passCount = 4,
completedEarly = false
)

Expand All @@ -98,7 +98,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
failures.map { ParameterizeFailure(it, emptyList()) },
failureCount = 3,
iterationCount = 7,
passCount = 4,
completedEarly = false
)

Expand All @@ -124,7 +124,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
failures.map { ParameterizeFailure(it, emptyList()) },
failureCount = 3,
iterationCount = 7,
passCount = 4,
completedEarly = false
)

Expand All @@ -148,7 +148,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
failures.map { ParameterizeFailure(it, emptyList()) },
failureCount = 1,
iterationCount = 7,
passCount = 6,
completedEarly = false
)

Expand All @@ -166,7 +166,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
List(2) { i -> ParameterizeFailure(Throwable("Failure $i"), emptyList()) },
failureCount = 3,
iterationCount = 7,
passCount = 4,
completedEarly = false
)

Expand All @@ -191,7 +191,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
failures.mapIndexed { index, it -> ParameterizeFailure(it, arguments.take(index)) },
failureCount = 3,
iterationCount = 7,
passCount = 4,
completedEarly = false
)

Expand All @@ -217,7 +217,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
failures.map { ParameterizeFailure(it, arguments) },
failureCount = 3,
iterationCount = 7,
passCount = 4,
completedEarly = false
)

Expand All @@ -232,7 +232,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
listOf(ParameterizeFailure(Throwable(), emptyList())),
failureCount = 1,
iterationCount = 1,
passCount = 0,
completedEarly = false
)

Expand All @@ -246,7 +246,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
listOf(ParameterizeFailure(Throwable(), arguments.take(1))),
failureCount = 1,
iterationCount = 1,
passCount = 0,
completedEarly = false
)

Expand All @@ -266,7 +266,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
listOf(ParameterizeFailure(Throwable(), arguments)),
failureCount = 1,
iterationCount = 1,
passCount = 0,
completedEarly = false
)

Expand All @@ -287,7 +287,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
listOf(),
failureCount = 1,
iterationCount = 1,
passCount = 0,
completedEarly = false
)

Expand All @@ -302,7 +302,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
listOf(ParameterizeFailure(failure, arguments)),
failureCount = 1,
iterationCount = 1,
passCount = 0,
completedEarly = false
)

Expand All @@ -317,7 +317,7 @@ class ParameterizeFailedErrorSpec {
val error = ParameterizeFailedError(
listOf(ParameterizeFailure(failure, arguments)),
failureCount = 1,
iterationCount = 1,
passCount = 0,
completedEarly = false
)

Expand Down
2 changes: 1 addition & 1 deletion src/jsMain/kotlin/ParameterizeFailedError.js.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package com.benwoodworth.parameterize
public actual class ParameterizeFailedError internal actual constructor(
internal actual val recordedFailures: List<ParameterizeFailure>,
internal actual val failureCount: Long,
internal actual val iterationCount: Long,
internal actual val passCount: Long,
internal actual val completedEarly: Boolean
) : AssertionError() {
public actual companion object;
Expand Down
Loading

0 comments on commit 007cd03

Please sign in to comment.