All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.jqwik.api.Arbitraries Maven / Gradle / Ivy

The newest version!
package net.jqwik.api;

import java.util.*;
import java.util.function.*;

import org.apiguardian.api.*;
import org.jspecify.annotations.*;

import net.jqwik.api.Tuple.*;
import net.jqwik.api.arbitraries.*;
import net.jqwik.api.arbitraries.TraverseArbitrary.*;
import net.jqwik.api.providers.*;
import net.jqwik.api.stateful.*;

import static org.apiguardian.api.API.Status.*;

@API(status = STABLE, since = "1.0")
public class Arbitraries {

	@API(status = INTERNAL)
	public static abstract class ArbitrariesFacade {
		private static final ArbitrariesFacade implementation;

		static {
			implementation = FacadeLoader.load(ArbitrariesFacade.class);
		}

		public abstract  Arbitrary oneOf(Collection> all);

		public abstract  ActionSequenceArbitrary sequences(Arbitrary> actionArbitrary);

		public abstract  Arbitrary frequencyOf(List>> frequencies);

		public abstract  Arbitrary just(T value);

		public abstract IntegerArbitrary integers();

		public abstract LongArbitrary longs();

		public abstract BigIntegerArbitrary bigIntegers();

		public abstract FloatArbitrary floats();

		public abstract BigDecimalArbitrary bigDecimals();

		public abstract DoubleArbitrary doubles();

		public abstract ByteArbitrary bytes();

		public abstract ShortArbitrary shorts();

		public abstract StringArbitrary strings();

		public abstract CharacterArbitrary chars();

		public abstract  Arbitrary defaultFor(Class type, Class[] typeParameters);

		public abstract  Arbitrary defaultFor(TypeUsage typeUsage, Function> noDefaultResolver);

		public abstract  Arbitrary lazy(Supplier> arbitrarySupplier);

		public abstract  TypeArbitrary forType(Class targetType);

		public abstract  MapArbitrary maps(Arbitrary keysArbitrary, Arbitrary valuesArbitrary);

		public abstract  Arbitrary> entries(Arbitrary keysArbitrary, Arbitrary valuesArbitrary);

		public abstract  Arbitrary recursive(
			Supplier> base,
			Function, ? extends Arbitrary> recur,
			int minDepth,
			int maxDepth
		);

		public abstract  Arbitrary lazyOf(List>> suppliers);

		public abstract  TraverseArbitrary traverse(Class targetType, Traverser traverser);

		public abstract Arbitrary of(char[] chars);

		public abstract  Arbitrary of(Collection values);

		public abstract  Arbitrary create(Supplier supplier);

		public abstract  Arbitrary> shuffle(List values);

		public abstract  Arbitrary fromGenerator(IntFunction> generatorSupplier);

		public abstract  Arbitrary frequency(List> frequencies);
	}

	private Arbitraries() {
	}

	/**
	 * Create an arbitrary of type T from a corresponding generator of type T.
	 *
	 * @param generator The generator to be used for generating the values
	 * @param        The type of values to generate
	 * @return a new arbitrary instance
	 */
	public static  Arbitrary fromGenerator(RandomGenerator generator) {
		return fromGeneratorWithSize(ignore -> generator);
	}

	/**
	 * Create an arbitrary of type T by supplying a corresponding generator of type T.
	 *
	 * @param generatorSupplier A function to supply a generator instance given the "size" of a generation attempt
	 * @param        The type of values to generate
	 * @return a new arbitrary instance
	 */
	@API(status = EXPERIMENTAL, since = "1.8.0")
	public static  Arbitrary fromGeneratorWithSize(IntFunction> generatorSupplier) {
		return ArbitrariesFacade.implementation.fromGenerator(generatorSupplier);
	}

	/**
	 * Create an arbitrary that will generate values of type T using a generator function.
	 * The generated values are unshrinkable.
	 *
	 * @param generator The generator function to be used for generating the values
	 * @param        The type of values to generate
	 * @return a new arbitrary instance
	 */
	public static  Arbitrary randomValue(Function generator) {
		IntFunction> generatorSupplier = ignore -> random -> Shrinkable.unshrinkable(generator.apply(random));
		return fromGeneratorWithSize(generatorSupplier);
	}

	/**
	 * Create an arbitrary for Random objects.
	 *
	 * @return a new arbitrary instance
	 */
	public static Arbitrary randoms() {
		return randomValue(random -> new Random(random.nextLong()));
	}

