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

net.jqwik.engine.properties.arbitraries.exhaustive.CombinedExhaustiveGenerator Maven / Gradle / Ivy

The newest version!
package net.jqwik.engine.properties.arbitraries.exhaustive;

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

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

import org.jspecify.annotations.*;

class CombinedExhaustiveGenerator implements ExhaustiveGenerator {
	private final Long maxCount;
	private final List> arbitraries;
	private final Function, ? extends R> combinator;

	static Optional calculateMaxCount(List> arbitraries, long maxNumberOfSamples) {
		long product = 1;
		for (Arbitrary arbitrary : arbitraries) {
			Optional> exhaustive = arbitrary.exhaustive(maxNumberOfSamples);
			if (!exhaustive.isPresent()) {
				return Optional.empty();
			}
			product *= exhaustive.get().maxCount();
			if (product > maxNumberOfSamples) {
				return Optional.empty();
			}
		}
		return Optional.of(product);
	}

	CombinedExhaustiveGenerator(Long maxCount, List> arbitraries, Function, ? extends R> combinator) {
		this.maxCount = maxCount;
		this.arbitraries = arbitraries;
		this.combinator = combinator;
	}

	@Override
	public long maxCount() {
		return maxCount;
	}

	@Override
	public Iterator iterator() {
		List> iterables = arbitraries
			.stream()
			.map(a -> (Iterable) a.exhaustive().get())
			.collect(Collectors.toList());
		Iterator> valuesIterator = Combinatorics.combine(iterables);

		return new Iterator() {
			@Override
			public boolean hasNext() {
				return valuesIterator.hasNext();
			}

			@Override
			public R next() {
				List values = valuesIterator.next();
				return combinator.apply(values);
			}
		};
	}
}