From 8376ed30f83c9193025da5962de5f5d78edfa185 Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro Date: Tue, 24 Nov 2015 12:57:27 +1100 Subject: Add an implicit generator for Sets --- pom.xml | 3 +- .../java/au/id/zancanaro/javacheck/Generators.java | 11 +++ .../javacheck/object/GeneratorProvider.java | 6 ++ .../au/id/zancanaro/javacheck/CollectionsTest.java | 23 +++++ .../javacheck/OptionalFunctorRulesTest.java | 107 --------------------- .../id/zancanaro/javacheck/OptionalRulesTest.java | 98 +++++++++++++++++++ .../zancanaro/javacheck/SetFunctorRulesTest.java | 106 ++++++++++++++++++++ .../javacheck/SimpleListOperationsTest.java | 10 +- 8 files changed, 250 insertions(+), 114 deletions(-) create mode 100644 src/test/java/au/id/zancanaro/javacheck/CollectionsTest.java delete mode 100644 src/test/java/au/id/zancanaro/javacheck/OptionalFunctorRulesTest.java create mode 100644 src/test/java/au/id/zancanaro/javacheck/OptionalRulesTest.java create mode 100644 src/test/java/au/id/zancanaro/javacheck/SetFunctorRulesTest.java diff --git a/pom.xml b/pom.xml index 9235383..245732f 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,6 @@ 1.8 -Xlint:all true - true @@ -38,4 +37,4 @@ - \ No newline at end of file + 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 Generator> setOf(Generator gen) { + return (random, size) -> { + Generator 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 Generator> mapOf(Generator keyGen, Generator 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 list) { + List 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/OptionalFunctorRulesTest.java deleted file mode 100644 index 5ef552e..0000000 --- a/src/test/java/au/id/zancanaro/javacheck/OptionalFunctorRulesTest.java +++ /dev/null @@ -1,107 +0,0 @@ -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.Optional; -import java.util.function.Function; - -import static au.id.zancanaro.javacheck.Generator.pure; -import static au.id.zancanaro.javacheck.Generators.integer; -import static au.id.zancanaro.javacheck.Generators.oneOf; -import static org.junit.Assert.assertEquals; - -@RunWith(Properties.class) -public class OptionalFunctorRulesTest { - - @DataSource - public static Generator> listOfIntegers = oneOf( - pure(Optional.empty()), - integer().map(Optional::of)); - - @DataSource - public static Generator> integerFunction = - oneOf( - integer().map(OptionalFunctorRulesTest::plusI), - integer().map(OptionalFunctorRulesTest::timesI), - integer().map(OptionalFunctorRulesTest::constantlyI)); - - @Property - public void mappingCompositionsWithStreams( - Optional optional, - Function f, - Function g) { - Optional left = optional - .map(g) - .map(f); - - Optional right = optional - .map(x -> f.apply(g.apply(x))); - - assertEquals(left, right); - } - - @Property - public void mappingCompositionsWithIntermediateList( - Optional optional, - Function f, - Function g) { - Optional intermediate = optional.map(g); - Optional left = intermediate.map(f); - - Optional right = optional - .map(x -> f.apply(g.apply(x))); - - assertEquals(left, right); - } - - @Property - public void mapIdentityIsIdentity(Optional optional) { - Optional mapped = optional.map(x -> x); - - assertEquals(optional, mapped); - } - - private static Function plusI(final int i) { - return new Function() { - @Override - public Integer apply(Integer integer) { - return i + integer; - } - - @Override - public String toString() { - return "x -> x + " + i; - } - }; - } - - private static Function timesI(final int i) { - return new Function() { - @Override - public Integer apply(Integer integer) { - return i * integer; - } - - @Override - public String toString() { - return "x -> x * " + i; - } - }; - } - private static Function constantlyI(final int i) { - return new Function() { - @Override - public Integer apply(Integer integer) { - return i; - } - - @Override - public String toString() { - return "x -> " + i; - } - }; - } -} diff --git a/src/test/java/au/id/zancanaro/javacheck/OptionalRulesTest.java b/src/test/java/au/id/zancanaro/javacheck/OptionalRulesTest.java new file mode 100644 index 0000000..407ffbd --- /dev/null +++ b/src/test/java/au/id/zancanaro/javacheck/OptionalRulesTest.java @@ -0,0 +1,98 @@ +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.Optional; +import java.util.function.Function; + +import static au.id.zancanaro.javacheck.Generator.pure; +import static au.id.zancanaro.javacheck.Generators.integer; +import static au.id.zancanaro.javacheck.Generators.oneOf; +import static org.junit.Assert.assertEquals; + +@RunWith(Properties.class) +public class OptionalRulesTest { + + @DataSource + public static Generator> listOfIntegers = oneOf( + pure(Optional.empty()), + integer().map(Optional::of)); + + @DataSource + public static Generator> integerFunction = + oneOf( + integer().map(OptionalRulesTest::plusI), + integer().map(OptionalRulesTest::timesI), + integer().map(OptionalRulesTest::constantlyI)); + + @Property + public void flatMapIdentity(Optional optional) { + assertEquals(optional, optional.flatMap(Optional::of)); + } + + @Property + public void mappingComposition( + Optional optional, + Function f, + Function g) { + Optional left = optional + .map(g) + .map(f); + + Optional right = optional + .map(x -> f.apply(g.apply(x))); + + assertEquals(left, right); + } + + @Property + public void mapIdentityIsIdentity(Optional optional) { + Optional mapped = optional.map(x -> x); + + assertEquals(optional, mapped); + } + + private static Function plusI(final int i) { + return new Function() { + @Override + public Integer apply(Integer integer) { + return i + integer; + } + + @Override + public String toString() { + return "x -> x + " + i; + } + }; + } + + private static Function timesI(final int i) { + return new Function() { + @Override + public Integer apply(Integer integer) { + return i * integer; + } + + @Override + public String toString() { + return "x -> x * " + i; + } + }; + } + private static Function constantlyI(final int i) { + return new Function() { + @Override + public Integer apply(Integer integer) { + return i; + } + + @Override + public String toString() { + return "x -> " + i; + } + }; + } +} 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> integerFunction = + oneOf( + longInteger().map(SetFunctorRulesTest::plusI), + longInteger().map(SetFunctorRulesTest::timesI), + longInteger().map(SetFunctorRulesTest::constantlyI)); + + @Property + public void mappingCompositionsWithStreams( + Set list, + Function f, + Function g) { + Set left = list.stream() + .map(g) + .map(f) + .collect(Collectors.toSet()); + + Set right = list.stream() + .map(f.compose(g)) + .collect(Collectors.toSet()); + + assertEquals(left, right); + } + + @Property + public void mappingCompositionsWithIntermediateList( + Set list, + Function f, + Function g) { + Set intermediate = list.stream().map(g).collect(Collectors.toSet()); + Set left = intermediate.stream().map(f).collect(Collectors.toSet()); + + Set right = list.stream() + .map(f.compose(g)) + .collect(Collectors.toSet()); + + assertEquals(left, right); + } + + @Property + public void mapIdentityIsIdentity(Set list) { + Set mapped = list.stream().map(x -> x).collect(Collectors.toSet()); + + assertEquals(list, mapped); + } + + private static Function plusI(final long i) { + return new Function() { + @Override + public Long apply(Long integer) { + return i + integer; + } + + @Override + public String toString() { + return "x -> x + " + i; + } + }; + } + + private static Function timesI(final long i) { + return new Function() { + @Override + public Long apply(Long integer) { + return i * integer; + } + + @Override + public String toString() { + return "x -> x * " + i; + } + }; + } + + private static Function constantlyI(final long i) { + return new Function() { + @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 list) { - List reversed = new ArrayList<>(list); - reverse(reversed); - reverse(reversed); + public void reverseIsInvolution(List list) { + List newList = new ArrayList<>(list); + reverse(newList); + reverse(newList); - assertEquals(list, reversed); + assertEquals(list, newList); } } -- cgit v1.2.3