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

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

There is a newer version: 1.9.1
Show newest version
package net.jqwik.api;

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

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

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

@API(status = STABLE, since = "1.0")
public interface RandomGenerator {

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

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

		public abstract  Shrinkable flatMap(Shrinkable self, Function> mapper, long nextLong);

		public abstract  Shrinkable flatMap(
			Shrinkable wrappedShrinkable,
			Function> mapper,
			int genSize,
			long nextLong,
			boolean withEmbeddedEdgeCases
		);

		public abstract  RandomGenerator filter(RandomGenerator self, Predicate filterPredicate, int maxMisses);

		public abstract  RandomGenerator withEdgeCases(RandomGenerator self, int genSize, EdgeCases edgeCases);

		public abstract  RandomGenerator> collect(RandomGenerator self, Predicate> until);

		public abstract  RandomGenerator injectDuplicates(RandomGenerator self, double duplicateProbability);

		public abstract  RandomGenerator ignoreExceptions(
			RandomGenerator self,
			Class[] exceptionTypes,
			int maxThrows
		);
	}

	/**
	 * @param random the source of randomness. Injected by jqwik itself.
	 * @return the next generated value wrapped within the Shrinkable interface. The method must ALWAYS return a next value.
	 */
	Shrinkable next(Random random);

	@API(status = INTERNAL)
	default  RandomGenerator map(Function mapper) {
		return this.mapShrinkable(s -> s.map(mapper));
	}

	@API(status = INTERNAL)
	default  RandomGenerator mapShrinkable(Function, ? extends Shrinkable> mapper) {
		return random -> {
			Shrinkable tShrinkable = RandomGenerator.this.next(random);
			return mapper.apply(tShrinkable);
		};
	}

	@API(status = INTERNAL)
	default  RandomGenerator flatMap(Function> mapper) {
		return random -> {
			Shrinkable wrappedShrinkable = RandomGenerator.this.next(random);
			return RandomGeneratorFacade.implementation.flatMap(wrappedShrinkable, mapper, random.nextLong());
		};
	}

	@API(status = INTERNAL)
	default  RandomGenerator flatMap(Function> mapper, int genSize, boolean withEmbeddedEdgeCases) {
		return random -> {
			Shrinkable wrappedShrinkable = RandomGenerator.this.next(random);
			return RandomGeneratorFacade.implementation
					   .flatMap(wrappedShrinkable, mapper, genSize, random.nextLong(), withEmbeddedEdgeCases);
		};
	}

	@API(status = INTERNAL)
	default RandomGenerator filter(Predicate filterPredicate, int maxMisses) {
		return RandomGeneratorFacade.implementation.filter(this, filterPredicate, maxMisses);
	}

	@API(status = INTERNAL)
	default RandomGenerator withEdgeCases(int genSize, EdgeCases edgeCases) {
		return RandomGeneratorFacade.implementation.withEdgeCases(this, genSize, edgeCases);
	}

	@API(status = INTERNAL)
	default Stream> stream(Random random) {
		return Stream.generate(() -> this.next(random));
	}

	@API(status = INTERNAL)
	default RandomGenerator> collect(Predicate> until) {
		return RandomGeneratorFacade.implementation.collect(this, until);
	}

	@API(status = INTERNAL)
	default RandomGenerator injectDuplicates(double duplicateProbability) {
		return RandomGeneratorFacade.implementation.injectDuplicates(this, duplicateProbability);
	}

	@API(status = INTERNAL)
	default RandomGenerator ignoreExceptions(int maxThrows, Class[] exceptionTypes) {
		return RandomGeneratorFacade.implementation.ignoreExceptions(this, exceptionTypes, maxThrows);
	}

	@API(status = INTERNAL)
	default RandomGenerator dontShrink() {
		return random -> {
			Shrinkable shrinkable = RandomGenerator.this.next(random).makeUnshrinkable();
			return shrinkable.makeUnshrinkable();
		};
	}

}