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

net.jqwik.engine.properties.RandomizedShrinkablesGenerator Maven / Gradle / Ivy

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

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

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

public class RandomizedShrinkablesGenerator implements ShrinkablesGenerator {

	public static RandomizedShrinkablesGenerator forParameters(
		List parameters,
		ArbitraryResolver arbitraryResolver,
		Random random,
		int genSize
	) {
		List parameterGenerators =
			parameters.stream()
					  .map(parameter -> resolveParameter(arbitraryResolver, parameter, genSize))
					  .collect(Collectors.toList());

		return new RandomizedShrinkablesGenerator(parameterGenerators, random);
	}

	private static RandomizedParameterGenerator resolveParameter(ArbitraryResolver arbitraryResolver, MethodParameter parameter, int genSize) {
		Set arbitraries =
			arbitraryResolver.forParameter(parameter).stream()
							 .map(GenericArbitrary::new)
							 .collect(Collectors.toSet());
		if (arbitraries.isEmpty()) {
			throw new CannotFindArbitraryException(TypeUsageImpl.forParameter(parameter), parameter.getAnnotation(ForAll.class));
		}
		return new RandomizedParameterGenerator(parameter, arbitraries, genSize);
	}

	private final List parameterGenerators;
	private final Random random;

	private RandomizedShrinkablesGenerator(List parameterGenerators, Random random) {
		this.parameterGenerators = parameterGenerators;
		this.random = random;
	}

	@Override
	public boolean hasNext() {
		// Randomized generation should always be able to generate a next set of values
		return true;
	}

	@Override
	public List next() {
		Map generatorsCache = new HashMap<>();
		return parameterGenerators
				   .stream()
				   .map(generator -> generator.next(random, generatorsCache))
				   .collect(Collectors.toList());
	}

	private static class RandomizedParameterGenerator {
		private final TypeUsage typeUsage;
		private final List arbitraries;
		private final int genSize;

		private RandomizedParameterGenerator(MethodParameter parameter, Set arbitraries, int genSize) {
			this.typeUsage = TypeUsageImpl.forParameter(parameter);
			this.arbitraries = new ArrayList<>(arbitraries);
			this.genSize = genSize;
		}

		private Shrinkable next(Random random, Map arbitrariesCache) {
			RandomGenerator selectedGenerator = selectGenerator(random, arbitrariesCache);
			return selectedGenerator.next(random);
		}

		private RandomGenerator selectGenerator(Random random, Map arbitrariesCache) {
			if (arbitrariesCache.containsKey(typeUsage)) {
				return arbitrariesCache.get(typeUsage).generator(genSize);
			}
			int index = arbitraries.size() == 1 ? 0 : random.nextInt(arbitraries.size());
			Arbitrary selectedArbitrary = arbitraries.get(index);
			arbitrariesCache.put(typeUsage, selectedArbitrary);
			return selectedArbitrary.generator(genSize);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy