net.jqwik.api.providers.ArbitraryProvider Maven / Gradle / Ivy
package net.jqwik.api.providers;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import org.apiguardian.api.*;
import net.jqwik.api.*;
import static org.apiguardian.api.API.Status.*;
/**
* Implementations of this class are used to provide default arbitraries to
* {@code ForAll} parameters without an explicit provider reference.
*
* Implementations must be registered in /META-INF/services/net.jqwik.api.providers.ArbitraryProvider
* so that they will be automatically considered for parameter resolution.
*
*
* Some examples that come with jqwik:
*
*
* - net.jqwik.engine.providers.EnumArbitraryProvider
* - net.jqwik.engine.providers.BigDecimalArbitraryProvider
* - net.jqwik.engine.providers.ListArbitraryProvider
*
*/
@API(status = MAINTAINED, since = "1.0")
public interface ArbitraryProvider {
@FunctionalInterface
interface SubtypeProvider extends Function>> {
/**
* Resolve all typeUsages and return a stream of all possible arbitraries
* combinations per type. The list of arbitraries returned in the
* stream has the same size as the number of typeUsages handed in.
*
* @param typeUsages
* @return stream of list of arbitraries
*/
@API(status = MAINTAINED, since = "1.2.0")
default Stream>> resolveAndCombine(TypeUsage... typeUsages) {
List>> arbitraries =
Arrays.stream(typeUsages)
.map((TypeUsage typeUsage) ->
Arbitraries.of(new ArrayList<>(this.apply(typeUsage))))
.collect(Collectors.toList());
Optional>>> optionalArbitraries =
Combinators
.combine(arbitraries)
.as(as -> as)
.allValues();
return optionalArbitraries.orElse(Stream.empty());
}
/**
* Convenience method to combine set of arbitraries in optional choice-based arbitrary.
*
* @param typeUsage
* @return Optional arbitrary instance
*/
@API(status = EXPERIMENTAL, since = "1.5.2")
default Optional> provideOneFor(TypeUsage typeUsage) {
Set> choices = this.apply(typeUsage);
if (choices.isEmpty()) {
return Optional.empty();
}
return Optional.of(Arbitraries.oneOf(choices));
}
}
/**
* Return true if the provider is suitable for {@code targetType}
*/
boolean canProvideFor(TypeUsage targetType);
/**
* This is the method you must override in your own implementations of {@code ArbitraryProvider}.
* It should return a set of arbitrary instances for a given {@code targetType}.
*
* Only {@code targetType}s that have been allowed by {@linkplain #canProvideFor(TypeUsage)}
* will be given to this method.
*
*
* For each try a single, randomly chosen element of the set will be used to generate
* all objects represented by this arbitrary. This is necessary in order to make
* generation of parameterized types stable.
*
* {@code subtypeProvider} can be used to get the arbitraries for any type argument of {@code targetType}.
*/
Set> provideFor(TypeUsage targetType, SubtypeProvider subtypeProvider);
/**
* Providers with higher priority will replace providers with lower priority. If there is more than one
* provider for a given type with the same priority, there results will add up in a single set of arbitraries
* to use.
*
*
* - Override with value > 0 to replace most of _jqwik_'s default providers.
* - Override with value > 100 to replace arbitrary provisioning for unrestricted type variables and wildcard types.
* - Override with value > 100 to replace arbitrary provisioning for plain type {@code Object}.
*
*/
default int priority() {
return 0;
}
}