	/**
	 * Create an arbitrary that will randomly choose from a given array of values.
	 * A generated value will be shrunk towards the start of the array.
	 *
	 * 

* Use this method only for immutable arrays of immutable values. * Changing a value will change subsequently generated values as well. * For mutable values use {@linkplain #ofSuppliers(Supplier[])} instead. * Modifying the array may cause erratic behavior, things may halt and * catch fire. * * @param values The array of values to choose from * @param The type of values to generate * @return a new arbitrary instance */ @SafeVarargs public static Arbitrary of(T... values) { return of(Arrays.asList(values)); } /** * Create an arbitrary that will randomly choose from a given collection of values. * A generated value will be shrunk towards the start of the collection. * *

* Use this method only for immutable collections of immutable values. * Changing a value will change subsequently generated values as well. * For mutable values use {@linkplain #ofSuppliers(Collection)} instead. * Modifying the collection may cause erratic behavior, kittens may die. * * @param values The collection of values to choose from * @param The type of values to generate * @return a new arbitrary instance */ @API(status = MAINTAINED, since = "1.3.1") public static Arbitrary of(Collection values) { return ArbitrariesFacade.implementation.of(values); } /** * Create an arbitrary that will randomly choose from a given array of value suppliers * and then get the value from the supplier. * A generated value will be shrunk towards the start of the array. * *

* Use this method instead of {@linkplain #of(Object[])} for mutable objects * to make sure that changing a generated object will not influence other generated * objects. * * @param valueSuppliers The array of values to choose from * @param The type of values to generate * @return a new arbitrary instance */ @API(status = MAINTAINED, since = "1.3.0") @SafeVarargs public static Arbitrary ofSuppliers(Supplier... valueSuppliers) { return of(valueSuppliers).map(Supplier::get); } /** * Create an arbitrary that will randomly choose from a given collection of value suppliers * and then get the value from the supplier. * A generated value will be shrunk towards the start of the collection. * *

* Use this method instead of {@linkplain #of(Collection)} for mutable objects * to make sure that changing a generated object will not influence other generated * objects. * * @param valueSuppliers The collection of values to choose from * @param The type of values to generate * @return a new arbitrary instance */ @API(status = MAINTAINED, since = "1.3.1") public static Arbitrary ofSuppliers(Collection> valueSuppliers) { return of(valueSuppliers).map(Supplier::get); } /** * Create an arbitrary of character values. * * @param values The array of characters to choose from. * @return a new arbitrary instance */ public static Arbitrary of(char[] values) { return ArbitrariesFacade.implementation.of(values); } /** * Create an arbitrary for enum values of type T. * * @param enumClass The enum class. * @param The type of values to generate * @return a new arbitrary instance */ public static > Arbitrary of(Class enumClass) { List values = Arrays.asList(enumClass.getEnumConstants()); return of(values); } /** * Create an arbitrary that will randomly choose between all given arbitraries of the same type T. * * @param first The first arbitrary to choose form * @param rest An array of arbitraries to choose from * @param The type of values to generate * @return a new arbitrary instance */ @SuppressWarnings("unchecked") @SafeVarargs public static Arbitrary oneOf(Arbitrary first, Arbitrary... rest) { List> all = new ArrayList<>(); all.add(first); for (Arbitrary arbitrary : rest) { all.add((Arbitrary) arbitrary); } return oneOf(all); } /** * Create an arbitrary that will randomly choose between all given arbitraries of the same type T. * * @param choices A collection of arbitraries to choose from * @param The type of values to generate * @return a new arbitrary instance */ @SuppressWarnings("unchecked") public static Arbitrary oneOf(Collection> choices) { if (choices.isEmpty()) { String message = "oneOf() must not be called with no choices"; throw new JqwikException(message); } if (choices.size() == 1) { return (Arbitrary) choices.iterator().next(); } // Simple flatMapping is not enough because of configurations return ArbitrariesFacade.implementation.oneOf(choices); } /** * Create an arbitrary that will randomly choose between all given values of the same type T. * The probability distribution is weighted with the first parameter of the tuple. * * @param frequencies An array of tuples of which the first parameter gives the weight and the second the value. * @param The type of values to generate * @return a new arbitrary instance */ @SafeVarargs public static Arbitrary frequency(Tuple2... frequencies) { return frequency(Arrays.asList(frequencies)); } /** * Create an arbitrary that will randomly choose between all given values of the same type T. * The probability distribution is weighted with the first parameter of the tuple. * * @param frequencies A list of tuples of which the first parameter gives the weight and the second the value. * @param The type of values to generate * @return a new arbitrary instance */ public static Arbitrary frequency(List> frequencies) { return ArbitrariesFacade.implementation.frequency(frequencies); } /** * Create an arbitrary that will randomly choose between all given arbitraries of the same type T. * The probability distribution is weighted with the first parameter of the tuple. * * @param frequencies An array of tuples of which the first parameter gives the weight and the second the arbitrary. * @param The type of values to generate * @return a new arbitrary instance */ @SuppressWarnings("unchecked") @SafeVarargs public static Arbitrary frequencyOf(Tuple2>... frequencies) { List>> all = new ArrayList<>(); for (Tuple2> frequency : frequencies) { all.add(Tuple.of(frequency.get1(), (Arbitrary) frequency.get2())); } return frequencyOf(all); } /** * Create an arbitrary that will randomly choose between all given arbitraries of the same type T. * The probability distribution is weighted with the first parameter of the tuple. * * @param frequencies A list of tuples of which the first parameter gives the weight and the second the arbitrary. * @param The type of values to generate * @return a new arbitrary instance */ public static Arbitrary frequencyOf(List>> frequencies) { // Simple flatMapping is not enough because of configurations return ArbitrariesFacade.implementation.frequencyOf(frequencies); } /** * Create an arbitrary that generates values of type Integer. * * @return a new arbitrary instance */ public static IntegerArbitrary integers() { return ArbitrariesFacade.implementation.integers(); } /** * Create an arbitrary that generates values of type Long. * * @return a new arbitrary instance */ public static LongArbitrary longs() { return ArbitrariesFacade.implementation.longs(); } /** * Create an arbitrary that generates values of type BigInteger. * * @return a new arbitrary instance */ public static BigIntegerArbitrary bigIntegers() { return ArbitrariesFacade.implementation.bigIntegers(); } /** * Create an arbitrary that generates values of type Float. * * @return a new arbitrary instance */ public static FloatArbitrary floats() { return ArbitrariesFacade.implementation.floats(); } /** * Create an arbitrary that generates values of type BigDecimal. * * @return a new arbitrary instance */ public static BigDecimalArbitrary bigDecimals() { return ArbitrariesFacade.implementation.bigDecimals(); } /** * Create an arbitrary that generates values of type Double. * * @return a new arbitrary instance */ public static DoubleArbitrary doubles() { return ArbitrariesFacade.implementation.doubles(); } /** * Create an arbitrary that generates values of type Byte. * * @return a new arbitrary instance */ public static ByteArbitrary bytes() { return ArbitrariesFacade.implementation.bytes(); } /** * Create an arbitrary that generates values of type Short. * * @return a new arbitrary instance */ public static ShortArbitrary shorts() { return ArbitrariesFacade.implementation.shorts(); } /** * Create an arbitrary that generates values of type String. * * @return a new arbitrary instance */ public static StringArbitrary strings() { return ArbitrariesFacade.implementation.strings(); } /** * Create an arbitrary that generates values of type Character. * * @return a new arbitrary instance */ public static CharacterArbitrary chars() { return ArbitrariesFacade.implementation.chars(); } /** * Create an arbitrary that will always generate the same value. * * @param value The value to "generate". * @param The type of the value * @return a new arbitrary instance */ @API(status = MAINTAINED, since = "1.3.2") public static Arbitrary just(T value) { return ArbitrariesFacade.implementation.just(value); } /** * Create an arbitrary that will use a supplier to generate a value. * The difference to {@linkplain Arbitraries#just(Object)} is that the value * is freshly generated for each try of a property. * *

* Mind that within a {@code supplier} you should never use other arbitraries * or do anything non-deterministic. *

* *

* For exhaustive shrinking all generated values are supposed to have identical behaviour, * i.e. that means that only one value is generated per combination. *

* * @param supplier The supplier use to generate a value * @param The type of values to generate * @return a new arbitrary instance */ @API(status = MAINTAINED, since = "1.1.1") public static Arbitrary create(Supplier supplier) { return ArbitrariesFacade.implementation.create(supplier); } /** * Create an arbitrary that will always generate a list which is a * permutation of the values handed to it. Permutations will * not be shrunk. * * @param values The values to permute * @param The type of values to generate * @return a new arbitrary instance */ @SafeVarargs public static Arbitrary> shuffle(T... values) { return shuffle(Arrays.asList(values)); } /** * Create an arbitrary that will always generate a list which is a * permutation of the values handed to it. Permutations will * not be shrunk. * * @param values The values to permute * @param The type of values to generate * @return a new arbitrary instance */ public static Arbitrary> shuffle(List values) { return ArbitrariesFacade.implementation.shuffle(values); } /** * Find a registered arbitrary that will be used to generate values of type T. * All default arbitrary providers and all registered arbitrary providers are considered. * This is more or less the same mechanism that jqwik uses to find arbitraries for * property method parameters. * * @param type The type of the value to find an arbitrary for * @param typeParameters The type parameters if type is a generic type * @param The type of values to generate * @return a new arbitrary instance * @throws CannotFindArbitraryException if there is no registered arbitrary provider to serve this type */ public static Arbitrary defaultFor(Class type, Class... typeParameters) { return ArbitrariesFacade.implementation.defaultFor(type, typeParameters); } /** * Find a registered arbitrary that will be used to generate values of type T. * All default arbitrary providers and all registered arbitrary providers are considered. * This is more or less the same mechanism that jqwik uses to find arbitraries for * property method parameters. * *

The returned arbitrary is lazy, i.e. it be evaluated at generation time to allow * domain contexts to be used.

* * @param typeUsage The type of the value to find an arbitrary for * @param The type of values to generate * @return a new arbitrary instance */ @API(status = MAINTAINED, since = "1.1") public static Arbitrary defaultFor(TypeUsage typeUsage) { return defaultFor(typeUsage, ignore -> {throw new CannotFindArbitraryException(typeUsage);}); } /** * Find a registered arbitrary that will be used to generate values of type T. * All default arbitrary providers and all registered arbitrary providers are considered. * This is more or less the same mechanism that jqwik uses to find arbitraries for * property method parameters. * *

The returned arbitrary is lazy, i.e. it be evaluated at generation time to allow * domain contexts to be used. Those

* * @param typeUsage The type of the value to find an arbitrary for * @param noDefaultResolver Alternative resolution when no default arbitrary can be found at generation time * @param The type of values to generate * @return a new arbitrary instance */ @API(status = EXPERIMENTAL, since = "1.6.1") public static Arbitrary defaultFor(TypeUsage typeUsage, Function> noDefaultResolver) { return ArbitrariesFacade.implementation.defaultFor(typeUsage, noDefaultResolver); } /** * Create an arbitrary for type {@code T} that will by default use the type's * public constructors and public factory methods. * * @param targetType The class of the type to create an arbitrary for * @param The type of values to generate * @return a new arbitrary instance * @see TypeArbitrary */ @API(status = MAINTAINED, since = "1.2.0") public static TypeArbitrary forType(Class targetType) { return ArbitrariesFacade.implementation.forType(targetType); } /** * Create an arbitrary for type {@code T} that will try to traverse a type * - and all types it is based on - given a {@linkplain Traverser} strategy. * *

* By default recursion is disable, i.e. that parameters of creator functions * can be resolved by the traverser, have a default arbitrary or generation fails at runtime. * Use {@linkplain TraverseArbitrary#enableRecursion()} to switch on recursive traversal. *

*

* One usage of this traversing mechanism is {@linkplain #forType(Class)} * which uses {@code #traverse(Class, Traverser)} under the hood. *

* * @param targetType The class of the type to create an arbitrary for * @param The type of values to generate * @param traverser The traversing strategy specification * @return a new arbitrary instance * @see TraverseArbitrary */ @API(status = EXPERIMENTAL, since = "1.6.1") public static TraverseArbitrary traverse(Class targetType, Traverser traverser) { return ArbitrariesFacade.implementation.traverse(targetType, traverser); } /** * Create an arbitrary that will evaluate arbitrarySupplier as soon as it is used for generating values. *

* This is useful (and necessary) when arbitrary providing functions use other arbitrary providing functions * in a recursive way. Without the use of lazy() this would result in a stack overflow. * Most of the time, however, using {@linkplain #lazyOf(Supplier, Supplier[])} is the better choice * because it has significantly better shrinking behaviour. * * @param arbitrarySupplier The supplier function being used to generate an arbitrary * @param The type of values to generate * @return a new arbitrary instance * @see #recursive(Supplier, Function, int) * @see #lazyOf(Supplier, Supplier[]) */ public static Arbitrary lazy(Supplier> arbitrarySupplier) { return ArbitrariesFacade.implementation.lazy(arbitrarySupplier); } /** * Create an arbitrary by deterministic recursion. *

* Mind that the arbitrary will be created by invoking recursion at arbitrary creation time. * Using {@linkplain #lazyOf(Supplier, Supplier[])} or {@linkplain #lazy(Supplier)} instead * will recur at value generation time. * * @param base The supplier returning the recursion's base case * @param recur The function to extend the base case * @param depth The number of times to invoke recursion * @param The type of values to generate * @return a new arbitrary instance * @see #lazy(Supplier) */ public static Arbitrary recursive( Supplier> base, Function, ? extends Arbitrary> recur, int depth ) { return ArbitrariesFacade.implementation.recursive(base, recur, depth, depth); } /** * Create an arbitrary by deterministic recursion. *

* Mind that the arbitrary will be created by invoking recursion at arbitrary creation time. * Using {@linkplain #lazyOf(Supplier, Supplier[])} or {@linkplain #lazy(Supplier)} instead * will recur at value generation time. * * @param base The supplier returning the recursion's base case * @param recur The function to extend the base case * @param minDepth The minimum number of times to invoke recursion * @param maxDepth The maximum number of times to invoke recursion * @param The type of values to generate * @return a new arbitrary instance * @see #lazy(Supplier) */ @API(status = MAINTAINED, since = "1.6.4") public static Arbitrary recursive( Supplier> base, Function, ? extends Arbitrary> recur, int minDepth, int maxDepth ) { return ArbitrariesFacade.implementation.recursive(base, recur, minDepth, maxDepth); } /** * Create an arbitrary by lazy supplying one of several arbitraries. * The main use of this function is to allow recursive generation of structured * values without overflowing the stack. * *

* One alternative is to use {@linkplain #lazy(Supplier)} combined with * {@linkplain Arbitraries#oneOf(Arbitrary, Arbitrary[])} * or {@linkplain Arbitraries#frequencyOf(Tuple.Tuple2[])}. * But {@code lazyOf()} has considerably better shrinking behaviour with recursion. *

* *

* Caveat: * Never use this construct if suppliers make use of variable state * like method parameters or changing instance members. * In those cases use {@linkplain #lazy(Supplier)} instead. *

* * @param first The first supplier to choose from * @param rest The rest of suppliers to choose from * @param The type of values to generate * @return a (potentially cached) arbitrary instance * @see #lazy(Supplier) * @see #recursive(Supplier, Function, int) */ @SuppressWarnings("unchecked") @SafeVarargs @API(status = MAINTAINED, since = "1.3.4") public static Arbitrary lazyOf(Supplier> first, Supplier>... rest) { List>> all = new ArrayList<>(); all.add(() -> (Arbitrary) first.get()); for (Supplier> arbitrarySupplier : rest) { all.add(() -> (Arbitrary) arbitrarySupplier.get()); } return ArbitrariesFacade.implementation.lazyOf(all); } /** * Create an arbitrary to create a sequence of actions. Useful for stateful testing. * * @param actionArbitrary The arbitrary to generate individual actions. * @param The type of actions to generate * @return a new arbitrary instance */ @API(status = MAINTAINED, since = "1.0") public static ActionSequenceArbitrary sequences(Arbitrary> actionArbitrary) { return ArbitrariesFacade.implementation.sequences(actionArbitrary); } /** * Create an arbitrary to create instances of {@linkplain Map}. * The generated maps are mutable. * * @param keysArbitrary The arbitrary to generate the keys * @param valuesArbitrary The arbitrary to generate the values * @param type of keys * @param type of values * @return a new arbitrary instance */ @API(status = MAINTAINED, since = "1.1.6") public static MapArbitrary maps(Arbitrary keysArbitrary, Arbitrary valuesArbitrary) { return ArbitrariesFacade.implementation.maps(keysArbitrary, valuesArbitrary); } /** * Create an arbitrary to create instances of {@linkplain java.util.Map.Entry}. * The generated entries are mutable. * * @param keysArbitrary The arbitrary to generate the keys * @param valuesArbitrary The arbitrary to generate the values * @param type of keys * @param type of values * @return a new arbitrary instance */ @API(status = MAINTAINED, since = "1.2.0") public static Arbitrary> entries(Arbitrary keysArbitrary, Arbitrary valuesArbitrary) { return ArbitrariesFacade.implementation.entries(keysArbitrary, valuesArbitrary); } /** * Create an arbitrary that never creates anything. Sometimes useful * when generating arbitraries of "functions" that have void as return type. * * @return arbitrary instance that will generate nothing */ @API(status = MAINTAINED, since = "1.3.0") public static Arbitrary nothing() { return just(null); } /** * Create a new arbitrary of element type {@code Set} using the handed in values as elements of the set. * * @return a new arbitrary instance */ @API(status = MAINTAINED, since = "1.6.4") public static SetArbitrary subsetOf(Collection values) { return Arbitraries.of(values).set(); } /** * Create a new arbitrary of element type {@code Set} using the handed in values as elements of the set. * * @return a new arbitrary instance */ @SafeVarargs @API(status = MAINTAINED, since = "1.6.4") public static SetArbitrary subsetOf(T... values) { return subsetOf(Arrays.asList(values)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy