From 7e1182355d54f0dc8461ce7df7c4aca8c40d2a92 Mon Sep 17 00:00:00 2001
From: Carlo Zancanaro <carlo@zancanaro.id.au>
Date: Mon, 1 Jun 2015 00:25:19 +1000
Subject: Just some rearranging, renaming and clean-up

---
 src/main/java/au/id/zancanaro/Generators.java      |  16 +-
 src/main/java/au/id/zancanaro/Properties.java      | 249 +++++++++++++++++++++
 src/main/java/au/id/zancanaro/PropertyError.java   |  45 ++++
 .../java/au/id/zancanaro/PropertyTestError.java    |  45 ----
 .../java/au/id/zancanaro/PropertyTestRunner.java   | 249 ---------------------
 .../au/id/zancanaro/annotations/Generator.java     |   8 -
 6 files changed, 302 insertions(+), 310 deletions(-)
 create mode 100644 src/main/java/au/id/zancanaro/Properties.java
 create mode 100644 src/main/java/au/id/zancanaro/PropertyError.java
 delete mode 100644 src/main/java/au/id/zancanaro/PropertyTestError.java
 delete mode 100644 src/main/java/au/id/zancanaro/PropertyTestRunner.java
 delete mode 100644 src/main/java/au/id/zancanaro/annotations/Generator.java

(limited to 'src/main/java')

diff --git a/src/main/java/au/id/zancanaro/Generators.java b/src/main/java/au/id/zancanaro/Generators.java
index 852a290..e0927ff 100644
--- a/src/main/java/au/id/zancanaro/Generators.java
+++ b/src/main/java/au/id/zancanaro/Generators.java
@@ -22,14 +22,6 @@ public class Generators {
         return integer(0, gens.length).flatMap(index -> gens[index]);
     }
 
