From 40961d4950c40643d5d71721a7e024e3951323ce Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro Date: Tue, 9 Jun 2015 23:31:54 +1000 Subject: Generalise the ObjectGeneration stuff The new ObjectGeneration stuff is now used to generate everything for a test case, which means it's all unified and "nice" now. Add a @UseGenerator annotation to be used to specify how to generate specific field values. Obviously, not everything can be generated magically, so if you specify a @DataSource in your test then it will be used in preference to any magically generated value. --- .../au/id/zancanaro/javacheck/object/CharType.java | 2 +- .../id/zancanaro/javacheck/object/DoubleRange.java | 2 +- .../javacheck/object/GeneratorProvider.java | 29 +++++++++++++++++++--- .../au/id/zancanaro/javacheck/object/IntRange.java | 2 +- .../id/zancanaro/javacheck/object/LongRange.java | 2 +- .../object/ObjectGenerationException.java | 4 +++ .../zancanaro/javacheck/object/UseGenerator.java | 14 +++++++++++ 7 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 src/main/java/au/id/zancanaro/javacheck/object/UseGenerator.java (limited to 'src/main/java/au/id/zancanaro/javacheck/object') diff --git a/src/main/java/au/id/zancanaro/javacheck/object/CharType.java b/src/main/java/au/id/zancanaro/javacheck/object/CharType.java index befbd04..aa3049e 100644 --- a/src/main/java/au/id/zancanaro/javacheck/object/CharType.java +++ b/src/main/java/au/id/zancanaro/javacheck/object/CharType.java @@ -5,7 +5,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Target(ElementType.FIELD) +@Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface CharType { public static enum TYPE { diff --git a/src/main/java/au/id/zancanaro/javacheck/object/DoubleRange.java b/src/main/java/au/id/zancanaro/javacheck/object/DoubleRange.java index ca7c9a9..08f8e3a 100644 --- a/src/main/java/au/id/zancanaro/javacheck/object/DoubleRange.java +++ b/src/main/java/au/id/zancanaro/javacheck/object/DoubleRange.java @@ -5,7 +5,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Target(ElementType.FIELD) +@Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface DoubleRange { double min(); 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 7e5964f..67769b6 100644 --- a/src/main/java/au/id/zancanaro/javacheck/object/GeneratorProvider.java +++ b/src/main/java/au/id/zancanaro/javacheck/object/GeneratorProvider.java @@ -1,8 +1,10 @@ package au.id.zancanaro.javacheck.object; +import au.id.zancanaro.javacheck.DataSourceHelper; import au.id.zancanaro.javacheck.Generator; import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; @@ -28,7 +30,14 @@ public interface GeneratorProvider { @Override public Generator getGenerator(Type type, Annotation[] annotations, GeneratorProvider provider) { - if (type == Integer.TYPE || type == Integer.class) { + UseGenerator generator = getAnnotation(annotations, UseGenerator.class); + if (generator != null) { + try { + return generator.value().getConstructor().newInstance(); + } catch (InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException ex) { + throw new ObjectGenerationException("Could not construct generator of type " + generator.value(), ex); + } + } else if (type == Integer.TYPE || type == Integer.class) { IntRange range = getAnnotation(annotations, IntRange.class); if (range == null) { return integer(); @@ -50,11 +59,11 @@ public interface GeneratorProvider { return doublePrecision(range.min(), range.max()); } } else if (type == String.class) { - CharType range = getAnnotation(annotations, CharType.class); - if (range == null) { + CharType charType = getAnnotation(annotations, CharType.class); + if (charType == null) { return string(); } else { - switch (range.value()) { + switch (charType.value()) { case ALPHA: return stringOf(alphaCharacter()); case ALPHA_NUMERIC: @@ -114,4 +123,16 @@ public interface GeneratorProvider { } }; } + + default GeneratorProvider withDataSources(Class wrappingType) { + DataSourceHelper helper = new DataSourceHelper(wrappingType); + Map> generators = helper.computeGenerators(); + return (type, annotations, provider) -> { + if (generators.containsKey(type)) { + return generators.get(type); + } else { + return this.getGenerator(type, annotations, provider); + } + }; + } } diff --git a/src/main/java/au/id/zancanaro/javacheck/object/IntRange.java b/src/main/java/au/id/zancanaro/javacheck/object/IntRange.java index 8dc3f28..5d2aa30 100644 --- a/src/main/java/au/id/zancanaro/javacheck/object/IntRange.java +++ b/src/main/java/au/id/zancanaro/javacheck/object/IntRange.java @@ -5,7 +5,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Target(ElementType.FIELD) +@Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface IntRange { int max(); diff --git a/src/main/java/au/id/zancanaro/javacheck/object/LongRange.java b/src/main/java/au/id/zancanaro/javacheck/object/LongRange.java index dd5a61f..dd5b8cf 100644 --- a/src/main/java/au/id/zancanaro/javacheck/object/LongRange.java +++ b/src/main/java/au/id/zancanaro/javacheck/object/LongRange.java @@ -5,7 +5,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -@Target(ElementType.FIELD) +@Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface LongRange { long max(); diff --git a/src/main/java/au/id/zancanaro/javacheck/object/ObjectGenerationException.java b/src/main/java/au/id/zancanaro/javacheck/object/ObjectGenerationException.java index d2147eb..444de32 100644 --- a/src/main/java/au/id/zancanaro/javacheck/object/ObjectGenerationException.java +++ b/src/main/java/au/id/zancanaro/javacheck/object/ObjectGenerationException.java @@ -8,4 +8,8 @@ public class ObjectGenerationException extends RuntimeException { public ObjectGenerationException(Throwable cause) { super(cause); } + + public ObjectGenerationException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/src/main/java/au/id/zancanaro/javacheck/object/UseGenerator.java b/src/main/java/au/id/zancanaro/javacheck/object/UseGenerator.java new file mode 100644 index 0000000..f62d978 --- /dev/null +++ b/src/main/java/au/id/zancanaro/javacheck/object/UseGenerator.java @@ -0,0 +1,14 @@ +package au.id.zancanaro.javacheck.object; + +import au.id.zancanaro.javacheck.Generator; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +public @interface UseGenerator { + Class value(); +} -- cgit v1.2.3