Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions core/src/main/java/org/quicktheories/generators/ArrayListDSL.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package org.quicktheories.generators;

import org.quicktheories.core.Gen;

import java.util.List;

/**
* A Class for creating ArrayList Sources that will produce List objects of either
* fixed or bounded size.
*
*/
public class ArrayListDSL {
/**
* Creates a ListGeneratorBuilder.
*
* @param <T>
* type to generate
*
* @param source
* a Source of type T for the items in the list
* @return a ListGeneratorBuilder of type T
*/
public <T> ListGeneratorBuilder<T> of(
Gen<T> source) {
return new ListGeneratorBuilder<>(source);
}

/**
* ListGeneratorBuilder enables the creation of Sources for Lists of fixed and
* bounded size.
*
* @param <T>
* type to generate
*/
public static class ListGeneratorBuilder<T> {

protected final Gen<T> source;

ListGeneratorBuilder(Gen<T> source) {
this.source = source;
}

/**
* Generates a List of objects, where the size of the List is fixed
*
* @param size
* size of lists to generate
* @return a Source of Lists of type T
*/
public Gen<List<T>> ofSize(int size) {
return ofSizeBetween(size, size);
}

/**
* Generates a List of objects, where the size of the List is bounded by
* minimumSize and maximumSize
*
* @param minimumSize
* - inclusive minimum size of List
* @param maximumSize
* - inclusive maximum size of List
* @return a Source of Lists of type T
*/
public Gen<List<T>> ofSizeBetween(int minimumSize, int maximumSize) {
checkBoundedListArguments(minimumSize, maximumSize);
return ofSizes(Generate.range(minimumSize,
maximumSize));
}


public Gen<List<T>> ofSizes(Gen<Integer> sizes) {
return Lists.arrayListOf(source, sizes);
}

}

private static void checkBoundedListArguments(int minimumSize,
int maximumSize) {
//TODO fork from ListsDSL, should this be shared but packaged private?
ArgumentAssertions.checkArguments(minimumSize <= maximumSize,
"The minimumSize (%s) is longer than the maximumSize(%s)",
minimumSize, maximumSize);
checkSizeNotNegative(minimumSize);
}

private static void checkSizeNotNegative(int size) {
//TODO fork from ListsDSL, should this be shared but packaged private?
ArgumentAssertions.checkArguments(size >= 0,
"The size of a List cannot be negative; %s is not an accepted argument",
size);
}
}
24 changes: 22 additions & 2 deletions core/src/main/java/org/quicktheories/generators/Lists.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public final class Lists {

static <T> Gen<List<T>> listsOf(
Gen<T> generator, Gen<Integer> sizes) {
return
listsOf(generator, arrayList(), sizes).mix(
return
arrayListOf(generator, sizes).mix(
listsOf(generator, linkedList(), sizes));
}

Expand All @@ -38,6 +38,26 @@ public static <T, A extends List<T>> Collector<T, A, A> toList(
});
}

/**
* Create a {@link Gen} using {@link ArrayList}.
*
* Why use this function rather than {@link #arrayList()} or {@link #listsOf(Gen, Gen)}? Mostly because of array
* pre-allocation. Since the size is known before the values are generated, can pre-allocate the array so array
* copying does not become a bottleneck; useful for theories which depend on large lists.
*/
public static <T> Gen<List<T>> arrayListOf(Gen<T> values, Gen<Integer> sizes) {
Gen<List<T>> gen = prng -> {
int size = sizes.generate(prng);
ArrayList<T> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
list.add(values.generate(prng));
}
return list;

};
return gen.describedAs(listDescriber(values::asString));
}

static <T> Gen<List<T>> listsOf(
Gen<T> values, Collector<T, List<T>, List<T>> collector, Gen<Integer> sizes) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public static ListsDSL lists() {
return new ListsDSL();
}

public static ArrayListDSL arrayLists() {
return new ArrayListDSL();
}

public static MapsDSL maps() {
return new MapsDSL();
}
Expand Down