-    public static Generator<Integer> integer() {
-        return (random, size) -> integer(-size, size).generate(random, size);
-    }
-
-    public static Generator<Integer> natural() {
-        return (random, size) -> integer(0, size).generate(random, size);
-    }
-
     public static Generator<Integer> integer(int lower, int upper) {
         return (random, size) -> {
             int value = lower + random.nextInt(upper - lower);
@@ -38,6 +30,14 @@ public class Generators {
         };
     }
 
+    public static Generator<Integer> integer() {
+        return (random, size) -> integer(-size, size).generate(random, size);
+    }
+
+    public static Generator<Integer> natural() {
+        return (random, size) -> integer(0, size).generate(random, size);
+    }
+
     private static Iterable<RoseTree<Integer>> intShrinkingIterable(final int value, final int bound) {
         return () -> new Iterator<RoseTree<Integer>>() {
             int curr = value - bound;
diff --git a/src/main/java/au/id/zancanaro/Properties.java b/src/main/java/au/id/zancanaro/Properties.java
new file mode 100644
index 0000000..fab48f4
--- /dev/null
+++ b/src/main/java/au/id/zancanaro/Properties.java
@@ -0,0 +1,249 @@
+package au.id.zancanaro;
+
+import au.id.zancanaro.annotations.Property;
+import au.id.zancanaro.annotations.Seed;
+import org.junit.AssumptionViolatedException;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestClass;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+
+public class Properties extends BlockJUnit4ClassRunner {
+    private final Map<Type, Generator<Object>> generators = new HashMap<>();
+
+    public Properties(Class<?> klass) throws InitializationError {
+        super(klass);
+    }
+
+    @Override
+    protected void collectInitializationErrors(List<Throwable> errors) {
+        super.collectInitializationErrors(errors);
+        validateGeneratorFields(errors);
+    }
+
+    private void validateGeneratorFields(List<Throwable> errors) {
+        Field[] fields = getTestClass().getJavaClass().getDeclaredFields();
+
+        for (Field field : fields) {
+            Type type = field.getGenericType();
+            if (!(type instanceof ParameterizedType)) {
+                continue;
+            }
+            ParameterizedType ptype = (ParameterizedType) type;
+            if (!(ptype.getRawType() instanceof Class)) {
+                continue;
+            }
+            Class<?> c = (Class) ptype.getRawType();
+            if (c != Generator.class) {
+                continue;
+            }
+            if (!Modifier.isStatic(field.getModifiers())) {
+                errors.add(new Error("Generator field " + field.getName() + " must be static"));
+            }
+            if (!Modifier.isPublic(field.getModifiers())) {
+                errors.add(new Error("Generator field " + field.getName() + " must be public"));
+            }
+        }
+    }
+
+    private static final Map<Type, Type> rawTypes;
+
+    static {
+        Map<Type, Type> types = new HashMap<>();
+        types.put(Double.class, Double.TYPE);
+        types.put(Float.class, Float.TYPE);
+        types.put(Long.class, Long.TYPE);
+        types.put(Integer.class, Integer.TYPE);
+        types.put(Short.class, Short.TYPE);
+        types.put(Byte.class, Byte.TYPE);
+        types.put(Character.class, Character.TYPE);
+        types.put(Boolean.class, Boolean.TYPE);
+        rawTypes = Collections.unmodifiableMap(types);
+    }
+
+    private Map<Type, Generator<Object>> computeGenerators() {
+        if (generators.isEmpty()) {
+            Field[] fields = getTestClass().getJavaClass().getDeclaredFields();
+
+            for (Field field : fields) {
+                Type type = field.getGenericType();
+                if (!(type instanceof ParameterizedType)) {
+                    continue;
+                }
+                ParameterizedType ptype = (ParameterizedType) type;
+                if (!(ptype.getRawType() instanceof Class)) {
+                    continue;
+                }
+                Class<?> c = (Class) ptype.getRawType();
+                if (c != Generator.class) {
+                    continue;
+                }
+                try {
+                    Type target = ptype.getActualTypeArguments()[0];
+                    @SuppressWarnings("unchecked")
+                    Generator<Object> generator = (Generator<Object>) field.get(null);
+                    generators.put(target, generator);
+                    if (rawTypes.containsKey(target)) {
+                        generators.put(rawTypes.get(target), generator);
+                    }
+                } catch (IllegalAccessException ex) {
+
+                }
+            }
+        }
+        return generators;
+    }
+
+    @Override
+    protected void validateConstructor(List<Throwable> errors) {
+        validateOnlyOneConstructor(errors);
+    }
+
+    @Override
+    protected void validateTestMethods(List<Throwable> errors) {
+        for (FrameworkMethod each : computeTestMethods()) {
+            if (each.getAnnotation(Property.class) != null) {
+                each.validatePublicVoid(false, errors);
+                each.validateNoTypeParametersOnArgs(errors);
+            } else {
+                each.validatePublicVoidNoArg(false, errors);
+            }
+        }
+    }
+
+    @Override
+    protected List<FrameworkMethod> computeTestMethods() {
+        List<FrameworkMethod> testMethods = new ArrayList<>(super.computeTestMethods());
+        List<FrameworkMethod> theoryMethods = getTestClass().getAnnotatedMethods(Property.class);
+        testMethods.removeAll(theoryMethods);
+        testMethods.addAll(theoryMethods);
+        return testMethods;
+    }
+
+    @Override
+    public Statement methodBlock(final FrameworkMethod method) {
+        return new GenerativeTester(method, getTestClass(), computeGenerators());
+    }
+
+    public static class GenerativeTester extends Statement {
+        private final FrameworkMethod testMethod;
+        private final TestClass testClass;
+        private final Map<Type, Generator<Object>> generators;
+
+        public GenerativeTester(FrameworkMethod testMethod, TestClass testClass, Map<Type, Generator<Object>> generators) {
+            this.testMethod = testMethod;
+            this.testClass = testClass;
+            this.generators = generators;
+        }
+
+        private long getSeed(Method method) {
+            Seed seed = method.getAnnotation(Seed.class);
+            if (seed == null) {
+                return System.currentTimeMillis();
+            } else {
+                return seed.value();
+            }
+        }
+
+        @Override
+        public void evaluate() throws Throwable {
+            Method method = testMethod.getMethod();
+            if (method.getParameterCount() == 0) {
+                runTest(new Object[0]);
+            } else {
+                @SuppressWarnings("unchecked")
+                Generator<Object>[] generators = (Generator<Object>[]) new Generator[method.getParameterCount()];
+                int index = 0;
+                for (Type type : method.getGenericParameterTypes()) {
+                    generators[index++] = this.generators.get(type);
+                }
+                Generator<Object[]> generator = Generator.tuple(generators);
+
+                long seed = getSeed(method);
+                Random random = new Random(seed);
+
+                Property property = testMethod.getAnnotation(Property.class);
+                int assumptionsViolated = 0;
+                int maxSize = property.maxSize();
+                int numTests = property.runs();
+                for (int i = 0; i < numTests; ++i) {
+                    int size = Math.min(i + 1, maxSize);
+                    RoseTree<Object[]> tree = generator.generate(random, size);
+                    try {
+                        runTest(tree.getValue());
+                        assumptionsViolated = 0;
+                    } catch (AssumptionViolatedException ex) {
+                        numTests++;
+                        if (assumptionsViolated++ == 50) {
+                            throw new Error("Violated 50 assumptions in a row: failing test");
+                        }
+                        ;
+                    } catch (Throwable ex) {
+                        throw new PropertyError(method.getName(), seed, shrink(tree, ex));
+                    }
+                }
+            }
+        }
+
+        private ShrinkResult shrink(RoseTree<Object[]> failed, Throwable originalEx) {
+            ShrinkResult smallest = new ShrinkResult(failed.getValue(), originalEx);
+            Iterator<RoseTree<Object[]>> trees = failed.getChildren();
+            Set<List<Object>> seenArgs = new HashSet<>();
+            while (trees.hasNext()) {
+                RoseTree<Object[]> tree = trees.next();
+                if (seenArgs.add(Arrays.asList(tree.getValue()))) {
+                    try {
+                        runTest(tree.getValue());
+                    } catch (AssumptionViolatedException ex) {
+                        // ignore, because it's not useful
+                    } catch (Throwable ex) {
+                        smallest = new ShrinkResult(tree.getValue(), ex);
+                        Iterator<RoseTree<Object[]>> children = tree.getChildren();
+                        if (children.hasNext()) {
+                            trees = children;
+                        } else {
+                            break;
+                        }
+                    }
+                }
+            }
+            return smallest;
+        }
+
+        public void runTest(final Object[] args) throws Throwable {
+            new BlockJUnit4ClassRunner(testClass.getJavaClass()) {
+                @Override
+                protected void collectInitializationErrors(
+                        List<Throwable> errors) {
+                    // do nothing
+                }
+
+                @Override
+                public Statement methodBlock(FrameworkMethod method) {
+                    return super.methodBlock(method);
+                }
+
+                @Override
+                protected Statement methodInvoker(FrameworkMethod method, Object test) {
+                    return new Statement() {
+                        @Override
+                        public void evaluate() throws Throwable {
+                            method.invokeExplosively(test, args);
+                        }
+                    };
+                }
+
+                @Override
+                public Object createTest() throws Exception {
+                    return getTestClass().getOnlyConstructor().newInstance();
+                }
+            }.methodBlock(testMethod).evaluate();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/au/id/zancanaro/PropertyError.java b/src/main/java/au/id/zancanaro/PropertyError.java
new file mode 100644
index 0000000..b2fb589
--- /dev/null
+++ b/src/main/java/au/id/zancanaro/PropertyError.java
@@ -0,0 +1,45 @@
+package au.id.zancanaro;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+
+public class PropertyError extends AssertionError {
+    public PropertyError(String methodName, long seed, ShrinkResult shrunk) {
+        super(String.format("%s(%s)\n\tSeed: %s\n%s",
+                methodName, join(", ", shrunk.args),
+                seed,
+                shrunk.thrown.getMessage()));
+        initCause(shrunk.thrown);
+    }
+
+
+    public static String join(String delimiter, Object... params) {
+        return join(delimiter, Arrays.asList(params));
+    }
+
+    public static String join(String delimiter, Collection<Object> values) {
+        StringBuilder sb = new StringBuilder();
+        Iterator<Object> iter = values.iterator();
+        while (iter.hasNext()) {
+            Object next = iter.next();
+            sb.append(stringValueOf(next));
+            if (iter.hasNext()) {
+                sb.append(delimiter);
+            }
+        }
+        return sb.toString();
+    }
+
+    private static String stringValueOf(Object next) {
+        if (next instanceof String) {
+            return '"' + ((String) next).replace("\"", "\\\"") + '"';
+        } else {
+            try {
+                return String.valueOf(next);
+            } catch (Throwable e) {
+                return "[toString failed]";
+            }
+        }
+    }
+}
diff --git a/src/main/java/au/id/zancanaro/PropertyTestError.java b/src/main/java/au/id/zancanaro/PropertyTestError.java
deleted file mode 100644
index afd614b..0000000
--- a/src/main/java/au/id/zancanaro/PropertyTestError.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package au.id.zancanaro;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-
-public class PropertyTestError extends AssertionError {
-    public PropertyTestError(String methodName, long seed, ShrinkResult shrunk) {
-        super(String.format("%s(%s)\n\tSeed: %s\n%s",
-                methodName, join(", ", shrunk.args),
-                seed,
-                shrunk.thrown.getMessage()));
-        initCause(shrunk.thrown);
-    }
-
-
-    public static String join(String delimiter, Object... params) {
-        return join(delimiter, Arrays.asList(params));
-    }
-
-    public static String join(String delimiter, Collection<Object> values) {
-        StringBuilder sb = new StringBuilder();
-        Iterator<Object> iter = values.iterator();
-        while (iter.hasNext()) {
-            Object next = iter.next();
-            sb.append(stringValueOf(next));
-            if (iter.hasNext()) {
-                sb.append(delimiter);
-            }
-        }
-        return sb.toString();
-    }
-
-    private static String stringValueOf(Object next) {
-        if (next instanceof String) {
-            return '"' + ((String) next).replace("\"", "\\\"") + '"';
-        } else {
-            try {
-                return String.valueOf(next);
-            } catch (Throwable e) {
-                return "[toString failed]";
-            }
-        }
-    }
-}
diff --git a/src/main/java/au/id/zancanaro/PropertyTestRunner.java b/src/main/java/au/id/zancanaro/PropertyTestRunner.java
deleted file mode 100644
index ea36341..0000000
--- a/src/main/java/au/id/zancanaro/PropertyTestRunner.java
+++ /dev/null
@@ -1,249 +0,0 @@
-package au.id.zancanaro;
-
-import au.id.zancanaro.annotations.Property;
-import au.id.zancanaro.annotations.Seed;
-import org.junit.AssumptionViolatedException;
-import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.InitializationError;
-import org.junit.runners.model.Statement;
-import org.junit.runners.model.TestClass;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-
-public class PropertyTestRunner extends BlockJUnit4ClassRunner {
-    private final Map<Type, Generator<Object>> generators = new HashMap<>();
-
-    public PropertyTestRunner(Class<?> klass) throws InitializationError {
-        super(klass);
-    }
-
-    @Override
-    protected void collectInitializationErrors(List<Throwable> errors) {
-        super.collectInitializationErrors(errors);
-        validateGeneratorFields(errors);
-    }
-
-    private void validateGeneratorFields(List<Throwable> errors) {
-        Field[] fields = getTestClass().getJavaClass().getDeclaredFields();
-
-        for (Field field : fields) {
-            Type type = field.getGenericType();
-            if (!(type instanceof ParameterizedType)) {
-                continue;
-            }
-            ParameterizedType ptype = (ParameterizedType) type;
-            if (!(ptype.getRawType() instanceof Class)) {
-                continue;
-            }
-            Class<?> c = (Class) ptype.getRawType();
-            if (c != Generator.class) {
-                continue;
-            }
-            if (!Modifier.isStatic(field.getModifiers())) {
-                errors.add(new Error("Generator field " + field.getName() + " must be static"));
-            }
-            if (!Modifier.isPublic(field.getModifiers())) {
-                errors.add(new Error("Generator field " + field.getName() + " must be public"));
-            }
-        }
-    }
-
-    private static final Map<Type, Type> rawTypes;
-
-    static {
-        Map<Type, Type> types = new HashMap<>();
-        types.put(Double.class, Double.TYPE);
-        types.put(Float.class, Float.TYPE);
-        types.put(Long.class, Long.TYPE);
-        types.put(Integer.class, Integer.TYPE);
-        types.put(Short.class, Short.TYPE);
-        types.put(Byte.class, Byte.TYPE);
-        types.put(Character.class, Character.TYPE);
-        types.put(Boolean.class, Boolean.TYPE);
-        rawTypes = Collections.unmodifiableMap(types);
-    }
-
-    private Map<Type, Generator<Object>> computeGenerators() {
-        if (generators.isEmpty()) {
-            Field[] fields = getTestClass().getJavaClass().getDeclaredFields();
-
-            for (Field field : fields) {
-                Type type = field.getGenericType();
-                if (!(type instanceof ParameterizedType)) {
-                    continue;
-                }
-                ParameterizedType ptype = (ParameterizedType) type;
-                if (!(ptype.getRawType() instanceof Class)) {
-                    continue;
-                }
-                Class<?> c = (Class) ptype.getRawType();
-                if (c != Generator.class) {
-                    continue;
-                }
-                try {
-                    Type target = ptype.getActualTypeArguments()[0];
-                    @SuppressWarnings("unchecked")
-                    Generator<Object> generator = (Generator<Object>) field.get(null);
-                    generators.put(target, generator);
-                    if (rawTypes.containsKey(target)) {
-                        generators.put(rawTypes.get(target), generator);
-                    }
-                } catch (IllegalAccessException ex) {
-
-                }
-            }
-        }
-        return generators;
-    }
-
-    @Override
-    protected void validateConstructor(List<Throwable> errors) {
-        validateOnlyOneConstructor(errors);
-    }
-
-    @Override
-    protected void validateTestMethods(List<Throwable> errors) {
-        for (FrameworkMethod each : computeTestMethods()) {
-            if (each.getAnnotation(Property.class) != null) {
-                each.validatePublicVoid(false, errors);
-                each.validateNoTypeParametersOnArgs(errors);
-            } else {
-                each.validatePublicVoidNoArg(false, errors);
-            }
-        }
-    }
-
-    @Override
-    protected List<FrameworkMethod> computeTestMethods() {
-        List<FrameworkMethod> testMethods = new ArrayList<>(super.computeTestMethods());
-        List<FrameworkMethod> theoryMethods = getTestClass().getAnnotatedMethods(Property.class);
-        testMethods.removeAll(theoryMethods);
-        testMethods.addAll(theoryMethods);
-        return testMethods;
-    }
-
-    @Override
-    public Statement methodBlock(final FrameworkMethod method) {
-        return new GenerativeTester(method, getTestClass(), computeGenerators());
-    }
-
-    public static class GenerativeTester extends Statement {
-        private final FrameworkMethod testMethod;
-        private final TestClass testClass;
-        private final Map<Type, Generator<Object>> generators;
-
-        public GenerativeTester(FrameworkMethod testMethod, TestClass testClass, Map<Type, Generator<Object>> generators) {
-            this.testMethod = testMethod;
-            this.testClass = testClass;
-            this.generators = generators;
-        }
-
-        private long getSeed(Method method) {
-            Seed seed = method.getAnnotation(Seed.class);
-            if (seed == null) {
-                return System.currentTimeMillis();
-            } else {
-                return seed.value();
-            }
-        }
-
-        @Override
-        public void evaluate() throws Throwable {
-            Method method = testMethod.getMethod();
-            if (method.getParameterCount() == 0) {
-                runTest(new Object[0]);
-            } else {
-                @SuppressWarnings("unchecked")
-                Generator<Object>[] generators = (Generator<Object>[]) new Generator[method.getParameterCount()];
-                int index = 0;
-                for (Type type : method.getGenericParameterTypes()) {
-                    generators[index++] = this.generators.get(type);
-                }
-                Generator<Object[]> generator = Generator.tuple(generators);
-
-                long seed = getSeed(method);
-                Random random = new Random(seed);
-
-                Property property = testMethod.getAnnotation(Property.class);
-                int assumptionsViolated = 0;
-                int maxSize = property.maxSize();
-                int numTests = property.runs();
-                for (int i = 0; i < numTests; ++i) {
-                    int size = Math.min(i + 1, maxSize);
-                    RoseTree<Object[]> tree = generator.generate(random, size);
-                    try {
-                        runTest(tree.getValue());
-                        assumptionsViolated = 0;
-                    } catch (AssumptionViolatedException ex) {
-                        numTests++;
-                        if (assumptionsViolated++ == 50) {
-                            throw new Error("Violated 50 assumptions in a row: failing test");
-                        }
-                        ;
-                    } catch (Throwable ex) {
-                        throw new PropertyTestError(method.getName(), seed, shrink(tree, ex));
-                    }
-                }
-            }
-        }
-
-        private ShrinkResult shrink(RoseTree<Object[]> failed, Throwable originalEx) {
-            ShrinkResult smallest = new ShrinkResult(failed.getValue(), originalEx);
-            Iterator<RoseTree<Object[]>> trees = failed.getChildren();
-            Set<List<Object>> seenArgs = new HashSet<>();
-            while (trees.hasNext()) {
-                RoseTree<Object[]> tree = trees.next();
-                if (seenArgs.add(Arrays.asList(tree.getValue()))) {
-                    try {
-                        runTest(tree.getValue());
-                    } catch (AssumptionViolatedException ex) {
-                        // ignore, because it's not useful
-                    } catch (Throwable ex) {
-                        smallest = new ShrinkResult(tree.getValue(), ex);
-                        Iterator<RoseTree<Object[]>> children = tree.getChildren();
-                        if (children.hasNext()) {
-                            trees = children;
-                        } else {
-                            break;
-                        }
-                    }
-                }
-            }
-            return smallest;
-        }
-
-        public void runTest(final Object[] args) throws Throwable {
-            new BlockJUnit4ClassRunner(testClass.getJavaClass()) {
-                @Override
-                protected void collectInitializationErrors(
-                        List<Throwable> errors) {
-                    // do nothing
-                }
-
-                @Override
-                public Statement methodBlock(FrameworkMethod method) {
-                    return super.methodBlock(method);
-                }
-
-                @Override
-                protected Statement methodInvoker(FrameworkMethod method, Object test) {
-                    return new Statement() {
-                        @Override
-                        public void evaluate() throws Throwable {
-                            method.invokeExplosively(test, args);
-                        }
-                    };
-                }
-
-                @Override
-                public Object createTest() throws Exception {
-                    return getTestClass().getOnlyConstructor().newInstance();
-                }
-            }.methodBlock(testMethod).evaluate();
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/src/main/java/au/id/zancanaro/annotations/Generator.java b/src/main/java/au/id/zancanaro/annotations/Generator.java
deleted file mode 100644
index 98e9446..0000000
--- a/src/main/java/au/id/zancanaro/annotations/Generator.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package au.id.zancanaro.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Target;
-
-@Target(ElementType.PARAMETER)
-public @interface Generator {
-}
-- 
cgit v1.2.3