diff options
author | Carlo Zancanaro <carlo@zancanaro.id.au> | 2015-11-24 12:57:27 +1100 |
---|---|---|
committer | Carlo Zancanaro <carlo@zancanaro.id.au> | 2015-11-24 12:57:27 +1100 |
commit | 8376ed30f83c9193025da5962de5f5d78edfa185 (patch) | |
tree | 6b79a0a9bdedce965d2905de2bc2a6ff10fbccc9 /src | |
parent | 1b0565b1f6b4d5009da689ba5d486bce203e4905 (diff) |
Add an implicit generator for Sets
Diffstat (limited to 'src')
-rw-r--r-- | src/main/java/au/id/zancanaro/javacheck/Generators.java | 11 | ||||
-rw-r--r-- | src/main/java/au/id/zancanaro/javacheck/object/GeneratorProvider.java | 6 | ||||
-rw-r--r-- | src/test/java/au/id/zancanaro/javacheck/CollectionsTest.java | 23 | ||||
-rw-r--r-- | src/test/java/au/id/zancanaro/javacheck/OptionalRulesTest.java (renamed from src/test/java/au/id/zancanaro/javacheck/OptionalFunctorRulesTest.java) | 29 | ||||
-rw-r--r-- | src/test/java/au/id/zancanaro/javacheck/SetFunctorRulesTest.java | 106 | ||||
-rw-r--r-- | src/test/java/au/id/zancanaro/javacheck/SimpleListOperationsTest.java | 10 |
6 files changed, 161 insertions, 24 deletions
diff --git a/src/main/java/au/id/zancanaro/javacheck/Generators.java b/src/main/java/au/id/zancanaro/javacheck/Generators.java index af8f8ad..631e14a 100644 --- a/src/main/java/au/id/zancanaro/javacheck/Generators.java +++ b/src/main/java/au/id/zancanaro/javacheck/Generators.java @@ -179,6 +179,17 @@ public final class Generators { }; } + public static <T> Generator<Set<T>> setOf(Generator<T> gen) { + return (random, size) -> { + Generator<Integer> countGen = sized(s -> integer(0, s)); + int count = countGen.generate(random, size).getValue(); + return Generator.list(count, gen) + .generate(random, size) + .map(HashSet::new) + .map(Collections::unmodifiableSet); + }; + } + @SuppressWarnings("unchecked") public static <K, V> Generator<Map<K, V>> mapOf(Generator<K> keyGen, Generator<V> valueGen) { return (random, size) -> { diff --git a/src/main/java/au/id/zancanaro/javacheck/object/GeneratorProvider.java b/src/main/java/au/id/zancanaro/javacheck/object/GeneratorProvider.java index 827ba3f..c975933 100644 --- a/src/main/java/au/id/zancanaro/javacheck/object/GeneratorProvider.java +++ b/src/main/java/au/id/zancanaro/javacheck/object/GeneratorProvider.java @@ -11,6 +11,7 @@ import java.lang.reflect.TypeVariable; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import static au.id.zancanaro.javacheck.Generators.*; @@ -81,6 +82,11 @@ public interface GeneratorProvider { List.class.getTypeParameters()[0], new Annotation[0], provider)); + } else if (type == Set.class) { + return setOf(provider.getGenerator( + Set.class.getTypeParameters()[0], + new Annotation[0], + provider)); } else if (type == Map.class) { TypeVariable<?>[] params = Map.class.getTypeParameters(); TypeVariable<?> keyType = params[0], valueType = params[1]; diff --git a/src/test/java/au/id/zancanaro/javacheck/CollectionsTest.java b/src/test/java/au/id/zancanaro/javacheck/CollectionsTest.java new file mode 100644 index 0000000..644e8a1 --- /dev/null +++ b/src/test/java/au/id/zancanaro/javacheck/CollectionsTest.java @@ -0,0 +1,23 @@ +package au.id.zancanaro.javacheck; + +import au.id.zancanaro.javacheck.annotations.Property; +import au.id.zancanaro.javacheck.junit.Properties; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Collections.reverse; +import static org.junit.Assert.assertEquals; + +@RunWith(Properties.class) +public class CollectionsTest { + @Property + public void reverseIsInvolution(List<Integer> list) { + List<Integer> newList = new ArrayList<>(list); + reverse(newList); + reverse(newList); + + assertEquals(list, newList); + } +} diff --git a/src/test/java/au/id/zancanaro/javacheck/OptionalFunctorRulesTest.java b/src/test/java/au/id/zancanaro/javacheck/OptionalRulesTest.java index 5ef552e..407ffbd 100644 --- a/src/test/java/au/id/zancanaro/javacheck/OptionalFunctorRulesTest.java +++ b/src/test/java/au/id/zancanaro/javacheck/OptionalRulesTest.java @@ -14,7 +14,7 @@ import static au.id.zancanaro.javacheck.Generators.oneOf; import static org.junit.Assert.assertEquals; @RunWith(Properties.class) -public class OptionalFunctorRulesTest { +public class OptionalRulesTest { @DataSource public static Generator<Optional<Integer>> listOfIntegers = oneOf( @@ -24,32 +24,23 @@ public class OptionalFunctorRulesTest { @DataSource public static Generator<Function<Integer, Integer>> integerFunction = oneOf( - integer().map(OptionalFunctorRulesTest::plusI), - integer().map(OptionalFunctorRulesTest::timesI), - integer().map(OptionalFunctorRulesTest::constantlyI)); + integer().map(OptionalRulesTest::plusI), + integer().map(OptionalRulesTest::timesI), + integer().map(OptionalRulesTest::constantlyI)); @Property - public void mappingCompositionsWithStreams( - Optional<Integer> optional, - Function<Integer, Integer> f, - Function<Integer, Integer> g) { - Optional<Integer> left = optional - .map(g) - .map(f); - - Optional<Integer> right = optional - .map(x -> f.apply(g.apply(x))); - - assertEquals(left, right); + public void flatMapIdentity(Optional<Integer> optional) { + assertEquals(optional, optional.flatMap(Optional::of)); } @Property - public void mappingCompositionsWithIntermediateList( + public void mappingComposition( Optional<Integer> optional, Function<Integer, Integer> f, Function<Integer, Integer> g) { - Optional<Integer> intermediate = optional.map(g); - Optional<Integer> left = intermediate.map(f); + Optional<Integer> left = optional + .map(g) + .map(f); Optional<Integer> right = optional .map(x -> f.apply(g.apply(x))); diff --git a/src/test/java/au/id/zancanaro/javacheck/SetFunctorRulesTest.java b/src/test/java/au/id/zancanaro/javacheck/SetFunctorRulesTest.java new file mode 100644 index 0000000..04fa674 --- /dev/null +++ b/src/test/java/au/id/zancanaro/javacheck/SetFunctorRulesTest.java @@ -0,0 +1,106 @@ +package au.id.zancanaro.javacheck; + +import au.id.zancanaro.javacheck.annotations.DataSource; +import au.id.zancanaro.javacheck.annotations.Property; +import au.id.zancanaro.javacheck.junit.Properties; +import org.junit.runner.RunWith; + +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static au.id.zancanaro.javacheck.Generators.longInteger; +import static au.id.zancanaro.javacheck.Generators.oneOf; +import static org.junit.Assert.assertEquals; + +@RunWith(Properties.class) +public class SetFunctorRulesTest { + + @DataSource + public static Generator<Function<Long, Long>> integerFunction = + oneOf( + longInteger().map(SetFunctorRulesTest::plusI), + longInteger().map(SetFunctorRulesTest::timesI), + longInteger().map(SetFunctorRulesTest::constantlyI)); + + @Property + public void mappingCompositionsWithStreams( + Set<Long> list, + Function<Long, Long> f, + Function<Long, Long> g) { + Set<Long> left = list.stream() + .map(g) + .map(f) + .collect(Collectors.toSet()); + + Set<Long> right = list.stream() + .map(f.compose(g)) + .collect(Collectors.toSet()); + + assertEquals(left, right); + } + + @Property + public void mappingCompositionsWithIntermediateList( + Set<Long> list, + Function<Long, Long> f, + Function<Long, Long> g) { + Set<Long> intermediate = list.stream().map(g).collect(Collectors.toSet()); + Set<Long> left = intermediate.stream().map(f).collect(Collectors.toSet()); + + Set<Long> right = list.stream() + .map(f.compose(g)) + .collect(Collectors.toSet()); + + assertEquals(left, right); + } + + @Property + public void mapIdentityIsIdentity(Set<Long> list) { + Set<Long> mapped = list.stream().map(x -> x).collect(Collectors.toSet()); + + assertEquals(list, mapped); + } + + private static Function<Long, Long> plusI(final long i) { + return new Function<Long, Long>() { + @Override + public Long apply(Long integer) { + return i + integer; + } + + @Override + public String toString() { + return "x -> x + " + i; + } + }; + } + + private static Function<Long, Long> timesI(final long i) { + return new Function<Long, Long>() { + @Override + public Long apply(Long integer) { + return i * integer; + } + + @Override + public String toString() { + return "x -> x * " + i; + } + }; + } + + private static Function<Long, Long> constantlyI(final long i) { + return new Function<Long, Long>() { + @Override + public Long apply(Long integer) { + return i; + } + + @Override + public String toString() { + return "x -> " + i; + } + }; + } +} diff --git a/src/test/java/au/id/zancanaro/javacheck/SimpleListOperationsTest.java b/src/test/java/au/id/zancanaro/javacheck/SimpleListOperationsTest.java index 3cfef37..93a40e2 100644 --- a/src/test/java/au/id/zancanaro/javacheck/SimpleListOperationsTest.java +++ b/src/test/java/au/id/zancanaro/javacheck/SimpleListOperationsTest.java @@ -27,11 +27,11 @@ public class SimpleListOperationsTest { } @Property - public void reverseIsItsOwnInverse(List<String> list) { - List<String> reversed = new ArrayList<>(list); - reverse(reversed); - reverse(reversed); + public void reverseIsInvolution(List<String> list) { + List<String> newList = new ArrayList<>(list); + reverse(newList); + reverse(newList); - assertEquals(list, reversed); + assertEquals(list, newList); } } |