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

net.jqwik.engine.facades.ShrinkingSupportFacadeImpl Maven / Gradle / Ivy

The newest version!
package net.jqwik.engine.facades;

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

import net.jqwik.api.*;
import net.jqwik.api.facades.*;
import net.jqwik.api.lifecycle.*;
import net.jqwik.engine.properties.*;
import net.jqwik.engine.properties.shrinking.*;

import org.jspecify.annotations.*;

public class ShrinkingSupportFacadeImpl extends ShrinkingSupportFacade {

	private final TestingSupportFacadeImpl testingSupportFacade = new TestingSupportFacadeImpl();

	@Override
	public  T falsifyThenShrink(Arbitrary arbitrary, Random random, Falsifier falsifier) {
		RandomGenerator generator = arbitrary.generator(10, true);
		return falsifyThenShrink(generator, random, falsifier);
	}

	@Override
	@SuppressWarnings("unchecked")
	public  T falsifyThenShrink(
			RandomGenerator generator,
			Random random,
			Falsifier falsifier
	) {
		Throwable[] originalError = new Throwable[1];
		Shrinkable falsifiedShrinkable =
				(Shrinkable) testingSupportFacade.generateUntil(generator, random, value -> {
					TryExecutionResult result = falsifier.execute(value);
					if (result.isFalsified()) {
						originalError[0] = result.throwable().orElse(null);
					}
					return result.isFalsified();
				});
		// System.out.println("### " + falsifiedShrinkable.value());
		return shrink(falsifiedShrinkable, falsifier, originalError[0]);
	}

	@Override
	@SuppressWarnings("unchecked")
	public  T shrink(
			Shrinkable falsifiedShrinkable,
			Falsifier falsifier,
			Throwable originalError
	) {
		ShrunkFalsifiedSample sample = shrinkToSample(falsifiedShrinkable, falsifier, originalError);
		return (T) sample.parameters().get(0);
	}

	@Override
	public  ShrunkFalsifiedSample shrinkToSample(
		Shrinkable falsifiedShrinkable,
		Falsifier falsifier,
		Throwable originalError
	) {
		FalsifiedSample sample = toFalsifiedSample(falsifiedShrinkable, originalError);
		Consumer parametersReporter = ignore -> {};
		PropertyShrinker shrinker = new PropertyShrinker(sample, ShrinkingMode.FULL, 10, parametersReporter, null);

		return shrinker.shrink(toParamFalsifier(falsifier));
	}

	@SuppressWarnings("unchecked")
	private static  Falsifier> toParamFalsifier(Falsifier tFalsifier) {
		return params -> {
			// At best PropertyShrinker should be parameterized, however, currently it is not
			// Even though PropertyShrinker passes List, the elements are of type T
			T t = (T) params.get(0);
			return tFalsifier.execute(t);
		};
	}

	@SuppressWarnings("unchecked")
	private static  FalsifiedSample toFalsifiedSample(Shrinkable falsifiedShrinkable, Throwable originalError) {
		List> shrinkables = Collections.singletonList((Shrinkable) falsifiedShrinkable);
		return toFalsifiedSample(shrinkables, originalError);
	}

	private static FalsifiedSample toFalsifiedSample(List> shrinkables, Throwable originalError) {
		List parameters = shrinkables.stream().map(Shrinkable::value).collect(Collectors.toList());
		return new FalsifiedSampleImpl(parameters, shrinkables, Optional.ofNullable(originalError), Collections.emptyList());
	}

}