net.jqwik.engine.properties.arbitraries.RecursiveArbitrary Maven / Gradle / Ivy
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