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

net.jqwik.engine.properties.stateful.ShrinkableActionSequence Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
package net.jqwik.engine.properties.stateful;

import java.util.*;
import java.util.function.*;
import java.util.stream.*;

import net.jqwik.api.*;
import net.jqwik.api.stateful.*;
import net.jqwik.engine.properties.shrinking.*;

class ShrinkableActionSequence implements Shrinkable> {

	private final ComprehensiveListShrinkingCandidates listShrinkingCandidates = new ComprehensiveListShrinkingCandidates();

	private final ActionSequence value;
	private final ActionGenerator actionGenerator;
	private final int minSize;
	private final ShrinkingDistance distance;

	ShrinkableActionSequence(ActionGenerator actionGenerator, int minSize, int maxSize, ShrinkingDistance distance) {
		this.actionGenerator = actionGenerator;
		this.minSize = minSize;
		this.distance = distance;
		this.value = new SequentialActionSequence<>(actionGenerator, maxSize);
	}

	@Override
	public ActionSequence value() {
		return value;
	}

	@Override
	public ShrinkingSequence> shrink(Falsifier> falsifier) {
		Falsifier> minRespectingFalsifier =
			falsifier.withPostFilter(actionSequence -> actionSequence.runActions().size() >= minSize);

		return shrinkSequenceOfActions(minRespectingFalsifier)
			.andThen(shrinkableList -> { //
				ShrinkableActionSequence shrinkableSequence = (ShrinkableActionSequence) shrinkableList;
				Falsifier>> listFalsifier = list -> minRespectingFalsifier.test(toRunnableActionSequence(list));
				return shrinkIndividualActions(shrinkableSequence, listFalsifier)
					// Shrink list of actions again since element shrinking
					// might have made some actions unnecessary
					.andThen(shrinkListOfActions(listFalsifier))
					.mapValue(this::toDisplayOnlyActionSequence);
			});

	}

	private Function>>, ShrinkingSequence>>> shrinkListOfActions(Falsifier>> listFalsifier) {
		return shrinkableListOfActions ->
			new DeepSearchShrinkingSequence<>(shrinkableListOfActions, this::shrinkActionListCandidates, listFalsifier);
	}

	private Set>>> shrinkActionListCandidates(Shrinkable>> shrinkableList) {
		//noinspection unchecked
		return listShrinkingCandidates
			.candidatesFor(shrinkableList.value())
			.stream()
			.map(elements -> elements.stream().map(Shrinkable::unshrinkable).collect(Collectors.toList()))
			.map((List>> shrinkableElements) -> (Shrinkable>>) new ShrinkableList(shrinkableElements, 1)) //
			.collect(Collectors.toSet());
	}

	private ElementsShrinkingSequence> shrinkIndividualActions(
		ShrinkableActionSequence shrinkableActionSequence,
		Falsifier>> listFalsifier
	) {
		return new ElementsShrinkingSequence<>(
			shrinkableActionSequence.actionGenerator.generated(),
			listFalsifier, ShrinkingDistance::forCollection
		);
	}

	private ActionSequence toDisplayOnlyActionSequence(List> listOfActions) {
		return new FixedActionsFailedActionSequence<>(listOfActions);
	}

	private ActionSequence toRunnableActionSequence(List> listOfActions) {
		ActionGenerator newActionGenerator = new ListActionGenerator<>(listOfActions);
		return new SequentialActionSequence(newActionGenerator, listOfActions.size());
	}

	private ShrinkableActionSequence toShrinkableActionSequence(List>> list) {
		ActionGenerator newGenerator = new ShrinkablesActionGenerator<>(list);
		ShrinkingDistance newDistance = ShrinkingDistance.forCollection(list);
		return new ShrinkableActionSequence<>(newGenerator, 1, list.size(), newDistance);
	}

	private DeepSearchShrinkingSequence> shrinkSequenceOfActions(Falsifier> falsifier) {
		return new DeepSearchShrinkingSequence<>(this, this::shrinkSequenceCandidates, falsifier);
	}

	private Set>> shrinkSequenceCandidates(Shrinkable> shrinkable) {
		ShrinkableActionSequence shrinkableSequence = (ShrinkableActionSequence) shrinkable;
		return listShrinkingCandidates
			.candidatesFor(shrinkableSequence.actionGenerator.generated())
			.stream()
			.map(this::toShrinkableActionSequence)
			.collect(Collectors.toSet());
	}

	@Override
	public ShrinkingDistance distance() {
		if (value.runState() == ActionSequence.RunState.NOT_RUN) {
			return distance;
		}
		return ShrinkingDistance.forCollection(actionGenerator.generated());
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy