├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── core ├── src │ ├── main │ │ └── java │ │ │ └── io │ │ │ └── github │ │ │ └── easymodeling │ │ │ ├── randomizer │ │ │ ├── Randomizer.java │ │ │ ├── primitive │ │ │ │ ├── BooleanRandomizer.java │ │ │ │ └── CharRandomizer.java │ │ │ ├── EnumRandomizer.java │ │ │ ├── collection │ │ │ │ ├── AbstractSetRandomizer.java │ │ │ │ ├── AbstractListRandomizer.java │ │ │ │ ├── SetRandomizer.java │ │ │ │ ├── HashSetRandomizer.java │ │ │ │ ├── TreeSetRandomizer.java │ │ │ │ ├── ArrayListRandomizer.java │ │ │ │ ├── ListRandomizer.java │ │ │ │ ├── LinkedListRandomizer.java │ │ │ │ ├── HashMapRandomizer.java │ │ │ │ ├── TreeMapRandomizer.java │ │ │ │ ├── MapRandomizer.java │ │ │ │ ├── AbstractMapRandomizer.java │ │ │ │ └── CollectionRandomizer.java │ │ │ ├── number │ │ │ │ ├── DoubleRandomizer.java │ │ │ │ ├── LongRandomizer.java │ │ │ │ ├── FloatRandomizer.java │ │ │ │ ├── ShortRandomizer.java │ │ │ │ ├── ByteRandomizer.java │ │ │ │ ├── IntegerRandomizer.java │ │ │ │ ├── NumberRandomizer.java │ │ │ │ ├── BigDecimalRandomizer.java │ │ │ │ └── BigIntegerRandomizer.java │ │ │ ├── string │ │ │ │ ├── StringRandomizer.java │ │ │ │ └── StringBuilderRandomizer.java │ │ │ ├── datetime │ │ │ │ ├── InstantRandomizer.java │ │ │ │ ├── DateRandomizer.java │ │ │ │ ├── LocalDateRandomizer.java │ │ │ │ ├── LocalTimeRandomizer.java │ │ │ │ ├── ZonedDateTimeRandomizer.java │ │ │ │ ├── SqlDateRandomizer.java │ │ │ │ ├── LocalDateTimeRandomizer.java │ │ │ │ ├── SqlTimestampRandomizer.java │ │ │ │ └── AbstractDateTimeRandomizer.java │ │ │ ├── CustomTypeRandomizer.java │ │ │ ├── stream │ │ │ │ ├── StreamRandomizer.java │ │ │ │ ├── LongStreamRandomizer.java │ │ │ │ ├── IntStreamRandomizer.java │ │ │ │ ├── DoubleStreamRandomizer.java │ │ │ │ └── AbstractStreamRandomizer.java │ │ │ ├── OptionalRandomizer.java │ │ │ ├── Modeler.java │ │ │ ├── ModelCache.java │ │ │ └── GenericRandomizer.java │ │ │ ├── EasyModelingException.java │ │ │ ├── Models.java │ │ │ ├── Model.java │ │ │ ├── QualifiedField.java │ │ │ └── Field.java │ └── test │ │ └── java │ │ └── io │ │ └── github │ │ └── easymodeling │ │ └── randomizer │ │ ├── SomeType.java │ │ ├── SomeTypeModeler.java │ │ ├── collection │ │ ├── TreeSetRandomizerTest.java │ │ ├── ListRandomizerTest.java │ │ ├── SetRandomizerTest.java │ │ ├── HashSetRandomizerTest.java │ │ ├── ArrayListRandomizerTest.java │ │ ├── LinkedListRandomizerTest.java │ │ ├── TreeMapRandomizerTest.java │ │ ├── MapRandomizerTest.java │ │ └── HashMapRandomizerTest.java │ │ ├── stream │ │ ├── LongStreamRandomizerTest.java │ │ ├── IntStreamRandomizerTest.java │ │ ├── DoubleStreamRandomizerTest.java │ │ └── StreamRandomizerTest.java │ │ ├── RandomizerTest.java │ │ ├── number │ │ ├── LongRandomizerTest.java │ │ ├── DoubleRandomizerTest.java │ │ ├── ByteRandomizerTest.java │ │ ├── IntegerRandomizerTest.java │ │ ├── ShortRandomizerTest.java │ │ ├── FloatRandomizerTest.java │ │ ├── BigIntegerRandomizerTest.java │ │ └── BigDecimalRandomizerTest.java │ │ ├── ModelerTest.java │ │ ├── datetime │ │ ├── InstantRandomizerTest.java │ │ ├── DateRandomizerTest.java │ │ ├── SqlTimestampRandomizerTest.java │ │ ├── SqlDateRandomizerTest.java │ │ ├── LocalDateRandomizerTest.java │ │ ├── LocalTimeRandomizerTest.java │ │ ├── ZonedDateTimeRandomizerTest.java │ │ └── LocalDateTimeRandomizerTest.java │ │ ├── EnumRandomizerTest.java │ │ └── OptionalRandomizerTest.java └── build.gradle ├── functional-test ├── src │ ├── test │ │ └── java │ │ │ └── io │ │ │ └── github │ │ │ └── easymodeling │ │ │ ├── MapModelConfig.java │ │ │ ├── EnumModelConfig.java │ │ │ ├── SomeModelConfig.java │ │ │ ├── CourseStudentConfig.java │ │ │ ├── StreamModelConfig.java │ │ │ ├── derived │ │ │ ├── DerivedConfig.java │ │ │ └── DerivedTest.java │ │ │ ├── ListModelConfig.java │ │ │ ├── OptionalModelConfig.java │ │ │ ├── NestingModelTest.java │ │ │ ├── EasyModelingConfig.java │ │ │ ├── MapModelTest.java │ │ │ ├── ArrayModelConfig.java │ │ │ ├── NumericalModelConfig.java │ │ │ ├── SomeModelTest.java │ │ │ ├── BoxedPrimitiveTypeModelTest.java │ │ │ ├── ListModelTest.java │ │ │ ├── CourseStudentTest.java │ │ │ ├── StringTypeModelConfig.java │ │ │ ├── DatetimeModelConfig.java │ │ │ ├── ModelerStreamTest.java │ │ │ ├── NumericalTypeModelTest.java │ │ │ ├── OrderTest.java │ │ │ ├── OrderLineTest.java │ │ │ ├── PrimitiveTypeTest.java │ │ │ ├── StreamModelTest.java │ │ │ ├── EnumModelTest.java │ │ │ └── StringTypeModelTest.java │ └── main │ │ └── java │ │ └── io │ │ └── github │ │ └── easymodeling │ │ ├── Course.java │ │ ├── Student.java │ │ ├── MapModel.java │ │ ├── EnumExample.java │ │ ├── derived │ │ ├── Base.java │ │ └── Derived.java │ │ ├── SomeModel.java │ │ ├── NestingModel.java │ │ ├── SomeNestedModel.java │ │ ├── EnumModel.java │ │ ├── BoxedPrimitiveTypeModel.java │ │ ├── DatetimeModel.java │ │ ├── Order.java │ │ ├── OrderLine.java │ │ ├── StringTypeModel.java │ │ ├── StreamModel.java │ │ ├── ListModel.java │ │ ├── NumericalTypeModel.java │ │ ├── PrimitiveTypeModel.java │ │ └── OptionalModel.java ├── build.gradle └── artifact-verification.build.gradle ├── processor └── src │ ├── main │ └── java │ │ └── io │ │ └── github │ │ └── easymodeling │ │ ├── modeler │ │ ├── FieldNotSupportedException.java │ │ ├── field │ │ │ ├── Initializable.java │ │ │ ├── BuilderMember.java │ │ │ ├── StatementProvider.java │ │ │ ├── EnumField.java │ │ │ ├── PlainField.java │ │ │ ├── UnknownField.java │ │ │ ├── string │ │ │ │ ├── StringField.java │ │ │ │ └── StringBuilderField.java │ │ │ ├── collection │ │ │ │ ├── AbstractMapField.java │ │ │ │ ├── ListField.java │ │ │ │ ├── MapField.java │ │ │ │ ├── ArrayListField.java │ │ │ │ ├── AbstractCollectionField.java │ │ │ │ ├── LinkedListField.java │ │ │ │ ├── HashMapField.java │ │ │ │ ├── TreeMapField.java │ │ │ │ ├── SetField.java │ │ │ │ ├── HashSetField.java │ │ │ │ └── TreeSetField.java │ │ │ ├── datetime │ │ │ │ ├── DateField.java │ │ │ │ ├── SqlDateField.java │ │ │ │ ├── InstantField.java │ │ │ │ ├── LocalDateField.java │ │ │ │ ├── LocalTimeField.java │ │ │ │ ├── SqlTimestampField.java │ │ │ │ ├── LocalDateTimeField.java │ │ │ │ └── ZonedDateTimeField.java │ │ │ ├── CustomField.java │ │ │ ├── Container.java │ │ │ ├── primitive │ │ │ │ ├── CharField.java │ │ │ │ └── BooleanField.java │ │ │ ├── stream │ │ │ │ ├── PrimitiveTypeStreamField.java │ │ │ │ ├── IntStreamField.java │ │ │ │ ├── LongStreamField.java │ │ │ │ └── DoubleStreamField.java │ │ │ ├── OptionalField.java │ │ │ ├── array │ │ │ │ └── ArrayField.java │ │ │ └── number │ │ │ │ ├── LongField.java │ │ │ │ ├── ByteField.java │ │ │ │ ├── DoubleField.java │ │ │ │ ├── FloatField.java │ │ │ │ ├── ShortField.java │ │ │ │ ├── IntegerField.java │ │ │ │ ├── BigDecimalField.java │ │ │ │ └── BigIntegerField.java │ │ └── HidingFieldsGrouper.java │ │ ├── processor │ │ ├── ProcessingException.java │ │ └── AnnoFieldWrapper.java │ │ └── log │ │ └── LogLevel.java │ └── test │ └── java │ └── io │ └── github │ └── easymodeling │ ├── modeler │ ├── provider │ │ └── ModelFieldProviderTest.java │ ├── field │ │ ├── AbstractFieldTest.java │ │ ├── primitive │ │ │ ├── CharFieldTest.java │ │ │ └── BooleanFieldTest.java │ │ ├── datetime │ │ │ ├── DateFieldTest.java │ │ │ ├── SqlDateFieldTest.java │ │ │ └── SqlTimestampFieldTest.java │ │ ├── stream │ │ │ ├── IntStreamFieldTest.java │ │ │ ├── LongStreamFieldTest.java │ │ │ ├── DoubleStreamFieldTest.java │ │ │ └── StreamFieldTest.java │ │ ├── collection │ │ │ ├── SetFieldTest.java │ │ │ ├── HashSetFieldTest.java │ │ │ ├── ListFieldTest.java │ │ │ ├── ArrayListFieldTest.java │ │ │ └── LinkedListFieldTest.java │ │ ├── UnknownFieldTest.java │ │ ├── EnumFieldTest.java │ │ └── CustomFieldTest.java │ └── ModelFieldRegistryTest.java │ ├── log │ └── LogLevelTest.java │ └── archunit │ └── ModelerPackageArchTest.java ├── changlog.md ├── .github ├── dependabot.yml ├── actions │ ├── sonarqube │ │ └── action.yml │ ├── set-up-jdk │ │ └── action.yml │ ├── unit-test │ │ └── action.yml │ └── publish-artifact │ │ └── action.yml ├── workflows │ ├── test.yml │ └── ci.yml └── ISSUE_TEMPLATE │ └── feature_request.yml ├── .gitignore ├── settings.gradle └── .gitattributes /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easymodeling/easy-modeling/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/Randomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | public interface Randomizer { 4 | 5 | T next(); 6 | } 7 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/MapModelConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | @Model(type = MapModel.class) 4 | public class MapModelConfig { 5 | } 6 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/EnumModelConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | @Model(type = EnumModel.class) 4 | public class EnumModelConfig { 5 | } 6 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/SomeModelConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | @Model(type = SomeModel.class) 4 | public class SomeModelConfig { 5 | } 6 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/CourseStudentConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | @Model(type = Course.class) 4 | public class CourseStudentConfig { 5 | } 6 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/StreamModelConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | @Model(type = StreamModel.class) 4 | public class StreamModelConfig { 5 | } 6 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/FieldNotSupportedException.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler; 2 | 3 | public class FieldNotSupportedException extends RuntimeException { 4 | } 5 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/Course.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.util.List; 4 | 5 | public class Course { 6 | 7 | private List students; 8 | } 9 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/Student.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.util.List; 4 | 5 | public class Student { 6 | 7 | private List courses; 8 | } 9 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/MapModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.util.Map; 4 | 5 | public class MapModel { 6 | 7 | public Map map; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/EnumExample.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | public enum EnumExample { 4 | 5 | A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/derived/DerivedConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.derived; 2 | 3 | import io.github.easymodeling.Model; 4 | 5 | @Model(type = Derived.class) 6 | class DerivedConfig { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /changlog.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## V_0.1.4 4 | 5 | - Static method `stream` of Modelers will return a limited stream of items instead of infinite. 6 | - Search for available constructors when creating instances. 7 | - Ignore modeler generation for inner classes 8 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/Initializable.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | 5 | public interface Initializable { 6 | 7 | CodeBlock initializer(); 8 | } 9 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/derived/Base.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.derived; 2 | 3 | public class Base { 4 | 5 | public Integer baseInt; 6 | 7 | public String baseString; 8 | 9 | public Long hidden; 10 | } 11 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/SomeType.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | public class SomeType { 4 | 5 | public SomeType(int anInt) { 6 | this.anInt = anInt; 7 | } 8 | 9 | public int anInt; 10 | } 11 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/ListModelConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.util.List; 4 | 5 | @Model(type = ListModel.class) 6 | public class ListModelConfig { 7 | 8 | public List listOfInts; 9 | } 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | - package-ecosystem: "gradle" 8 | directory: "/" 9 | schedule: 10 | interval: "daily" 11 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/OptionalModelConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | @Model(type = OptionalModel.class, fields = { 4 | @Field(name = "nullableInteger", allowEmpty = true), 5 | }) 6 | public class OptionalModelConfig { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/SomeModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.time.Instant; 4 | 5 | public class SomeModel { 6 | 7 | public String string; 8 | 9 | public Instant instant; 10 | 11 | public SomeNestedModel someNestedModel; 12 | } 13 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/NestingModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | public class NestingModel { 4 | 5 | public String name; 6 | 7 | public InnerModel innerModel; 8 | 9 | public static class InnerModel { 10 | public String name; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/SomeNestedModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | public class SomeNestedModel { 4 | 5 | public String string; 6 | 7 | public Integer integer; 8 | 9 | public SomeNestedModel nestedModel; 10 | 11 | public SomeNestedModel[] arrayOfNestedModel; 12 | } 13 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/provider/ModelFieldProviderTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.provider; 2 | 3 | import io.github.easymodeling.modeler.ModelFieldProvider; 4 | 5 | abstract class ModelFieldProviderTest { 6 | 7 | ModelFieldProvider modelFieldProvider = new ModelFieldProvider(); 8 | } 9 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/BuilderMember.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.FieldSpec; 4 | import com.squareup.javapoet.MethodSpec; 5 | 6 | public interface BuilderMember { 7 | 8 | FieldSpec field(); 9 | 10 | MethodSpec setter(); 11 | } 12 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/EnumModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.util.List; 4 | 5 | public class EnumModel { 6 | 7 | public EnumExample enumExample; 8 | 9 | public EnumExample[] enumExamples; 10 | 11 | public List listOfEnumExamples; 12 | 13 | public EnumModel node; 14 | } 15 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/StatementProvider.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | 5 | public interface StatementProvider { 6 | 7 | CodeBlock constructorStatement(); 8 | 9 | CodeBlock populateStatement(); 10 | 11 | CodeBlock buildStatement(); 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/primitive/BooleanRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.primitive; 2 | 3 | import io.github.easymodeling.randomizer.GenericRandomizer; 4 | 5 | public class BooleanRandomizer extends GenericRandomizer { 6 | 7 | public Boolean random() { 8 | return random.nextBoolean(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/NestingModelTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | @Model(type = NestingModel.class) 6 | class NestingModelTest { 7 | 8 | @Test 9 | void should_populate_field_of_inner_class() { 10 | NestingModelModeler modeler = new NestingModelModeler(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/EasyModelingConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | @Model(type = Order.class) 4 | @Model(type = OrderLine.class) 5 | @Model(type = PrimitiveTypeModel.class, fields = { 6 | @Field(name = "aString", min = 1, max = 12), 7 | }) 8 | @Model(type = BoxedPrimitiveTypeModel.class) 9 | public class EasyModelingConfig { 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/EasyModelingException.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | public class EasyModelingException extends RuntimeException { 4 | 5 | public EasyModelingException(String message, Throwable cause) { 6 | super(message, cause); 7 | } 8 | 9 | public EasyModelingException(String message) { 10 | super(message); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/primitive/CharRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.primitive; 2 | 3 | import io.github.easymodeling.randomizer.GenericRandomizer; 4 | 5 | public class CharRandomizer extends GenericRandomizer { 6 | 7 | public Character random() { 8 | return (char) random.nextInt(Character.MAX_VALUE); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /build/ 3 | **/build/ 4 | 5 | # Ignore Gradle GUI config 6 | gradle-app.setting 7 | 8 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 9 | !gradle-wrapper.jar 10 | 11 | # Cache of project 12 | .gradletasknamecache 13 | 14 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 15 | # gradle/wrapper/gradle-wrapper.properties 16 | 17 | .idea 18 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/derived/Derived.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.derived; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class Derived extends Base { 6 | 7 | public int derivedInt; 8 | 9 | public Integer derivedInteger; 10 | 11 | public String derivedString; 12 | 13 | public BigDecimal hiddenField; 14 | 15 | public Long hidden; 16 | } 17 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/Models.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.TYPE) 9 | @Retention(RetentionPolicy.CLASS) 10 | public @interface Models { 11 | 12 | Model[] value(); 13 | } 14 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/processor/ProcessingException.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.processor; 2 | 3 | public class ProcessingException extends RuntimeException { 4 | 5 | public ProcessingException(String message) { 6 | super(message); 7 | } 8 | 9 | public ProcessingException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/MapModelTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | class MapModelTest { 8 | 9 | @Test 10 | void should_populate_map() { 11 | final MapModel next = MapModelModeler.next(); 12 | 13 | assertThat(next).isNotNull(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'easy-modeling' 2 | include 'core', 'processor', 'functional-test' 3 | 4 | if (startParameter.projectProperties.get('artifact-verification') != null) { 5 | include 'artifact-verification' 6 | 7 | def artifactVerification = project(':artifact-verification') 8 | artifactVerification.projectDir = file('functional-test') 9 | artifactVerification.buildFileName = 'artifact-verification.build.gradle' 10 | } 11 | 12 | -------------------------------------------------------------------------------- /.github/actions/sonarqube/action.yml: -------------------------------------------------------------------------------- 1 | name: Sonarqube Scan 2 | description: Scan the project and report to SonarQube 3 | runs: 4 | using: 'composite' 5 | steps: 6 | - name: Cache SonarCloud packages 7 | uses: actions/cache@v1 8 | with: 9 | path: ~/.sonar/cache 10 | key: ${{ runner.os }}-sonar 11 | restore-keys: ${{ runner.os }}-sonar 12 | - name: Build and analyze 13 | shell: bash 14 | run: ./gradlew jacocoTestReport sonarqube --info 15 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/EnumRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | public class EnumRandomizer> extends GenericRandomizer { 4 | 5 | private final E[] values; 6 | 7 | public EnumRandomizer(E[] values) { 8 | this.values = values; 9 | } 10 | 11 | @Override 12 | protected E random() { 13 | final int index = random.nextInt(values.length); 14 | return values[index]; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/AbstractSetRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.Set; 6 | 7 | public abstract class AbstractSetRandomizer, E> extends CollectionRandomizer { 8 | 9 | protected AbstractSetRandomizer(Randomizer elementRandomizer, int maxSize) { 10 | super(elementRandomizer, 1, maxSize); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/ArrayModelConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | @Model(type = ArrayModel.class, fields = { 4 | @Field(name = "anIntArray", minSize = 2, maxSize = 5), 5 | @Field(name = "aStringArray", string = "abc"), 6 | @Field(name = "aShortMatrix", constant = -8), 7 | @Field(name = "aFloatArray", min = -1.1, max = 5.5), 8 | @Field(name = "aByteMatrix", size = 8), 9 | }) 10 | public class ArrayModelConfig { 11 | } 12 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/SomeTypeModeler.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | public class SomeTypeModeler extends Modeler { 4 | 5 | public static SomeType next() { 6 | return new SomeTypeModeler().next(null); 7 | } 8 | 9 | @Override 10 | protected void populate(SomeType model, ModelCache modelCache) { 11 | } 12 | 13 | @Override 14 | protected Class type() { 15 | return SomeType.class; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/Model.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Repeatable; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | @Target(ElementType.TYPE) 10 | @Retention(RetentionPolicy.CLASS) 11 | @Repeatable(Models.class) 12 | public @interface Model { 13 | 14 | Class type(); 15 | 16 | Field[] fields() default {}; 17 | } 18 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/AbstractListRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.List; 6 | 7 | public abstract class AbstractListRandomizer, E> extends CollectionRandomizer { 8 | 9 | protected AbstractListRandomizer(Randomizer elementRandomizer, int minSize, int maxSize) { 10 | super(elementRandomizer, minSize, maxSize); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/number/DoubleRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | 4 | public class DoubleRandomizer extends NumberRandomizer { 5 | 6 | public DoubleRandomizer(double min, double max) { 7 | super(min, max); 8 | } 9 | 10 | public DoubleRandomizer(Double constant) { 11 | super(constant); 12 | } 13 | 14 | @Override 15 | public Double random() { 16 | return doubleBetween(min, max); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/number/LongRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | 4 | public class LongRandomizer extends NumberRandomizer { 5 | 6 | public LongRandomizer(double min, double max) { 7 | super(min, max); 8 | } 9 | 10 | public LongRandomizer(Long constant) { 11 | super(constant); 12 | } 13 | 14 | @Override 15 | public Long random() { 16 | return doubleBetween(min, max).longValue(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/number/FloatRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | 4 | public class FloatRandomizer extends NumberRandomizer { 5 | 6 | public FloatRandomizer(double min, double max) { 7 | super(min, max); 8 | } 9 | 10 | public FloatRandomizer(Float constant) { 11 | super(constant); 12 | } 13 | 14 | @Override 15 | public Float random() { 16 | return doubleBetween(min, max).floatValue(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/number/ShortRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | 4 | public class ShortRandomizer extends NumberRandomizer { 5 | 6 | public ShortRandomizer(double min, double max) { 7 | super(min, max); 8 | } 9 | 10 | public ShortRandomizer(Short constant) { 11 | super(constant); 12 | } 13 | 14 | @Override 15 | public Short random() { 16 | return doubleBetween(min, max).shortValue(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/number/ByteRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | 4 | public class ByteRandomizer extends NumberRandomizer { 5 | 6 | public ByteRandomizer(double min, double max) { 7 | super(min, max); 8 | } 9 | 10 | public ByteRandomizer(Byte constant) { 11 | super(constant); 12 | } 13 | 14 | @Override 15 | public Byte random() { 16 | return doubleBetween(this.min, this.max).byteValue(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/string/StringRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.string; 2 | 3 | public class StringRandomizer extends CharSequenceRandomizer { 4 | 5 | public StringRandomizer(long min, long max, int charRange) { 6 | super(min, max, charRange); 7 | } 8 | 9 | public StringRandomizer(String constant) { 10 | super(constant); 11 | } 12 | 13 | protected String random() { 14 | return nextStringBuilder().toString(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/number/IntegerRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | 4 | public class IntegerRandomizer extends NumberRandomizer { 5 | 6 | public IntegerRandomizer(double min, double max) { 7 | super(min, max); 8 | } 9 | 10 | public IntegerRandomizer(Integer constant) { 11 | super(constant); 12 | } 13 | 14 | @Override 15 | protected Integer random() { 16 | return doubleBetween(min, max).intValue(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/NumericalModelConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | @Model(type = NumericalTypeModel.class, fields = { 4 | @Field(name = "anInt", max = 3, constant = 11.), 5 | @Field(name = "aShort", max = 10, constant = 11), 6 | @Field(name = "aByte", constant = 11), 7 | @Field(name = "aLong", constant = 11), 8 | @Field(name = "aFloat", constant = 11), 9 | @Field(name = "aDouble", constant = 11), 10 | }) 11 | public class NumericalModelConfig { 12 | } 13 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/SomeModelTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | class SomeModelTest { 8 | 9 | @Test 10 | void should_populate_nested_model() { 11 | final SomeModel next = SomeModelModeler.next(); 12 | 13 | assertThat(next).isNotNull(); 14 | assertThat(next.someNestedModel).isNotNull(); 15 | assertThat(next.someNestedModel.string).isNotNull(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/datetime/InstantRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import java.time.Instant; 4 | 5 | public class InstantRandomizer extends AbstractDateTimeRandomizer { 6 | 7 | public InstantRandomizer(long min, long max) { 8 | super(min, max); 9 | } 10 | 11 | public InstantRandomizer(Instant constant) { 12 | super(constant); 13 | } 14 | 15 | @Override 16 | public Instant random() { 17 | return instant(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/BoxedPrimitiveTypeModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | public class BoxedPrimitiveTypeModel { 4 | 5 | private Integer anInt; 6 | 7 | private Byte aByte; 8 | 9 | private Short aShort; 10 | 11 | private Long aLong; 12 | 13 | private Float aFloat; 14 | 15 | private Double aDouble; 16 | 17 | private Boolean aBoolean; 18 | 19 | private Character aChar; 20 | 21 | private String aString; 22 | 23 | public Integer getAnInt() { 24 | return anInt; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/BoxedPrimitiveTypeModelTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | class BoxedPrimitiveTypeModelTest { 8 | 9 | @Test 10 | void should_create_test_model_and_build_string_field() { 11 | final BoxedPrimitiveTypeModel model = BoxedPrimitiveTypeModelModeler.builder().build(); 12 | 13 | assertThat(model).isNotNull(); 14 | assertThat(model.getAnInt()).isNotNull(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/CustomTypeRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | public class CustomTypeRandomizer extends GenericRandomizer { 4 | 5 | private final Modeler modeler; 6 | 7 | private final ModelCache modelCache; 8 | 9 | public CustomTypeRandomizer(Modeler modeler, ModelCache modelCache) { 10 | this.modeler = modeler; 11 | this.modelCache = modelCache; 12 | } 13 | 14 | @Override 15 | protected T random() { 16 | return modeler.next(modelCache); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/number/NumberRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | import io.github.easymodeling.randomizer.GenericRandomizer; 4 | 5 | public abstract class NumberRandomizer extends GenericRandomizer { 6 | 7 | protected double min; 8 | 9 | protected double max; 10 | 11 | protected NumberRandomizer(double min, double max) { 12 | this.min = min; 13 | this.max = max; 14 | } 15 | 16 | protected NumberRandomizer(T constant) { 17 | super(constant); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/datetime/DateRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import java.time.Instant; 4 | import java.util.Date; 5 | 6 | public class DateRandomizer extends AbstractDateTimeRandomizer { 7 | 8 | public DateRandomizer(long min, long max) { 9 | super(min, max); 10 | } 11 | 12 | public DateRandomizer(Instant constant) { 13 | super(Date.from(constant)); 14 | } 15 | 16 | @Override 17 | public Date random() { 18 | return Date.from(instant()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/string/StringBuilderRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.string; 2 | 3 | public class StringBuilderRandomizer extends CharSequenceRandomizer { 4 | 5 | public StringBuilderRandomizer(long min, long max, int charRange) { 6 | super(min, max, charRange); 7 | } 8 | 9 | public StringBuilderRandomizer(StringBuilder constant) { 10 | super(constant); 11 | } 12 | 13 | @Override 14 | public StringBuilder random() { 15 | return nextStringBuilder(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/number/BigDecimalRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class BigDecimalRandomizer extends NumberRandomizer { 6 | 7 | public BigDecimalRandomizer(double min, double max) { 8 | super(min, max); 9 | } 10 | 11 | public BigDecimalRandomizer(BigDecimal constant) { 12 | super(constant); 13 | } 14 | 15 | @Override 16 | public BigDecimal random() { 17 | return BigDecimal.valueOf(doubleBetween(min, max)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/stream/StreamRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.stream; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.stream.Stream; 6 | 7 | public class StreamRandomizer extends AbstractStreamRandomizer, E> { 8 | 9 | public StreamRandomizer(Randomizer elementRandomizer, int minSize, int maxSize) { 10 | super(elementRandomizer, minSize, maxSize); 11 | } 12 | 13 | @Override 14 | protected Stream random() { 15 | return originalStream(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/ListModelTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | class ListModelTest { 8 | 9 | @Test 10 | void should_populate_list_model() { 11 | final ListModel model = ListModelModeler.next(); 12 | 13 | assertThat(model).isNotNull(); 14 | assertThat(model.listOfInts).isNotNull(); 15 | assertThat(model.listOfPrimitiveInts).isNull(); 16 | assertThat(model.arrayListOfListOfInts).isNotNull(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/number/BigIntegerRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | import java.math.BigInteger; 4 | 5 | public class BigIntegerRandomizer extends NumberRandomizer { 6 | 7 | public BigIntegerRandomizer(double min, double max) { 8 | super(min, max); 9 | } 10 | 11 | public BigIntegerRandomizer(BigInteger constant) { 12 | super(constant); 13 | } 14 | 15 | @Override 16 | public BigInteger random() { 17 | return BigInteger.valueOf(doubleBetween(min, max).longValue()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/CourseStudentTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | class CourseStudentTest { 8 | 9 | @Test 10 | void should_generate_course() { 11 | final Course course = CourseModeler.next(); 12 | 13 | assertThat(course).isNotNull(); 14 | } 15 | 16 | @Test 17 | void should_generate_student() { 18 | final Student student = StudentModeler.next(); 19 | 20 | assertThat(student).isNotNull(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/StringTypeModelConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | @Model(type = StringTypeModel.class, fields = { 4 | @Field(name = "commonString", min = 10, max = 20), 5 | @Field(name = "alphanumericString"), 6 | @Field(name = "alphabeticString", alphabetic = true), 7 | @Field(name = "numericString", numeric = true), 8 | @Field(name = "constString", string = "constString"), 9 | @Field(name = "builder"), 10 | }) 11 | @Model(type = Integer.class) 12 | @Model(type = int.class) 13 | public class StringTypeModelConfig { 14 | } 15 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/DatetimeModelConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | @Model(type = DatetimeModel.class, fields = { 4 | @Field(name = "instant"), 5 | @Field(name = "now", now = true), 6 | @Field(name = "before", before = "2000-01-01T00:00:00Z"), 7 | @Field(name = "after", after = "2000-01-01T00:00:00Z"), 8 | @Field(name = "localDate", datetime = "2000-01-01T00:00:00Z"), 9 | @Field(name = "nowDate", now = true), 10 | @Field(name = "constantDate", datetime = "2000-01-01T00:00:00Z"), 11 | }) 12 | public class DatetimeModelConfig { 13 | } 14 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/ModelerStreamTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.stream.Stream; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | @Model(type = Student.class) 10 | public class ModelerStreamTest { 11 | 12 | @Test 13 | void should_stream_be_infinite() { 14 | final long aBigInteger = 1_000_000_000L; 15 | 16 | final Stream studentStream = StudentModeler.stream(); 17 | 18 | assertThat(studentStream.limit(aBigInteger).count()).isLessThan(aBigInteger); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/SetRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | import java.util.function.Supplier; 8 | 9 | public class SetRandomizer extends AbstractSetRandomizer, E> { 10 | 11 | public SetRandomizer(Randomizer elementRandomizer, int maxSize) { 12 | super(elementRandomizer, maxSize); 13 | } 14 | 15 | @Override 16 | protected Supplier> collectionFactory() { 17 | return HashSet::new; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /functional-test/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | java { 4 | toolchain { 5 | languageVersion = JavaLanguageVersion.of(8) 6 | } 7 | } 8 | 9 | dependencies { 10 | testImplementation project(':core') 11 | testAnnotationProcessor project(':processor') 12 | 13 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1' 14 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.1' 15 | testImplementation 'org.assertj:assertj-core:3.23.1' 16 | } 17 | 18 | compileTestJava { 19 | options.compilerArgs << "-Aeasymodeling.log.model=DEBUG" 20 | } 21 | 22 | test { 23 | useJUnitPlatform() 24 | } 25 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/stream/LongStreamRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.stream; 2 | 3 | import io.github.easymodeling.randomizer.number.LongRandomizer; 4 | 5 | import java.util.stream.LongStream; 6 | 7 | public class LongStreamRandomizer extends AbstractStreamRandomizer { 8 | 9 | public LongStreamRandomizer(LongRandomizer elementRandomizer, int minSize, int maxSize) { 10 | super(elementRandomizer, minSize, maxSize); 11 | } 12 | 13 | @Override 14 | protected LongStream random() { 15 | return originalStream().mapToLong(Long::intValue); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/HashSetRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | import java.util.function.Supplier; 8 | 9 | public class HashSetRandomizer extends AbstractSetRandomizer, E> { 10 | 11 | public HashSetRandomizer(Randomizer elementRandomizer, int maxSize) { 12 | super(elementRandomizer, maxSize); 13 | } 14 | 15 | @Override 16 | protected Supplier> collectionFactory() { 17 | return HashSet::new; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/TreeSetRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.Set; 6 | import java.util.TreeSet; 7 | import java.util.function.Supplier; 8 | 9 | public class TreeSetRandomizer extends AbstractSetRandomizer, E> { 10 | 11 | public TreeSetRandomizer(Randomizer elementRandomizer, int maxSize) { 12 | super(elementRandomizer, maxSize); 13 | } 14 | 15 | @Override 16 | protected Supplier> collectionFactory() { 17 | return TreeSet::new; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/stream/IntStreamRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.stream; 2 | 3 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 4 | 5 | import java.util.stream.IntStream; 6 | 7 | public class IntStreamRandomizer extends AbstractStreamRandomizer { 8 | 9 | public IntStreamRandomizer(IntegerRandomizer elementRandomizer, int minSize, int maxSize) { 10 | super(elementRandomizer, minSize, maxSize); 11 | } 12 | 13 | @Override 14 | protected IntStream random() { 15 | return originalStream().mapToInt(Integer::intValue); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/ArrayListRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.ArrayList; 6 | import java.util.function.Supplier; 7 | 8 | public class ArrayListRandomizer extends AbstractListRandomizer, E> { 9 | 10 | public ArrayListRandomizer(Randomizer elementRandomizer, int minSize, int maxSize) { 11 | super(elementRandomizer, minSize, maxSize); 12 | } 13 | 14 | @Override 15 | protected Supplier> collectionFactory() { 16 | return ArrayList::new; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/ListRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.function.Supplier; 8 | 9 | public class ListRandomizer extends AbstractListRandomizer, E> { 10 | 11 | public ListRandomizer(Randomizer elementRandomizer, int minSize, int maxSize) { 12 | super(elementRandomizer, minSize, maxSize); 13 | } 14 | 15 | @Override 16 | protected Supplier> collectionFactory() { 17 | return ArrayList::new; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/stream/DoubleStreamRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.stream; 2 | 3 | import io.github.easymodeling.randomizer.number.DoubleRandomizer; 4 | 5 | import java.util.stream.DoubleStream; 6 | 7 | public class DoubleStreamRandomizer extends AbstractStreamRandomizer { 8 | 9 | public DoubleStreamRandomizer(DoubleRandomizer elementRandomizer, int minSize, int maxSize) { 10 | super(elementRandomizer, minSize, maxSize); 11 | } 12 | 13 | @Override 14 | protected DoubleStream random() { 15 | return originalStream().mapToDouble(Double::intValue); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/NumericalTypeModelTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | class NumericalTypeModelTest { 8 | 9 | @Test 10 | void should_create_numerical_type_model() { 11 | final NumericalTypeModel model = NumericalTypeModelModeler.builder().build(); 12 | 13 | assertThat(model.getAnInt()).isEqualTo(11); 14 | assertThat(model.getaShort()).isEqualTo((short) 11); 15 | 16 | assertThat(model.aBigDecimal).isNotNull(); 17 | assertThat(model.aBigInteger).isNotNull(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/LinkedListRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.LinkedList; 6 | import java.util.function.Supplier; 7 | 8 | public class LinkedListRandomizer extends AbstractListRandomizer, E> { 9 | 10 | public LinkedListRandomizer(Randomizer elementRandomizer, int minSize, int maxSize) { 11 | super(elementRandomizer, minSize, maxSize); 12 | } 13 | 14 | @Override 15 | protected Supplier> collectionFactory() { 16 | return LinkedList::new; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/HashMapRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.HashMap; 6 | import java.util.function.Supplier; 7 | 8 | public class HashMapRandomizer extends AbstractMapRandomizer, K, V> { 9 | 10 | public HashMapRandomizer(Randomizer keyRandomizer, Randomizer valueRandomizer, int maxSize) { 11 | super(keyRandomizer, valueRandomizer, maxSize); 12 | } 13 | 14 | @Override 15 | protected Supplier> collectionFactory() { 16 | return HashMap::new; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/TreeMapRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.TreeMap; 6 | import java.util.function.Supplier; 7 | 8 | public class TreeMapRandomizer extends AbstractMapRandomizer, K, V> { 9 | 10 | public TreeMapRandomizer(Randomizer keyRandomizer, Randomizer valueRandomizer, int maxSize) { 11 | super(keyRandomizer, valueRandomizer, maxSize); 12 | } 13 | 14 | @Override 15 | protected Supplier> collectionFactory() { 16 | return TreeMap::new; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/MapRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.Randomizer; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.function.Supplier; 8 | 9 | public class MapRandomizer extends AbstractMapRandomizer, K, V> { 10 | 11 | public MapRandomizer(Randomizer keyRandomizer, Randomizer valueRandomizer, int maxSize) { 12 | super(keyRandomizer, valueRandomizer, maxSize); 13 | } 14 | 15 | @Override 16 | protected Supplier> collectionFactory() { 17 | return HashMap::new; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/OrderTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.math.BigDecimal; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class OrderTest { 10 | 11 | @Test 12 | void should_generate_order() { 13 | final Order order = OrderModeler.builder().id("some-id").unitPrice(BigDecimal.TEN).build(); 14 | 15 | assertThat(order).isNotNull(); 16 | assertThat(order.getUnitPrice()).isEqualTo(BigDecimal.TEN); 17 | 18 | assertThat(order.getCreationTime()).isNotNull(); 19 | 20 | assertThat(order.orderLines).isNotNull(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/datetime/LocalDateRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import java.time.Instant; 4 | import java.time.LocalDate; 5 | import java.time.ZoneId; 6 | 7 | public class LocalDateRandomizer extends AbstractDateTimeRandomizer { 8 | 9 | public LocalDateRandomizer(long min, long max) { 10 | super(min, max); 11 | } 12 | 13 | public LocalDateRandomizer(Instant constant) { 14 | super(constant.atZone(ZoneId.systemDefault()).toLocalDate()); 15 | } 16 | 17 | @Override 18 | public LocalDate random() { 19 | return instant().atZone(ZoneId.systemDefault()).toLocalDate(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/datetime/LocalTimeRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import java.time.Instant; 4 | import java.time.LocalTime; 5 | import java.time.ZoneId; 6 | 7 | public class LocalTimeRandomizer extends AbstractDateTimeRandomizer { 8 | 9 | public LocalTimeRandomizer(long min, long max) { 10 | super(min, max); 11 | } 12 | 13 | public LocalTimeRandomizer(Instant constant) { 14 | super(constant.atZone(ZoneId.systemDefault()).toLocalTime()); 15 | } 16 | 17 | @Override 18 | public LocalTime random() { 19 | return instant().atZone(ZoneId.systemDefault()).toLocalTime(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/datetime/ZonedDateTimeRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import java.time.Instant; 4 | import java.time.ZoneId; 5 | import java.time.ZonedDateTime; 6 | 7 | public class ZonedDateTimeRandomizer extends AbstractDateTimeRandomizer { 8 | 9 | public ZonedDateTimeRandomizer(long min, long max) { 10 | super(min, max); 11 | } 12 | 13 | public ZonedDateTimeRandomizer(Instant constant) { 14 | super(constant.atZone(ZoneId.systemDefault())); 15 | } 16 | 17 | @Override 18 | public ZonedDateTime random() { 19 | return instant().atZone(ZoneId.systemDefault()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/datetime/SqlDateRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import java.sql.Date; 4 | import java.time.Instant; 5 | import java.time.ZoneId; 6 | 7 | public class SqlDateRandomizer extends AbstractDateTimeRandomizer { 8 | 9 | public SqlDateRandomizer(long min, long max) { 10 | super(min, max); 11 | } 12 | 13 | public SqlDateRandomizer(Instant constant) { 14 | super(Date.valueOf(constant.atZone(ZoneId.systemDefault()).toLocalDate())); 15 | } 16 | 17 | @Override 18 | public Date random() { 19 | return Date.valueOf(instant().atZone(ZoneId.systemDefault()).toLocalDate()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/OptionalRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | import java.util.Optional; 4 | 5 | public class OptionalRandomizer extends GenericRandomizer> { 6 | 7 | private final Randomizer valueRandomizer; 8 | 9 | private final Boolean allowEmpty; 10 | 11 | public OptionalRandomizer(Randomizer valueRandomizer, Boolean allowEmpty) { 12 | this.valueRandomizer = valueRandomizer; 13 | this.allowEmpty = allowEmpty; 14 | } 15 | 16 | @Override 17 | protected Optional random() { 18 | return (allowEmpty && oneThirdTruth()) ? Optional.empty() : Optional.of(valueRandomizer.next()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/DatetimeModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.time.Instant; 4 | import java.time.LocalDate; 5 | import java.time.LocalDateTime; 6 | import java.time.LocalTime; 7 | import java.util.Date; 8 | 9 | public class DatetimeModel { 10 | 11 | public Instant instant; 12 | 13 | public Instant now; 14 | 15 | public Instant before; 16 | 17 | public Instant after; 18 | 19 | public String[] strings; 20 | 21 | public LocalDate localDate; 22 | 23 | public LocalTime localTime; 24 | 25 | public LocalDateTime localDateTime; 26 | 27 | public Date date; 28 | 29 | public Date nowDate; 30 | 31 | public Date constantDate; 32 | } 33 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/derived/DerivedTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.derived; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | class DerivedTest { 8 | 9 | @Test 10 | void should_populate_derived_class_fields() { 11 | final Derived derived = DerivedModeler.next(); 12 | 13 | assertThat(derived).isNotNull(); 14 | assertThat(derived.derivedInt).isNotZero(); 15 | assertThat(derived.derivedInteger).isNotNull(); 16 | assertThat(derived.derivedString).isNotBlank(); 17 | assertThat(derived.baseInt).isNotNull(); 18 | assertThat(derived.baseString).isNotNull(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/datetime/LocalDateTimeRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import java.time.Instant; 4 | import java.time.LocalDateTime; 5 | import java.time.ZoneId; 6 | 7 | public class LocalDateTimeRandomizer extends AbstractDateTimeRandomizer { 8 | 9 | public LocalDateTimeRandomizer(long min, long max) { 10 | super(min, max); 11 | } 12 | 13 | public LocalDateTimeRandomizer(Instant constant) { 14 | super(constant.atZone(ZoneId.systemDefault()).toLocalDateTime()); 15 | } 16 | 17 | @Override 18 | public LocalDateTime random() { 19 | return instant().atZone(ZoneId.systemDefault()).toLocalDateTime(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/datetime/SqlTimestampRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import java.sql.Timestamp; 4 | import java.time.Instant; 5 | import java.time.ZoneId; 6 | 7 | public class SqlTimestampRandomizer extends AbstractDateTimeRandomizer { 8 | 9 | public SqlTimestampRandomizer(long min, long max) { 10 | super(min, max); 11 | } 12 | 13 | public SqlTimestampRandomizer(Instant constant) { 14 | super(Timestamp.valueOf(constant.atZone(ZoneId.systemDefault()).toLocalDateTime())); 15 | } 16 | 17 | @Override 18 | public Timestamp random() { 19 | return Timestamp.valueOf(instant().atZone(ZoneId.systemDefault()).toLocalDateTime()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/Order.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.Instant; 5 | import java.util.List; 6 | 7 | public class Order { 8 | 9 | private String id; 10 | 11 | private BigDecimal unitPrice; 12 | 13 | private long amount; 14 | 15 | private Instant creationTime; 16 | 17 | public String getId() { 18 | return id; 19 | } 20 | 21 | public BigDecimal getUnitPrice() { 22 | return unitPrice; 23 | } 24 | 25 | public long getAmount() { 26 | return amount; 27 | } 28 | 29 | public Instant getCreationTime() { 30 | return creationTime; 31 | } 32 | 33 | // @OneToMany 34 | public List orderLines; 35 | } 36 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/AbstractFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.TypeName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | 6 | public abstract class AbstractFieldTest { 7 | 8 | public static final String CLASS_NAME = "packageName.className"; 9 | 10 | public static final String FIELD_NAME = "fieldName"; 11 | 12 | public static final String QUALIFIED_NAME = CLASS_NAME + "#" + FIELD_NAME; 13 | 14 | protected FieldCustomization fieldCustomization; 15 | 16 | protected TypeName typeName; 17 | 18 | protected ModelField modelField; 19 | 20 | protected String $(Class clazz) { 21 | return clazz.getCanonicalName(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/log/LogLevel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.log; 2 | 3 | public enum LogLevel { 4 | ERROR(4), 5 | WARN(3), 6 | INFO(2), 7 | DEBUG(1), 8 | ; 9 | 10 | public static final LogLevel DEFAULT_LEVEL = WARN; 11 | 12 | private final int level; 13 | 14 | LogLevel(int level) { 15 | this.level = level; 16 | } 17 | 18 | boolean meets(LogLevel givenLevel) { 19 | return this.level >= givenLevel.level; 20 | } 21 | 22 | public static LogLevel of(String name) { 23 | for (LogLevel level : LogLevel.values()) { 24 | if (level.name().equalsIgnoreCase(name)) { 25 | return level; 26 | } 27 | } 28 | return DEFAULT_LEVEL; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/OrderLineTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.math.BigDecimal; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class OrderLineTest { 10 | 11 | @Test 12 | void should_generate_order_line() { 13 | OrderLine orderLine = OrderLineModeler.builder().id("some-id").build(); 14 | 15 | assertThat(orderLine).isNotNull(); 16 | assertThat(orderLine.getId()).isEqualTo("some-id"); 17 | } 18 | 19 | @Test 20 | void should_create_builder() { 21 | final Order order = OrderModeler.builder().id("some-id").unitPrice(BigDecimal.TEN).build(); 22 | 23 | assertThat(order.getUnitPrice()).isEqualTo(BigDecimal.TEN); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/datetime/AbstractDateTimeRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import io.github.easymodeling.randomizer.GenericRandomizer; 4 | 5 | import java.time.Instant; 6 | 7 | public abstract class AbstractDateTimeRandomizer extends GenericRandomizer { 8 | 9 | private long min; 10 | 11 | private long max; 12 | 13 | protected AbstractDateTimeRandomizer(long min, long max) { 14 | this.min = min; 15 | this.max = max; 16 | } 17 | 18 | protected AbstractDateTimeRandomizer(T constant) { 19 | super(constant); 20 | } 21 | 22 | public Instant instant() { 23 | final long milli = doubleBetween(min, max).longValue(); 24 | return Instant.ofEpochMilli(milli); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.github/actions/set-up-jdk/action.yml: -------------------------------------------------------------------------------- 1 | name: Set Up JDK 2 | description: Set up JDK with specific version 3 | inputs: 4 | jdk-version: 5 | required: true 6 | description: The JDK version to use for the test 7 | default: '8' 8 | runs: 9 | using: 'composite' 10 | steps: 11 | - name: 'Cache gradle dependencies' 12 | uses: actions/cache@v2 13 | with: 14 | path: | 15 | ~/.gradle/caches 16 | ~/.gradle/wrapper 17 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} 18 | restore-keys: | 19 | ${{ runner.os }}-gradle- 20 | - name: 'Set up JDK ${{ inputs.jdk-version }}' 21 | uses: actions/setup-java@v2 22 | with: 23 | java-version: ${{ inputs.jdk-version }} 24 | distribution: 'zulu' 25 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/OrderLine.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public class OrderLine { 6 | 7 | private String id; 8 | 9 | private String sku; 10 | 11 | private BigDecimal unitPrice; 12 | 13 | private BigDecimal amount; 14 | 15 | private BigDecimal taxRate; 16 | 17 | public String getId() { 18 | return id; 19 | } 20 | 21 | public String getSku() { 22 | return sku; 23 | } 24 | 25 | public BigDecimal getUnitPrice() { 26 | return unitPrice; 27 | } 28 | 29 | public BigDecimal getAmount() { 30 | return amount; 31 | } 32 | 33 | public BigDecimal getTaxRate() { 34 | return taxRate; 35 | } 36 | 37 | // @ManyToOne 38 | public Order order; 39 | } 40 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/collection/TreeSetRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | 6 | import java.util.Set; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | class TreeSetRandomizerTest { 11 | 12 | @RepeatedTest(100) 13 | void should_generate_random_set_with_size_in_the_range() { 14 | TreeSetRandomizer randomizer = new TreeSetRandomizer<>(new IntegerRandomizer(-200, 300), 33); 15 | 16 | final Set set = randomizer.next(); 17 | 18 | assertThat(set) 19 | .hasSizeLessThanOrEqualTo(33 - 1) 20 | .allMatch(i -> i >= -200 && i < 300); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | pull_request: 5 | types: [ opened, synchronize, reopened ] 6 | 7 | env: 8 | OSSRH_USERNAME: 'OSSRH_USERNAME' 9 | OSSRH_PASSWORD: 'OSSRH_PASSWORD' 10 | 11 | jobs: 12 | unit-test: 13 | name: Unit Test 14 | runs-on: ubuntu-latest 15 | timeout-minutes: 3 16 | strategy: 17 | matrix: 18 | java: [ '8', '11', '17', '18' ] 19 | steps: 20 | - name: 'Cancel previous runs' 21 | uses: styfle/cancel-workflow-action@0.11.0 22 | with: 23 | access_token: ${{ github.token }} 24 | - name: 'Checkout repository' 25 | uses: actions/checkout@v3 26 | - uses: ./.github/actions/set-up-jdk 27 | with: 28 | jdk-version: '${{ matrix.java }}' 29 | - name: 'Run test' 30 | run: ./gradlew clean test 31 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/stream/LongStreamRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.stream; 2 | 3 | import io.github.easymodeling.randomizer.number.LongRandomizer; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class LongStreamRandomizerTest { 12 | 13 | @RepeatedTest(100) 14 | void should_generate_long_stream() { 15 | LongStreamRandomizer randomizer = new LongStreamRandomizer(new LongRandomizer(1, 10), 2, 8); 16 | 17 | final List longs = randomizer.next().boxed().collect(Collectors.toList()); 18 | 19 | assertThat(longs) 20 | .hasSizeBetween(2, 7) 21 | .allMatch(i -> i >= 1 && i < 10); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | # Java sources 4 | *.java text diff=java 5 | *.gradle text diff=java 6 | 7 | # These files are binary and should be left untouched 8 | # (binary is a macro for -text -diff) 9 | *.class binary 10 | *.dll binary 11 | *.ear binary 12 | *.jar binary 13 | *.so binary 14 | *.war binary 15 | *.jks binary 16 | 17 | *.md text diff=markdown 18 | 19 | # Force batch scripts to always use CRLF line endings so that if a repo is accessed 20 | # in Windows via a file share from Linux, the scripts will work. 21 | *.{cmd,[cC][mM][dD]} text eol=crlf 22 | *.{bat,[bB][aA][tT]} text eol=crlf 23 | 24 | # Force bash scripts to always use LF line endings so that if a repo is accessed 25 | # in Unix via a file share from Windows, the scripts will work. 26 | *.sh text eol=lf 27 | -------------------------------------------------------------------------------- /.github/actions/unit-test/action.yml: -------------------------------------------------------------------------------- 1 | name: Unit Test 2 | description: Run unit tests 3 | inputs: 4 | jdk-version: 5 | required: true 6 | description: The JDK version to use for the test 7 | default: '8' 8 | runs: 9 | using: 'composite' 10 | steps: 11 | - name: 'Cache gradle dependencies' 12 | uses: actions/cache@v2 13 | with: 14 | path: | 15 | ~/.gradle/caches 16 | ~/.gradle/wrapper 17 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} 18 | restore-keys: | 19 | ${{ runner.os }}-gradle- 20 | - name: 'Set up JDK ${{ inputs.jdk-version }}' 21 | uses: actions/setup-java@v2 22 | with: 23 | java-version: ${{ inputs.jdk-version }} 24 | distribution: 'zulu' 25 | - name: 'Run test' 26 | shell: bash 27 | run: ./gradlew clean test 28 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/collection/ListRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 5 | import org.junit.jupiter.api.RepeatedTest; 6 | 7 | import java.util.List; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class ListRandomizerTest extends RandomizerTest { 12 | 13 | @RepeatedTest(100) 14 | void should_generate_random_list_with_size_in_the_range() { 15 | ListRandomizer randomizer = new ListRandomizer<>(new IntegerRandomizer(-2, 3), 3, 7); 16 | 17 | final List list = randomizer.next(); 18 | 19 | assertThat(list) 20 | .hasSizeBetween(3, 6) 21 | .allMatch(i -> i >= -2 && i < 3); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/collection/SetRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 5 | import org.junit.jupiter.api.RepeatedTest; 6 | 7 | import java.util.Set; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class SetRandomizerTest extends RandomizerTest { 12 | 13 | @RepeatedTest(100) 14 | void should_generate_random_set_with_size_in_the_range() { 15 | SetRandomizer randomizer = new SetRandomizer<>(new IntegerRandomizer(-2, 300), 7); 16 | 17 | final Set set = randomizer.next(); 18 | 19 | assertThat(set) 20 | .hasSizeLessThanOrEqualTo(7 - 1) 21 | .allMatch(i -> i >= -2 && i < 300); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/EnumField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.TypeName; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.randomizer.EnumRandomizer; 7 | 8 | public class EnumField extends ModelField { 9 | 10 | public EnumField(TypeName type, FieldCustomization customization) { 11 | super(type, customization); 12 | } 13 | 14 | @Override 15 | public CodeBlock initializer() { 16 | return CodeBlock.of("new $T<>($T.values())", EnumRandomizer.class, type); 17 | } 18 | 19 | @Override 20 | public ModelField create(FieldCustomization customization, ModelField... valueFields) { 21 | throw new UnsupportedOperationException("Create EnumField with constructor"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/PlainField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.TypeName; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.randomizer.Randomizer; 7 | 8 | public abstract class PlainField extends ModelField { 9 | 10 | protected PlainField() { 11 | } 12 | 13 | protected PlainField(TypeName type, FieldCustomization customization) { 14 | super(type, customization); 15 | } 16 | 17 | @Override 18 | public CodeBlock initializer() { 19 | return CodeBlock.of("new $T($L)", initializerType(), initializerParameter()); 20 | } 21 | 22 | protected abstract Class> initializerType(); 23 | 24 | protected abstract CodeBlock initializerParameter(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/log/LogLevelTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.log; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.ValueSource; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | 8 | class LogLevelTest { 9 | 10 | @ParameterizedTest 11 | @ValueSource(strings = {"ERROR", "WARN", "INFO", "DEBUG"}) 12 | void should_create_log_level_with_string(String name) { 13 | LogLevel level = LogLevel.of(name); 14 | 15 | assertThat(level.name()).isEqualTo(name); 16 | } 17 | 18 | @ParameterizedTest 19 | @ValueSource(strings = {"", "\t", "UNKNOWN"}) 20 | void should_create_default_level_with_unknown_names(String unknownName) { 21 | LogLevel level = LogLevel.of(unknownName); 22 | 23 | assertThat(level).isEqualTo(LogLevel.DEFAULT_LEVEL); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/RandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | import org.junit.jupiter.api.BeforeAll; 4 | 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.Modifier; 7 | import java.util.Random; 8 | 9 | public abstract class RandomizerTest { 10 | 11 | @BeforeAll 12 | protected static void baseSetUp() { 13 | try { 14 | final Field field = GenericRandomizer.class.getDeclaredField("random"); 15 | Field modifiersField = Field.class.getDeclaredField("modifiers"); 16 | modifiersField.setAccessible(true); 17 | modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 18 | 19 | field.set(null, new Random(0)); 20 | } catch (NoSuchFieldException | IllegalAccessException e) { 21 | throw new RuntimeException(e); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/collection/HashSetRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 5 | import org.junit.jupiter.api.RepeatedTest; 6 | 7 | import java.util.Set; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class HashSetRandomizerTest extends RandomizerTest { 12 | 13 | @RepeatedTest(100) 14 | void should_generate_random_set_with_size_in_the_range() { 15 | HashSetRandomizer randomizer = new HashSetRandomizer<>(new IntegerRandomizer(-2, 300), 7); 16 | 17 | final Set set = randomizer.next(); 18 | 19 | assertThat(set) 20 | .hasSizeLessThanOrEqualTo(7 - 1) 21 | .allMatch(i -> i >= -2 && i < 300); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/collection/ArrayListRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 5 | import org.junit.jupiter.api.RepeatedTest; 6 | 7 | import java.util.ArrayList; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class ArrayListRandomizerTest extends RandomizerTest { 12 | 13 | @RepeatedTest(100) 14 | void should_generate_random_array_list_with_size_in_the_range() { 15 | ArrayListRandomizer randomizer = new ArrayListRandomizer<>(new IntegerRandomizer(-2, 3), 3, 7); 16 | 17 | final ArrayList list = randomizer.next(); 18 | 19 | assertThat(list) 20 | .hasSizeBetween(3, 6) 21 | .allMatch(i -> i >= -2 && i < 3); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/collection/LinkedListRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 5 | import org.junit.jupiter.api.RepeatedTest; 6 | 7 | import java.util.LinkedList; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class LinkedListRandomizerTest extends RandomizerTest { 12 | 13 | @RepeatedTest(100) 14 | void should_generate_random_linked_list_with_size_in_the_range() { 15 | LinkedListRandomizer randomizer = new LinkedListRandomizer<>(new IntegerRandomizer(-2, 3), 3, 7); 16 | 17 | final LinkedList list = randomizer.next(); 18 | 19 | assertThat(list) 20 | .hasSizeBetween(3, 6) 21 | .allMatch(i -> i >= -2 && i < 3); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/number/LongRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class LongRandomizerTest extends RandomizerTest { 10 | 11 | @RepeatedTest(100) 12 | void should_generate_long_between_range() { 13 | LongRandomizer randomizer = new LongRandomizer(-2., 2.); 14 | 15 | final Long next = randomizer.next(); 16 | 17 | assertThat(next).isBetween((long) -2, (long) 2); 18 | } 19 | 20 | @Test 21 | void should_generate_constant_long() { 22 | LongRandomizer randomizer = new LongRandomizer(-2L); 23 | 24 | final Long next = randomizer.next(); 25 | 26 | assertThat(next).isEqualTo(-2L); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/number/DoubleRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class DoubleRandomizerTest extends RandomizerTest { 10 | 11 | @RepeatedTest(100) 12 | void should_generate_double_between_range() { 13 | DoubleRandomizer randomizer = new DoubleRandomizer(-2., 2.); 14 | 15 | final Double next = randomizer.next(); 16 | 17 | assertThat(next).isBetween(-2., 2.); 18 | } 19 | 20 | @Test 21 | void should_generate_constant_double() { 22 | DoubleRandomizer randomizer = new DoubleRandomizer(-2.); 23 | 24 | final Double next = randomizer.next(); 25 | 26 | assertThat(next).isEqualTo(-2); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/number/ByteRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class ByteRandomizerTest extends RandomizerTest { 10 | 11 | @RepeatedTest(100) 12 | void should_generate_byte_between_range() { 13 | ByteRandomizer randomizer = new ByteRandomizer(-2., 2.); 14 | 15 | final Byte next = randomizer.next(); 16 | 17 | assertThat(next).isBetween((byte) -2, (byte) 2); 18 | } 19 | 20 | @Test 21 | void should_generate_constant_byte() { 22 | ByteRandomizer randomizer = new ByteRandomizer((byte) -2); 23 | 24 | final Byte next = randomizer.next(); 25 | 26 | assertThat(next).isEqualTo((byte) -2); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/number/IntegerRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class IntegerRandomizerTest extends RandomizerTest { 10 | 11 | @RepeatedTest(100) 12 | void should_generate_integer_between_range() { 13 | IntegerRandomizer randomizer = new IntegerRandomizer(-2., 2.); 14 | 15 | final Integer next = randomizer.next(); 16 | 17 | assertThat(next).isBetween(-2, 2); 18 | } 19 | 20 | @Test 21 | void should_generate_constant_integer() { 22 | IntegerRandomizer randomizer = new IntegerRandomizer(-2); 23 | 24 | final Integer next = randomizer.next(); 25 | 26 | assertThat(next).isEqualTo(-2); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/stream/IntStreamRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.stream; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 5 | import org.junit.jupiter.api.RepeatedTest; 6 | 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | class IntStreamRandomizerTest extends RandomizerTest { 13 | 14 | @RepeatedTest(100) 15 | void should_generate_int_stream() { 16 | IntStreamRandomizer randomizer = new IntStreamRandomizer(new IntegerRandomizer(-5, 10), 100, 110); 17 | 18 | final List ints = randomizer.next().boxed().collect(Collectors.toList()); 19 | 20 | assertThat(ints) 21 | .hasSizeBetween(100, 109) 22 | .allMatch(i -> i >= -5 && i < 10); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/number/ShortRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class ShortRandomizerTest extends RandomizerTest { 10 | 11 | @RepeatedTest(100) 12 | void should_generate_short_between_range() { 13 | ShortRandomizer randomizer = new ShortRandomizer(-2., 2.); 14 | 15 | final Short next = randomizer.next(); 16 | 17 | assertThat(next).isBetween((short) -2, (short) 2); 18 | } 19 | 20 | @Test 21 | void should_generate_constant_short() { 22 | ShortRandomizer randomizer = new ShortRandomizer((short) 2); 23 | 24 | final Short next = randomizer.next(); 25 | 26 | assertThat(next).isEqualTo((short) 2); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/UnknownField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.TypeName; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | 7 | public class UnknownField extends ModelField { 8 | 9 | public UnknownField(TypeName type, FieldCustomization customization) { 10 | super(type, customization); 11 | } 12 | 13 | @Override 14 | public CodeBlock initialValue() { 15 | return CodeBlock.of("null"); 16 | } 17 | 18 | @Override 19 | public CodeBlock initializer() { 20 | throw new UnsupportedOperationException("Not supported yet."); 21 | } 22 | 23 | @Override 24 | public PlainField create(FieldCustomization customization, ModelField... valueFields) { 25 | throw new UnsupportedOperationException("Create UnknownField with constructor"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/number/FloatRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class FloatRandomizerTest extends RandomizerTest { 10 | 11 | @RepeatedTest(100) 12 | void should_generate_float_between_range() { 13 | FloatRandomizer randomizer = new FloatRandomizer(-2., 2.); 14 | 15 | final Float next = randomizer.next(); 16 | 17 | assertThat(next).isBetween((float) -2, (float) 2); 18 | } 19 | 20 | @Test 21 | void should_generate_constant_float() { 22 | FloatRandomizer randomizer = new FloatRandomizer((float) -2); 23 | 24 | final Float next = randomizer.next(); 25 | 26 | assertThat(next).isEqualTo((float) -2); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/stream/DoubleStreamRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.stream; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import io.github.easymodeling.randomizer.number.DoubleRandomizer; 5 | import org.junit.jupiter.api.RepeatedTest; 6 | 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | class DoubleStreamRandomizerTest extends RandomizerTest { 13 | 14 | @RepeatedTest(100) 15 | void should_generate_double_stream() { 16 | DoubleStreamRandomizer randomizer = new DoubleStreamRandomizer(new DoubleRandomizer(-0.1, 1.1), 2, 7); 17 | 18 | final List doubles = randomizer.next().boxed().collect(Collectors.toList()); 19 | 20 | assertThat(doubles) 21 | .hasSizeBetween(2, 6) 22 | .allMatch(i -> i >= -0.1 && i < 1.1); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/stream/StreamRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.stream; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 5 | import org.junit.jupiter.api.RepeatedTest; 6 | 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | class StreamRandomizerTest extends RandomizerTest { 13 | 14 | @RepeatedTest(100) 15 | void should_generate_stream_with_size_between_given_range() { 16 | StreamRandomizer randomizer = new StreamRandomizer<>(new IntegerRandomizer(-5, 10), 1, 10); 17 | 18 | final List generated = randomizer.next().collect(Collectors.toList()); 19 | 20 | assertThat(generated) 21 | .hasSizeBetween(1, 9) 22 | .allMatch(i -> i >= -5 && i < 10); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/StringTypeModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | public class StringTypeModel { 4 | 5 | private String commonString; 6 | 7 | private String alphanumericString; 8 | 9 | private String alphabeticString; 10 | 11 | private String numericString; 12 | 13 | private String constString; 14 | 15 | private StringBuilder builder; 16 | 17 | public String getCommonString() { 18 | return commonString; 19 | } 20 | 21 | public String getAlphanumericString() { 22 | return alphanumericString; 23 | } 24 | 25 | public String getAlphabeticString() { 26 | return alphabeticString; 27 | } 28 | 29 | public String getNumericString() { 30 | return numericString; 31 | } 32 | 33 | public String getConstString() { 34 | return constString; 35 | } 36 | 37 | public StringBuilder getBuilder() { 38 | return builder; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/Modeler.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | import io.github.easymodeling.ReflectionUtil; 4 | 5 | public abstract class Modeler { 6 | 7 | protected T next(ModelCache modelCache) { 8 | if (modelCache == null) { 9 | modelCache = new ModelCache(); 10 | } 11 | final Class clazz = type(); 12 | if (modelCache.avoidInfinity(clazz)) { 13 | return modelCache.random(clazz); 14 | } 15 | return createModel(modelCache); 16 | } 17 | 18 | private T createModel(ModelCache modelCache) { 19 | final Class clazz = type(); 20 | final T model = ReflectionUtil.createModelOf(clazz); 21 | modelCache.push(model); 22 | populate(model, modelCache); 23 | return model; 24 | } 25 | 26 | protected abstract void populate(T model, ModelCache modelCache); 27 | 28 | protected abstract Class type(); 29 | } 30 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/StreamModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.util.stream.DoubleStream; 4 | import java.util.stream.IntStream; 5 | import java.util.stream.LongStream; 6 | import java.util.stream.Stream; 7 | 8 | public class StreamModel { 9 | 10 | public Stream streamOfStrings; 11 | 12 | public IntStream intStream; 13 | 14 | public Stream streamOfIntStreams; 15 | 16 | public IntStream[] intStreamArray; 17 | 18 | public IntStream[][] intStreamMatrix; 19 | 20 | public LongStream longStream; 21 | 22 | public Stream streamOfLongStreams; 23 | 24 | public LongStream[] longStreamArray; 25 | 26 | public LongStream[][] longStreamMatrix; 27 | 28 | public DoubleStream doubleStream; 29 | 30 | public Stream streamOfDoubleStreams; 31 | 32 | public DoubleStream[] doubleStreamArray; 33 | 34 | public DoubleStream[][] doubleStreamMatrix; 35 | } 36 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/ListModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class ListModel { 7 | 8 | public List> listOfListOfArrayOfInts; 9 | 10 | public List[]> listOfArrayOfListOfArrayOfInts; 11 | 12 | public List listOfArrayOfInts; 13 | 14 | public List[] arrayOfListOfArrayOfInts; 15 | 16 | public List listOfMatrixOfInts; 17 | 18 | public List[][][] cubeOfListOfInts; 19 | 20 | public List[][] matrixOfListOfInts; 21 | 22 | public List[] arrayOfListOfInts; 23 | 24 | public List listOfInts; 25 | 26 | public List listOfPrimitiveInts; 27 | 28 | public List> listOfListOfInts; 29 | 30 | public List>> listOfListOfListOfInts; 31 | 32 | public ArrayList> arrayListOfListOfInts; 33 | } 34 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/NumericalTypeModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.BigInteger; 5 | 6 | public class NumericalTypeModel { 7 | 8 | private Integer anInt; 9 | 10 | private Byte aByte; 11 | 12 | private Short aShort; 13 | 14 | private Long aLong; 15 | 16 | private Float aFloat; 17 | 18 | private Double aDouble; 19 | 20 | public BigDecimal aBigDecimal; 21 | 22 | public BigInteger aBigInteger; 23 | 24 | public Integer getAnInt() { 25 | return anInt; 26 | } 27 | 28 | public Byte getaByte() { 29 | return aByte; 30 | } 31 | 32 | public Short getaShort() { 33 | return aShort; 34 | } 35 | 36 | public Long getaLong() { 37 | return aLong; 38 | } 39 | 40 | public Float getaFloat() { 41 | return aFloat; 42 | } 43 | 44 | public Double getaDouble() { 45 | return aDouble; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/collection/TreeMapRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 4 | import io.github.easymodeling.randomizer.string.StringRandomizer; 5 | import org.junit.jupiter.api.RepeatedTest; 6 | 7 | import java.util.TreeMap; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class TreeMapRandomizerTest { 12 | 13 | @RepeatedTest(100) 14 | void should_generate_random_map() { 15 | final TreeMapRandomizer treeMapRandomizer = new TreeMapRandomizer<>(new IntegerRandomizer(-2, 300), new StringRandomizer("some-string"), 7); 16 | 17 | final TreeMap next = treeMapRandomizer.next(); 18 | 19 | assertThat(next).hasSizeLessThanOrEqualTo(7 - 1); 20 | assertThat(next.keySet()).allMatch(key -> key >= -2 && key <= 300); 21 | assertThat(next.values()).containsOnly("some-string"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /functional-test/artifact-verification.build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | java { 4 | toolchain { 5 | languageVersion = JavaLanguageVersion.of(8) 6 | } 7 | } 8 | 9 | repositories { 10 | maven { 11 | url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' 12 | } 13 | } 14 | 15 | dependencies { 16 | testImplementation "io.github.easymodeling:easy-modeling:${projectVersion}" 17 | testAnnotationProcessor "io.github.easymodeling:easy-modeling-processor:${projectVersion}" 18 | 19 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' 20 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' 21 | testImplementation 'org.assertj:assertj-core:3.21.0' 22 | } 23 | 24 | test { 25 | def liner = '===========================================' 26 | println "\n" + liner + "\n" + 27 | "artifact-verification.build.gradle\n\n" + 28 | "Test on artifact Version: ${projectVersion}\n" + 29 | liner + "\n" 30 | useJUnitPlatform() 31 | } 32 | -------------------------------------------------------------------------------- /.github/actions/publish-artifact/action.yml: -------------------------------------------------------------------------------- 1 | name: Publish Artifacts 2 | description: Publish artifacts to maven central 3 | 4 | inputs: 5 | signing-secret-key-ring-b64: 6 | required: true 7 | description: The base64 encoded signing secret key ring 8 | signing-key-id: 9 | required: true 10 | description: The signing key id 11 | signing-key-password: 12 | required: true 13 | description: The signing key password 14 | 15 | runs: 16 | using: 'composite' 17 | steps: 18 | - name: 'Decode Secret' 19 | shell: bash 20 | run: | 21 | echo "${{ inputs.signing-secret-key-ring-b64 }}" > ~/.gradle/secring.gpg.b64 22 | base64 -d ~/.gradle/secring.gpg.b64 > ~/.gradle/secring.gpg 23 | - name: 'Publish Artifact' 24 | shell: bash 25 | run: | 26 | ./gradlew clean build publish \ 27 | -Psigning.keyId=${{ inputs.signing-key-id }} \ 28 | -Psigning.password="${{ inputs.signing-key-password }}" \ 29 | -Psigning.secretKeyRingFile=$(echo ~/.gradle/secring.gpg) 30 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/stream/AbstractStreamRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.stream; 2 | 3 | import io.github.easymodeling.randomizer.GenericRandomizer; 4 | import io.github.easymodeling.randomizer.Randomizer; 5 | 6 | import java.util.stream.BaseStream; 7 | import java.util.stream.Stream; 8 | 9 | public abstract class AbstractStreamRandomizer, E> extends GenericRandomizer { 10 | 11 | protected Randomizer elementRandomizer; 12 | 13 | protected int minSize; 14 | 15 | protected int maxSize; 16 | 17 | protected AbstractStreamRandomizer(Randomizer elementRandomizer, int minSize, int maxSize) { 18 | this.elementRandomizer = elementRandomizer; 19 | this.minSize = minSize; 20 | this.maxSize = maxSize; 21 | } 22 | 23 | protected Stream originalStream() { 24 | int size = doubleBetween(minSize, maxSize).intValue(); 25 | return Stream.generate(elementRandomizer::next).limit(size); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/collection/MapRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 5 | import io.github.easymodeling.randomizer.string.StringRandomizer; 6 | import org.junit.jupiter.api.RepeatedTest; 7 | 8 | import java.util.Map; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | class MapRandomizerTest extends RandomizerTest { 13 | 14 | @RepeatedTest(100) 15 | void should_generate_random_map() { 16 | final MapRandomizer mapRandomizer = new MapRandomizer<>(new IntegerRandomizer(-2, 300), new StringRandomizer("some-string"), 7); 17 | 18 | final Map next = mapRandomizer.next(); 19 | 20 | assertThat(next).hasSizeLessThanOrEqualTo(7 - 1); 21 | assertThat(next.keySet()).allMatch(key -> key >= -2 && key <= 300); 22 | assertThat(next.values()).containsOnly("some-string"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/ModelerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | import java.util.stream.IntStream; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class ModelerTest { 12 | 13 | @Test 14 | void should_create_model() { 15 | final SomeType next = SomeTypeModeler.next(); 16 | 17 | assertThat(next).isNotNull(); 18 | } 19 | 20 | @Test 21 | void should_return_cached_model_randomly_of_pool_to_avoid_infinity() { 22 | final ModelCache modelCache = new ModelCache(); 23 | final List modelList = IntStream.range(0, ModelCache.POOL_SIZE) 24 | .mapToObj(SomeType::new) 25 | .collect(Collectors.toList()); 26 | modelList.forEach(modelCache::push); 27 | 28 | final SomeType random = new SomeTypeModeler().next(modelCache); 29 | 30 | assertThat(random).isNotNull().isIn(modelList); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/PrimitiveTypeTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | class PrimitiveTypeTest { 8 | 9 | @Test 10 | void should_create_test_model() { 11 | final PrimitiveTypeModel testModel = PrimitiveTypeModelModeler.builder().build(); 12 | 13 | assertThat(testModel).isNotNull(); 14 | assertThat(testModel.getaString()).isNotNull(); 15 | } 16 | 17 | @Test 18 | void should_create_test_model_and_build_string_field() { 19 | final PrimitiveTypeModel testModel = PrimitiveTypeModelModeler.builder().aString("some-string").build(); 20 | 21 | assertThat(testModel).isNotNull(); 22 | assertThat(testModel.getaString()).isEqualTo("some-string"); 23 | } 24 | 25 | @Test 26 | void should_create_test_model_with_next_method() { 27 | final PrimitiveTypeModel testModel = PrimitiveTypeModelModeler.next(); 28 | 29 | assertThat(testModel).isNotNull(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/number/BigIntegerRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.math.BigInteger; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class BigIntegerRandomizerTest extends RandomizerTest { 12 | 13 | @RepeatedTest(100) 14 | void should_generate_byte_between_range() { 15 | BigIntegerRandomizer randomizer = new BigIntegerRandomizer(-3., 1.); 16 | 17 | final BigInteger next = randomizer.next(); 18 | 19 | assertThat(next).isBetween(BigInteger.valueOf(-3L), BigInteger.valueOf(1L)); 20 | } 21 | 22 | @Test 23 | void should_generate_constant_byte() { 24 | BigIntegerRandomizer randomizer = new BigIntegerRandomizer(BigInteger.valueOf(-2L)); 25 | 26 | final BigInteger next = randomizer.next(); 27 | 28 | assertThat(next).isEqualTo(BigInteger.valueOf(-2L)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/number/BigDecimalRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.number; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.math.BigDecimal; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class BigDecimalRandomizerTest extends RandomizerTest { 12 | 13 | @RepeatedTest(100) 14 | void should_generate_byte_between_range() { 15 | BigDecimalRandomizer randomizer = new BigDecimalRandomizer(-3.6, 1.1); 16 | 17 | final BigDecimal next = randomizer.next(); 18 | 19 | assertThat(next).isBetween(BigDecimal.valueOf(-3.6), BigDecimal.valueOf(1.1)); 20 | } 21 | 22 | @Test 23 | void should_generate_constant_byte() { 24 | BigDecimalRandomizer randomizer = new BigDecimalRandomizer(BigDecimal.valueOf(-2.1)); 25 | 26 | final BigDecimal next = randomizer.next(); 27 | 28 | assertThat(next).isEqualTo(BigDecimal.valueOf(-2.1)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/AbstractMapRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.GenericRandomizer; 4 | import io.github.easymodeling.randomizer.Randomizer; 5 | 6 | import java.util.Map; 7 | import java.util.function.Supplier; 8 | 9 | public abstract class AbstractMapRandomizer, K, V> extends GenericRandomizer { 10 | 11 | protected SetRandomizer keyRandomizer; 12 | 13 | protected Randomizer valueRandomizer; 14 | 15 | protected AbstractMapRandomizer(Randomizer keyRandomizer, Randomizer valueRandomizer, int maxSize) { 16 | this.keyRandomizer = new SetRandomizer<>(keyRandomizer, maxSize); 17 | this.valueRandomizer = valueRandomizer; 18 | } 19 | 20 | @Override 21 | protected M random() { 22 | return keyRandomizer.next().stream() 23 | .collect(collectionFactory(), (m, k) -> m.put(k, valueRandomizer.next()), Map::putAll); 24 | } 25 | 26 | protected abstract Supplier collectionFactory(); 27 | } 28 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/collection/HashMapRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 5 | import io.github.easymodeling.randomizer.string.StringRandomizer; 6 | import org.junit.jupiter.api.RepeatedTest; 7 | 8 | import java.util.HashMap; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | class HashMapRandomizerTest extends RandomizerTest { 13 | 14 | @RepeatedTest(100) 15 | void should_generate_random_map() { 16 | final HashMapRandomizer hashMapRandomizer = new HashMapRandomizer<>(new IntegerRandomizer(-2, 300), new StringRandomizer("some-string"), 7); 17 | 18 | final HashMap next = hashMapRandomizer.next(); 19 | 20 | assertThat(next).hasSizeLessThanOrEqualTo(7 - 1); 21 | assertThat(next.keySet()).allMatch(key -> key >= -2 && key <= 300); 22 | assertThat(next.values()).containsOnly("some-string"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/string/StringField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.string; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.randomizer.Randomizer; 7 | import io.github.easymodeling.randomizer.string.StringRandomizer; 8 | 9 | public class StringField extends CharSequenceField { 10 | 11 | public static final ClassName TYPE = ClassName.get(String.class); 12 | 13 | public StringField() { 14 | this.type = TYPE; 15 | } 16 | 17 | @Override 18 | public StringField create(FieldCustomization customization, ModelField... valueFields) { 19 | return new StringField(customization); 20 | } 21 | 22 | private StringField(FieldCustomization customization) { 23 | super(TYPE, customization); 24 | } 25 | 26 | @Override 27 | protected Class> initializerType() { 28 | return StringRandomizer.class; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/collection/AbstractMapField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import com.squareup.javapoet.ParameterizedTypeName; 6 | import io.github.easymodeling.modeler.FieldCustomization; 7 | import io.github.easymodeling.modeler.field.Container; 8 | import io.github.easymodeling.modeler.field.ModelField; 9 | 10 | public abstract class AbstractMapField extends Container { 11 | 12 | protected AbstractMapField() { 13 | } 14 | 15 | protected AbstractMapField(ClassName container, FieldCustomization customization, ModelField keyField, ModelField valueField) { 16 | super(ParameterizedTypeName.get(container, keyField.type(), valueField.type()), customization, keyField, valueField); 17 | } 18 | 19 | @Override 20 | protected CodeBlock initializerParameter() { 21 | return CodeBlock.of("$L", maxSize()); 22 | } 23 | 24 | private int maxSize() { 25 | return customization.maxSize().orElse(20); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/HidingFieldsGrouper.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler; 2 | 3 | import io.github.easymodeling.modeler.field.ModelField; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.function.Function; 9 | import java.util.stream.Collector; 10 | import java.util.stream.Collectors; 11 | 12 | public class HidingFieldsGrouper { 13 | 14 | private HidingFieldsGrouper() { 15 | } 16 | 17 | public static final Collector>> GROUPER = 18 | Collectors.groupingBy( 19 | ModelField::fieldName, 20 | Collector.of(ArrayList::new, List::add, (l, r) -> null, hiddenFieldsMarker())); 21 | 22 | private static Function, List> hiddenFieldsMarker() { 23 | return fields -> { 24 | if (fields.size() > 1) { 25 | fields.stream().filter(ModelField::isInherited).forEach(ModelField::setHidden); 26 | } 27 | return fields; 28 | }; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/datetime/DateField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.datetime; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.randomizer.Randomizer; 7 | import io.github.easymodeling.randomizer.datetime.DateRandomizer; 8 | 9 | import java.util.Date; 10 | 11 | public class DateField extends AbstractDateTimeField { 12 | 13 | public static final ClassName TYPE = ClassName.get(Date.class); 14 | 15 | public DateField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public DateField create(FieldCustomization customization, ModelField... valueFields) { 21 | return new DateField(customization); 22 | } 23 | 24 | private DateField(FieldCustomization customization) { 25 | super(TYPE, customization); 26 | } 27 | 28 | @Override 29 | protected Class> initializerType() { 30 | return DateRandomizer.class; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/primitive/CharFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.primitive; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 7 | import io.github.easymodeling.randomizer.primitive.CharRandomizer; 8 | import org.junit.jupiter.api.BeforeEach; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | class CharFieldTest extends ModelFieldTest { 13 | 14 | @BeforeEach 15 | @Override 16 | protected void setUp() { 17 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).build(); 18 | typeName = ClassName.get(Character.class); 19 | modelField = new CharField().create(fieldCustomization); 20 | } 21 | 22 | @Override 23 | protected void should_generate_initializer() { 24 | final CodeBlock initialValue = modelField.initializer(); 25 | 26 | assertThat(initialValue).hasToString("new " + $(CharRandomizer.class) + "()"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/datetime/SqlDateField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.datetime; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.randomizer.Randomizer; 7 | import io.github.easymodeling.randomizer.datetime.SqlDateRandomizer; 8 | 9 | import java.sql.Date; 10 | 11 | public class SqlDateField extends AbstractDateTimeField { 12 | 13 | public static final ClassName TYPE = ClassName.get(Date.class); 14 | 15 | public SqlDateField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public SqlDateField create(FieldCustomization customization, ModelField... valueFields) { 21 | return new SqlDateField(customization); 22 | } 23 | 24 | private SqlDateField(FieldCustomization customization) { 25 | super(TYPE, customization); 26 | } 27 | 28 | @Override 29 | protected Class> initializerType() { 30 | return SqlDateRandomizer.class; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/primitive/BooleanFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.primitive; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 7 | import io.github.easymodeling.randomizer.primitive.BooleanRandomizer; 8 | import org.junit.jupiter.api.BeforeEach; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | class BooleanFieldTest extends ModelFieldTest { 13 | 14 | @BeforeEach 15 | @Override 16 | protected void setUp() { 17 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).build(); 18 | typeName = ClassName.get(Boolean.class); 19 | modelField = new BooleanField().create(fieldCustomization); 20 | } 21 | 22 | @Override 23 | protected void should_generate_initializer() { 24 | final CodeBlock initialValue = modelField.initializer(); 25 | 26 | assertThat(initialValue).hasToString("new " + $(BooleanRandomizer.class) + "()"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/datetime/InstantField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.datetime; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.randomizer.Randomizer; 7 | import io.github.easymodeling.randomizer.datetime.InstantRandomizer; 8 | 9 | import java.time.Instant; 10 | 11 | public class InstantField extends AbstractDateTimeField { 12 | 13 | public static final ClassName TYPE = ClassName.get(Instant.class); 14 | 15 | public InstantField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public InstantField create(FieldCustomization customization, ModelField... valueFields) { 21 | return new InstantField(customization); 22 | } 23 | 24 | private InstantField(FieldCustomization customization) { 25 | super(TYPE, customization); 26 | } 27 | 28 | @Override 29 | protected Class> initializerType() { 30 | return InstantRandomizer.class; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/collection/ListField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.collection.ListRandomizer; 8 | 9 | import java.util.List; 10 | 11 | public class ListField extends AbstractCollectionField { 12 | 13 | public static final ClassName TYPE = ClassName.get(List.class); 14 | 15 | public ListField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public ListField create(FieldCustomization customization, ModelField... nestedFields) { 21 | return new ListField(customization, nestedFields[0]); 22 | } 23 | 24 | private ListField(FieldCustomization customization, ModelField nestedFields) { 25 | super(TYPE, customization, nestedFields); 26 | } 27 | 28 | @Override 29 | protected CodeBlock initializerType() { 30 | return CodeBlock.of("$T", ListRandomizer.class); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/PrimitiveTypeModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | public class PrimitiveTypeModel { 4 | 5 | private int anInt; 6 | 7 | private byte aByte; 8 | 9 | private short aShort; 10 | 11 | private long aLong; 12 | 13 | private float aFloat; 14 | 15 | private double aDouble; 16 | 17 | private boolean aBoolean; 18 | 19 | private char aChar; 20 | 21 | private String aString; 22 | 23 | public int getAnInt() { 24 | return anInt; 25 | } 26 | 27 | public byte getaByte() { 28 | return aByte; 29 | } 30 | 31 | public short getaShort() { 32 | return aShort; 33 | } 34 | 35 | public long getaLong() { 36 | return aLong; 37 | } 38 | 39 | public float getaFloat() { 40 | return aFloat; 41 | } 42 | 43 | public double getaDouble() { 44 | return aDouble; 45 | } 46 | 47 | public boolean isaBoolean() { 48 | return aBoolean; 49 | } 50 | 51 | public char getaChar() { 52 | return aChar; 53 | } 54 | 55 | public String getaString() { 56 | return aString; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/StreamModelTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | class StreamModelTest { 8 | 9 | @Test 10 | void should_create_fields() { 11 | final StreamModel next = StreamModelModeler.next(); 12 | 13 | assertThat(next).isNotNull(); 14 | assertThat(next.streamOfStrings).isNotNull(); 15 | assertThat(next.intStream).isNotNull(); 16 | assertThat(next.streamOfIntStreams).isNotNull(); 17 | assertThat(next.intStreamArray).isNotNull(); 18 | assertThat(next.intStreamMatrix).isNotNull(); 19 | assertThat(next.longStream).isNotNull(); 20 | assertThat(next.streamOfLongStreams).isNotNull(); 21 | assertThat(next.longStreamArray).isNotNull(); 22 | assertThat(next.longStreamMatrix).isNotNull(); 23 | assertThat(next.doubleStream).isNotNull(); 24 | assertThat(next.streamOfDoubleStreams).isNotNull(); 25 | assertThat(next.doubleStreamArray).isNotNull(); 26 | assertThat(next.doubleStreamMatrix).isNotNull(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/string/StringBuilderField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.string; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.randomizer.Randomizer; 7 | import io.github.easymodeling.randomizer.string.StringBuilderRandomizer; 8 | 9 | public class StringBuilderField extends CharSequenceField { 10 | 11 | public static final ClassName TYPE = ClassName.get(StringBuilder.class); 12 | 13 | public StringBuilderField() { 14 | this.type = TYPE; 15 | } 16 | 17 | @Override 18 | public StringBuilderField create(FieldCustomization customization, ModelField... valueFields) { 19 | return new StringBuilderField(customization); 20 | } 21 | 22 | private StringBuilderField(FieldCustomization customization) { 23 | super(TYPE, customization); 24 | } 25 | 26 | @Override 27 | protected Class> initializerType() { 28 | return StringBuilderRandomizer.class; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/EnumModelTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.stream.Stream; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class EnumModelTest { 10 | 11 | @Test 12 | void should_generate_enum_field() { 13 | final EnumModel next = EnumModelModeler.next(); 14 | 15 | assertThat(next).isNotNull(); 16 | assertThat(next.enumExample).isNotNull(); 17 | assertThat(next.enumExamples).isNotNull(); 18 | assertThat(next.listOfEnumExamples).isNotNull(); 19 | assertThat(next.node).isNotNull(); 20 | } 21 | 22 | @Test 23 | void should_provide_stream_of_models() { 24 | final Stream models = EnumModelModeler.stream().limit(5); 25 | 26 | models.forEach(model -> { 27 | assertThat(model).isNotNull(); 28 | assertThat(model.enumExample).isNotNull(); 29 | assertThat(model.enumExamples).isNotNull(); 30 | assertThat(model.listOfEnumExamples).isNotNull(); 31 | assertThat(model.node).isNotNull(); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/datetime/LocalDateField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.datetime; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.randomizer.Randomizer; 7 | import io.github.easymodeling.randomizer.datetime.LocalDateRandomizer; 8 | 9 | import java.time.LocalDate; 10 | 11 | public class LocalDateField extends AbstractDateTimeField { 12 | 13 | public static final ClassName TYPE = ClassName.get(LocalDate.class); 14 | 15 | public LocalDateField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public LocalDateField create(FieldCustomization customization, ModelField... valueFields) { 21 | return new LocalDateField(customization); 22 | } 23 | 24 | private LocalDateField(FieldCustomization customization) { 25 | super(TYPE, customization); 26 | } 27 | 28 | @Override 29 | protected Class> initializerType() { 30 | return LocalDateRandomizer.class; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/datetime/LocalTimeField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.datetime; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.randomizer.Randomizer; 7 | import io.github.easymodeling.randomizer.datetime.LocalTimeRandomizer; 8 | 9 | import java.time.LocalTime; 10 | 11 | public class LocalTimeField extends AbstractDateTimeField { 12 | 13 | public static final ClassName TYPE = ClassName.get(LocalTime.class); 14 | 15 | public LocalTimeField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public LocalTimeField create(FieldCustomization customization, ModelField... valueFields) { 21 | return new LocalTimeField(customization); 22 | } 23 | 24 | private LocalTimeField(FieldCustomization customization) { 25 | super(TYPE, customization); 26 | } 27 | 28 | @Override 29 | protected Class> initializerType() { 30 | return LocalTimeRandomizer.class; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/collection/MapField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.collection.MapRandomizer; 8 | 9 | import java.util.Map; 10 | 11 | public class MapField extends AbstractMapField { 12 | 13 | public static final ClassName TYPE = ClassName.get(Map.class); 14 | 15 | public MapField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public MapField create(FieldCustomization customization, ModelField... nestedFields) { 21 | return new MapField(customization, nestedFields[0], nestedFields[1]); 22 | } 23 | 24 | private MapField(FieldCustomization customization, ModelField keyField, ModelField valueField) { 25 | super(TYPE, customization, keyField, valueField); 26 | } 27 | 28 | @Override 29 | protected CodeBlock initializerType() { 30 | return CodeBlock.of("$T", MapRandomizer.class); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/datetime/SqlTimestampField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.datetime; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.randomizer.Randomizer; 7 | import io.github.easymodeling.randomizer.datetime.SqlTimestampRandomizer; 8 | 9 | import java.sql.Timestamp; 10 | 11 | public class SqlTimestampField extends AbstractDateTimeField { 12 | 13 | public static final ClassName TYPE = ClassName.get(Timestamp.class); 14 | 15 | public SqlTimestampField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public SqlTimestampField create(FieldCustomization customization, ModelField... valueFields) { 21 | return new SqlTimestampField(customization); 22 | } 23 | 24 | private SqlTimestampField(FieldCustomization customization) { 25 | super(TYPE, customization); 26 | } 27 | 28 | @Override 29 | protected Class> initializerType() { 30 | return SqlTimestampRandomizer.class; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/QualifiedField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | public class QualifiedField { 4 | 5 | private static final String SPLITTER = "#"; 6 | 7 | private final String className; 8 | 9 | private final String fieldName; 10 | 11 | QualifiedField(String qualifiedFieldName) throws NoSuchFieldException { 12 | final int splitter = qualifiedFieldName.lastIndexOf(SPLITTER); 13 | if (splitter == -1 || splitter == qualifiedFieldName.length() - 1 || splitter == 0) { 14 | throw new NoSuchFieldException(qualifiedFieldName); 15 | } 16 | this.className = qualifiedFieldName.substring(0, splitter); 17 | this.fieldName = qualifiedFieldName.substring(splitter + 1); 18 | } 19 | 20 | String getClassName() { 21 | return className; 22 | } 23 | 24 | String getFieldName() { 25 | return fieldName; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return toQualifiedFieldName(className, fieldName); 31 | } 32 | 33 | public static String toQualifiedFieldName(String className, String fieldName) { 34 | return className + SPLITTER + fieldName; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/collection/ArrayListField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.collection.ArrayListRandomizer; 8 | 9 | import java.util.ArrayList; 10 | 11 | public class ArrayListField extends AbstractCollectionField { 12 | 13 | public static final ClassName TYPE = ClassName.get(ArrayList.class); 14 | 15 | public ArrayListField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public ArrayListField create(FieldCustomization customization, ModelField... nestedFields) { 21 | return new ArrayListField(customization, nestedFields[0]); 22 | } 23 | 24 | private ArrayListField(FieldCustomization customization, ModelField nestedField) { 25 | super(TYPE, customization, nestedField); 26 | } 27 | 28 | @Override 29 | protected CodeBlock initializerType() { 30 | return CodeBlock.of("$T", ArrayListRandomizer.class); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/collection/AbstractCollectionField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import com.squareup.javapoet.ParameterizedTypeName; 6 | import io.github.easymodeling.modeler.FieldCustomization; 7 | import io.github.easymodeling.modeler.field.Container; 8 | import io.github.easymodeling.modeler.field.ModelField; 9 | 10 | public abstract class AbstractCollectionField extends Container { 11 | 12 | protected AbstractCollectionField() { 13 | } 14 | 15 | protected AbstractCollectionField(ClassName container, FieldCustomization customization, ModelField nestedField) { 16 | super(ParameterizedTypeName.get(container, nestedField.type()), customization, nestedField); 17 | } 18 | 19 | @Override 20 | protected CodeBlock initializerParameter() { 21 | return CodeBlock.of("$L, $L", minSize(), maxSize()); 22 | } 23 | 24 | protected int maxSize() { 25 | return customization.maxSize().orElse(20); 26 | } 27 | 28 | private int minSize() { 29 | return customization.minSize().orElse(1); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/collection/LinkedListField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.collection.LinkedListRandomizer; 8 | 9 | import java.util.LinkedList; 10 | 11 | public class LinkedListField extends AbstractCollectionField { 12 | 13 | public static final ClassName TYPE = ClassName.get(LinkedList.class); 14 | 15 | public LinkedListField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public LinkedListField create(FieldCustomization customization, ModelField... nestedFields) { 21 | return new LinkedListField(customization, nestedFields[0]); 22 | } 23 | 24 | private LinkedListField(FieldCustomization customization, ModelField nestedField) { 25 | super(TYPE, customization, nestedField); 26 | } 27 | 28 | @Override 29 | protected CodeBlock initializerType() { 30 | return CodeBlock.of("$T", LinkedListRandomizer.class); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/CustomField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.TypeName; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.randomizer.CustomTypeRandomizer; 7 | 8 | import static io.github.easymodeling.modeler.GenerationPatterns.MODELER_NAME_PATTERN; 9 | import static io.github.easymodeling.modeler.GenerationPatterns.MODEL_CACHE_PARAMETER_NAME; 10 | 11 | public class CustomField extends ModelField { 12 | 13 | public CustomField(TypeName type, FieldCustomization customization) { 14 | super(type, customization); 15 | } 16 | 17 | @Override 18 | public CodeBlock initializer() { 19 | final String factoryTypeName = String.format(MODELER_NAME_PATTERN, type); 20 | return CodeBlock.of("new $T<>(new $L(), $L)", CustomTypeRandomizer.class, factoryTypeName, MODEL_CACHE_PARAMETER_NAME); 21 | } 22 | 23 | @Override 24 | public ModelField create(FieldCustomization customization, ModelField... valueFields) { 25 | throw new UnsupportedOperationException("Create CustomerField with constructor"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/collection/HashMapField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.collection.HashMapRandomizer; 8 | 9 | import java.util.HashMap; 10 | 11 | public class HashMapField extends AbstractMapField { 12 | 13 | public static final ClassName TYPE = ClassName.get(HashMap.class); 14 | 15 | public HashMapField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public HashMapField create(FieldCustomization customization, ModelField... nestedFields) { 21 | return new HashMapField(customization, nestedFields[0], nestedFields[1]); 22 | } 23 | 24 | private HashMapField(FieldCustomization customization, ModelField keyField, ModelField valueField) { 25 | super(TYPE, customization, keyField, valueField); 26 | } 27 | 28 | @Override 29 | protected CodeBlock initializerType() { 30 | return CodeBlock.of("$T", HashMapRandomizer.class); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/collection/TreeMapField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.collection.TreeMapRandomizer; 8 | 9 | import java.util.TreeMap; 10 | 11 | public class TreeMapField extends AbstractMapField { 12 | 13 | public static final ClassName TYPE = ClassName.get(TreeMap.class); 14 | 15 | public TreeMapField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public TreeMapField create(FieldCustomization customization, ModelField... nestedFields) { 21 | return new TreeMapField(customization, nestedFields[0], nestedFields[1]); 22 | } 23 | 24 | private TreeMapField(FieldCustomization customization, ModelField keyField, ModelField valueField) { 25 | super(TYPE, customization, keyField, valueField); 26 | } 27 | 28 | @Override 29 | protected CodeBlock initializerType() { 30 | return CodeBlock.of("$T", TreeMapRandomizer.class); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/datetime/LocalDateTimeField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.datetime; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.randomizer.Randomizer; 7 | import io.github.easymodeling.randomizer.datetime.LocalDateTimeRandomizer; 8 | 9 | import java.time.LocalDateTime; 10 | 11 | public class LocalDateTimeField extends AbstractDateTimeField { 12 | 13 | public static final ClassName TYPE = ClassName.get(LocalDateTime.class); 14 | 15 | public LocalDateTimeField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public LocalDateTimeField create(FieldCustomization customization, ModelField... valueFields) { 21 | return new LocalDateTimeField(customization); 22 | } 23 | 24 | private LocalDateTimeField(FieldCustomization customization) { 25 | super(TYPE, customization); 26 | } 27 | 28 | @Override 29 | protected Class> initializerType() { 30 | return LocalDateTimeRandomizer.class; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/datetime/ZonedDateTimeField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.datetime; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.randomizer.Randomizer; 7 | import io.github.easymodeling.randomizer.datetime.ZonedDateTimeRandomizer; 8 | 9 | import java.time.ZonedDateTime; 10 | 11 | public class ZonedDateTimeField extends AbstractDateTimeField { 12 | 13 | public static final ClassName TYPE = ClassName.get(ZonedDateTime.class); 14 | 15 | public ZonedDateTimeField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public ZonedDateTimeField create(FieldCustomization customization, ModelField... valueFields) { 21 | return new ZonedDateTimeField(customization); 22 | } 23 | 24 | private ZonedDateTimeField(FieldCustomization customization) { 25 | super(TYPE, customization); 26 | } 27 | 28 | @Override 29 | protected Class> initializerType() { 30 | return ZonedDateTimeRandomizer.class; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/Field.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.FIELD) 9 | @Retention(RetentionPolicy.CLASS) 10 | public @interface Field { 11 | 12 | String name(); 13 | 14 | Class clazz() default void.class; 15 | 16 | double max() default Double.NaN; 17 | 18 | double min() default Double.NaN; 19 | 20 | double constant() default Double.NaN; 21 | 22 | boolean alphanumeric() default true; 23 | 24 | boolean alphabetic() default false; 25 | 26 | boolean numeric() default false; 27 | 28 | String string() default ""; 29 | 30 | boolean now() default false; 31 | 32 | boolean past() default false; 33 | 34 | boolean future() default false; 35 | 36 | String before() default ""; 37 | 38 | String after() default ""; 39 | 40 | String datetime() default ""; 41 | 42 | int size() default Integer.MAX_VALUE; 43 | 44 | int minSize() default Integer.MAX_VALUE; 45 | 46 | int maxSize() default Integer.MAX_VALUE; 47 | 48 | boolean allowEmpty() default false; 49 | } 50 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/collection/CollectionRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.collection; 2 | 3 | import io.github.easymodeling.randomizer.GenericRandomizer; 4 | import io.github.easymodeling.randomizer.Randomizer; 5 | 6 | import java.util.Collection; 7 | import java.util.function.Supplier; 8 | import java.util.stream.Collectors; 9 | import java.util.stream.Stream; 10 | 11 | public abstract class CollectionRandomizer, E> extends GenericRandomizer { 12 | 13 | protected Randomizer elementRandomizer; 14 | 15 | protected int minSize; 16 | 17 | protected int maxSize; 18 | 19 | protected CollectionRandomizer(Randomizer elementRandomizer, int minSize, int maxSize) { 20 | this.elementRandomizer = elementRandomizer; 21 | this.minSize = minSize; 22 | this.maxSize = maxSize; 23 | } 24 | 25 | @Override 26 | protected C random() { 27 | int size = doubleBetween(minSize, maxSize).intValue(); 28 | return Stream.generate(elementRandomizer::next) 29 | .limit(size) 30 | .collect(Collectors.toCollection(collectionFactory())); 31 | } 32 | 33 | protected abstract Supplier collectionFactory(); 34 | } 35 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/Container.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.TypeName; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | 7 | import java.util.Arrays; 8 | 9 | public abstract class Container extends ModelField { 10 | 11 | protected ModelField[] nestedFields; 12 | 13 | protected Container() { 14 | } 15 | 16 | protected Container(TypeName type, FieldCustomization customization, ModelField... nestedFields) { 17 | super(type, customization); 18 | this.nestedFields = nestedFields; 19 | } 20 | 21 | @Override 22 | public CodeBlock initializer() { 23 | return CodeBlock.of("new $L<>($L, $L)", initializerType(), nestedRandomizers(), initializerParameter()); 24 | } 25 | 26 | protected CodeBlock nestedRandomizers() { 27 | return Arrays.stream(nestedFields) 28 | .map(ModelField::initializer) 29 | .map(init -> CodeBlock.of("$L", init)) 30 | .collect(CodeBlock.joining(", ")); 31 | } 32 | 33 | protected abstract CodeBlock initializerType(); 34 | 35 | protected abstract CodeBlock initializerParameter(); 36 | } 37 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/datetime/InstantRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.time.Instant; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class InstantRandomizerTest extends RandomizerTest { 12 | 13 | @RepeatedTest(100) 14 | void should_generate_random_instant_within_range() { 15 | final Instant min = Instant.parse("2020-01-01T00:00:00Z"); 16 | final Instant max = Instant.parse("2020-01-01T23:59:59Z"); 17 | final InstantRandomizer instantRandomizer = new InstantRandomizer(min.toEpochMilli(), max.toEpochMilli()); 18 | 19 | final Instant next = instantRandomizer.next(); 20 | 21 | assertThat(next).isBetween(min, max); 22 | } 23 | 24 | @Test 25 | void should_generate_constant_instant() { 26 | final Instant constant = Instant.now(); 27 | final InstantRandomizer instantRandomizer = new InstantRandomizer(constant); 28 | 29 | final Instant next = instantRandomizer.next(); 30 | 31 | assertThat(next).isEqualTo(constant); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/datetime/DateFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.datetime; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 7 | import io.github.easymodeling.randomizer.datetime.DateRandomizer; 8 | import org.junit.jupiter.api.BeforeEach; 9 | 10 | import java.util.Date; 11 | 12 | import static org.assertj.core.api.Assertions.assertThat; 13 | 14 | class DateFieldTest extends ModelFieldTest { 15 | 16 | @Override 17 | @BeforeEach 18 | protected void setUp() { 19 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).after("1991-01-23T00:00:00Z").before("1991-02-22T00:00:00Z").build(); 20 | typeName = ClassName.get(Date.class); 21 | modelField = new DateField().create(fieldCustomization); 22 | } 23 | 24 | @Override 25 | protected void should_generate_initializer() { 26 | final CodeBlock initializer = modelField.initializer(); 27 | 28 | assertThat(initializer) 29 | .hasToString("new " + $(DateRandomizer.class) + "(664588800000L, 667180800000L)"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/datetime/SqlDateFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.datetime; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 7 | import io.github.easymodeling.randomizer.datetime.SqlDateRandomizer; 8 | import org.junit.jupiter.api.BeforeEach; 9 | 10 | import java.sql.Date; 11 | 12 | import static org.assertj.core.api.Assertions.assertThat; 13 | 14 | class SqlDateFieldTest extends ModelFieldTest { 15 | 16 | @Override 17 | @BeforeEach 18 | protected void setUp() { 19 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).after("1991-01-23T00:00:00Z").before("1991-02-22T00:00:00Z").build(); 20 | typeName = ClassName.get(Date.class); 21 | modelField = new SqlDateField().create(fieldCustomization); 22 | } 23 | 24 | @Override 25 | protected void should_generate_initializer() { 26 | final CodeBlock initializer = modelField.initializer(); 27 | 28 | assertThat(initializer) 29 | .hasToString("new " + $(SqlDateRandomizer.class) + "(664588800000L, 667180800000L)"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/EnumRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | import org.junit.jupiter.api.RepeatedTest; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.Arrays; 7 | import java.util.Map; 8 | import java.util.stream.Collectors; 9 | import java.util.stream.Stream; 10 | 11 | import static org.assertj.core.api.Assertions.assertThat; 12 | 13 | class EnumRandomizerTest extends RandomizerTest { 14 | 15 | @RepeatedTest(100) 16 | void should_create_instance_of_enum() { 17 | final SomeEnum random = new EnumRandomizer<>(SomeEnum.values()).next(); 18 | 19 | assertThat(random).isNotNull().isIn(Arrays.asList(SomeEnum.values())); 20 | } 21 | 22 | @Test 23 | void should_roughly_fall_evenly_into_enums() { 24 | final Map collect = Stream.generate(() -> new EnumRandomizer<>(SomeEnum.values()).next()) 25 | .limit(100) 26 | .collect(Collectors.groupingBy(SomeEnum::name, Collectors.counting())); 27 | 28 | assertThat(collect) 29 | .containsEntry("A", 33L) 30 | .containsEntry("B", 31L) 31 | .containsEntry("C", 36L); 32 | } 33 | 34 | enum SomeEnum { 35 | A, B, C 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/collection/SetField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.collection.SetRandomizer; 8 | 9 | import java.util.Set; 10 | 11 | public class SetField extends AbstractCollectionField { 12 | 13 | public static final ClassName TYPE = ClassName.get(Set.class); 14 | 15 | public SetField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public SetField create(FieldCustomization customization, ModelField... nestedFields) { 21 | return new SetField(customization, nestedFields[0]); 22 | } 23 | 24 | private SetField(FieldCustomization customization, ModelField nestedField) { 25 | super(TYPE, customization, nestedField); 26 | } 27 | 28 | @Override 29 | protected CodeBlock initializerParameter() { 30 | return CodeBlock.of("$L", maxSize()); 31 | } 32 | 33 | @Override 34 | protected CodeBlock initializerType() { 35 | return CodeBlock.of("$T", SetRandomizer.class); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/datetime/SqlTimestampFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.datetime; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 7 | import io.github.easymodeling.randomizer.datetime.SqlTimestampRandomizer; 8 | import org.junit.jupiter.api.BeforeEach; 9 | 10 | import java.sql.Timestamp; 11 | 12 | import static org.assertj.core.api.Assertions.assertThat; 13 | 14 | class SqlTimestampFieldTest extends ModelFieldTest { 15 | 16 | @Override 17 | @BeforeEach 18 | protected void setUp() { 19 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).after("1991-01-23T00:00:00Z").before("1991-02-22T00:00:00Z").build(); 20 | typeName = ClassName.get(Timestamp.class); 21 | modelField = new SqlTimestampField().create(fieldCustomization); 22 | } 23 | 24 | @Override 25 | protected void should_generate_initializer() { 26 | final CodeBlock initializer = modelField.initializer(); 27 | 28 | assertThat(initializer) 29 | .hasToString("new " + $(SqlTimestampRandomizer.class) + "(664588800000L, 667180800000L)"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/datetime/DateRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.time.Instant; 8 | import java.util.Date; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | class DateRandomizerTest extends RandomizerTest { 13 | 14 | @RepeatedTest(100) 15 | void should_generate_random_date_within_range() { 16 | final Instant min = Instant.parse("2020-01-01T10:59:35Z"); 17 | final Instant max = Instant.parse("2020-01-01T11:01:01Z"); 18 | final DateRandomizer zonedDateTimeRandomizer = new DateRandomizer(min.toEpochMilli(), max.toEpochMilli()); 19 | 20 | final Date next = zonedDateTimeRandomizer.next(); 21 | 22 | assertThat(next).isBetween(Date.from(min), Date.from(max)); 23 | } 24 | 25 | @Test 26 | void should_generate_constant_date() { 27 | final Instant constant = Instant.now(); 28 | final DateRandomizer zonedDateTimeRandomizer = new DateRandomizer(constant); 29 | 30 | final Date next = zonedDateTimeRandomizer.next(); 31 | 32 | assertThat(next).isEqualTo(Date.from(constant)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/datetime/SqlTimestampRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import org.junit.jupiter.api.RepeatedTest; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.sql.Timestamp; 7 | import java.time.Instant; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | class SqlTimestampRandomizerTest { 12 | 13 | @RepeatedTest(100) 14 | void should_generate_random_sql_timestamp_within_range() { 15 | final Instant min = Instant.parse("2020-01-02T12:34:56Z"); 16 | final Instant max = Instant.parse("2020-01-08T01:02:03Z"); 17 | final SqlTimestampRandomizer sqlTimestampRandomizer = new SqlTimestampRandomizer(min.toEpochMilli(), max.toEpochMilli()); 18 | 19 | final Timestamp next = sqlTimestampRandomizer.next(); 20 | 21 | assertThat(next.toInstant()).isBetween(min, max); 22 | } 23 | 24 | @Test 25 | void should_generate_constant_sql_timestamp() { 26 | final Instant constant = Instant.parse("2020-01-02T12:34:56Z"); 27 | final SqlTimestampRandomizer sqlTimestampRandomizer = new SqlTimestampRandomizer(constant); 28 | 29 | final Timestamp next = sqlTimestampRandomizer.next(); 30 | 31 | assertThat(next.toInstant()).isEqualTo(constant); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/primitive/CharField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.primitive; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.modeler.field.PlainField; 8 | import io.github.easymodeling.randomizer.Randomizer; 9 | import io.github.easymodeling.randomizer.primitive.CharRandomizer; 10 | 11 | public class CharField extends PlainField { 12 | 13 | public static final ClassName TYPE = ClassName.get(Character.class); 14 | 15 | public CharField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public CharField create(FieldCustomization customization, ModelField... valueFields) { 21 | return new CharField(customization); 22 | } 23 | 24 | private CharField(FieldCustomization customization) { 25 | super(TYPE, customization); 26 | } 27 | 28 | @Override 29 | protected Class> initializerType() { 30 | return CharRandomizer.class; 31 | } 32 | 33 | @Override 34 | protected CodeBlock initializerParameter() { 35 | return CodeBlock.of(""); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /core/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'maven-publish' 3 | apply plugin: 'signing' 4 | 5 | java { 6 | toolchain { 7 | languageVersion = JavaLanguageVersion.of(8) 8 | } 9 | withJavadocJar() 10 | withSourcesJar() 11 | } 12 | 13 | dependencies { 14 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1' 15 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.1' 16 | testImplementation 'org.assertj:assertj-core:3.23.1' 17 | testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.1' 18 | } 19 | 20 | test { 21 | useJUnitPlatform() 22 | } 23 | 24 | jacocoTestReport { 25 | dependsOn test 26 | reports { 27 | xml.required = true 28 | csv.required = false 29 | html.required = false 30 | } 31 | } 32 | 33 | publishing { 34 | publications { 35 | mavenJava(MavenPublication) { 36 | artifactId = "${project.parent.name}" 37 | from components.java 38 | pom publicationPom 39 | } 40 | } 41 | repositories { 42 | maven mavenCentral 43 | } 44 | } 45 | 46 | signing { 47 | sign publishing.publications.mavenJava 48 | } 49 | 50 | javadoc { 51 | if (JavaVersion.current().isJava9Compatible()) { 52 | options.addBooleanOption('html5', true) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/collection/HashSetField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.collection.HashSetRandomizer; 8 | 9 | import java.util.HashSet; 10 | 11 | public class HashSetField extends AbstractCollectionField { 12 | 13 | public static final ClassName TYPE = ClassName.get(HashSet.class); 14 | 15 | public HashSetField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public HashSetField create(FieldCustomization customization, ModelField... nestedFields) { 21 | return new HashSetField(customization, nestedFields[0]); 22 | } 23 | 24 | private HashSetField(FieldCustomization customization, ModelField nestedField) { 25 | super(TYPE, customization, nestedField); 26 | } 27 | 28 | @Override 29 | protected CodeBlock initializerParameter() { 30 | return CodeBlock.of("$L", maxSize()); 31 | } 32 | 33 | @Override 34 | protected CodeBlock initializerType() { 35 | return CodeBlock.of("$T", HashSetRandomizer.class); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/collection/TreeSetField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.collection.TreeSetRandomizer; 8 | 9 | import java.util.TreeSet; 10 | 11 | public class TreeSetField extends AbstractCollectionField { 12 | 13 | public static final ClassName TYPE = ClassName.get(TreeSet.class); 14 | 15 | public TreeSetField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public TreeSetField create(FieldCustomization customization, ModelField... nestedFields) { 21 | return new TreeSetField(customization, nestedFields[0]); 22 | } 23 | 24 | private TreeSetField(FieldCustomization customization, ModelField nestedField) { 25 | super(TYPE, customization, nestedField); 26 | } 27 | 28 | @Override 29 | protected CodeBlock initializerParameter() { 30 | return CodeBlock.of("$L", maxSize()); 31 | } 32 | 33 | @Override 34 | protected CodeBlock initializerType() { 35 | return CodeBlock.of("$T", TreeSetRandomizer.class); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/processor/AnnoFieldWrapper.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.processor; 2 | 3 | import io.github.easymodeling.Field; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | 6 | public class AnnoFieldWrapper { 7 | 8 | private final AnnoModelWrapper model; 9 | 10 | private final Field field; 11 | 12 | public AnnoFieldWrapper(AnnoModelWrapper model, Field field) { 13 | this.model = model; 14 | this.field = field; 15 | } 16 | 17 | public FieldCustomization toFieldCustomization() { 18 | return new FieldCustomization( 19 | model.getCanonicalName(), 20 | field.name(), 21 | field.max(), 22 | field.min(), 23 | field.constant(), 24 | field.alphanumeric(), 25 | field.alphabetic(), 26 | field.numeric(), 27 | field.string(), 28 | field.now(), 29 | field.before(), 30 | field.after(), 31 | field.future(), 32 | field.past(), 33 | field.datetime(), 34 | field.size(), 35 | field.minSize(), 36 | field.maxSize(), 37 | field.allowEmpty() 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/primitive/BooleanField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.primitive; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.modeler.field.PlainField; 8 | import io.github.easymodeling.randomizer.Randomizer; 9 | import io.github.easymodeling.randomizer.primitive.BooleanRandomizer; 10 | 11 | public class BooleanField extends PlainField { 12 | 13 | public static final ClassName TYPE = ClassName.get(Boolean.class); 14 | 15 | public BooleanField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public BooleanField create(FieldCustomization customization, ModelField... valueFields) { 21 | return new BooleanField(customization); 22 | } 23 | 24 | private BooleanField(FieldCustomization customization) { 25 | super(TYPE, customization); 26 | } 27 | 28 | @Override 29 | protected Class> initializerType() { 30 | return BooleanRandomizer.class; 31 | } 32 | 33 | @Override 34 | protected CodeBlock initializerParameter() { 35 | return CodeBlock.of(""); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/stream/PrimitiveTypeStreamField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.stream; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.TypeName; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.PlainField; 7 | import io.github.easymodeling.modeler.field.number.NumericField; 8 | 9 | import java.util.stream.BaseStream; 10 | 11 | public abstract class PrimitiveTypeStreamField, E extends Number> extends PlainField { 12 | 13 | protected PrimitiveTypeStreamField() { 14 | } 15 | 16 | protected PrimitiveTypeStreamField(TypeName type, FieldCustomization customization) { 17 | super(type, customization); 18 | } 19 | 20 | @Override 21 | protected CodeBlock initializerParameter() { 22 | final CodeBlock elementInitializer = element().create(customization).initializer(); 23 | return CodeBlock.of("$L, $L, $L", elementInitializer, minSize(), maxSize()); 24 | } 25 | 26 | protected abstract NumericField element(); 27 | 28 | private int maxSize() { 29 | return customization.maxSize().orElse(20); 30 | } 31 | 32 | private int minSize() { 33 | return customization.minSize().orElse(1); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/OptionalField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import com.squareup.javapoet.ParameterizedTypeName; 6 | import io.github.easymodeling.modeler.FieldCustomization; 7 | import io.github.easymodeling.randomizer.OptionalRandomizer; 8 | 9 | import java.util.Optional; 10 | 11 | public class OptionalField extends Container { 12 | 13 | public static final ClassName TYPE = ClassName.get(Optional.class); 14 | 15 | public OptionalField() { 16 | this.type = TYPE; 17 | } 18 | 19 | @Override 20 | public OptionalField create(FieldCustomization customization, ModelField... valueFields) { 21 | return new OptionalField(customization, valueFields[0]); 22 | } 23 | 24 | private OptionalField(FieldCustomization customization, ModelField valueField) { 25 | super(ParameterizedTypeName.get(TYPE, valueField.type()), customization, valueField); 26 | } 27 | 28 | @Override 29 | protected CodeBlock initializerType() { 30 | return CodeBlock.of("$T", OptionalRandomizer.class); 31 | } 32 | 33 | @Override 34 | protected CodeBlock initializerParameter() { 35 | return CodeBlock.of("$L", customization.allowEmpty()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/ModelCache.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.Random; 8 | 9 | public class ModelCache { 10 | 11 | public static final int POOL_SIZE = 10; 12 | 13 | private final Map, List> cache; 14 | 15 | private final Random random = new Random(); 16 | 17 | public ModelCache() { 18 | this.cache = new HashMap<>(); 19 | } 20 | 21 | public void push(T obj) { 22 | final Class clazz = obj.getClass(); 23 | List pool = (List) cache.computeIfAbsent(clazz, k -> new ArrayList<>()); 24 | pool.add(obj); 25 | } 26 | 27 | public boolean avoidInfinity(Class clazz) { 28 | return cache.containsKey(clazz) && cache.get(clazz).size() >= POOL_SIZE; 29 | } 30 | 31 | public T random(Class clazz) { 32 | final List pool = this.poolOf(clazz); 33 | return pool.get(random.nextInt(pool.size())); 34 | } 35 | 36 | private List poolOf(Class clazz) { 37 | List pool = (List) cache.get(clazz); 38 | if (pool == null) { 39 | throw new IllegalStateException("No pool for class " + clazz); 40 | } 41 | return pool; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | pull_request: 8 | types: [ assigned ] 9 | 10 | env: 11 | OSSRH_USERNAME: 'OSSRH_USERNAME' 12 | OSSRH_PASSWORD: 'OSSRH_PASSWORD' 13 | 14 | jobs: 15 | unit-test: 16 | name: Unit Test 17 | runs-on: ubuntu-latest 18 | timeout-minutes: 3 19 | strategy: 20 | matrix: 21 | java: [ '8', '11', '17', '18' ] 22 | steps: 23 | - name: 'Cancel previous runs' 24 | uses: styfle/cancel-workflow-action@0.11.0 25 | with: 26 | access_token: ${{ github.token }} 27 | - name: 'Checkout repository' 28 | uses: actions/checkout@v3 29 | - uses: ./.github/actions/set-up-jdk 30 | with: 31 | jdk-version: '${{ matrix.java }}' 32 | - name: 'Run test' 33 | run: ./gradlew clean test 34 | 35 | sonarqube: 36 | name: Sonarqube Report 37 | runs-on: ubuntu-latest 38 | timeout-minutes: 3 39 | steps: 40 | - uses: actions/checkout@v3 41 | with: 42 | fetch-depth: 0 43 | - uses: ./.github/actions/set-up-jdk 44 | with: 45 | jdk-version: '11' 46 | - uses: ./.github/actions/sonarqube 47 | env: 48 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any 49 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 50 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/datetime/SqlDateRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.sql.Date; 8 | import java.time.Instant; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | class SqlDateRandomizerTest extends RandomizerTest { 13 | 14 | @RepeatedTest(100) 15 | void should_generate_random_sql_date_within_range() { 16 | final Instant min = Instant.parse("2020-01-02T00:00:00Z"); 17 | final Instant max = Instant.parse("2020-01-08T00:00:00Z"); 18 | final SqlDateRandomizer sqlDateRandomizer = new SqlDateRandomizer(min.toEpochMilli(), max.toEpochMilli()); 19 | 20 | final Date next = sqlDateRandomizer.next(); 21 | 22 | assertThat(next).isBetween(Date.valueOf("2020-01-02"), Date.valueOf("2020-01-08"), true, true); 23 | } 24 | 25 | @Test 26 | void should_generate_constant_sql_date() { 27 | final Instant constant = Instant.parse("2020-01-02T00:00:00Z"); 28 | final SqlDateRandomizer sqlDateRandomizer = new SqlDateRandomizer(constant); 29 | 30 | final Date next = sqlDateRandomizer.next(); 31 | 32 | assertThat(next).isEqualTo(Date.valueOf("2020-01-02")); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/stream/IntStreamFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.stream; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.field.number.IntegerField; 7 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 8 | import io.github.easymodeling.randomizer.stream.IntStreamRandomizer; 9 | import org.junit.jupiter.api.BeforeEach; 10 | 11 | import java.util.stream.IntStream; 12 | 13 | import static org.assertj.core.api.Assertions.assertThat; 14 | 15 | class IntStreamFieldTest extends ModelFieldTest { 16 | 17 | @Override 18 | @BeforeEach 19 | protected void setUp() { 20 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).min(2.).max(9.).minSize(10).maxSize(15).build(); 21 | typeName = ClassName.get(IntStream.class); 22 | modelField = new IntStreamField().create(fieldCustomization); 23 | } 24 | 25 | @Override 26 | protected void should_generate_initializer() { 27 | final CodeBlock initializer = modelField.initializer(); 28 | 29 | assertThat(initializer).hasToString( 30 | "new " + $(IntStreamRandomizer.class) + "(" + new IntegerField().create(fieldCustomization).initializer() + ", 10, 15)"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/stream/LongStreamFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.stream; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.field.number.LongField; 7 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 8 | import io.github.easymodeling.randomizer.stream.LongStreamRandomizer; 9 | import org.junit.jupiter.api.BeforeEach; 10 | 11 | import java.util.stream.LongStream; 12 | 13 | import static org.assertj.core.api.Assertions.assertThat; 14 | 15 | class LongStreamFieldTest extends ModelFieldTest { 16 | 17 | @Override 18 | @BeforeEach 19 | protected void setUp() { 20 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).min(2.).max(9.).minSize(10).maxSize(15).build(); 21 | typeName = ClassName.get(LongStream.class); 22 | modelField = new LongStreamField().create(fieldCustomization); 23 | } 24 | 25 | @Override 26 | protected void should_generate_initializer() { 27 | final CodeBlock initializer = modelField.initializer(); 28 | 29 | assertThat(initializer).hasToString( 30 | "new " + $(LongStreamRandomizer.class) + "(" + new LongField().create(fieldCustomization).initializer() + ", 10, 15)"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/array/ArrayField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.array; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.TypeName; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.Container; 7 | import io.github.easymodeling.modeler.field.ModelField; 8 | import io.github.easymodeling.randomizer.array.ArrayRandomizer; 9 | 10 | public class ArrayField extends Container { 11 | 12 | public ArrayField(TypeName type, FieldCustomization customization, ModelField elementField) { 13 | super(type, customization, elementField); 14 | } 15 | 16 | @Override 17 | protected CodeBlock initializerType() { 18 | return CodeBlock.of("$T", ArrayRandomizer.class); 19 | } 20 | 21 | @Override 22 | protected CodeBlock initializerParameter() { 23 | return CodeBlock.of("$L, $L", minSize(), maxSize()); 24 | } 25 | 26 | private int maxSize() { 27 | return customization.maxSize().orElse(20); 28 | } 29 | 30 | private int minSize() { 31 | return customization.minSize().orElse(1); 32 | } 33 | 34 | @Override 35 | public Container create(FieldCustomization customization, ModelField... valueFields) { 36 | throw new UnsupportedOperationException("Create ArrayField with constructor"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/stream/DoubleStreamFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.stream; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.field.number.DoubleField; 7 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 8 | import io.github.easymodeling.randomizer.stream.DoubleStreamRandomizer; 9 | import org.junit.jupiter.api.BeforeEach; 10 | 11 | import java.util.stream.DoubleStream; 12 | 13 | import static org.assertj.core.api.Assertions.assertThat; 14 | 15 | class DoubleStreamFieldTest extends ModelFieldTest { 16 | 17 | @Override 18 | @BeforeEach 19 | protected void setUp() { 20 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).min(2.).max(9.).minSize(10).maxSize(15).build(); 21 | typeName = ClassName.get(DoubleStream.class); 22 | modelField = new DoubleStreamField().create(fieldCustomization); 23 | } 24 | 25 | @Override 26 | protected void should_generate_initializer() { 27 | final CodeBlock initializer = modelField.initializer(); 28 | 29 | assertThat(initializer).hasToString( 30 | "new " + $(DoubleStreamRandomizer.class) + "(" + new DoubleField().create(fieldCustomization).initializer() + ", 10, 15)"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /functional-test/src/test/java/io/github/easymodeling/StringTypeModelTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.regex.Pattern; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class StringTypeModelTest { 10 | 11 | private final StringTypeModel model = StringTypeModelModeler.next(); 12 | 13 | @Test 14 | void getCommonString() { 15 | final String commonString = model.getCommonString(); 16 | 17 | assertThat(commonString).hasSizeGreaterThanOrEqualTo(10).hasSizeLessThan(20); 18 | } 19 | 20 | @Test 21 | void getAlphanumericString() { 22 | Pattern alphanumericPattern = Pattern.compile("^[a-zA-Z0-9]+$"); 23 | 24 | assertThat(model.getAlphanumericString()).containsPattern(alphanumericPattern); 25 | } 26 | 27 | @Test 28 | void getAlphabeticString() { 29 | Pattern alphabeticPattern = Pattern.compile("^[a-zA-Z]+$"); 30 | 31 | assertThat(model.getAlphabeticString()).containsPattern(alphabeticPattern); 32 | } 33 | 34 | @Test 35 | void getNumericString() { 36 | Pattern numericPattern = Pattern.compile("^[0-9]+$"); 37 | 38 | assertThat(model.getNumericString()).containsPattern(numericPattern); 39 | } 40 | 41 | @Test 42 | void getConstString() { 43 | assertThat(model.getConstString()).isEqualTo("constString"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/ModelFieldRegistryTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.TypeName; 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.params.ParameterizedTest; 7 | import org.junit.jupiter.params.provider.Arguments; 8 | import org.junit.jupiter.params.provider.MethodSource; 9 | 10 | import java.math.BigDecimal; 11 | import java.util.stream.Stream; 12 | 13 | import static org.assertj.core.api.Assertions.assertThat; 14 | 15 | class ModelFieldRegistryTest { 16 | 17 | @ParameterizedTest 18 | @MethodSource("typeNameProvider") 19 | void should_be_true_for_declared_types(TypeName typeName) { 20 | final boolean typeContains = ModelFieldRegistry.basicTypeContains(typeName); 21 | 22 | assertThat(typeContains).isTrue(); 23 | } 24 | 25 | @Test 26 | void should_be_false_for_undeclared_types() { 27 | final boolean typeContains = ModelFieldRegistry.basicTypeContains(ClassName.get(ClassName.class)); 28 | 29 | assertThat(typeContains).isFalse(); 30 | } 31 | 32 | public static Stream typeNameProvider() { 33 | return Stream.of( 34 | Arguments.of(ClassName.get(String.class)), 35 | Arguments.of(ClassName.get(Double.class)), 36 | Arguments.of(ClassName.get(BigDecimal.class)) 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/OptionalRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.Map; 8 | import java.util.Optional; 9 | import java.util.stream.Collectors; 10 | import java.util.stream.Stream; 11 | 12 | import static org.assertj.core.api.Assertions.assertThat; 13 | 14 | class OptionalRandomizerTest extends RandomizerTest { 15 | 16 | @Test 17 | void should_generate_optional_randomly() { 18 | final boolean allowEmpty = true; 19 | OptionalRandomizer randomizer = new OptionalRandomizer<>(new IntegerRandomizer(1), allowEmpty); 20 | 21 | final Map collect = Stream.generate(randomizer::next).limit(100).collect(Collectors.groupingBy(Optional::isPresent, Collectors.counting())); 22 | assertThat(collect) 23 | .containsEntry(true, 67L) 24 | .containsEntry(false, 33L); 25 | } 26 | 27 | @RepeatedTest(100) 28 | void should_generate_non_empty_optional() { 29 | final boolean allowEmpty = false; 30 | OptionalRandomizer randomizer = new OptionalRandomizer<>(new IntegerRandomizer(1), allowEmpty); 31 | 32 | final Optional next = randomizer.next(); 33 | 34 | assertThat(next).isNotEmpty(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/collection/SetFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.ParameterizedTypeName; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.field.string.StringField; 7 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 8 | import io.github.easymodeling.randomizer.collection.SetRandomizer; 9 | import org.junit.jupiter.api.BeforeEach; 10 | 11 | import java.util.Set; 12 | 13 | import static org.assertj.core.api.Assertions.assertThat; 14 | 15 | class SetFieldTest extends ModelFieldTest { 16 | 17 | private StringField stringField; 18 | 19 | @BeforeEach 20 | @Override 21 | protected void setUp() { 22 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).maxSize(50).build(); 23 | typeName = ParameterizedTypeName.get(Set.class, String.class); 24 | stringField = new StringField().create(fieldCustomization); 25 | modelField = new SetField().create(fieldCustomization, stringField); 26 | } 27 | 28 | @Override 29 | protected void should_generate_initializer() { 30 | final CodeBlock initializer = modelField.initializer(); 31 | 32 | assertThat(initializer) 33 | .hasToString("new " + $(SetRandomizer.class) + "<>(" + stringField.initializer() + ", 50)"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/number/LongField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.number; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.Randomizer; 8 | import io.github.easymodeling.randomizer.number.LongRandomizer; 9 | 10 | public class LongField extends NumericField { 11 | 12 | public static final ClassName TYPE = ClassName.get(Long.class); 13 | 14 | public LongField() { 15 | this.type = TYPE; 16 | } 17 | 18 | @Override 19 | public LongField create(FieldCustomization customization, ModelField... valueFields) { 20 | return new LongField(customization); 21 | } 22 | 23 | private LongField(FieldCustomization customization) { 24 | super(TYPE, customization); 25 | } 26 | 27 | @Override 28 | protected double ceiling() { 29 | return Long.MAX_VALUE; 30 | } 31 | 32 | @Override 33 | protected double floor() { 34 | return Long.MIN_VALUE; 35 | } 36 | 37 | @Override 38 | protected CodeBlock constantInit(Double c) { 39 | return CodeBlock.of("$LL", c.longValue()); 40 | } 41 | 42 | @Override 43 | protected Class> initializerType() { 44 | return LongRandomizer.class; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/UnknownFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.TypeName; 5 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 6 | import org.junit.jupiter.api.BeforeEach; 7 | import org.junit.jupiter.api.Test; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | import static org.assertj.core.api.Assertions.catchThrowable; 11 | 12 | class UnknownFieldTest { 13 | 14 | private UnknownField unknownField; 15 | 16 | @BeforeEach 17 | void setUp() { 18 | unknownField = new UnknownField(TypeName.VOID, FieldPatternFactory.any()); 19 | } 20 | 21 | @Test 22 | void should_generate_null_as_init_value() { 23 | final CodeBlock initialValue = unknownField.initialValue(); 24 | 25 | assertThat(initialValue).hasToString("null"); 26 | } 27 | 28 | @Test 29 | void should_not_invoke_initializer() { 30 | final Throwable throwable = catchThrowable(() -> unknownField.initializer()); 31 | 32 | assertThat(throwable).isInstanceOf(UnsupportedOperationException.class); 33 | } 34 | 35 | @Test 36 | void should_not_invoke_create() { 37 | final Throwable throwable = catchThrowable(() -> unknownField.create(FieldPatternFactory.any())); 38 | 39 | assertThat(throwable).isInstanceOf(UnsupportedOperationException.class); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/number/ByteField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.number; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.Randomizer; 8 | import io.github.easymodeling.randomizer.number.ByteRandomizer; 9 | 10 | public class ByteField extends NumericField { 11 | 12 | public static final ClassName TYPE = ClassName.get(Byte.class); 13 | 14 | public ByteField() { 15 | this.type = TYPE; 16 | } 17 | 18 | @Override 19 | public ByteField create(FieldCustomization customization, ModelField... valueFields) { 20 | return new ByteField(customization); 21 | } 22 | 23 | private ByteField(FieldCustomization customization) { 24 | super(TYPE, customization); 25 | } 26 | 27 | @Override 28 | protected double ceiling() { 29 | return Byte.MAX_VALUE; 30 | } 31 | 32 | @Override 33 | protected double floor() { 34 | return Byte.MIN_VALUE; 35 | } 36 | 37 | @Override 38 | protected CodeBlock constantInit(Double c) { 39 | return CodeBlock.of("(byte) $L", c.byteValue()); 40 | } 41 | 42 | @Override 43 | protected Class> initializerType() { 44 | return ByteRandomizer.class; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/number/DoubleField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.number; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.Randomizer; 8 | import io.github.easymodeling.randomizer.number.DoubleRandomizer; 9 | 10 | public class DoubleField extends NumericField { 11 | 12 | public static final ClassName TYPE = ClassName.get(Double.class); 13 | 14 | public DoubleField() { 15 | this.type = TYPE; 16 | } 17 | 18 | @Override 19 | public DoubleField create(FieldCustomization customization, ModelField... valueFields) { 20 | return new DoubleField(customization); 21 | } 22 | 23 | private DoubleField(FieldCustomization customization) { 24 | super(TYPE, customization); 25 | } 26 | 27 | @Override 28 | protected double ceiling() { 29 | return Long.MAX_VALUE; 30 | } 31 | 32 | @Override 33 | protected double floor() { 34 | return Long.MIN_VALUE; 35 | } 36 | 37 | @Override 38 | protected CodeBlock constantInit(Double c) { 39 | return CodeBlock.of("$L", c); 40 | } 41 | 42 | @Override 43 | protected Class> initializerType() { 44 | return DoubleRandomizer.class; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/number/FloatField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.number; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.Randomizer; 8 | import io.github.easymodeling.randomizer.number.FloatRandomizer; 9 | 10 | public class FloatField extends NumericField { 11 | 12 | public static final ClassName TYPE = ClassName.get(Float.class); 13 | 14 | public FloatField() { 15 | this.type = TYPE; 16 | } 17 | 18 | @Override 19 | public FloatField create(FieldCustomization customization, ModelField... valueFields) { 20 | return new FloatField(customization); 21 | } 22 | 23 | private FloatField(FieldCustomization customization) { 24 | super(TYPE, customization); 25 | } 26 | 27 | @Override 28 | protected double ceiling() { 29 | return Long.MAX_VALUE; 30 | } 31 | 32 | @Override 33 | protected double floor() { 34 | return Long.MIN_VALUE; 35 | } 36 | 37 | @Override 38 | protected CodeBlock constantInit(Double c) { 39 | return CodeBlock.of("$LF", c.floatValue()); 40 | } 41 | 42 | @Override 43 | protected Class> initializerType() { 44 | return FloatRandomizer.class; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/datetime/LocalDateRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.time.Instant; 8 | import java.time.LocalDate; 9 | import java.time.ZoneId; 10 | 11 | import static org.assertj.core.api.Assertions.assertThat; 12 | 13 | class LocalDateRandomizerTest extends RandomizerTest { 14 | 15 | @RepeatedTest(100) 16 | void should_generate_random_local_date_within_range() { 17 | final Instant min = Instant.parse("2020-01-01T00:00:00Z"); 18 | final Instant max = Instant.parse("2020-01-01T23:59:59Z"); 19 | final LocalDateRandomizer localDateRandomizer = new LocalDateRandomizer(min.toEpochMilli(), max.toEpochMilli()); 20 | 21 | final LocalDate next = localDateRandomizer.next(); 22 | 23 | assertThat(next).isBetween(min.atZone(ZoneId.systemDefault()).toLocalDate(), max.atZone(ZoneId.systemDefault()).toLocalDate()); 24 | } 25 | 26 | @Test 27 | void should_generate_constant_local_date() { 28 | final Instant constant = Instant.now(); 29 | final LocalDateRandomizer localDateRandomizer = new LocalDateRandomizer(constant); 30 | 31 | final LocalDate next = localDateRandomizer.next(); 32 | 33 | assertThat(next).isEqualTo(constant.atZone(ZoneId.systemDefault()).toLocalDate()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/datetime/LocalTimeRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.time.Instant; 8 | import java.time.LocalTime; 9 | import java.time.ZoneId; 10 | 11 | import static org.assertj.core.api.Assertions.assertThat; 12 | 13 | class LocalTimeRandomizerTest extends RandomizerTest { 14 | 15 | @RepeatedTest(100) 16 | void should_generate_random_local_time_within_range() { 17 | final Instant min = Instant.parse("2020-01-01T10:59:35Z"); 18 | final Instant max = Instant.parse("2020-01-01T11:01:01Z"); 19 | final LocalTimeRandomizer localTimeRandomizer = new LocalTimeRandomizer(min.toEpochMilli(), max.toEpochMilli()); 20 | 21 | final LocalTime next = localTimeRandomizer.next(); 22 | 23 | assertThat(next).isBetween(min.atZone(ZoneId.systemDefault()).toLocalTime(), max.atZone(ZoneId.systemDefault()).toLocalTime()); 24 | } 25 | 26 | @Test 27 | void should_generate_constant_local_time() { 28 | final Instant constant = Instant.now(); 29 | final LocalTimeRandomizer localTimeRandomizer = new LocalTimeRandomizer(constant); 30 | 31 | final LocalTime next = localTimeRandomizer.next(); 32 | 33 | assertThat(next).isEqualTo(constant.atZone(ZoneId.systemDefault()).toLocalTime()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/number/ShortField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.number; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.Randomizer; 8 | import io.github.easymodeling.randomizer.number.ShortRandomizer; 9 | 10 | public class ShortField extends NumericField { 11 | 12 | public static final ClassName TYPE = ClassName.get(Short.class); 13 | 14 | public ShortField() { 15 | this.type = TYPE; 16 | } 17 | 18 | @Override 19 | public ShortField create(FieldCustomization customization, ModelField... valueFields) { 20 | return new ShortField(customization); 21 | } 22 | 23 | private ShortField(FieldCustomization customization) { 24 | super(TYPE, customization); 25 | } 26 | 27 | @Override 28 | protected double ceiling() { 29 | return Short.MAX_VALUE; 30 | } 31 | 32 | @Override 33 | protected double floor() { 34 | return Short.MIN_VALUE; 35 | } 36 | 37 | @Override 38 | protected CodeBlock constantInit(Double c) { 39 | return CodeBlock.of("(short) $L", c.shortValue()); 40 | } 41 | 42 | @Override 43 | protected Class> initializerType() { 44 | return ShortRandomizer.class; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /functional-test/src/main/java/io/github/easymodeling/OptionalModel.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.BigInteger; 5 | import java.time.Instant; 6 | import java.util.Optional; 7 | 8 | public class OptionalModel { 9 | 10 | public Optional[]> optionalOfArrayOfOptionalInstantArray; 11 | 12 | public Optional[]>[] arrayOfOptionalOfArrayOfOptionalInstantArray; 13 | 14 | public Optional[]> optionalOfArrayOfOptionalInstant; 15 | 16 | public Optional> optionalOfOptionalInstantArray; 17 | 18 | public Optional>> optionalOfOptionalOfOptionalInstantArray; 19 | 20 | public Optional optionalInteger; 21 | 22 | public Optional optionalInstant; 23 | 24 | public Optional nullableInteger; 25 | 26 | public Optional> optionalOfOptionalInstant; 27 | 28 | public Optional optionalOfInstantArray; 29 | 30 | public Optional optionalOfInstantMatrix; 31 | 32 | public Optional[] arrayOfOptionalInstant; 33 | 34 | public Optional[][] matrixOfOptionalInstant; 35 | 36 | public Optional[] arrayOfOptionalArrayOfInstant; 37 | 38 | public Optional[] arrayOfOptionalMatrixOfInstant; 39 | 40 | public Optional optionalBigDecimal; 41 | 42 | public Optional optionalBigInteger; 43 | } 44 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/collection/HashSetFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.ParameterizedTypeName; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.field.number.IntegerField; 7 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 8 | import io.github.easymodeling.randomizer.collection.HashSetRandomizer; 9 | import org.junit.jupiter.api.BeforeEach; 10 | 11 | import java.util.HashSet; 12 | 13 | import static org.assertj.core.api.Assertions.assertThat; 14 | 15 | class HashSetFieldTest extends ModelFieldTest { 16 | 17 | private IntegerField integerField; 18 | 19 | @BeforeEach 20 | @Override 21 | protected void setUp() { 22 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).maxSize(100).build(); 23 | integerField = new IntegerField().create(fieldCustomization); 24 | typeName = ParameterizedTypeName.get(HashSet.class, Integer.class); 25 | modelField = new HashSetField().create(fieldCustomization, integerField); 26 | } 27 | 28 | @Override 29 | protected void should_generate_initializer() { 30 | final CodeBlock initializer = modelField.initializer(); 31 | 32 | assertThat(initializer).hasToString( 33 | "new " + $(HashSetRandomizer.class) + "<>(" + integerField.initializer() + ", 100)"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/number/IntegerField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.number; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.Randomizer; 8 | import io.github.easymodeling.randomizer.number.IntegerRandomizer; 9 | 10 | public class IntegerField extends NumericField { 11 | 12 | public static final ClassName TYPE = ClassName.get(Integer.class); 13 | 14 | public IntegerField() { 15 | this.type = TYPE; 16 | } 17 | 18 | @Override 19 | public IntegerField create(FieldCustomization customization, ModelField... valueFields) { 20 | return new IntegerField(customization); 21 | } 22 | 23 | private IntegerField(FieldCustomization customization) { 24 | super(TYPE, customization); 25 | } 26 | 27 | @Override 28 | protected double ceiling() { 29 | return Integer.MAX_VALUE; 30 | } 31 | 32 | @Override 33 | protected double floor() { 34 | return Integer.MIN_VALUE; 35 | } 36 | 37 | @Override 38 | protected CodeBlock constantInit(Double c) { 39 | return CodeBlock.of("$L", c.intValue()); 40 | } 41 | 42 | @Override 43 | protected Class> initializerType() { 44 | return IntegerRandomizer.class; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/EnumFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 6 | import io.github.easymodeling.randomizer.EnumRandomizer; 7 | import org.junit.jupiter.api.BeforeEach; 8 | import org.junit.jupiter.api.Test; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | import static org.assertj.core.api.Assertions.catchThrowable; 12 | 13 | class EnumFieldTest extends ModelFieldTest { 14 | 15 | @Override 16 | @BeforeEach 17 | protected void setUp() { 18 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).build(); 19 | typeName = ClassName.get(SomeEnum.class); 20 | modelField = new EnumField(typeName, fieldCustomization); 21 | } 22 | 23 | @Override 24 | protected void should_generate_initializer() { 25 | final CodeBlock initializer = modelField.initializer(); 26 | 27 | assertThat(initializer).hasToString("new " + $(EnumRandomizer.class) + "<>(" + $(SomeEnum.class) + ".values())"); 28 | } 29 | 30 | @Test 31 | void should_not_create_enum_fields() { 32 | final Throwable throwable = catchThrowable(() -> modelField.create(fieldCustomization)); 33 | 34 | assertThat(throwable).isInstanceOf(UnsupportedOperationException.class); 35 | } 36 | 37 | enum SomeEnum { 38 | A, B, C 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/stream/IntStreamField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.stream; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.modeler.field.PlainField; 7 | import io.github.easymodeling.modeler.field.number.IntegerField; 8 | import io.github.easymodeling.modeler.field.number.NumericField; 9 | import io.github.easymodeling.randomizer.Randomizer; 10 | import io.github.easymodeling.randomizer.stream.IntStreamRandomizer; 11 | 12 | import java.util.stream.IntStream; 13 | 14 | public class IntStreamField extends PrimitiveTypeStreamField { 15 | 16 | public static final ClassName TYPE = ClassName.get(IntStream.class); 17 | 18 | public IntStreamField() { 19 | type = TYPE; 20 | } 21 | 22 | @Override 23 | public PlainField create(FieldCustomization customization, ModelField... valueFields) { 24 | return new IntStreamField(customization); 25 | } 26 | 27 | private IntStreamField(FieldCustomization customization) { 28 | super(TYPE, customization); 29 | } 30 | 31 | @Override 32 | protected Class> initializerType() { 33 | return IntStreamRandomizer.class; 34 | } 35 | 36 | @Override 37 | protected NumericField element() { 38 | return new IntegerField(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/stream/LongStreamField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.stream; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.modeler.field.PlainField; 7 | import io.github.easymodeling.modeler.field.number.LongField; 8 | import io.github.easymodeling.modeler.field.number.NumericField; 9 | import io.github.easymodeling.randomizer.Randomizer; 10 | import io.github.easymodeling.randomizer.stream.LongStreamRandomizer; 11 | 12 | import java.util.stream.LongStream; 13 | 14 | public class LongStreamField extends PrimitiveTypeStreamField { 15 | 16 | public static final ClassName TYPE = ClassName.get(LongStream.class); 17 | 18 | public LongStreamField() { 19 | type = TYPE; 20 | } 21 | 22 | @Override 23 | public PlainField create(FieldCustomization customization, ModelField... valueFields) { 24 | return new LongStreamField(customization); 25 | } 26 | 27 | private LongStreamField(FieldCustomization customization) { 28 | super(TYPE, customization); 29 | } 30 | 31 | @Override 32 | protected Class> initializerType() { 33 | return LongStreamRandomizer.class; 34 | } 35 | 36 | @Override 37 | protected NumericField element() { 38 | return new LongField(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/datetime/ZonedDateTimeRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.time.Instant; 8 | import java.time.ZoneId; 9 | import java.time.ZonedDateTime; 10 | 11 | import static org.assertj.core.api.Assertions.assertThat; 12 | 13 | class ZonedDateTimeRandomizerTest extends RandomizerTest { 14 | 15 | @RepeatedTest(100) 16 | void should_generate_random_zoned_date_time_within_range() { 17 | final Instant min = Instant.parse("2020-01-01T10:59:35Z"); 18 | final Instant max = Instant.parse("2020-01-01T11:01:01Z"); 19 | final ZonedDateTimeRandomizer zonedDateTimeRandomizer = new ZonedDateTimeRandomizer(min.toEpochMilli(), max.toEpochMilli()); 20 | 21 | final ZonedDateTime next = zonedDateTimeRandomizer.next(); 22 | 23 | assertThat(next).isBetween(ZonedDateTime.parse("2020-01-01T10:59:35Z"), ZonedDateTime.parse("2020-01-01T11:01:01Z")); 24 | } 25 | 26 | @Test 27 | void should_generate_constant_zoned_date_time() { 28 | final Instant constant = Instant.now(); 29 | final ZonedDateTimeRandomizer zonedDateTimeRandomizer = new ZonedDateTimeRandomizer(constant); 30 | 31 | final ZonedDateTime next = zonedDateTimeRandomizer.next(); 32 | 33 | assertThat(next).isEqualTo(constant.atZone(ZoneId.systemDefault())); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/collection/ListFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.ParameterizedTypeName; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.field.string.StringField; 7 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 8 | import io.github.easymodeling.randomizer.collection.ListRandomizer; 9 | import org.junit.jupiter.api.BeforeEach; 10 | 11 | import java.util.List; 12 | 13 | import static org.assertj.core.api.Assertions.assertThat; 14 | 15 | class ListFieldTest extends ModelFieldTest { 16 | 17 | private StringField stringField; 18 | 19 | @BeforeEach 20 | @Override 21 | protected void setUp() { 22 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).string("").min(3.).max(9.).minSize(20).maxSize(50).build(); 23 | this.stringField = new StringField().create(fieldCustomization); 24 | typeName = ParameterizedTypeName.get(List.class, String.class); 25 | modelField = new ListField().create(fieldCustomization, this.stringField); 26 | } 27 | 28 | @Override 29 | protected void should_generate_initializer() { 30 | final CodeBlock initializer = modelField.initializer(); 31 | 32 | assertThat(initializer) 33 | .hasToString("new " + $(ListRandomizer.class) + "<>(" + stringField.initializer() + ", 20, 50)"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "🚀 Feature Request" 3 | description: "Suggest an idea for this project" 4 | title: "(Short description of the feature)" 5 | labels: [ feature-request ] 6 | assignees: [ ] 7 | body: 8 | - type: textarea 9 | id: description 10 | attributes: 11 | label: Describe the feature 12 | description: Please description of the feature you are proposing. 13 | validations: 14 | required: true 15 | 16 | - type: textarea 17 | id: use-case 18 | attributes: 19 | label: Use Case 20 | description: | 21 | Why do we need this feature? Who could this feature be useful? 22 | validations: 23 | required: true 24 | 25 | - type: textarea 26 | id: notes 27 | attributes: 28 | label: Possible Solution / Additional Notes 29 | description: | 30 | Do you have any suggestions on how to implement this feature? Or any other notes? 31 | validations: 32 | required: false 33 | 34 | - type: checkboxes 35 | id: ack 36 | attributes: 37 | label: Acknowledgements 38 | options: 39 | - label: I may be able to implement this feature 40 | required: false 41 | - label: This feature will introduce some breaking changes 42 | required: false 43 | 44 | - type: input 45 | id: easy-modeling-version 46 | attributes: 47 | label: EasyModeling Version 48 | description: On which EasyModeling version is this feature request based? 49 | validations: 50 | required: true 51 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/archunit/ModelerPackageArchTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.archunit; 2 | 3 | import com.tngtech.archunit.junit.AnalyzeClasses; 4 | import com.tngtech.archunit.junit.ArchTest; 5 | import com.tngtech.archunit.lang.ArchRule; 6 | import io.github.easymodeling.Field; 7 | import io.github.easymodeling.Model; 8 | import io.github.easymodeling.Models; 9 | 10 | import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; 11 | 12 | @AnalyzeClasses(packages = "io.github.easymodeling.modeler") 13 | public class ModelerPackageArchTest { 14 | 15 | @ArchTest 16 | private final ArchRule modeler_pkg_should_not_depend_on_Model_and_Models_annotations = 17 | noClasses() 18 | .that().resideInAPackage("io.github.easymodeling.modeler..") 19 | .should().dependOnClassesThat().belongToAnyOf(Model.class, Models.class); 20 | 21 | @ArchTest 22 | private final ArchRule modeler_pkg_should_not_depend_on_Field_annotations = 23 | noClasses() 24 | .that().resideInAPackage("io.github.easymodeling.modeler..") 25 | .should().dependOnClassesThat().belongToAnyOf(Field.class); 26 | 27 | @ArchTest 28 | private final ArchRule should_modeler_pkg_not_depends_on_processor_pkg = 29 | noClasses() 30 | .that().resideInAPackage("io.github.easymodeling.modeler..") 31 | .should().dependOnClassesThat().resideInAnyPackage("io.github.easymodeling.processor.."); 32 | } 33 | -------------------------------------------------------------------------------- /core/src/main/java/io/github/easymodeling/randomizer/GenericRandomizer.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer; 2 | 3 | import java.util.Optional; 4 | import java.util.Random; 5 | 6 | public abstract class GenericRandomizer implements Randomizer { 7 | 8 | protected static final Random random = new Random(); 9 | 10 | protected T constant; 11 | 12 | protected GenericRandomizer() { 13 | } 14 | 15 | protected GenericRandomizer(T constant) { 16 | this.constant = constant; 17 | } 18 | 19 | @Override 20 | public final T next() { 21 | return constant().orElseGet(this::random); 22 | } 23 | 24 | private Optional constant() { 25 | return Optional.ofNullable(constant); 26 | } 27 | 28 | protected abstract T random(); 29 | 30 | /** 31 | * Generate a random double value between given min and max. 32 | * 33 | * @param min inclusive lower bound 34 | * @param max exclusive upper bound, should be greater than or equal to min 35 | * @return a random double between min (inclusive) and max (exclusive) 36 | */ 37 | protected Double doubleBetween(double min, double max) { 38 | final double value = random.nextDouble() * (max - min) + min; 39 | if (value <= min) { 40 | return min; 41 | } else if (value > max) { 42 | return max; 43 | } else { 44 | return value; 45 | } 46 | } 47 | 48 | protected boolean oneThirdTruth() { 49 | return random.nextInt(3) == 0; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/stream/DoubleStreamField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.stream; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import io.github.easymodeling.modeler.FieldCustomization; 5 | import io.github.easymodeling.modeler.field.ModelField; 6 | import io.github.easymodeling.modeler.field.PlainField; 7 | import io.github.easymodeling.modeler.field.number.DoubleField; 8 | import io.github.easymodeling.modeler.field.number.NumericField; 9 | import io.github.easymodeling.randomizer.Randomizer; 10 | import io.github.easymodeling.randomizer.stream.DoubleStreamRandomizer; 11 | 12 | import java.util.stream.DoubleStream; 13 | 14 | public class DoubleStreamField extends PrimitiveTypeStreamField { 15 | 16 | public static final ClassName TYPE = ClassName.get(DoubleStream.class); 17 | 18 | public DoubleStreamField() { 19 | type = TYPE; 20 | } 21 | 22 | @Override 23 | public PlainField create(FieldCustomization customization, ModelField... valueFields) { 24 | return new DoubleStreamField(customization); 25 | } 26 | 27 | private DoubleStreamField(FieldCustomization customization) { 28 | super(TYPE, customization); 29 | } 30 | 31 | @Override 32 | protected Class> initializerType() { 33 | return DoubleStreamRandomizer.class; 34 | } 35 | 36 | @Override 37 | protected NumericField element() { 38 | return new DoubleField(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core/src/test/java/io/github/easymodeling/randomizer/datetime/LocalDateTimeRandomizerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.randomizer.datetime; 2 | 3 | import io.github.easymodeling.randomizer.RandomizerTest; 4 | import org.junit.jupiter.api.RepeatedTest; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.time.Instant; 8 | import java.time.LocalDateTime; 9 | import java.time.ZoneId; 10 | 11 | import static org.assertj.core.api.Assertions.assertThat; 12 | 13 | class LocalDateTimeRandomizerTest extends RandomizerTest { 14 | 15 | @RepeatedTest(100) 16 | void should_generate_random_local_time_within_range() { 17 | final Instant min = Instant.parse("2020-01-01T10:59:35Z"); 18 | final Instant max = Instant.parse("2020-01-01T11:01:01Z"); 19 | final LocalDateTimeRandomizer localDateTimeRandomizer = new LocalDateTimeRandomizer(min.toEpochMilli(), max.toEpochMilli()); 20 | 21 | final LocalDateTime next = localDateTimeRandomizer.next(); 22 | 23 | assertThat(next).isBetween(min.atZone(ZoneId.systemDefault()).toLocalDateTime(), max.atZone(ZoneId.systemDefault()).toLocalDateTime()); 24 | } 25 | 26 | @Test 27 | void should_generate_constant_local_time() { 28 | final Instant constant = Instant.now(); 29 | final LocalDateTimeRandomizer localDateTimeRandomizer = new LocalDateTimeRandomizer(constant); 30 | 31 | final LocalDateTime next = localDateTimeRandomizer.next(); 32 | 33 | assertThat(next).isEqualTo(constant.atZone(ZoneId.systemDefault()).toLocalDateTime()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/number/BigDecimalField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.number; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.Randomizer; 8 | import io.github.easymodeling.randomizer.number.BigDecimalRandomizer; 9 | 10 | import java.math.BigDecimal; 11 | 12 | public class BigDecimalField extends NumericField { 13 | 14 | public static final ClassName TYPE = ClassName.get(BigDecimal.class); 15 | 16 | public BigDecimalField() { 17 | this.type = TYPE; 18 | } 19 | 20 | @Override 21 | public ModelField create(FieldCustomization customization, ModelField... valueFields) { 22 | return new BigDecimalField(customization); 23 | } 24 | 25 | private BigDecimalField(FieldCustomization customization) { 26 | super(TYPE, customization); 27 | } 28 | 29 | @Override 30 | protected Class> initializerType() { 31 | return BigDecimalRandomizer.class; 32 | } 33 | 34 | @Override 35 | protected double ceiling() { 36 | return Long.MAX_VALUE; 37 | } 38 | 39 | @Override 40 | protected double floor() { 41 | return Long.MIN_VALUE; 42 | } 43 | 44 | @Override 45 | protected CodeBlock constantInit(Double c) { 46 | return CodeBlock.of("$L", c); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/stream/StreamFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.stream; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.ParameterizedTypeName; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.field.PlainField; 7 | import io.github.easymodeling.modeler.field.number.IntegerField; 8 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 9 | import io.github.easymodeling.randomizer.stream.StreamRandomizer; 10 | import org.junit.jupiter.api.BeforeEach; 11 | 12 | import java.util.stream.Stream; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | 16 | class StreamFieldTest extends ModelFieldTest { 17 | 18 | private PlainField integerField; 19 | 20 | @BeforeEach 21 | @Override 22 | protected void setUp() { 23 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).minSize(2).maxSize(9).build(); 24 | integerField = new IntegerField().create(fieldCustomization); 25 | typeName = ParameterizedTypeName.get(Stream.class, Integer.class); 26 | modelField = new StreamField().create(fieldCustomization, integerField); 27 | } 28 | 29 | @Override 30 | protected void should_generate_initializer() { 31 | final CodeBlock initializer = modelField.initializer(); 32 | 33 | assertThat(initializer) 34 | .hasToString("new " + $(StreamRandomizer.class) + "<>(" + integerField.initializer() + ", 2, 9)"); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /processor/src/main/java/io/github/easymodeling/modeler/field/number/BigIntegerField.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.number; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.FieldCustomization; 6 | import io.github.easymodeling.modeler.field.ModelField; 7 | import io.github.easymodeling.randomizer.Randomizer; 8 | import io.github.easymodeling.randomizer.number.BigIntegerRandomizer; 9 | 10 | import java.math.BigInteger; 11 | 12 | public class BigIntegerField extends NumericField { 13 | 14 | public static final ClassName TYPE = ClassName.get(BigInteger.class); 15 | 16 | public BigIntegerField() { 17 | this.type = TYPE; 18 | } 19 | 20 | @Override 21 | public ModelField create(FieldCustomization customization, ModelField... valueFields) { 22 | return new BigIntegerField(customization); 23 | } 24 | 25 | private BigIntegerField(FieldCustomization customization) { 26 | super(TYPE, customization); 27 | } 28 | 29 | @Override 30 | protected Class> initializerType() { 31 | return BigIntegerRandomizer.class; 32 | } 33 | 34 | @Override 35 | protected double ceiling() { 36 | return Long.MAX_VALUE; 37 | } 38 | 39 | @Override 40 | protected double floor() { 41 | return Long.MIN_VALUE; 42 | } 43 | 44 | @Override 45 | protected CodeBlock constantInit(Double c) { 46 | return CodeBlock.of("$LL", c.longValue()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/collection/ArrayListFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.ParameterizedTypeName; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.field.PlainField; 7 | import io.github.easymodeling.modeler.field.number.IntegerField; 8 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 9 | import io.github.easymodeling.randomizer.collection.ArrayListRandomizer; 10 | import org.junit.jupiter.api.BeforeEach; 11 | 12 | import java.util.ArrayList; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | 16 | class ArrayListFieldTest extends ModelFieldTest { 17 | 18 | private PlainField integerField; 19 | 20 | @BeforeEach 21 | @Override 22 | protected void setUp() { 23 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).build(); 24 | integerField = new IntegerField().create(fieldCustomization); 25 | typeName = ParameterizedTypeName.get(ArrayList.class, Integer.class); 26 | modelField = new ArrayListField().create(fieldCustomization, integerField); 27 | } 28 | 29 | @Override 30 | protected void should_generate_initializer() { 31 | final CodeBlock initializer = modelField.initializer(); 32 | 33 | assertThat(initializer).hasToString( 34 | "new " + $(ArrayListRandomizer.class) + "<>(" + integerField.initializer() + ", 1, 20)"); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/CustomFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field; 2 | 3 | import com.squareup.javapoet.ClassName; 4 | import com.squareup.javapoet.CodeBlock; 5 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 6 | import io.github.easymodeling.randomizer.CustomTypeRandomizer; 7 | import org.junit.jupiter.api.BeforeEach; 8 | import org.junit.jupiter.api.Test; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | import static org.assertj.core.api.Assertions.catchThrowable; 12 | 13 | class CustomFieldTest extends ModelFieldTest { 14 | 15 | @Override 16 | @BeforeEach 17 | protected void setUp() { 18 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).build(); 19 | typeName = ClassName.get(SomeTest.class); 20 | modelField = new CustomField(typeName, fieldCustomization); 21 | } 22 | 23 | @Override 24 | protected void should_generate_initializer() { 25 | final CodeBlock initializer = modelField.initializer(); 26 | 27 | assertThat(initializer).hasToString("new " + $(CustomTypeRandomizer.class) + "<>(new " + $(SomeTest.class) + "Modeler(), modelCache)"); 28 | } 29 | 30 | @Test 31 | void should_not_create_enum_fields() { 32 | final Throwable throwable = catchThrowable(() -> modelField.create(fieldCustomization)); 33 | 34 | assertThat(throwable).isInstanceOf(UnsupportedOperationException.class); 35 | } 36 | 37 | @SuppressWarnings("InnerClassMayBeStatic") 38 | public class SomeTest { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /processor/src/test/java/io/github/easymodeling/modeler/field/collection/LinkedListFieldTest.java: -------------------------------------------------------------------------------- 1 | package io.github.easymodeling.modeler.field.collection; 2 | 3 | import com.squareup.javapoet.CodeBlock; 4 | import com.squareup.javapoet.ParameterizedTypeName; 5 | import io.github.easymodeling.modeler.field.ModelFieldTest; 6 | import io.github.easymodeling.modeler.field.PlainField; 7 | import io.github.easymodeling.modeler.field.number.IntegerField; 8 | import io.github.easymodeling.modeler.helper.FieldPatternFactory; 9 | import io.github.easymodeling.randomizer.collection.LinkedListRandomizer; 10 | import org.junit.jupiter.api.BeforeEach; 11 | 12 | import java.util.LinkedList; 13 | 14 | import static org.assertj.core.api.Assertions.assertThat; 15 | 16 | class LinkedListFieldTest extends ModelFieldTest { 17 | 18 | private PlainField integerField; 19 | 20 | @BeforeEach 21 | @Override 22 | protected void setUp() { 23 | fieldCustomization = FieldPatternFactory.one(FIELD_NAME).minSize(2).maxSize(5).build(); 24 | typeName = ParameterizedTypeName.get(LinkedList.class, Integer.class); 25 | integerField = new IntegerField().create(fieldCustomization); 26 | modelField = new LinkedListField().create(fieldCustomization, integerField); 27 | } 28 | 29 | @Override 30 | protected void should_generate_initializer() { 31 | final CodeBlock codeBlock = modelField.initializer(); 32 | 33 | assertThat(codeBlock) 34 | .hasToString("new " + $(LinkedListRandomizer.class) + "<>(" + integerField.initializer() + ", 2, 5)"); 35 | } 36 | } 37 | --------------------------------------------------------------------------------