quicktheories / QuickTheories

Property based testing for Java 8
Apache License 2.0
505 stars 51 forks source link

Generating primitive-type arrays #37

Open edrdo opened 6 years ago

edrdo commented 6 years ago

Hi,

What is the most suitable way of generating primitive-type arrays, say int[] values (not Integer[]) ? For instance the following will not work for obvious reasons (Integer[] is not type-compatible with int[])

static int[] dummy(int[] v) {
  return v;
}

@Test 
public void testDummy() {
  qt()
  .forAll(arrays().ofIntegers(integers().all()).withLengthBetween(1,16))
  .check( v -> v == dummy(v) );
}

I guess a PrimitiveArraysDSL should make sense as a future development (I would love to contribute it, but don't have sufficient familiarity with QuickTheories yet, I started using it this week!).

As a first step towards a work-around I tried to do the following:

Gen<int[]> generator = 
    in -> {
      int[] a = new int[16];
      for (int i = 0; i < a.length; i++) {
        a[i] = (int) in.next(Constraint.none());
      }
      return a;
    };
qt()
.forAll(generator)
.check( v -> v == dummy(v) );

As you can see above the array length (16) is fixed. How can I "plug-in" in elegant form the equivalent to the withLengthBetween(1,16)) constraint in the first fragment ?

Thanks, Eduardo

hcoles commented 6 years ago

You can use org.quicktheories.generators.Generate.intArrays.

This accepts two Gen of Integer to supply the sizes and contents for the arrays.

This hasn't been incorporated into the DSL, not entirely sure if that was due to oversight or by design.

edrdo commented 6 years ago

Thanks, I didn't pay attention to the existence of intArrays (sorry for posting here, but I didn't find a user group link if one exists). As you say, the following works fine:

qt()
.forAll(intArrays(integers().between(1,16), integers().all()))
.check( arr -> someProp(arr) );

A minor suggestion I make is to have a more "regular" API for handling primitive type arrays in future releases, e.g. there is no equivalent shortArrays for short[], longArrays for long[], etc. And for byte[] the API defines byteArrays method but no bytes() method / DSL, but instead the bytes(int,int,int) method.

Best, Eduardo