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

net.jqwik.engine.properties.arbitraries.RecursiveArbitrary Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
package net.jqwik.engine.properties.arbitraries;

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

import net.jqwik.api.*;

public class RecursiveArbitrary implements Arbitrary {
	private final Supplier> base;
	private final Function, Arbitrary> recur;
	private final int depth;

	// Not used for exhaustive generation
	private final Arbitrary arbitrary;

	public RecursiveArbitrary(Supplier> base, Function, Arbitrary> recur, int depth) {
		this.base = base;
		this.recur = recur;
		this.depth = depth;
		this.arbitrary = iteratedArbitrary();
	}

	@Override
	public RandomGenerator generator(int genSize) {
		return arbitrary.generator(genSize);
	}

	@Override
	public EdgeCases edgeCases(int maxEdgeCases) {
		// Very deep nesting tends to overflow the stack
		if (depth > 100) {
			return EdgeCases.none();
		}
		return arbitrary.edgeCases(maxEdgeCases);
	}

	@Override
	public Optional> exhaustive(long maxNumberOfSamples) {
		// The straightforward implementation can easily overflow:
		// return arbitrary.exhaustive(maxNumberOfSamples);

		Arbitrary current = base.get();
		Optional> last = current.exhaustive(maxNumberOfSamples);
		for (int i = 0; i < depth; i++) {
			if (!last.isPresent()) {
				return Optional.empty();
			}
			current = recur.apply(current);
			last = current.exhaustive(maxNumberOfSamples);
		}
		return last;
	}

	private Arbitrary iteratedArbitrary() {
		// Real recursion can blow the stack
		Arbitrary current = base.get();
		for (int i = 0; i < depth; i++) {
			current = recur.apply(current);
		}
		return current;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy