net.jqwik.engine.properties.shrinking.ShrinkableList Maven / Gradle / Ivy
package net.jqwik.engine.properties.shrinking;
import java.util.*;
import java.util.stream.*;
import net.jqwik.api.*;
import net.jqwik.engine.properties.*;
import net.jqwik.engine.support.*;
import static net.jqwik.engine.properties.UniquenessChecker.*;
public class ShrinkableList extends ShrinkableContainer, E> {
// Only used in tests
ShrinkableList(List> elements, int minSize, int maxSize) {
this(elements, minSize, maxSize, Collections.emptySet());
}
public ShrinkableList(List> elements, int minSize, int maxSize, Collection> uniquenessExtractors) {
super(elements, minSize, maxSize, uniquenessExtractors);
}
@Override
Collector> containerCollector() {
return Collectors.toList();
}
@Override
Shrinkable> createShrinkable(List> shrunkElements) {
return new ShrinkableList<>(shrunkElements, minSize, maxSize, uniquenessExtractors);
}
@Override
public Stream>> shrink() {
return JqwikStreamSupport.concat(
super.shrink(),
sortElements(),
moveIndividualValuesTowardsEnd()
);
}
// TODO: Simplify and clean up
private Stream>> moveIndividualValuesTowardsEnd() {
ShrinkingDistance distance = distance();
return Combinatorics
.distinctPairs(elements.size())
.map(pair -> {
int firstIndex = Math.min(pair.get1(), pair.get2());
int secondIndex = Math.max(pair.get1(), pair.get2());
Shrinkable first = elements.get(firstIndex);
Shrinkable second = elements.get(secondIndex);
return Tuple.of(firstIndex, first, secondIndex, second);
})
.filter(quadruple -> quadruple.get2().compareTo(quadruple.get4()) <= 0)
.flatMap(quadruple -> {
int firstIndex = quadruple.get1();
Shrinkable first = quadruple.get2();
int secondIndex = quadruple.get3();
Shrinkable second = quadruple.get4();
return first.shrink()
.map(after -> {
Optional> grow = second.grow(first, after);
return Tuple.of(after, grow);
})
.filter(tuple -> tuple.get2().isPresent())
.map(tuple -> {
List> pairMove = new ArrayList<>(elements);
pairMove.set(firstIndex, tuple.get1());
pairMove.set(secondIndex, tuple.get2().get());
return pairMove;
})
.filter(shrinkables -> checkUniquenessOfShrinkables(uniquenessExtractors, shrinkables))
.map(this::createShrinkable);
})
// In rare cases of nested lists shrinkGrow can increase the distance
.filter(s -> s.distance().compareTo(distance) <= 0);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy