All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.jqwik.engine.properties.shrinking.ShrinkableList Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
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