net.jqwik.engine.properties.arbitraries.OneOfArbitrary Maven / Gradle / Ivy
package net.jqwik.engine.properties.arbitraries;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import net.jqwik.api.*;
import net.jqwik.api.Tuple.*;
import net.jqwik.api.configurators.*;
import net.jqwik.api.providers.*;
import net.jqwik.engine.properties.arbitraries.exhaustive.*;
import net.jqwik.engine.properties.arbitraries.randomized.*;
import org.jspecify.annotations.*;
public class OneOfArbitrary implements Arbitrary, SelfConfiguringArbitrary {
private final List> all = new ArrayList<>();
private final boolean isGeneratorMemoizable;
@SuppressWarnings("unchecked")
public OneOfArbitrary(Collection extends Arbitrary extends T>> choices) {
for (Arbitrary extends T> choice : choices) {
// TODO: double-check cast
all.add((Arbitrary) choice);
}
isGeneratorMemoizable = all.stream().allMatch(Arbitrary::isGeneratorMemoizable);
}
@Override
public RandomGenerator generator(int genSize) {
return rawGeneration(genSize, false);
}
@Override
public RandomGenerator generatorWithEmbeddedEdgeCases(int genSize) {
return rawGeneration(genSize, true);
}
@Override
public boolean isGeneratorMemoizable() {
return isGeneratorMemoizable;
}
private RandomGenerator rawGeneration(int genSize, boolean withEmbeddedEdgeCases) {
List>> frequencies =
all.stream()
.map(a -> Tuple.of(1, a))
.collect(Collectors.toList());
return RandomGenerators.frequencyOf(frequencies, genSize, withEmbeddedEdgeCases);
}
@Override
public Optional> exhaustive(long maxNumberOfSamples) {
return ExhaustiveGenerators.choose(all, maxNumberOfSamples)
.flatMap(generator -> ExhaustiveGenerators
.flatMap(generator, Function.identity(), maxNumberOfSamples));
}
@Override
public EdgeCases edgeCases(int maxEdgeCases) {
return EdgeCasesSupport.concatFrom(all, maxEdgeCases);
}
@Override
public Arbitrary configure(ArbitraryConfigurator configurator, TypeUsage targetType) {
Arbitrary configuredArbitrary = configurator.configure(this, targetType);
if (configuredArbitrary == this) {
all.replaceAll(arbitrary -> SelfConfiguringArbitrary.configure(arbitrary, configurator, targetType));
}
return configuredArbitrary;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OneOfArbitrary> that = (OneOfArbitrary>) o;
return all.equals(that.all);
}
@Override
public int hashCode() {
return all.hashCode();
}
}