net.jqwik.engine.properties.arbitraries.IntegralGeneratingArbitrary Maven / Gradle / Ivy
package net.jqwik.engine.properties.arbitraries;
import java.math.*;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import net.jqwik.api.*;
import net.jqwik.engine.properties.arbitraries.exhaustive.*;
import net.jqwik.engine.properties.arbitraries.randomized.*;
import net.jqwik.engine.properties.shrinking.*;
import static java.math.BigInteger.*;
class IntegralGeneratingArbitrary implements Arbitrary {
BigInteger min;
BigInteger max;
BigInteger shrinkingTarget;
IntegralGeneratingArbitrary(BigInteger defaultMin, BigInteger defaultMax) {
this.min = defaultMin;
this.max = defaultMax;
this.shrinkingTarget = null;
}
@Override
public RandomGenerator generator(int genSize) {
BigInteger[] partitionPoints = RandomGenerators.calculateDefaultPartitionPoints(genSize, this.min, this.max);
return createGenerator(partitionPoints, genSize);
}
@Override
public Optional> exhaustive() {
BigInteger maxCount = max.subtract(min).add(BigInteger.ONE);
if (maxCount.compareTo(valueOf(ExhaustiveGenerators.MAXIMUM_ACCEPTED_MAX_COUNT)) > 0) {
return Optional.empty();
} else {
return ExhaustiveGenerators.fromIterable(RangeIterator::new, maxCount.longValueExact());
}
}
private RandomGenerator createGenerator(BigInteger[] partitionPoints, int genSize) {
List> edgeCases =
streamEdgeCases()
.filter(aBigInt -> aBigInt.compareTo(min) >= 0 && aBigInt.compareTo(max) <= 0) //
.map(anInt -> new ShrinkableBigInteger(anInt, Range.of(min, max), shrinkingTarget(anInt))) //
.collect(Collectors.toList());
return RandomGenerators.bigIntegers(min, max, shrinkingTargetCalculator(), partitionPoints)
.withEdgeCases(genSize, edgeCases);
}
private Stream streamEdgeCases() {
BigInteger[] literalEdgeCases = new BigInteger[]{
valueOf(-10), valueOf(-5), valueOf(-4), valueOf(-3), valueOf(-2), valueOf(-1),
BigInteger.ZERO, BigInteger.ZERO, BigInteger.ZERO, // more weight for 0
valueOf(10), valueOf(5), valueOf(4), valueOf(3), valueOf(2), valueOf(1),
min, max
};
return shrinkingTarget == null
? Arrays.stream(literalEdgeCases)
: Stream.concat(Stream.of(shrinkingTarget), Arrays.stream(literalEdgeCases));
}
private Function shrinkingTargetCalculator() {
if (shrinkingTarget == null) {
return RandomGenerators.defaultShrinkingTargetCalculator(min, max);
} else {
return ignore -> shrinkingTarget;
}
}
private BigInteger shrinkingTarget(BigInteger anInt) {
return shrinkingTargetCalculator().apply(anInt);
}
class RangeIterator implements Iterator {
BigInteger current = min;
@Override
public boolean hasNext() {
return current.compareTo(max) <= 0;
}
@Override
public BigInteger next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
BigInteger next = current;
current = current.add(BigInteger.ONE);
return next;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy