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

net.jqwik.engine.execution.AfterFailureParametersGenerator Maven / Gradle / Ivy

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

import java.util.*;
import java.util.logging.*;

import net.jqwik.api.*;
import net.jqwik.api.lifecycle.*;

public class AfterFailureParametersGenerator implements ParametersGenerator {

	private static final Logger LOG = Logger.getLogger(AfterFailureParametersGenerator.class.getName());

	private final GenerationInfo previousFailureGeneration;
	private final ParametersGenerator parametersGenerator;

	private boolean continueWithSeed = false;
	private boolean runWithPreviousSample = false;
	private boolean previousSampleHasJustRun = false;

	public AfterFailureParametersGenerator(
		AfterFailureMode afterFailureMode,
		GenerationInfo previousFailureGeneration,
		ParametersGenerator parametersGenerator
	) {
		logAfterFailureHandling(afterFailureMode, previousFailureGeneration);
		initializeRunningState(afterFailureMode, previousFailureGeneration);
		this.previousFailureGeneration = previousFailureGeneration;
		this.parametersGenerator = parametersGenerator;
	}

	private void initializeRunningState(
		AfterFailureMode afterFailureMode,
		GenerationInfo previousFailureGeneration
	) {
		if (shouldRunWithPreviousSample(afterFailureMode, previousFailureGeneration)) {
			this.runWithPreviousSample = true;
		}
		if (shouldContiueWithPreviousSeed(afterFailureMode)) {
			this.continueWithSeed = true;
		}
	}

	private boolean shouldContiueWithPreviousSeed(AfterFailureMode afterFailureMode) {
		return afterFailureMode == AfterFailureMode.SAMPLE_FIRST || afterFailureMode == AfterFailureMode.PREVIOUS_SEED;
	}

	private boolean shouldRunWithPreviousSample(AfterFailureMode afterFailureMode, GenerationInfo previousFailureGeneration) {
		return previousFailureGeneration.generationIndex() > 0
				&& (afterFailureMode == AfterFailureMode.SAMPLE_FIRST || afterFailureMode == AfterFailureMode.SAMPLE_ONLY);
	}

	private void logAfterFailureHandling(AfterFailureMode afterFailureMode, GenerationInfo previousFailureGeneration) {
		String message = String.format("After Failure Handling: %s, Previous Generation: <%s>", afterFailureMode, previousFailureGeneration);
		LOG.log(Level.INFO, message);
	}

	@Override
	public boolean hasNext() {
		if (runWithPreviousSample) {
			return true;
		}
		if (continueWithSeed) {
			return parametersGenerator.hasNext();
		}
		return false;
	}

	@Override
	public List> next(TryLifecycleContext context) {
		if (runWithPreviousSample) {
			Optional>> previousSample = generatePreviousSample(context);
			runWithPreviousSample = false;
			parametersGenerator.reset();
			if (previousSample.isPresent()) {
				previousSampleHasJustRun = true;
				return previousSample.get();
			} else {
				logFailingOfPreviousSampleGeneration();
				continueWithSeed = true;
				return next(context);
			}
		}
		if (continueWithSeed) {
			previousSampleHasJustRun = false;
			return parametersGenerator.next(context);
		}
		return null;
	}

	private void logFailingOfPreviousSampleGeneration() {
		String message = String.format(
			"Cannot generate previous falsified sample <%s>.%n" +
				"\tUsing previous seed instead.", previousFailureGeneration
		);
		LOG.warning(message);
	}

	private Optional>> generatePreviousSample(TryLifecycleContext context) {
		return previousFailureGeneration.generateOn(parametersGenerator, context);
	}

	@Override
	public int edgeCasesTotal() {
		return parametersGenerator.edgeCasesTotal();
	}

	@Override
	public int edgeCasesTried() {
		return parametersGenerator.edgeCasesTried();
	}

	@Override
	public GenerationInfo generationInfo(String randomSeed) {
		if (previousSampleHasJustRun) {
			return previousFailureGeneration;
		}
		return parametersGenerator.generationInfo(randomSeed);
	}

	@Override
	public void reset() {
		throw new UnsupportedOperationException("Should only be used on delegate generators");
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy