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

net.jqwik.engine.facades.ArbitraryFacadeImpl Maven / Gradle / Ivy

The newest version!
package net.jqwik.engine.facades;

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

import net.jqwik.api.*;
import net.jqwik.api.arbitraries.*;
import net.jqwik.engine.*;
import net.jqwik.engine.properties.arbitraries.*;
import net.jqwik.engine.properties.arbitraries.randomized.*;

import org.jspecify.annotations.*;

import static net.jqwik.engine.properties.arbitraries.ArbitrariesSupport.*;

/**
 * Is loaded through reflection in api module
 */
public class ArbitraryFacadeImpl extends Arbitrary.ArbitraryFacade {

	@Override
	public  ListArbitrary list(Arbitrary elementArbitrary) {
		return new DefaultListArbitrary<>(elementArbitrary);
	}

	@Override
	public  SetArbitrary set(Arbitrary elementArbitrary) {
		// The set can never be larger than the max number of possible elements
		return new DefaultSetArbitrary<>(elementArbitrary)
				   .ofMaxSize(maxNumberOfElements(elementArbitrary, RandomGenerators.DEFAULT_COLLECTION_SIZE));
	}

	@Override
	public  StreamArbitrary stream(Arbitrary elementArbitrary) {
		return new DefaultStreamArbitrary<>(elementArbitrary);
	}

	@Override
	public  IteratorArbitrary iterator(Arbitrary elementArbitrary) {
		return new DefaultIteratorArbitrary<>(elementArbitrary);
	}

	@Override
	public  ArrayArbitrary array(Arbitrary elementArbitrary, Class arrayClass) {
		return DefaultArrayArbitrary.forArrayType(elementArbitrary, arrayClass);
	}

	@Override
	public  Arbitrary filter(Arbitrary self, Predicate filterPredicate, int maxMisses) {
		return new ArbitraryFilter<>(self, filterPredicate, maxMisses);
	}

	@Override
	public  Arbitrary map(Arbitrary self, Function mapper) {
		return new ArbitraryMap<>(self, mapper);
	}

	@Override
	public  Arbitrary flatMap(Arbitrary self, Function> mapper) {
		return new ArbitraryFlatMap<>(self, mapper);
	}

	@Override
	public  Stream sampleStream(Arbitrary arbitrary) {
		return new SampleStreamFacade().sampleStream(arbitrary);
	}

	@Override
	public  Arbitrary<@Nullable T> injectNull(Arbitrary self, double nullProbability) {
		int frequencyNull = (int) Math.round(nullProbability * 1000);
		int frequencyNotNull = 1000 - frequencyNull;
		if (frequencyNull <= 0) {
			return self;
		}
		if (frequencyNull >= 1000) {
			return Arbitraries.just(null);
		}
		return Arbitraries.frequencyOf(
			Tuple.of(frequencyNull, Arbitraries.just(null)),
			Tuple.of(frequencyNotNull, self)
		);
	}

	@Override
	public  Arbitrary ignoreExceptions(Arbitrary self, int maxThrows, Class[] exceptionTypes) {
		if (exceptionTypes.length == 0) {
			return self;
		}
		return new ArbitraryDelegator(self) {
			@Override
			public RandomGenerator generator(int genSize) {
				return super.generator(genSize).ignoreExceptions(maxThrows, exceptionTypes);
			}

			@Override
			public RandomGenerator generatorWithEmbeddedEdgeCases(int genSize) {
				return super.generatorWithEmbeddedEdgeCases(genSize).ignoreExceptions(maxThrows, exceptionTypes);
			}

			@Override
			public Optional> exhaustive(long maxNumberOfSamples) {
				return super.exhaustive(maxNumberOfSamples)
							.map(generator -> generator.ignoreExceptions(maxThrows, exceptionTypes));
			}

			@Override
			public EdgeCases edgeCases(int maxEdgeCases) {
				return EdgeCasesSupport.ignoreExceptions(self.edgeCases(maxEdgeCases), exceptionTypes);
			}
		};
	}

	@Override
	public  Arbitrary dontShrink(Arbitrary self) {
		return new ArbitraryDelegator(self) {
			@Override
			public RandomGenerator generator(int genSize) {
				return super.generator(genSize).dontShrink();
			}

			@Override
			public RandomGenerator generatorWithEmbeddedEdgeCases(int genSize) {
				return super.generatorWithEmbeddedEdgeCases(genSize).dontShrink();
			}

			@Override
			public EdgeCases edgeCases(int maxEdgeCases) {
				return EdgeCasesSupport.dontShrink(super.edgeCases(maxEdgeCases));
			}
		};
	}

	@Override
	public  Arbitrary configureEdgeCases(Arbitrary self, Consumer> configurator) {
		return new ArbitraryDelegator(self) {
			@Override
			public EdgeCases edgeCases(int maxEdgeCases) {
				GenericEdgeCasesConfiguration config = new GenericEdgeCasesConfiguration<>();
				return config.configure(configurator, self::edgeCases, maxEdgeCases);
			}
		};
	}

	@Override
	public  Arbitrary withoutEdgeCases(Arbitrary self) {
		return new ArbitraryDelegator(self) {
			@Override
			public RandomGenerator generator(int genSize, boolean withEdgeCases) {
				return Memoize.memoizedGenerator(self, genSize, withEdgeCases, () -> self.generator(genSize));
			}

			@Override
			public EdgeCases edgeCases(int maxEdgeCases) {
				return EdgeCases.none();
			}

			@Override
			public RandomGenerator generatorWithEmbeddedEdgeCases(int genSize) {
				return self.generator(genSize, false);
			}
		};
	}

	@Override
	public  Arbitrary fixGenSize(Arbitrary self, int genSize) {
		return new ArbitraryDelegator(self) {
			@Override
			public RandomGenerator generator(int ignoredGenSize) {
				return super.generator(genSize);
			}

			@Override
			public RandomGenerator generatorWithEmbeddedEdgeCases(int ignoredGenSize) {
				return super.generatorWithEmbeddedEdgeCases(genSize);
			}
		};
	}

	@Override
	public  Arbitrary> collect(Arbitrary self, Predicate> until) {
		return new ArbitraryCollect<>(self, until);
	}

	@Override
	public  RandomGenerator memoizedGenerator(Arbitrary self, int genSize, boolean withEdgeCases) {
		return Memoize.memoizedGenerator(self, genSize, withEdgeCases, () -> generator(self, genSize, withEdgeCases));
	}

	private  RandomGenerator generator(Arbitrary arbitrary, int genSize, boolean withEdgeCases) {
		if (withEdgeCases) {
			int maxEdgeCases = Math.max(genSize, 10);
			return arbitrary.generatorWithEmbeddedEdgeCases(genSize).withEdgeCases(genSize, arbitrary.edgeCases(maxEdgeCases));
		} else {
			return arbitrary.generator(genSize);
		}
	}

}