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

spock.genesis.generators.values.LongGenerator.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.values

import groovy.transform.CompileStatic
import spock.genesis.generators.Generator
import spock.genesis.generators.InfiniteGenerator
import spock.genesis.generators.InfiniteIterator

@CompileStatic
class LongGenerator extends InfiniteGenerator {

    final Long min
    final Long max
    private final IntegerGenerator integerGenerator

    LongGenerator() {
        this.min = Long.MIN_VALUE
        this.max = Long.MAX_VALUE
    }

    LongGenerator(long min, long max) {
        assert min < max
        this.min = min
        this.max = max
        def magnitude = magnitude(min, max)
        if (magnitude <= Integer.MAX_VALUE) {
            integerGenerator = new IntegerGenerator(0, magnitude as int)
        }
    }

    InfiniteIterator chooseProvider(long min, long max) {
        BigInteger magnitude = magnitude(min, max)
        if (magnitude <= Integer.MAX_VALUE) {
            new ShiftedIntegerIterator(min as long)
        } else if (magnitude <= Long.MAX_VALUE) {
            new ShiftedLongIterator(magnitude as long, min as long)
        } else {
            new RandomLongIterator()
        }
    }

    private static BigInteger magnitude(long min, long max) {
        max.toBigInteger() - min.toBigInteger()
    }

    InfiniteIterator iterator() {
        final InfiniteIterator CANDIDATE_PROVIDER = chooseProvider(min, max)
        new InfiniteIterator() {
            @Override
            Long next() {
                while (true) {
                    Long val = CANDIDATE_PROVIDER.next()
                    if (val >= min && val <= max) {
                        return val
                    }
                }
            }
        }
    }

    class RandomLongIterator extends InfiniteIterator {
        Long next() {
            random.nextLong()
        }
    }

    class ShiftedLongIterator extends InfiniteIterator {
        final long magnitude
        final long shift

        ShiftedLongIterator(long magnitude, long shift) {
            this.magnitude = magnitude
            this.shift = shift
        }

        Long next() {
            // error checking and 2^x checking removed for simplicity.
            long bits
            long val

            boolean seek = true
            while (seek) {
                bits = (random.nextLong() << 1) >>> 1
                val = bits % magnitude
                seek = bits - val + (magnitude - 1) < 0L
            }
            shift + val
        }
    }

    class ShiftedIntegerIterator extends InfiniteIterator {
        final InfiniteIterator iterator
        final long shift

        ShiftedIntegerIterator(long shift) {
            iterator = integerGenerator.iterator()
            this.shift = shift
        }

        Long next() {
            shift + iterator.next()
        }
    }

    @Override
    Generator seed(Long seed) {
        super.seed(seed)
        integerGenerator?.seed(seed)
        this
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy