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

net.jqwik.engine.properties.shrinking.ShrinkingCommons 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.function.*;
import java.util.stream.*;

import net.jqwik.api.*;
import net.jqwik.engine.support.*;

import org.jspecify.annotations.*;

import static net.jqwik.engine.properties.UniquenessChecker.*;

class ShrinkingCommons {

	@FunctionalInterface
	interface ContainerCreator extends Function>, Shrinkable> {}

	/**
	 * Shrink elements of a container pairwise
	 *
	 * @param elements container elements
	 * @param createContainer function to create shrinkable container
	 * @param              type of container
	 * @param              type of elements
	 * @return stream of shrunk containers
	 */
	static   Stream> shrinkPairsOfElements(List> elements, ContainerCreator createContainer) {
		return Combinatorics
			.distinctPairs(elements.size())
			.flatMap(pair -> JqwikStreamSupport.zip(
				elements.get(pair.get1()).shrink(),
				elements.get(pair.get2()).shrink(),
				(Shrinkable s1, Shrinkable s2) -> {
					List> newElements = new ArrayList<>(elements);
					newElements.set(pair.get1(), s1);
					newElements.set(pair.get2(), s2);
					return createContainer.apply(newElements);
				}
			));
	}

	/**
	 * Sort elements of container pairwise
	 *
	 * @param elements        Unsorted elements
	 * @param createContainer function to create shrinkable container
	 * @param              type of container
	 * @param              type of elements
	 * @return stream of shrunk containers
	 */
	static  Stream> sortElements(List> elements, ContainerCreator createContainer) {
		List> sortedElements = new ArrayList<>(elements);
		sortedElements.sort(Comparator.comparing(Shrinkable::distance));
		if (elements.equals(sortedElements)) {
			return Stream.empty();
		}
		return JqwikStreamSupport.concat(
			fullSort(sortedElements, createContainer),
			pairwiseSort(elements, createContainer)
		);
	}

	private static  Stream> fullSort(List> sortedElements, ContainerCreator createContainer) {
		return Stream.of(createContainer.apply(sortedElements));
	}

	private static  Stream> pairwiseSort(List> elements, ContainerCreator createContainer) {
		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)
							.map(quadruple -> {
								List> pairSwap = new ArrayList<>(elements);
								pairSwap.set(quadruple.get1(), quadruple.get4());
								pairSwap.set(quadruple.get3(), quadruple.get2());
								return createContainer.apply(pairSwap);
							});
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy