property-testingvavrvavr-test

Generating tuples containing Long for Vavr Property Checking


I need a pair of random longs for property checking with Vavr.

My implementation looks like this:

Gen<Long> longs = Gen.choose(Long.MIN_VALUE, Long.MAX_VALUE);
Arbitrary<Tuple2<Long, Long>> pairOfLongs = longs
        .flatMap(value -> random -> Tuple.of(value, longs.apply(random)))
        .arbitrary();

Is any better/nicer way to do the same in vavr?


Solution

  • Arbitrary<T> can be seen as a function of type

    int -> Random -> T
    

    Generating arbitrary integers

    Because the sample size is of type int, it would be natural to do the following:

    Arbitrary<Tuple2<Integer, Integer>> intPairs = size -> {
        Gen<Integer> ints = Gen.choose(-size, size);
        return random -> Tuple.of(ints.apply(random), ints.apply(random));
    };
    

    Let's test it:

    Property.def("print int pairs")
            .forAll(intPairs.peek(System.out::println))
            .suchThat(pair -> true)
            .check(10, 5);
    

    Output:

    (-9, 2)
    (-2, -10)
    (5, -2)
    (3, 8)
    (-10, 10)
    

    Generating arbitrary long values

    Currently we are not able to define a size of type long, so the workaround is to ignore the size and use the full long range:

    Arbitrary<Tuple2<Long, Long>> longPairs = ignored -> {
        Gen<Long> longs = Gen.choose(Long.MIN_VALUE, Long.MAX_VALUE);
        return random -> Tuple.of(longs.apply(random), longs.apply(random));
    };
    

    Let's test it again:

    Property.def("print long pairs")
        .forAll(longPairs.peek(System.out::println))
        .suchThat(pair -> true)
        .check(0, 5);
    

    Output:

    (2766956995563010048, 1057025805628715008)
    (-6881523912167376896, 7985876340547620864)
    (7449864279215405056, 6862094372652388352)
    (3203043896949684224, -2508953386204733440)
    (1541228130048020480, 4106286124314660864)
    

    Interpreting an integer size as long

    The size parameter can be interpreted in a custom way. More specifically we could map a given int size to a long size:

    Arbitrary<Tuple2<Long, Long>> longPairs = size -> {
        long longSize = ((long) size) << 32;
        Gen<Long> longs = Gen.choose(-longSize, longSize);
        return random -> Tuple.of(longs.apply(random), longs.apply(random));
    };
    

    However, the last example does not match the full long range. Maybe it is possible to find a better mapping.

    Disclaimer: I'm the author of Vavr (formerly known as Javaslang)