net.jqwik.engine.properties.ExhaustiveShrinkablesGenerator Maven / Gradle / Ivy
The newest version!
package net.jqwik.engine.properties;
import java.util.*;
import java.util.stream.*;
import net.jqwik.api.*;
import net.jqwik.engine.support.*;
import net.jqwik.engine.support.types.*;
public class ExhaustiveShrinkablesGenerator implements ForAllParametersGenerator {
public static ExhaustiveShrinkablesGenerator forParameters(
List parameters,
ArbitraryResolver arbitraryResolver,
long maxNumberOfSamples
) {
List>> exhaustiveGenerators =
parameters.stream()
.map(parameter -> resolveParameter(arbitraryResolver, parameter, maxNumberOfSamples))
.collect(Collectors.toList());
return new ExhaustiveShrinkablesGenerator(exhaustiveGenerators);
}
@SuppressWarnings({"rawtypes", "unchecked"})
private static List> resolveParameter(
ArbitraryResolver arbitraryResolver,
MethodParameter parameter,
long maxNumberOfSamples
) {
Set> arbitraries = arbitraryResolver.forParameter(parameter);
if (arbitraries.isEmpty()) {
throw new CannotFindArbitraryException(TypeUsageImpl.forParameter(parameter), parameter.getAnnotation(ForAll.class));
}
List> exhaustiveGenerators = new ArrayList<>();
for (Arbitrary arbitrary : arbitraries) {
Optional> optionalGenerator = arbitrary.exhaustive(maxNumberOfSamples);
if (!optionalGenerator.isPresent()) {
String message = String.format("Arbitrary %s does not provide exhaustive generator", arbitrary);
throw new JqwikException(message);
}
exhaustiveGenerators.add(optionalGenerator.get());
}
return exhaustiveGenerators;
}
private final List>> generators;
private final long maxCount;
private Iterator>> combinatorialIterator;
private ExhaustiveShrinkablesGenerator(List>> generators) {
this.maxCount = generators
.stream()
.mapToLong(set -> set.stream().mapToLong(ExhaustiveGenerator::maxCount).sum())
.reduce((product, count) -> product * count)
.orElse(1L);
this.generators = generators;
this.reset();
}
private Iterator>> combine(List>> generators) {
List> iterables = generators
.stream()
.map(this::concat)
.collect(Collectors.toList());
return new Iterator>>() {
final Iterator> iterator = Combinatorics.combine(iterables);
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public List> next() {
List> values = new ArrayList<>();
for (Object o : iterator.next()) {
values.add(Shrinkable.unshrinkable(o));
}
return values;
}
};
}
private Iterable