From e0fc94269698982d937b80ff5fd5b1ef8ef28cf4 Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro Date: Wed, 3 Jun 2015 19:43:14 +1000 Subject: Change shrinking a bit, add more generators, fix some types, moved suchThat Shrinking is now done using a "ShrinkStrategy". It's pretty similar to what it used to be in the end, but instead of generating new ShrinkTrees yourself, you just generate smaller s, and the generator framework will re-call your strategy to shrink smaller elements. (So, essentially, ShrinkStrategy.shrink(T obj) returns an Iterator which then has smaller trees calculated from it.) Added some more generators. In particular: longs and doubles. Fixed some types, so now Generator.tuple(integer(), string()) will work. Yay! Move suchThat to Generator, so now integer().suchThat(x -> x < 10) will work instead of the old Generators.suchThat(x -> x < 10, integer()), which felt a bit weird. --- .../java/au/id/zancanaro/javacheck/ShrinkTree.java | 44 +++++++++++++++------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'src/main/java/au/id/zancanaro/javacheck/ShrinkTree.java') diff --git a/src/main/java/au/id/zancanaro/javacheck/ShrinkTree.java b/src/main/java/au/id/zancanaro/javacheck/ShrinkTree.java index a424806..7dff917 100644 --- a/src/main/java/au/id/zancanaro/javacheck/ShrinkTree.java +++ b/src/main/java/au/id/zancanaro/javacheck/ShrinkTree.java @@ -2,16 +2,21 @@ package au.id.zancanaro.javacheck; import java.io.IOException; import java.io.Writer; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; import java.util.function.Function; import java.util.function.Predicate; +import static au.id.zancanaro.javacheck.Iterators.*; + @SuppressWarnings("unused") public class ShrinkTree { private final T value; private final Iterable> children; - public ShrinkTree(T value, Iterable> children) { + private ShrinkTree(T value, Iterable> children) { this.value = value; this.children = children; } @@ -31,15 +36,15 @@ public class ShrinkTree { public static ShrinkTree join(ShrinkTree> tree) { return new ShrinkTree<>( tree.getValue().getValue(), - () -> Iterators.concat( - Iterators.mappingIterator(ShrinkTree::join, tree.children.iterator()), + () -> concat( + mappingIterator(ShrinkTree::join, tree.children.iterator()), tree.getValue().children.iterator())); } private static Iterator[]> permutations(ShrinkTree[] trees) { - return Iterators.flatten( - Iterators.rangeIterator(trees.length, - index -> Iterators.mappingIterator(child -> { + return flatten( + rangeIterator(trees.length, + index -> mappingIterator(child -> { @SuppressWarnings("unchecked") ShrinkTree[] result = (ShrinkTree[]) new ShrinkTree[trees.length]; for (int i = 0; i < trees.length; ++i) { @@ -61,14 +66,14 @@ public class ShrinkTree { public static ShrinkTree zip(Function, R> fn, ShrinkTree[] trees) { return new ShrinkTree<>( fn.apply(makeHeadList(trees)), - () -> Iterators.mappingIterator( + () -> mappingIterator( shrinks -> ShrinkTree.zip(fn, shrinks), ShrinkTree.permutations(trees))); } private static Iterator[]> removeEach(ShrinkTree[] trees) { - return Iterators.concat( - Iterators.rangeIterator(trees.length, index -> { + return concat( + rangeIterator(trees.length, index -> { @SuppressWarnings("unchecked") ShrinkTree[] result = (ShrinkTree[]) new ShrinkTree[trees.length - 1]; for (int i = 0; i < trees.length - 1; ++i) { @@ -82,7 +87,7 @@ public class ShrinkTree { public static ShrinkTree shrink(Function, R> fn, ShrinkTree[] trees) { return new ShrinkTree<>( fn.apply(makeHeadList(trees)), - () -> Iterators.mappingIterator( + () -> mappingIterator( shrinks -> ShrinkTree.shrink(fn, shrinks), ShrinkTree.removeEach(trees))); } @@ -90,7 +95,7 @@ public class ShrinkTree { public ShrinkTree map(Function f) { return new ShrinkTree<>( f.apply(this.value), - () -> Iterators.mappingIterator(tree -> tree.map(f), this.children.iterator())); + () -> mappingIterator(tree -> tree.map(f), this.children.iterator())); } public ShrinkTree flatMap(Function> f) { @@ -101,8 +106,8 @@ public class ShrinkTree { if (predicate.test(this.getValue())) { return new ShrinkTree<>( this.getValue(), - () -> Iterators.mappingIterator(tree -> tree.filter(predicate), - Iterators.filteringIterator( + () -> mappingIterator(tree -> tree.filter(predicate), + filteringIterator( tree -> predicate.test(tree.getValue()), this.getChildren()))); } else { @@ -110,6 +115,17 @@ public class ShrinkTree { } } + public ShrinkTree withShrinkStrategy(ShrinkStrategy strategy) { + return new ShrinkTree<>(this.getValue(), strategyIterable(this.getValue(), strategy)); + } + + private static Iterable> strategyIterable(final T value, final ShrinkStrategy strategy) { + return () -> + mappingIterator( + v -> new ShrinkTree<>(v, strategyIterable(v, strategy)), + strategy.shrink(value)); + } + @SuppressWarnings("unused") public void print(Writer output) throws IOException { print(output, Object::toString); -- cgit v1.2.3