net.jqwik.engine.properties.shrinking.ElementsShrinkingSequence Maven / Gradle / Ivy
package net.jqwik.engine.properties.shrinking;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import net.jqwik.api.*;
public class ElementsShrinkingSequence implements ShrinkingSequence> {
private final Falsifier> listFalsifier;
private final List> currentResults;
private final Function>, ShrinkingDistance> distanceFunction;
private int currentShrinkingPosition = 0;
private ShrinkingSequence currentShrinkingSequence = null;
private Throwable currentThrowable;
public ElementsShrinkingSequence(
List> currentElements,
Falsifier> listFalsifier,
Function>, ShrinkingDistance> distanceFunction
) {
this.currentResults =
currentElements
.stream()
.map(FalsificationResult::falsified)
.collect(Collectors.toList());
this.listFalsifier = listFalsifier;
this.distanceFunction = distanceFunction;
}
@Override
public void init(FalsificationResult> initialCurrent) {
this.currentThrowable = initialCurrent.throwable().orElse(null);
for (int i = 0; i < currentResults.size(); i++) {
FalsificationResult newResult = FalsificationResult.falsified(currentResults.get(i).shrinkable(), currentThrowable);
currentResults.set(i, newResult);
}
}
@Override
public boolean next(Runnable count, Consumer>> falsifiedReporter) {
if (isShrinkingDone())
return false;
return shrinkCurrentPosition(count, falsifiedReporter);
}
private boolean isShrinkingDone() {
return currentShrinkingPosition >= currentResults.size();
}
private boolean shrinkCurrentPosition(Runnable count, Consumer>> falsifiedReporter) {
if (currentShrinkingSequence == null) {
currentShrinkingSequence = createShrinkingSequence(currentShrinkingPosition);
}
if (!currentShrinkingSequence.next(count, currentFalsifiedReporter(falsifiedReporter))) {
return advanceToNextShrinkingPosition(count, falsifiedReporter);
}
replaceCurrentPosition(currentShrinkingSequence.current());
return true;
}
private boolean advanceToNextShrinkingPosition(
Runnable count, Consumer>> falsifiedReporter
) {
currentShrinkingSequence = null;
currentShrinkingPosition++;
return next(count, falsifiedReporter);
}
private Consumer> currentFalsifiedReporter(
Consumer>> listReporter
) {
if (isShrinkingDone()) return ignore -> {};
return resultOnCurrentShrinkingPosition -> { //
listReporter.accept(resultOnCurrentShrinkingPosition.map(shrinkable -> shrinkable.map(valueOnCurrentShrinkingPosition -> {
List values = toValueList(currentResults);
values.set(currentShrinkingPosition, resultOnCurrentShrinkingPosition.value());
return values;
})));
};
}
private void replaceCurrentPosition(FalsificationResult falsificationResult) {
currentResults.set(currentShrinkingPosition, falsificationResult);
currentThrowable = falsificationResult.throwable().orElse(null);
}
private ShrinkingSequence createShrinkingSequence(int position) {
FalsificationResult positionResult = currentResults.get(position);
Falsifier positionFalsifier = falsifierForPosition(position, currentResults);
return positionResult.shrinkable().shrink(positionFalsifier);
}
private Falsifier falsifierForPosition(int position, List> falsificationResults) {
return elementValue -> {
List effectiveParams = toValueList(falsificationResults);
effectiveParams.set(position, elementValue);
return listFalsifier.test(effectiveParams);
};
}
@Override
public FalsificationResult> current() {
return FalsificationResult.falsified(createCurrent(currentResults), currentThrowable);
}
private Shrinkable> createCurrent(List> falsificationResults) {
return new Shrinkable>() {
final List value = toValueList(falsificationResults);
@Override
public List value() {
return value;
}
@Override
public ShrinkingSequence> shrink(Falsifier> falsifier) {
return ElementsShrinkingSequence.this;
}
@Override
public ShrinkingDistance distance() {
return distanceFunction.apply(toShrinkableList(falsificationResults));
}
};
}
private List toValueList(List> results) {
return results
.stream()
.map(FalsificationResult::value)
.collect(Collectors.toList());
}
private List> toShrinkableList(List> results) {
return results
.stream()
.map(FalsificationResult::shrinkable)
.collect(Collectors.toList());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy