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.stream.*;

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

import org.jspecify.annotations.*;

class ShrinkableActionSequence implements Shrinkable> {

	private final ActionGenerator actionGenerator;
	private final int maxSize;
	private final ShrinkingDistance distance;

	private @Nullable SequentialActionSequence generatedSequence = null;

	ShrinkableActionSequence(ActionGenerator actionGenerator, int maxSize, ShrinkingDistance distance) {
		this.actionGenerator = actionGenerator;
		this.maxSize = maxSize;
		this.distance = distance;
	}

	@Override
	public ActionSequence value() {
		// Cannot be recreated on each access because creation takes place on first access and must be preserved for shrinking
		if (generatedSequence == null) {
			generatedSequence = new SequentialActionSequence<>(actionGenerator, maxSize);
		}
		return generatedSequence;
	}

	@Override
	public Stream>> shrink() {
		if (generatedSequence == null) {
			return Stream.empty();
		}
		return JqwikStreamSupport.concat(
			shrinkSequenceOfActions(),
			shrinkActionsOneAfterTheOther()
		);
	}

	private Stream>> shrinkSequenceOfActions() {
		return new ComprehensiveSizeOfListShrinker()
				   .shrink(actionGenerator.generated(), 1)
				   .map(this::createShrinkableActionSequence);
	}

	private Stream>> shrinkActionsOneAfterTheOther() {
		List>> shrinkableActions = actionGenerator.generated();
		List>>> shrinkPerElementStreams = new ArrayList<>();
		for (int i = 0; i < shrinkableActions.size(); i++) {
			int index = i;
			Shrinkable> element = shrinkableActions.get(i);
			Stream>> shrinkElement = element.shrink().flatMap(shrunkElement -> {
				List>> actionsCopy = new ArrayList<>(shrinkableActions);
				actionsCopy.set(index, shrunkElement);
				return Stream.of(createShrinkableActionSequence(actionsCopy));
			});
			shrinkPerElementStreams.add(shrinkElement);
		}
		return JqwikStreamSupport.concat(shrinkPerElementStreams);
	}

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

	@Override
	public ShrinkingDistance distance() {
		if (generatedSequence == null) {
			return distance;
		}
		return ShrinkingDistance.forCollection(actionGenerator.generated());
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy