diff --git a/src/main/java/com/github/nylle/javafixture/ISpecimen.java b/src/main/java/com/github/nylle/javafixture/ISpecimen.java index 9376b2b..334fd50 100644 --- a/src/main/java/com/github/nylle/javafixture/ISpecimen.java +++ b/src/main/java/com/github/nylle/javafixture/ISpecimen.java @@ -6,5 +6,11 @@ public interface ISpecimen { T create(final CustomizationContext customizationContext, Annotation[] annotations); + interface IMeta { + + boolean supports(SpecimenType type); + + ISpecimen create(SpecimenType type, Context context, SpecimenFactory specimenFactory); + } } diff --git a/src/main/java/com/github/nylle/javafixture/SpecimenFactory.java b/src/main/java/com/github/nylle/javafixture/SpecimenFactory.java index b221f18..b5ca971 100644 --- a/src/main/java/com/github/nylle/javafixture/SpecimenFactory.java +++ b/src/main/java/com/github/nylle/javafixture/SpecimenFactory.java @@ -13,7 +13,21 @@ import com.github.nylle.javafixture.specimen.SpecialSpecimen; import com.github.nylle.javafixture.specimen.TimeSpecimen; +import java.util.List; + public class SpecimenFactory { + private final static List specimenCandidates = List.of( + SpecialSpecimen.meta(), + PrimitiveSpecimen.meta(), + EnumSpecimen.meta(), + CollectionSpecimen.meta(), + MapSpecimen.meta(), + GenericSpecimen.meta(), + ArraySpecimen.meta(), + TimeSpecimen.meta(), + InterfaceSpecimen.meta(), + AbstractSpecimen.meta() + ); private final Context context; @@ -21,57 +35,17 @@ public SpecimenFactory(Context context) { this.context = context; } - public ISpecimen build(final SpecimenType type) { + public ISpecimen build(SpecimenType type) { if (context.isCached(type)) { return new PredefinedSpecimen<>(type, context); } - if (type.isPrimitive() || type.isBoxed() || type.asClass() == String.class) { - return new PrimitiveSpecimen<>(type, context); - } - - if (type.isEnum()) { - return new EnumSpecimen<>(type); - } - - if (type.isCollection()) { - return new CollectionSpecimen<>(type, context, this); - } - - if (type.isMap()) { - return new MapSpecimen<>(type, context, this); - } - - if (type.isParameterized() && !type.isInterface() && !type.isAbstract()) { - return new GenericSpecimen<>(type, context, this); - } - - if (type.isParameterized() && (type.isInterface() || type.isAbstract())) { - return new GenericSpecimen<>(type, context, this); - } - - if (type.isArray()) { - return new ArraySpecimen<>(type, context, this); - } - - if (type.isTimeType()) { - return new TimeSpecimen<>(type, context); - } - - if (type.isInterface()) { - return new InterfaceSpecimen<>(type, context, this); - } - - if (type.isAbstract()) { - return new AbstractSpecimen<>(type, context, this); - } - - if (type.isSpecialType()) { - return new SpecialSpecimen<>(type, context); - } - - return new ObjectSpecimen<>(type, context, this); + return specimenCandidates.stream() + .filter(x -> x.supports(type)) + .map(x -> x.create(type, context, this)) + .findFirst() + .orElseGet(() -> new ObjectSpecimen<>(type, context, this)); } } diff --git a/src/main/java/com/github/nylle/javafixture/SpecimenType.java b/src/main/java/com/github/nylle/javafixture/SpecimenType.java index bebb6f2..0de24d5 100644 --- a/src/main/java/com/github/nylle/javafixture/SpecimenType.java +++ b/src/main/java/com/github/nylle/javafixture/SpecimenType.java @@ -6,10 +6,6 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; -import java.time.ZoneId; -import java.time.temporal.Temporal; -import java.time.temporal.TemporalAdjuster; -import java.time.temporal.TemporalAmount; import java.util.Collection; import java.util.List; import java.util.Map; @@ -143,50 +139,6 @@ public boolean isMap() { return Map.class.isAssignableFrom(asClass()); } - public boolean isTimeType() { - if (Temporal.class.isAssignableFrom(asClass())) { - return true; - } - - if (TemporalAdjuster.class.isAssignableFrom(asClass())) { - return true; - } - - if (TemporalAmount.class.isAssignableFrom(asClass())) { - return true; - } - - if (asClass().equals(ZoneId.class)) { - return true; - } - - if (asClass().equals(java.util.Date.class)) { - return true; - } - - if (asClass().equals(java.sql.Date.class)) { - return true; - } - - return false; - } - - public boolean isSpecialType() { - if (asClass().equals(java.math.BigInteger.class)) { - return true; - } - if (asClass().equals(java.math.BigDecimal.class)) { - return true; - } - if (asClass().equals(java.io.File.class)) { - return true; - } - if (asClass().equals(java.net.URI.class)) { - return true; - } - return false; - } - public boolean isPrimitive() { return asClass().isPrimitive(); } diff --git a/src/main/java/com/github/nylle/javafixture/specimen/AbstractSpecimen.java b/src/main/java/com/github/nylle/javafixture/specimen/AbstractSpecimen.java index eb83c19..7a9c7b3 100644 --- a/src/main/java/com/github/nylle/javafixture/specimen/AbstractSpecimen.java +++ b/src/main/java/com/github/nylle/javafixture/specimen/AbstractSpecimen.java @@ -20,7 +20,7 @@ public class AbstractSpecimen implements ISpecimen { private final SpecimenFactory specimenFactory; private final InstanceFactory instanceFactory; - public AbstractSpecimen(final SpecimenType type, final Context context, final SpecimenFactory specimenFactory) { + public AbstractSpecimen(SpecimenType type, Context context, SpecimenFactory specimenFactory) { if (type == null) { throw new IllegalArgumentException("type: null"); @@ -34,7 +34,7 @@ public AbstractSpecimen(final SpecimenType type, final Context context, final throw new IllegalArgumentException("specimenFactory: null"); } - if (!type.isAbstract() || type.isMap() || type.isCollection()) { + if (!supportsType(type)) { throw new IllegalArgumentException("type: " + type.getName()); } @@ -44,6 +44,24 @@ public AbstractSpecimen(final SpecimenType type, final Context context, final this.instanceFactory = new InstanceFactory(specimenFactory); } + public static boolean supportsType(SpecimenType type) { + return type.isAbstract() && !type.isMap() && !type.isCollection(); + } + + public static IMeta meta() { + return new IMeta() { + @Override + public boolean supports(SpecimenType type) { + return supportsType(type); + } + + @Override + public ISpecimen create(SpecimenType type, Context context, SpecimenFactory specimenFactory) { + return new AbstractSpecimen<>(type, context, specimenFactory); + } + }; + } + @Override public T create(final CustomizationContext customizationContext, Annotation[] annotations) { if (context.isCached(type)) { diff --git a/src/main/java/com/github/nylle/javafixture/specimen/ArraySpecimen.java b/src/main/java/com/github/nylle/javafixture/specimen/ArraySpecimen.java index ea94dae..94af303 100644 --- a/src/main/java/com/github/nylle/javafixture/specimen/ArraySpecimen.java +++ b/src/main/java/com/github/nylle/javafixture/specimen/ArraySpecimen.java @@ -15,7 +15,7 @@ public class ArraySpecimen implements ISpecimen { private final Context context; private final SpecimenFactory specimenFactory; - public ArraySpecimen(final SpecimenType type, Context context, SpecimenFactory specimenFactory) { + public ArraySpecimen(SpecimenType type, Context context, SpecimenFactory specimenFactory) { if (type == null) { throw new IllegalArgumentException("type: null"); } @@ -28,7 +28,7 @@ public ArraySpecimen(final SpecimenType type, Context context, SpecimenFactor throw new IllegalArgumentException("specimenFactory: null"); } - if (!type.isArray()) { + if (!supportsType(type)) { throw new IllegalArgumentException("type: " + type.getName()); } @@ -37,8 +37,26 @@ public ArraySpecimen(final SpecimenType type, Context context, SpecimenFactor this.specimenFactory = specimenFactory; } + public static boolean supportsType(SpecimenType type) { + return type.isArray(); + } + + public static IMeta meta() { + return new IMeta() { + @Override + public boolean supports(SpecimenType type) { + return supportsType(type); + } + + @Override + public ISpecimen create(SpecimenType type, Context context, SpecimenFactory specimenFactory) { + return new ArraySpecimen<>(type, context, specimenFactory); + } + }; + } + @Override - public T create(final CustomizationContext customizationContext, Annotation[] annotations) { + public T create(CustomizationContext customizationContext, Annotation[] annotations) { if (context.isCached(type)) { return context.cached(type); } diff --git a/src/main/java/com/github/nylle/javafixture/specimen/CollectionSpecimen.java b/src/main/java/com/github/nylle/javafixture/specimen/CollectionSpecimen.java index 0a4b890..f15df88 100644 --- a/src/main/java/com/github/nylle/javafixture/specimen/CollectionSpecimen.java +++ b/src/main/java/com/github/nylle/javafixture/specimen/CollectionSpecimen.java @@ -21,7 +21,7 @@ public class CollectionSpecimen implements ISpecimen { private ISpecimen specimen; private final InstanceFactory instanceFactory; - public CollectionSpecimen(final SpecimenType type, final Context context, final SpecimenFactory specimenFactory) { + public CollectionSpecimen(SpecimenType type, Context context, SpecimenFactory specimenFactory) { if (type == null) { throw new IllegalArgumentException("type: null"); @@ -35,7 +35,7 @@ public CollectionSpecimen(final SpecimenType type, final Context context, fin throw new IllegalArgumentException("specimenFactory: null"); } - if (!type.isCollection()) { + if (!supportsType(type)) { throw new IllegalArgumentException("type: " + type.getName()); } @@ -48,6 +48,24 @@ public CollectionSpecimen(final SpecimenType type, final Context context, fin this.instanceFactory = new InstanceFactory(specimenFactory); } + public static boolean supportsType(SpecimenType type) { + return type.isCollection(); + } + + public static IMeta meta() { + return new IMeta() { + @Override + public boolean supports(SpecimenType type) { + return supportsType(type); + } + + @Override + public ISpecimen create(SpecimenType type, Context context, SpecimenFactory specimenFactory) { + return new CollectionSpecimen<>(type, context, specimenFactory); + } + }; + } + @Override public T create(final CustomizationContext customizationContext, Annotation[] annotations) { if (context.isCached(type)) { diff --git a/src/main/java/com/github/nylle/javafixture/specimen/EnumSpecimen.java b/src/main/java/com/github/nylle/javafixture/specimen/EnumSpecimen.java index 358231b..d31ca98 100644 --- a/src/main/java/com/github/nylle/javafixture/specimen/EnumSpecimen.java +++ b/src/main/java/com/github/nylle/javafixture/specimen/EnumSpecimen.java @@ -1,7 +1,9 @@ package com.github.nylle.javafixture.specimen; +import com.github.nylle.javafixture.Context; import com.github.nylle.javafixture.CustomizationContext; import com.github.nylle.javafixture.ISpecimen; +import com.github.nylle.javafixture.SpecimenFactory; import com.github.nylle.javafixture.SpecimenType; import java.lang.annotation.Annotation; @@ -12,13 +14,13 @@ public class EnumSpecimen implements ISpecimen { private final SpecimenType type; private final Random random; - public EnumSpecimen(final SpecimenType type) { + public EnumSpecimen(SpecimenType type) { if (type == null) { throw new IllegalArgumentException("type: null"); } - if (!type.isEnum()) { + if (!supportsType(type)) { throw new IllegalArgumentException("type: " + type.getName()); } @@ -26,6 +28,24 @@ public EnumSpecimen(final SpecimenType type) { this.random = new Random(); } + public static boolean supportsType(SpecimenType type) { + return type.isEnum(); + } + + public static IMeta meta() { + return new IMeta() { + @Override + public boolean supports(SpecimenType type) { + return supportsType(type); + } + + @Override + public ISpecimen create(SpecimenType type, Context context, SpecimenFactory specimenFactory) { + return new EnumSpecimen<>(type); + } + }; + } + @Override public T create(CustomizationContext customizationContext, Annotation[] annotations) { return type.getEnumConstants()[random.nextInt(type.getEnumConstants().length)]; diff --git a/src/main/java/com/github/nylle/javafixture/specimen/GenericSpecimen.java b/src/main/java/com/github/nylle/javafixture/specimen/GenericSpecimen.java index 8e49e3d..14126f7 100644 --- a/src/main/java/com/github/nylle/javafixture/specimen/GenericSpecimen.java +++ b/src/main/java/com/github/nylle/javafixture/specimen/GenericSpecimen.java @@ -31,16 +31,12 @@ public GenericSpecimen(SpecimenType type, Context context, SpecimenFactory sp throw new IllegalArgumentException("context: null"); } - if (specimenFactory == null) { - throw new IllegalArgumentException("specimenFactory: null"); - } - - if (!type.isParameterized()) { + if (!supportsType(type)) { throw new IllegalArgumentException("type: " + type.getName()); } - if (type.isCollection() || type.isMap()) { - throw new IllegalArgumentException("type: " + type.getName()); + if (specimenFactory == null) { + throw new IllegalArgumentException("specimenFactory: null"); } this.type = type; @@ -50,6 +46,24 @@ public GenericSpecimen(SpecimenType type, Context context, SpecimenFactory sp this.specimens = type.getTypeParameterNamesAndTypes(x -> specimenFactory.build(x)); } + public static boolean supportsType(SpecimenType type) { + return type.isParameterized() && !type.isCollection() && !type.isMap(); + } + + public static IMeta meta() { + return new IMeta() { + @Override + public boolean supports(SpecimenType type) { + return supportsType(type); + } + + @Override + public ISpecimen create(SpecimenType type, Context context, SpecimenFactory specimenFactory) { + return new GenericSpecimen<>(type, context, specimenFactory); + } + }; + } + @Override public T create(CustomizationContext customizationContext, Annotation[] annotations) { if (type.asClass().equals(Class.class)) { @@ -61,6 +75,7 @@ public T create(CustomizationContext customizationContext, Annotation[] annotati } if (type.isInterface()) { + //TODO: shouldn't this be covered by InterfaceSpecimen? return (T) instanceFactory.proxy(type, specimens); } diff --git a/src/main/java/com/github/nylle/javafixture/specimen/InterfaceSpecimen.java b/src/main/java/com/github/nylle/javafixture/specimen/InterfaceSpecimen.java index bc18ced..7945588 100644 --- a/src/main/java/com/github/nylle/javafixture/specimen/InterfaceSpecimen.java +++ b/src/main/java/com/github/nylle/javafixture/specimen/InterfaceSpecimen.java @@ -15,7 +15,7 @@ public class InterfaceSpecimen implements ISpecimen { private final Context context; private final InstanceFactory instanceFactory; - public InterfaceSpecimen(final SpecimenType type, final Context context, final SpecimenFactory specimenFactory) { + public InterfaceSpecimen(SpecimenType type, Context context, SpecimenFactory specimenFactory) { if (type == null) { throw new IllegalArgumentException("type: null"); @@ -29,7 +29,7 @@ public InterfaceSpecimen(final SpecimenType type, final Context context, fina throw new IllegalArgumentException("specimenFactory: null"); } - if (!type.isInterface() || type.isMap() || type.isCollection()) { + if (!supportsType(type)) { throw new IllegalArgumentException("type: " + type.getName()); } @@ -38,6 +38,24 @@ public InterfaceSpecimen(final SpecimenType type, final Context context, fina this.instanceFactory = new InstanceFactory(specimenFactory); } + public static boolean supportsType(SpecimenType type) { + return type.isInterface() && !type.isMap() && !type.isCollection(); + } + + public static IMeta meta() { + return new IMeta() { + @Override + public boolean supports(SpecimenType type) { + return supportsType(type); + } + + @Override + public ISpecimen create(SpecimenType type, Context context, SpecimenFactory specimenFactory) { + return new InterfaceSpecimen<>(type, context, specimenFactory); + } + }; + } + @Override public T create(final CustomizationContext customizationContext, Annotation[] annotations) { return (T) instanceFactory.proxy(type); diff --git a/src/main/java/com/github/nylle/javafixture/specimen/MapSpecimen.java b/src/main/java/com/github/nylle/javafixture/specimen/MapSpecimen.java index d3196ed..36d7416 100644 --- a/src/main/java/com/github/nylle/javafixture/specimen/MapSpecimen.java +++ b/src/main/java/com/github/nylle/javafixture/specimen/MapSpecimen.java @@ -27,7 +27,7 @@ public class MapSpecimen implements ISpecimen { private ISpecimen keySpecimen; private ISpecimen valueSpecimen; - public MapSpecimen(final SpecimenType type, final Context context, final SpecimenFactory specimenFactory) { + public MapSpecimen(SpecimenType type, Context context, SpecimenFactory specimenFactory) { if (type == null) { throw new IllegalArgumentException("type: null"); @@ -41,7 +41,7 @@ public MapSpecimen(final SpecimenType type, final Context context, final Spec throw new IllegalArgumentException("specimenFactory: null"); } - if (!type.isMap()) { + if (!supportsType(type)) { throw new IllegalArgumentException("type: " + type.getName()); } @@ -54,8 +54,26 @@ public MapSpecimen(final SpecimenType type, final Context context, final Spec } } + public static boolean supportsType(SpecimenType type) { + return type.isMap(); + } + + public static IMeta meta() { + return new IMeta() { + @Override + public boolean supports(SpecimenType type) { + return supportsType(type); + } + + @Override + public ISpecimen create(SpecimenType type, Context context, SpecimenFactory specimenFactory) { + return new MapSpecimen<>(type, context, specimenFactory); + } + }; + } + @Override - public T create(final CustomizationContext customizationContext, Annotation[] annotations) { + public T create(CustomizationContext customizationContext, Annotation[] annotations) { if (context.isCached(type)) { return context.cached(type); } @@ -107,5 +125,4 @@ private Map createFromInterfaceType(final Class type) { throw new SpecimenException("Unsupported type: " + type); } - } diff --git a/src/main/java/com/github/nylle/javafixture/specimen/PrimitiveSpecimen.java b/src/main/java/com/github/nylle/javafixture/specimen/PrimitiveSpecimen.java index 27d175a..7b29a3e 100644 --- a/src/main/java/com/github/nylle/javafixture/specimen/PrimitiveSpecimen.java +++ b/src/main/java/com/github/nylle/javafixture/specimen/PrimitiveSpecimen.java @@ -6,6 +6,7 @@ import com.github.nylle.javafixture.ISpecimen; import com.github.nylle.javafixture.PseudoRandom; import com.github.nylle.javafixture.SpecimenException; +import com.github.nylle.javafixture.SpecimenFactory; import com.github.nylle.javafixture.SpecimenType; import com.github.nylle.javafixture.specimen.constraints.StringConstraints; @@ -17,13 +18,13 @@ public class PrimitiveSpecimen implements ISpecimen { private final PseudoRandom pseudoRandom; private final Configuration configuration; - public PrimitiveSpecimen(final SpecimenType type, final Context context) { + public PrimitiveSpecimen(SpecimenType type, Context context) { if (type == null) { throw new IllegalArgumentException("type: null"); } - if (!type.isPrimitive() && !type.isBoxed() && type.asClass() != String.class) { + if (!supportsType(type)) { throw new IllegalArgumentException("type: " + type.getName()); } @@ -36,8 +37,26 @@ public PrimitiveSpecimen(final SpecimenType type, final Context context) { this.configuration = context.getConfiguration(); } + public static boolean supportsType(SpecimenType type) { + return type.isPrimitive() || type.isBoxed() || type.asClass() == String.class; + } + + public static IMeta meta() { + return new IMeta() { + @Override + public boolean supports(SpecimenType type) { + return supportsType(type); + } + + @Override + public ISpecimen create(SpecimenType type, Context context, SpecimenFactory specimenFactory) { + return new PrimitiveSpecimen<>(type, context); + } + }; + } + @Override - public T create(final CustomizationContext customizationContext, Annotation[] annotations) { + public T create(CustomizationContext customizationContext, Annotation[] annotations) { if (type.asClass().equals(String.class)) { StringConstraints constraints = getStringConstraints(annotations); return (T) pseudoRandom.nextString(constraints); @@ -85,12 +104,12 @@ private StringConstraints getStringConstraints(Annotation[] annotations) { case "jakarta.persistence.Column": constraints = new StringConstraints(0, ((jakarta.persistence.Column) annotation).length()); break; - case "jakarta.validation.constraints.Size": - constraints = new StringConstraints(((jakarta.validation.constraints.Size) annotation).min(), ((jakarta.validation.constraints.Size) annotation).max()); - break; case "javax.persistence.Column": constraints = new StringConstraints(0, ((javax.persistence.Column) annotation).length()); break; + case "jakarta.validation.constraints.Size": + constraints = new StringConstraints(((jakarta.validation.constraints.Size) annotation).min(), ((jakarta.validation.constraints.Size) annotation).max()); + break; case "javax.validation.constraints.Size": constraints = new StringConstraints(((javax.validation.constraints.Size) annotation).min(), ((javax.validation.constraints.Size) annotation).max()); break; diff --git a/src/main/java/com/github/nylle/javafixture/specimen/SpecialSpecimen.java b/src/main/java/com/github/nylle/javafixture/specimen/SpecialSpecimen.java index 420ad50..c255999 100644 --- a/src/main/java/com/github/nylle/javafixture/specimen/SpecialSpecimen.java +++ b/src/main/java/com/github/nylle/javafixture/specimen/SpecialSpecimen.java @@ -4,6 +4,7 @@ import com.github.nylle.javafixture.CustomizationContext; import com.github.nylle.javafixture.ISpecimen; import com.github.nylle.javafixture.PseudoRandom; +import com.github.nylle.javafixture.SpecimenFactory; import com.github.nylle.javafixture.SpecimenType; import java.io.File; @@ -12,21 +13,28 @@ import java.math.BigInteger; import java.net.URI; import java.net.URISyntaxException; +import java.util.Map; import java.util.Random; import java.util.UUID; +import java.util.function.Function; public class SpecialSpecimen implements ISpecimen { - private static final int MAXIMUM_BITLENGTH_FOR_RANDOM_BIGINT = 1024; + private final static int MAXIMUM_BITLENGTH_FOR_RANDOM_BIGINT = 1024; + private final static Map, Function> creators = Map.of( + File.class, x -> new File(UUID.randomUUID().toString()), + BigInteger.class, bigInteger(), + BigDecimal.class, bigDecimal(), + URI.class, uri()); + private final SpecimenType type; private final Context context; - public SpecialSpecimen(SpecimenType type, Context context) { if (type == null) { throw new IllegalArgumentException("type: null"); } - if (!type.isSpecialType()) { + if (!supportsType(type)) { throw new IllegalArgumentException("type: " + type.getName()); } @@ -38,40 +46,57 @@ public SpecialSpecimen(SpecimenType type, Context context) { this.context = context; } + public static boolean supportsType(SpecimenType type) { + return creators.containsKey(type.asClass()); + } + + public static IMeta meta() { + return new IMeta() { + @Override + public boolean supports(SpecimenType type) { + return supportsType(type); + } + + @Override + public ISpecimen create(SpecimenType type, Context context, SpecimenFactory specimenFactory) { + return new SpecialSpecimen<>(type, context); + } + }; + } + @Override public T create(CustomizationContext customizationContext, Annotation[] annotations) { - if (type.asClass().equals(File.class)) { - return (T) new File(UUID.randomUUID().toString()); - } - if (type.asClass().equals(BigInteger.class)) { - return (T) createBigInteger(); - } - if (type.asClass().equals(BigDecimal.class)) { - return (T) createBigDecimal(); - } - try { - return (T) new URI("https://localhost/" + UUID.randomUUID()); - } catch (URISyntaxException e) { - return null; - } + return (T) creators.get(type.asClass()).apply(context); } - private BigInteger createBigInteger() { - var rnd = new Random(); - var result = new BigInteger(rnd.nextInt(MAXIMUM_BITLENGTH_FOR_RANDOM_BIGINT), new Random()); - if (!context.getConfiguration().usePositiveNumbersOnly()) { - if (rnd.nextBoolean()) { // negate randomly - return result.negate(); + private static Function bigInteger() { + return context -> { + var rnd = new Random(); + var result = new BigInteger(rnd.nextInt(MAXIMUM_BITLENGTH_FOR_RANDOM_BIGINT), new Random()); + if (context.getConfiguration().usePositiveNumbersOnly()) { + return result; } - } - return result; + return rnd.nextBoolean() ? result.negate() : result; // negate randomly + }; } - private BigDecimal createBigDecimal() { - var bd = new BigDecimal(new PseudoRandom().nextLong(new Random().nextBoolean())); - if (context.getConfiguration().usePositiveNumbersOnly()) { - return bd.abs(); - } - return bd; + private static Function bigDecimal() { + return context -> { + var result = new BigDecimal(new PseudoRandom().nextLong(new Random().nextBoolean())); + if (context.getConfiguration().usePositiveNumbersOnly()) { + return result.abs(); + } + return result; + }; + } + + private static Function uri() { + return x -> { + try { + return new URI("https://localhost/" + UUID.randomUUID()); + } catch (URISyntaxException e) { + return null; + } + }; } } diff --git a/src/main/java/com/github/nylle/javafixture/specimen/TimeSpecimen.java b/src/main/java/com/github/nylle/javafixture/specimen/TimeSpecimen.java index 5eb4a02..bd366f0 100644 --- a/src/main/java/com/github/nylle/javafixture/specimen/TimeSpecimen.java +++ b/src/main/java/com/github/nylle/javafixture/specimen/TimeSpecimen.java @@ -4,6 +4,7 @@ import com.github.nylle.javafixture.CustomizationContext; import com.github.nylle.javafixture.ISpecimen; import com.github.nylle.javafixture.SpecimenException; +import com.github.nylle.javafixture.SpecimenFactory; import com.github.nylle.javafixture.SpecimenType; import java.lang.annotation.Annotation; @@ -18,6 +19,8 @@ import java.time.ZoneOffset; import java.time.chrono.JapaneseEra; import java.time.temporal.Temporal; +import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalAmount; import java.util.Random; public class TimeSpecimen implements ISpecimen { @@ -26,12 +29,12 @@ public class TimeSpecimen implements ISpecimen { private final Random random; private final Context context; - public TimeSpecimen(final SpecimenType type, final Context context) { + public TimeSpecimen(SpecimenType type, Context context) { if (type == null) { throw new IllegalArgumentException("type: null"); } - if (!type.isTimeType()) { + if (!supportsType(type)) { throw new IllegalArgumentException("type: " + type.getName()); } @@ -44,6 +47,48 @@ public TimeSpecimen(final SpecimenType type, final Context context) { this.context = context; } + public static boolean supportsType(SpecimenType type) { + if (Temporal.class.isAssignableFrom(type.asClass())) { + return true; + } + + if (TemporalAdjuster.class.isAssignableFrom(type.asClass())) { + return true; + } + + if (TemporalAmount.class.isAssignableFrom(type.asClass())) { + return true; + } + + if (type.asClass().equals(ZoneId.class)) { + return true; + } + + if (type.asClass().equals(java.util.Date.class)) { + return true; + } + + if (type.asClass().equals(java.sql.Date.class)) { + return true; + } + + return false; + } + + public static IMeta meta() { + return new IMeta() { + @Override + public boolean supports(SpecimenType type) { + return supportsType(type); + } + + @Override + public ISpecimen create(SpecimenType type, Context context, SpecimenFactory specimenFactory) { + return new TimeSpecimen<>(type, context); + } + }; + } + @Override public T create(final CustomizationContext customizationContext, Annotation[] annotations) { if (Temporal.class.isAssignableFrom(type.asClass())) { diff --git a/src/test/java/com/github/nylle/javafixture/SpecimenTypeTest.java b/src/test/java/com/github/nylle/javafixture/SpecimenTypeTest.java index c969be9..49bacde 100644 --- a/src/test/java/com/github/nylle/javafixture/SpecimenTypeTest.java +++ b/src/test/java/com/github/nylle/javafixture/SpecimenTypeTest.java @@ -14,21 +14,8 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import java.io.File; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.URI; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.time.MonthDay; -import java.time.Period; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.chrono.JapaneseEra; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -229,54 +216,6 @@ void isAbstract() { assertThat(SpecimenType.fromClass(TestAbstractClass.class).isAbstract()).isTrue(); } - @Test - void isTimeType() { - assertThat(new SpecimenType() {}.isTimeType()).isFalse(); // false - assertThat(new SpecimenType() {}.isTimeType()).isTrue(); - assertThat(new SpecimenType() {}.isTimeType()).isTrue(); - assertThat(new SpecimenType() {}.isTimeType()).isTrue(); - assertThat(new SpecimenType() {}.isTimeType()).isTrue(); - assertThat(new SpecimenType() {}.isTimeType()).isTrue(); - assertThat(new SpecimenType() {}.isTimeType()).isTrue(); - assertThat(new SpecimenType() {}.isTimeType()).isTrue(); - } - - @TestWithCases - @TestCase(class1 = String.class, bool2 = false) - @TestCase(class1 = Duration.class, bool2 = true) - @TestCase(class1 = JapaneseEra.class, bool2 = true) - @TestCase(class1 = MonthDay.class, bool2 = true) - @TestCase(class1 = Period.class, bool2 = true) - @TestCase(class1 = ZoneId.class, bool2 = true) - @TestCase(class1 = ZoneOffset.class, bool2 = true) - @TestCase(class1 = ZonedDateTime.class, bool2 = true) - @TestCase(class1 = Instant.class, bool2 = true) - @TestCase(class1 = LocalDate.class, bool2 = true) - @TestCase(class1 = java.util.Date.class, bool2 = true) - @TestCase(class1 = java.sql.Date.class, bool2 = true) - void isTimeTypeFromClass(Class value, boolean expected) { - assertThat(SpecimenType.fromClass(value).isTimeType()).isEqualTo(expected); - } - - @Test - void isSpecialType() { - assertThat(new SpecimenType() {}.isSpecialType()).isFalse(); // false - assertThat(new SpecimenType() {}.isSpecialType()).isTrue(); - assertThat(new SpecimenType() {}.isSpecialType()).isTrue(); - assertThat(new SpecimenType() {}.isSpecialType()).isTrue(); - assertThat(new SpecimenType() {}.isSpecialType()).isTrue(); - } - - @TestWithCases - @TestCase(class1 = String.class, bool2 = false) - @TestCase(class1 = File.class, bool2 = true) - @TestCase(class1 = URI.class, bool2 = true) - @TestCase(class1 = BigInteger.class, bool2 = true) - @TestCase(class1 = BigDecimal.class, bool2 = true) - void isSpecialTypeFromClass(Class value, boolean expected) { - assertThat(SpecimenType.fromClass(value).isSpecialType()).isEqualTo(expected); - } - @Test void getGenericTypeArgument() { var sut = new SpecimenType>>() {}; diff --git a/src/test/java/com/github/nylle/javafixture/specimen/AbstractSpecimenTest.java b/src/test/java/com/github/nylle/javafixture/specimen/AbstractSpecimenTest.java index 5625177..81c3dc6 100644 --- a/src/test/java/com/github/nylle/javafixture/specimen/AbstractSpecimenTest.java +++ b/src/test/java/com/github/nylle/javafixture/specimen/AbstractSpecimenTest.java @@ -5,7 +5,10 @@ import com.github.nylle.javafixture.SpecimenException; import com.github.nylle.javafixture.SpecimenFactory; import com.github.nylle.javafixture.SpecimenType; +import com.github.nylle.javafixture.annotations.testcases.TestCase; +import com.github.nylle.javafixture.annotations.testcases.TestWithCases; import com.github.nylle.javafixture.testobjects.TestAbstractClass; +import com.github.nylle.javafixture.testobjects.abstractclasses.AbstractClassWithAbstractImplementation; import com.github.nylle.javafixture.testobjects.abstractclasses.AbstractClassWithConcreteMethod; import com.github.nylle.javafixture.testobjects.abstractclasses.AbstractClassWithConstructorException; import com.github.nylle.javafixture.testobjects.interfaces.InterfaceWithoutImplementation; @@ -156,5 +159,36 @@ void resultIsNotCached() { assertThat(original.toString()).isNotEqualTo(second.toString()); assertThat(original.getString()).isNotEqualTo(second.getString()); } + + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = AbstractClassWithAbstractImplementation.class, bool2 = true) + void supportsType(Class type, boolean expected) { + assertThat(AbstractSpecimen.supportsType(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Nested + class SpecTest { + + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = AbstractClassWithAbstractImplementation.class, bool2 = true) + void supports(Class type, boolean expected) { + assertThat(AbstractSpecimen.meta().supports(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Test + void createReturnsNewSpecimen() { + assertThat(AbstractSpecimen.meta().create(SpecimenType.fromClass(AbstractClassWithAbstractImplementation.class), context, specimenFactory)) + .isInstanceOf(AbstractSpecimen.class); + } + + @Test + void createThrows() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> AbstractSpecimen.meta().create(SpecimenType.fromClass(String.class), context, specimenFactory)) + .withMessageContaining("type: java.lang.String"); + } + } } diff --git a/src/test/java/com/github/nylle/javafixture/specimen/ArraySpecimenTest.java b/src/test/java/com/github/nylle/javafixture/specimen/ArraySpecimenTest.java index 26602b2..9551cf7 100644 --- a/src/test/java/com/github/nylle/javafixture/specimen/ArraySpecimenTest.java +++ b/src/test/java/com/github/nylle/javafixture/specimen/ArraySpecimenTest.java @@ -4,8 +4,11 @@ import com.github.nylle.javafixture.Context; import com.github.nylle.javafixture.SpecimenFactory; import com.github.nylle.javafixture.SpecimenType; +import com.github.nylle.javafixture.annotations.testcases.TestCase; +import com.github.nylle.javafixture.annotations.testcases.TestWithCases; import com.github.nylle.javafixture.testobjects.example.AccountManager; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.lang.annotation.Annotation; @@ -14,6 +17,7 @@ import static com.github.nylle.javafixture.CustomizationContext.noContext; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; class ArraySpecimenTest { @@ -27,32 +31,43 @@ void setup() { specimenFactory = new SpecimenFactory(context); } - @Test - void onlyArrayTypes() { - assertThatThrownBy(() -> new ArraySpecimen<>(SpecimenType.fromClass(Map.class), context, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: " + Map.class.getName()); - } - - @Test - void typeIsRequired() { - assertThatThrownBy(() -> new ArraySpecimen<>((SpecimenType) null, context, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: null"); - } - - @Test - void contextIsRequired() { - assertThatThrownBy(() -> new ArraySpecimen<>(SpecimenType.fromClass(int[].class), null, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("context: null"); + @Nested + class WhenConstructing { + + @Test + void onlyArrayTypes() { + assertThatThrownBy(() -> new ArraySpecimen<>(SpecimenType.fromClass(Map.class), context, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: " + Map.class.getName()); + } + + @Test + void typeIsRequired() { + assertThatThrownBy(() -> new ArraySpecimen<>((SpecimenType) null, context, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: null"); + } + + @Test + void contextIsRequired() { + assertThatThrownBy(() -> new ArraySpecimen<>(SpecimenType.fromClass(int[].class), null, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("context: null"); + } + + @Test + void specimenFactoryIsRequired() { + assertThatThrownBy(() -> new ArraySpecimen<>(SpecimenType.fromClass(int[].class), context, null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("specimenFactory: null"); + } } - @Test - void specimenFactoryIsRequired() { - assertThatThrownBy(() -> new ArraySpecimen<>(SpecimenType.fromClass(int[].class), context, null)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("specimenFactory: null"); + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = int[].class, bool2 = true) + void supportsType(Class type, boolean expected) { + assertThat(ArraySpecimen.supportsType(SpecimenType.fromClass(type))).isEqualTo(expected); } @Test @@ -98,4 +113,30 @@ void createdArraysAreNotCached() { assertThat(Arrays.asList(actual)).doesNotContainAnyElementsOf(Arrays.asList(second)); } + + @Nested + class SpecTest { + + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = int[].class, bool2 = true) + void supports(Class type, boolean expected) { + assertThat(ArraySpecimen.meta().supports(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @TestWithCases + @TestCase(class1 = int[].class) + @TestCase(class1 = Object[].class) + void createReturnsNewSpecimen(Class type) { + assertThat(ArraySpecimen.meta().create(SpecimenType.fromClass(type), context, specimenFactory)) + .isInstanceOf(ArraySpecimen.class); + } + + @Test + void createThrows() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> ArraySpecimen.meta().create(SpecimenType.fromClass(String.class), context, specimenFactory)) + .withMessageContaining("type: java.lang.String"); + } + } } diff --git a/src/test/java/com/github/nylle/javafixture/specimen/CollectionSpecimenTest.java b/src/test/java/com/github/nylle/javafixture/specimen/CollectionSpecimenTest.java index 0a5c53d..9bd11e6 100644 --- a/src/test/java/com/github/nylle/javafixture/specimen/CollectionSpecimenTest.java +++ b/src/test/java/com/github/nylle/javafixture/specimen/CollectionSpecimenTest.java @@ -4,9 +4,12 @@ import com.github.nylle.javafixture.Context; import com.github.nylle.javafixture.SpecimenFactory; import com.github.nylle.javafixture.SpecimenType; +import com.github.nylle.javafixture.annotations.testcases.TestCase; +import com.github.nylle.javafixture.annotations.testcases.TestWithCases; import com.github.nylle.javafixture.testobjects.TestEnum; import com.github.nylle.javafixture.testobjects.TestObject; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.lang.annotation.Annotation; @@ -33,6 +36,7 @@ import static com.github.nylle.javafixture.CustomizationContext.noContext; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; class CollectionSpecimenTest { @@ -46,32 +50,36 @@ void setup() { specimenFactory = new SpecimenFactory(context); } - @Test - void onlyCollectionTypes() { - assertThatThrownBy(() -> new CollectionSpecimen<>(SpecimenType.fromClass(Map.class), context, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: " + Map.class.getName()); - } - - @Test - void typeIsRequired() { - assertThatThrownBy(() -> new CollectionSpecimen<>(null, context, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: null"); - } - - @Test - void contextIsRequired() { - assertThatThrownBy(() -> new CollectionSpecimen<>(SpecimenType.fromClass(List.class), null, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("context: null"); - } - - @Test - void specimenFactoryIsRequired() { - assertThatThrownBy(() -> new CollectionSpecimen<>(SpecimenType.fromClass(List.class), context, null)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("specimenFactory: null"); + @Nested + class WhenConstructing { + + @Test + void onlyCollectionTypesAreAllowed() { + assertThatThrownBy(() -> new CollectionSpecimen<>(SpecimenType.fromClass(Map.class), context, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: " + Map.class.getName()); + } + + @Test + void typeIsRequired() { + assertThatThrownBy(() -> new CollectionSpecimen<>(null, context, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: null"); + } + + @Test + void contextIsRequired() { + assertThatThrownBy(() -> new CollectionSpecimen<>(SpecimenType.fromClass(List.class), null, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("context: null"); + } + + @Test + void specimenFactoryIsRequired() { + assertThatThrownBy(() -> new CollectionSpecimen<>(SpecimenType.fromClass(List.class), context, null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("specimenFactory: null"); + } } @Test @@ -336,4 +344,39 @@ void nonPrimitiveElementsAreNotCached() { assertThat(actual.get(0)).isNotEqualTo(actual.get(1)); } + + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = Map.class, bool2 = false) + @TestCase(class1 = Collection.class, bool2 = true) + @TestCase(class1 = List.class, bool2 = true) + void supportsType(Class type, boolean expected) { + assertThat(CollectionSpecimen.supportsType(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Nested + class SpecTest { + + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = Map.class, bool2 = false) + @TestCase(class1 = Collection.class, bool2 = true) + @TestCase(class1 = List.class, bool2 = true) + void supports(Class type, boolean expected) { + assertThat(CollectionSpecimen.meta().supports(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Test + void createReturnsNewSpecimen() { + assertThat(CollectionSpecimen.meta().create(SpecimenType.fromClass(List.class), context, specimenFactory)) + .isInstanceOf(CollectionSpecimen.class); + } + + @Test + void createThrows() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CollectionSpecimen.meta().create(SpecimenType.fromClass(String.class), context, specimenFactory)) + .withMessageContaining("type: java.lang.String"); + } + } } diff --git a/src/test/java/com/github/nylle/javafixture/specimen/EnumSpecimenTest.java b/src/test/java/com/github/nylle/javafixture/specimen/EnumSpecimenTest.java index cd98044..a27c632 100644 --- a/src/test/java/com/github/nylle/javafixture/specimen/EnumSpecimenTest.java +++ b/src/test/java/com/github/nylle/javafixture/specimen/EnumSpecimenTest.java @@ -1,7 +1,10 @@ package com.github.nylle.javafixture.specimen; import com.github.nylle.javafixture.SpecimenType; +import com.github.nylle.javafixture.annotations.testcases.TestCase; +import com.github.nylle.javafixture.annotations.testcases.TestWithCases; import com.github.nylle.javafixture.testobjects.TestEnum; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.lang.annotation.Annotation; @@ -9,33 +12,38 @@ import static com.github.nylle.javafixture.CustomizationContext.noContext; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; class EnumSpecimenTest { - @Test - void typeIsRequired() { - assertThatThrownBy(() -> new EnumSpecimen<>(null )) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: null"); - } + @Nested + class WhenConstructing { - @Test - void onlyEnumTypes() { - assertThatThrownBy(() -> new EnumSpecimen<>(SpecimenType.fromClass(Object.class) )) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: " + Object.class.getName()); - } + @Test + void typeIsRequired() { + assertThatThrownBy(() -> new EnumSpecimen<>(null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: null"); + } - @Test - void contextIsNotRequired() { - assertThatCode(() -> new EnumSpecimen<>(SpecimenType.fromClass(TestEnum.class) )) - .doesNotThrowAnyException(); + @Test + void onlyEnumTypes() { + assertThatThrownBy(() -> new EnumSpecimen<>(SpecimenType.fromClass(Object.class))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: " + Object.class.getName()); + } + + @Test + void contextIsNotRequired() { + assertThatCode(() -> new EnumSpecimen<>(SpecimenType.fromClass(TestEnum.class))) + .doesNotThrowAnyException(); + } } @Test void createEnum() { - var sut = new EnumSpecimen<>(SpecimenType.fromClass(TestEnum.class) ); + var sut = new EnumSpecimen<>(SpecimenType.fromClass(TestEnum.class)); var actual = sut.create(noContext(), new Annotation[0]); @@ -43,4 +51,34 @@ void createEnum() { assertThat(actual.toString()).isIn("VALUE1", "VALUE2", "VALUE3"); } + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = TestEnum.class, bool2 = true) + void supportsType(Class type, boolean expected) { + assertThat(EnumSpecimen.supportsType(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Nested + class SpecTest { + + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = TestEnum.class, bool2 = true) + void supports(Class type, boolean expected) { + assertThat(EnumSpecimen.meta().supports(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Test + void createReturnsNewSpecimen() { + assertThat(EnumSpecimen.meta().create(SpecimenType.fromClass(TestEnum.class), null, null)) + .isInstanceOf(EnumSpecimen.class); + } + + @Test + void createThrows() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> EnumSpecimen.meta().create(SpecimenType.fromClass(String.class), null, null)) + .withMessageContaining("type: java.lang.String"); + } + } } diff --git a/src/test/java/com/github/nylle/javafixture/specimen/GenericSpecimenTest.java b/src/test/java/com/github/nylle/javafixture/specimen/GenericSpecimenTest.java index a7dabdd..667893c 100644 --- a/src/test/java/com/github/nylle/javafixture/specimen/GenericSpecimenTest.java +++ b/src/test/java/com/github/nylle/javafixture/specimen/GenericSpecimenTest.java @@ -79,12 +79,40 @@ void contextIsRequired() { @Test void specimenFactoryIsRequired() { - assertThatThrownBy(() -> new GenericSpecimen<>(SpecimenType.fromClass(Optional.class), context, null)) + assertThatThrownBy(() -> new GenericSpecimen<>(new SpecimenType>(){}, context, null)) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("specimenFactory: null"); } } + @Nested + class SupportsType { + + @Test + void returnsFalseForCollections() { + assertThat(GenericSpecimen.supportsType(new SpecimenType>(){})).isFalse(); + } + + @Test + void returnsFalseForMaps() { + assertThat(GenericSpecimen.supportsType(new SpecimenType>(){})).isFalse(); + } + + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = Map.class, bool2 = false) + @TestCase(class1 = Collection.class, bool2 = false) + @TestCase(class1 = Optional.class, bool2 = true) + void returnsFalseForNonParametrizedTypes(Class type) { + assertThat(GenericSpecimen.supportsType(SpecimenType.fromClass(type))).isFalse(); + } + + @Test + void returnsTrueForParametrizedTypes() { + assertThat(GenericSpecimen.supportsType(new SpecimenType>(){})).isTrue(); + } + } + @Test void createClass() { var sut = new GenericSpecimen<>(new SpecimenType>() {}, context, specimenFactory); @@ -269,6 +297,37 @@ void firstFieldPerNameIsOmitted() { } } + @Nested + class SpecTest { + + @TestWithCases + @TestCase(class1 = Map.class) + @TestCase(class1 = String.class) + @TestCase(class1 = Collection.class) + @TestCase(class1 = Optional.class) + void supportsReturnsFalse(Class type) { + assertThat(GenericSpecimen.meta().supports(SpecimenType.fromClass(type))).isFalse(); + } + + @Test + void supportsReturnsTrue() { + assertThat(GenericSpecimen.meta().supports(new SpecimenType>(){})).isTrue(); + } + + @Test + void createReturnsNewSpecimen() { + assertThat(GenericSpecimen.meta().create(new SpecimenType>(){}, context, specimenFactory)) + .isInstanceOf(GenericSpecimen.class); + } + + @Test + void createThrows() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> GenericSpecimen.meta().create(SpecimenType.fromClass(String.class), context, specimenFactory)) + .withMessageContaining("type: java.lang.String"); + } + } + public static class WithTestObject { private T topLevelValue; private TestObject testObject; diff --git a/src/test/java/com/github/nylle/javafixture/specimen/InterfaceSpecimenTest.java b/src/test/java/com/github/nylle/javafixture/specimen/InterfaceSpecimenTest.java index a5cd840..dacdda2 100644 --- a/src/test/java/com/github/nylle/javafixture/specimen/InterfaceSpecimenTest.java +++ b/src/test/java/com/github/nylle/javafixture/specimen/InterfaceSpecimenTest.java @@ -4,9 +4,13 @@ import com.github.nylle.javafixture.Context; import com.github.nylle.javafixture.SpecimenFactory; import com.github.nylle.javafixture.SpecimenType; +import com.github.nylle.javafixture.annotations.testcases.TestCase; +import com.github.nylle.javafixture.annotations.testcases.TestWithCases; import com.github.nylle.javafixture.testobjects.TestObject; +import com.github.nylle.javafixture.testobjects.abstractclasses.AbstractClassWithAbstractImplementation; import com.github.nylle.javafixture.testobjects.interfaces.InterfaceWithoutImplementation; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.lang.annotation.Annotation; @@ -14,6 +18,7 @@ import static com.github.nylle.javafixture.CustomizationContext.noContext; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; class InterfaceSpecimenTest { @@ -27,25 +32,29 @@ void setup() { specimenFactory = new SpecimenFactory(context); } - @Test - void onlyInterfaceTypes() { - assertThatThrownBy(() -> new InterfaceSpecimen<>(SpecimenType.fromClass(Charset.class), context, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: " + Charset.class.getName()); - } - - @Test - void typeIsRequired() { - assertThatThrownBy(() -> new InterfaceSpecimen<>((SpecimenType) null, context, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: null"); - } - - @Test - void contextIsRequired() { - assertThatThrownBy(() -> new InterfaceSpecimen<>(SpecimenType.fromClass(InterfaceWithoutImplementation.class), null, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("context: null"); + @Nested + class WhenConstructing { + + @Test + void onlyInterfaceTypes() { + assertThatThrownBy(() -> new InterfaceSpecimen<>(SpecimenType.fromClass(Charset.class), context, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: " + Charset.class.getName()); + } + + @Test + void typeIsRequired() { + assertThatThrownBy(() -> new InterfaceSpecimen<>((SpecimenType) null, context, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: null"); + } + + @Test + void contextIsRequired() { + assertThatThrownBy(() -> new InterfaceSpecimen<>(SpecimenType.fromClass(InterfaceWithoutImplementation.class), null, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("context: null"); + } } @Test @@ -80,5 +89,36 @@ void resultIsNotCached() { assertThat(original.toString()).isNotEqualTo(second.toString()); assertThat(original.getTestObject()).isNotEqualTo(second.getTestObject()); } + + @TestWithCases + @TestCase(class1 = AbstractClassWithAbstractImplementation.class, bool2 = false) + @TestCase(class1 = InterfaceWithoutImplementation.class, bool2 = true) + void supportsType(Class type, boolean expected) { + assertThat(InterfaceSpecimen.supportsType(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Nested + class SpecTest { + + @TestWithCases + @TestCase(class1 = AbstractClassWithAbstractImplementation.class, bool2 = false) + @TestCase(class1 = InterfaceWithoutImplementation.class, bool2 = true) + void supports(Class type, boolean expected) { + assertThat(InterfaceSpecimen.meta().supports(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Test + void createReturnsNewSpecimen() { + assertThat(InterfaceSpecimen.meta().create(SpecimenType.fromClass(InterfaceWithoutImplementation.class), context, specimenFactory)) + .isInstanceOf(InterfaceSpecimen.class); + } + + @Test + void createThrows() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> InterfaceSpecimen.meta().create(SpecimenType.fromClass(String.class), context, specimenFactory)) + .withMessageContaining("type: java.lang.String"); + } + } } diff --git a/src/test/java/com/github/nylle/javafixture/specimen/MapSpecimenTest.java b/src/test/java/com/github/nylle/javafixture/specimen/MapSpecimenTest.java index 5ee1ebb..5774d77 100644 --- a/src/test/java/com/github/nylle/javafixture/specimen/MapSpecimenTest.java +++ b/src/test/java/com/github/nylle/javafixture/specimen/MapSpecimenTest.java @@ -4,9 +4,12 @@ import com.github.nylle.javafixture.Context; import com.github.nylle.javafixture.SpecimenFactory; import com.github.nylle.javafixture.SpecimenType; +import com.github.nylle.javafixture.annotations.testcases.TestCase; +import com.github.nylle.javafixture.annotations.testcases.TestWithCases; import com.github.nylle.javafixture.testobjects.TestEnum; import com.github.nylle.javafixture.testobjects.TestObject; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.lang.annotation.Annotation; @@ -24,6 +27,7 @@ import static com.github.nylle.javafixture.CustomizationContext.noContext; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; class MapSpecimenTest { @@ -36,32 +40,43 @@ void setup() { specimenFactory = new SpecimenFactory(context); } - @Test - void onlyMapTypes() { - assertThatThrownBy(() -> new MapSpecimen<>(SpecimenType.fromClass(List.class), context, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: " + List.class.getName()); - } + @Nested + class WhenConstructing { - @Test - void typeIsRequired() { - assertThatThrownBy(() -> new MapSpecimen<>(null, context, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: null"); - } + @Test + void onlyMapTypes() { + assertThatThrownBy(() -> new MapSpecimen<>(SpecimenType.fromClass(List.class), context, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: " + List.class.getName()); + } - @Test - void contextIsRequired() { - assertThatThrownBy(() -> new MapSpecimen<>(SpecimenType.fromClass(Map.class), null, specimenFactory)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("context: null"); + @Test + void typeIsRequired() { + assertThatThrownBy(() -> new MapSpecimen<>(null, context, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: null"); + } + + @Test + void contextIsRequired() { + assertThatThrownBy(() -> new MapSpecimen<>(SpecimenType.fromClass(Map.class), null, specimenFactory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("context: null"); + } + + @Test + void specimenFactoryIsRequired() { + assertThatThrownBy(() -> new MapSpecimen<>(SpecimenType.fromClass(Map.class), context, null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("specimenFactory: null"); + } } - @Test - void specimenFactoryIsRequired() { - assertThatThrownBy(() -> new MapSpecimen<>(SpecimenType.fromClass(Map.class), context, null)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("specimenFactory: null"); + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = Map.class, bool2 = true) + void supportsType(Class type, boolean expected) { + assertThat(MapSpecimen.supportsType(SpecimenType.fromClass(type))).isEqualTo(expected); } @Test @@ -230,4 +245,28 @@ void nonPrimitiveElementsAreSameInstance() { assertThat(first.getValue()).isSameAs(second.getValue()); } + + @Nested + class SpecTest { + + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = Map.class, bool2 = true) + void supports(Class type, boolean expected) { + assertThat(MapSpecimen.meta().supports(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Test + void createReturnsNewSpecimen() { + assertThat(MapSpecimen.meta().create(SpecimenType.fromClass(Map.class), context, specimenFactory)) + .isInstanceOf(MapSpecimen.class); + } + + @Test + void createThrows() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> MapSpecimen.meta().create(SpecimenType.fromClass(String.class), context, specimenFactory)) + .withMessageContaining("type: java.lang.String"); + } + } } diff --git a/src/test/java/com/github/nylle/javafixture/specimen/PrimitiveSpecimenTest.java b/src/test/java/com/github/nylle/javafixture/specimen/PrimitiveSpecimenTest.java index 180d3dc..4fa652b 100644 --- a/src/test/java/com/github/nylle/javafixture/specimen/PrimitiveSpecimenTest.java +++ b/src/test/java/com/github/nylle/javafixture/specimen/PrimitiveSpecimenTest.java @@ -4,6 +4,7 @@ import com.github.nylle.javafixture.SpecimenType; import com.github.nylle.javafixture.annotations.testcases.TestCase; import com.github.nylle.javafixture.annotations.testcases.TestWithCases; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.lang.annotation.Annotation; @@ -12,29 +13,34 @@ import static com.github.nylle.javafixture.CustomizationContext.noContext; import static com.github.nylle.javafixture.SpecimenType.fromClass; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; class PrimitiveSpecimenTest { - @Test - void contextIsRequired() { - assertThatThrownBy(() -> new PrimitiveSpecimen<>(SpecimenType.fromClass(Integer.class), null)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("context: null"); - } - - @Test - void typeIsRequired() { - assertThatThrownBy(() -> new PrimitiveSpecimen<>(null, new Context(configure()))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: null"); - } - - @Test - void onlyPrimitiveTypes() { - assertThatThrownBy(() -> new PrimitiveSpecimen<>(fromClass(Object.class), new Context(configure()))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("type: " + Object.class.getName()); + @Nested + class WhenConstructing { + + @Test + void contextIsRequired() { + assertThatThrownBy(() -> new PrimitiveSpecimen<>(SpecimenType.fromClass(Integer.class), null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("context: null"); + } + + @Test + void typeIsRequired() { + assertThatThrownBy(() -> new PrimitiveSpecimen<>(null, new Context(configure()))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: null"); + } + + @Test + void onlyPrimitiveTypes() { + assertThatThrownBy(() -> new PrimitiveSpecimen<>(fromClass(Object.class), new Context(configure()))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("type: " + Object.class.getName()); + } } @Test @@ -127,4 +133,38 @@ void createDouble(boolean positiveOnly, double min, double max) { assertThat(actual).isBetween(min, max); } + @TestWithCases + @TestCase(class1 = Object.class, bool2 = false) + @TestCase(class1 = String.class, bool2 = true) + @TestCase(class1 = Integer.class, bool2 = true) + @TestCase(class1 = boolean.class, bool2 = true) + void supportsType(Class type, boolean expected) { + assertThat(PrimitiveSpecimen.supportsType(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Nested + class SpecTest { + + @TestWithCases + @TestCase(class1 = Object.class, bool2 = false) + @TestCase(class1 = String.class, bool2 = true) + @TestCase(class1 = Integer.class, bool2 = true) + @TestCase(class1 = boolean.class, bool2 = true) + void supports(Class type, boolean expected) { + assertThat(PrimitiveSpecimen.meta().supports(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Test + void createReturnsNewSpecimen() { + assertThat(PrimitiveSpecimen.meta().create(SpecimenType.fromClass(String.class), new Context(configure()), null)) + .isInstanceOf(PrimitiveSpecimen.class); + } + + @Test + void createThrows() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> PrimitiveSpecimen.meta().create(SpecimenType.fromClass(Object.class), new Context(configure()), null)) + .withMessageContaining("type: java.lang.Object"); + } + } } diff --git a/src/test/java/com/github/nylle/javafixture/specimen/SpecialSpecimenTest.java b/src/test/java/com/github/nylle/javafixture/specimen/SpecialSpecimenTest.java index 27ec69a..1e9f36f 100644 --- a/src/test/java/com/github/nylle/javafixture/specimen/SpecialSpecimenTest.java +++ b/src/test/java/com/github/nylle/javafixture/specimen/SpecialSpecimenTest.java @@ -4,6 +4,8 @@ import com.github.nylle.javafixture.Configuration; import com.github.nylle.javafixture.Context; import com.github.nylle.javafixture.SpecimenType; +import com.github.nylle.javafixture.annotations.testcases.TestCase; +import com.github.nylle.javafixture.annotations.testcases.TestWithCases; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -18,6 +20,7 @@ import static com.github.nylle.javafixture.CustomizationContext.noContext; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; public class SpecialSpecimenTest { @@ -54,7 +57,17 @@ void contextIsRequired() { .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("context: null"); } + } + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = Object.class, bool2 = false) + @TestCase(class1 = BigInteger.class, bool2 = true) + @TestCase(class1 = BigDecimal.class, bool2 = true) + @TestCase(class1 = File.class, bool2 = true) + @TestCase(class1 = URI.class, bool2 = true) + void supportsType(Class type, boolean expected) { + assertThat(SpecialSpecimen.supportsType(SpecimenType.fromClass(type))).isEqualTo(expected); } @Test @@ -78,7 +91,6 @@ void createFileWithoutContext() { assertThat(actual.getAbsolutePath()).isNotEmpty(); } - @Test @DisplayName("create URI creates URI with host, scheme and random path") void craeteURI() { @@ -130,4 +142,38 @@ void createNonNegativeBigDecimal() { assertThat(actual).isNotNegative(); } + + @Nested + class SpecTest { + + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = Object.class, bool2 = false) + @TestCase(class1 = BigInteger.class, bool2 = true) + @TestCase(class1 = BigDecimal.class, bool2 = true) + @TestCase(class1 = File.class, bool2 = true) + @TestCase(class1 = URI.class, bool2 = true) + void supports(Class type, boolean expected) { + assertThat(SpecialSpecimen.meta().supports(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @TestWithCases + @TestCase(class1 = BigInteger.class) + @TestCase(class1 = BigDecimal.class) + @TestCase(class1 = File.class) + @TestCase(class1 = URI.class) + void createReturnsNewSpecimen(Class type) { + assertThat(SpecialSpecimen.meta().create(SpecimenType.fromClass(type), context, null)) + .isInstanceOf(SpecialSpecimen.class); + } + + @TestWithCases + @TestCase(class1 = String.class) + @TestCase(class1 = Object.class) + void createThrows(Class type) { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> SpecialSpecimen.meta().create(SpecimenType.fromClass(type), context, null)) + .withMessageContaining("type: " + type.getName()); + } + } } diff --git a/src/test/java/com/github/nylle/javafixture/specimen/TimeSpecimenTest.java b/src/test/java/com/github/nylle/javafixture/specimen/TimeSpecimenTest.java index 5a25d01..099d405 100644 --- a/src/test/java/com/github/nylle/javafixture/specimen/TimeSpecimenTest.java +++ b/src/test/java/com/github/nylle/javafixture/specimen/TimeSpecimenTest.java @@ -8,6 +8,7 @@ import com.github.nylle.javafixture.annotations.testcases.TestWithCases; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -32,11 +33,14 @@ import java.time.chrono.JapaneseEra; import java.time.chrono.MinguoDate; import java.time.chrono.ThaiBuddhistDate; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalAmount; import java.util.Map; import static com.github.nylle.javafixture.CustomizationContext.noContext; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.when; @@ -129,4 +133,58 @@ void createWithClock() { assertThat(actual).isEqualTo(Instant.MIN); } + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = Object.class, bool2 = false) + @TestCase(class1 = Temporal.class, bool2 = true) + @TestCase(class1 = TemporalAdjuster.class, bool2 = true) + @TestCase(class1 = TemporalAmount.class, bool2 = true) + @TestCase(class1 = ZoneId.class, bool2 = true) + @TestCase(class1 = java.util.Date.class, bool2 = true) + @TestCase(class1 = java.sql.Date.class, bool2 = true) + void supportsType(Class type, boolean expected) { + assertThat(TimeSpecimen.supportsType(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @Nested + class SpecTest { + + @TestWithCases + @TestCase(class1 = String.class, bool2 = false) + @TestCase(class1 = Temporal.class, bool2 = true) + @TestCase(class1 = TemporalAdjuster.class, bool2 = true) + @TestCase(class1 = TemporalAmount.class, bool2 = true) + @TestCase(class1 = ZoneId.class, bool2 = true) + @TestCase(class1 = java.util.Date.class, bool2 = true) + @TestCase(class1 = java.sql.Date.class, bool2 = true) + @TestCase(class1 = Duration.class, bool2 = true) + @TestCase(class1 = JapaneseEra.class, bool2 = true) + @TestCase(class1 = MonthDay.class, bool2 = true) + @TestCase(class1 = Period.class, bool2 = true) + @TestCase(class1 = ZoneId.class, bool2 = true) + @TestCase(class1 = ZoneOffset.class, bool2 = true) + @TestCase(class1 = ZonedDateTime.class, bool2 = true) + void supports(Class type, boolean expected) { + assertThat(TimeSpecimen.meta().supports(SpecimenType.fromClass(type))).isEqualTo(expected); + } + + @TestWithCases + @TestCase(class1 = Temporal.class) + @TestCase(class1 = TemporalAdjuster.class) + @TestCase(class1 = TemporalAmount.class) + @TestCase(class1 = ZoneId.class) + @TestCase(class1 = java.util.Date.class) + @TestCase(class1 = java.sql.Date.class) + void createReturnsNewSpecimen(Class type) { + assertThat(TimeSpecimen.meta().create(SpecimenType.fromClass(type), context, null)) + .isInstanceOf(TimeSpecimen.class); + } + + @Test + void createThrows() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> TimeSpecimen.meta().create(SpecimenType.fromClass(String.class), context, null)) + .withMessageContaining("type: java.lang.String"); + } + } }