parameterize

inline fun parameterize(configuration: ParameterizeConfiguration = ParameterizeConfiguration.default, block: ParameterizeScope.() -> Unit)(source)

Executes the block for each combination of arguments, as declared with the parameter functions:

parameterize {
val letter by parameter('a'..'z')
val primeUnder20 by parameterOf(2, 3, 5, 7, 11, 13, 17, 19)
val computedValue by parameter { slowArgumentsComputation() }

// ...
}

With its default behavior, parameterize is strictly an alternative syntax to nested for loops, with loop variables defined within the body instead of up front, and without the indentation that's required for additional inner loops. For example, this sequence is equivalent to nested red/green/blue for loops with the same dependent ranges:

val reddishYellows = sequence {
parameterize {
val red by parameter(128..255)
val green by parameter(64..(red - 32))
val blue by parameter(0..(green - 64))

yield(Color(red, green, blue))
}
}

In addition to its default behavior, parameterize has a configuration with options to decorate its iterations, handle and record failures, and summarize the overall loop execution. The flexibility parameterize offers makes it suitable for many different specific use cases. Supported use cases include built in ways to access the named parameter arguments when a failure occurs, recording failures while continuing to the next iteration, and throwing a comprehensive multi-failure with the recorded failures and the arguments when each occurred.

Restrictions

  • The parameterized block must be deterministic, executing the same way for the same parameter arguments.

  • Parameter arguments must not be mutated, as they are re-used between iterations, and mutations from previous iterations could result in different execution, breaking the determinism assumption.

  • Parameters cannot be declared within another parameter's arguments, such as nesting within a lazy parameter {}.

  • Care should be taken with any asynchronous code, since the order that parameters are used must be the same between iterations, and all async code must be awaited before the block completes.

Throws

ParameterizeException

if the DSL is used incorrectly. (See restrictions)


inline fun parameterize(configuration: ParameterizeConfiguration = ParameterizeConfiguration.default, noinline decorator: suspend DecoratorScope.(iteration: suspend DecoratorScope.() -> Unit) -> Unit = configuration.decorator, noinline onFailure: OnFailureScope.(failure: Throwable) -> Unit = configuration.onFailure, noinline onComplete: OnCompleteScope.() -> Unit = configuration.onComplete, block: ParameterizeScope.() -> Unit)(source)

Calls parameterize with a copy of the configuration that has options overridden.

Parameters

See also