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

spock.genesis.generators.MultiSourceGenerator.groovy Maven / Gradle / Ivy

Go to download

Mostly lazy data generators for property based testing using the Spock test framework

The newest version!
package spock.genesis.generators

import groovy.transform.CompileStatic
import spock.genesis.extension.ExtensionMethods

/**
 * A generator that returns the next value from one of its source generators at random.
 * @param < E >   the generated type
 */
@CompileStatic
class MultiSourceGenerator extends Generator implements Closeable {

    private final List> generators

    MultiSourceGenerator(Collection> iterables) {
        this.generators = iterables.collect { ExtensionMethods.toGenerator(it) }
    }

    MultiSourceGenerator(Map, Integer> weightedIterators) {
        List i = []
        weightedIterators.each { iterable, qty ->
            def generator = ExtensionMethods.toGenerator(iterable)
            qty.times { i << generator }
        }
        this.generators = i
    }

    UnmodifiableIterator iterator() {
        new UnmodifiableIterator() {
            private final List> iterators = generators*.iterator()
            /**
             * @return true if any of the source generators has next
             */
            @Override
            boolean hasNext() {
                iterators.any { it.hasNext() }
            }

            /** generates a value from one of the source generators
             * @return the generated value
             */
            @Override
            E next() {
                boolean search = hasNext()

                while (search) {
                    int i = random.nextInt(iterators.size())
                    def generator = iterators[i]
                    if (generator.hasNext()) {
                        return generator.next()
                    }
                }
            }
        }
    }

    @SuppressWarnings('ExplicitCallToPlusMethod')
    MultiSourceGenerator plus(Iterable additional) {
        plus([additional])
    }

    /**
     * Adds additional source generators to this generators source generators.
     * This method does not mutate but does reuse the source generators.
     * @param additional
     * @return a new MultiSourceGenerator
     */
    MultiSourceGenerator plus(Collection> additional) {
        new MultiSourceGenerator(additional + generators)
    }

    void close() {
        generators.each { it.close() }
    }

    boolean isFinite() {
        generators.every { it.finite }
    }

    @Override
    MultiSourceGenerator seed(Long seed) {
        generators.each { it.seed(seed) }
        super.seed(seed)
        this
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy