GithubHelp home page GithubHelp logo

goodforgod / dummymaker Goto Github PK

View Code? Open in Web Editor NEW
13.0 3.0 5.0 2.21 MB

๐Ÿงฐ Generates random Java Classes/Records for you.

Home Page: http://goodforgod.dev/dummymaker/

License: MIT License

Java 100.00%
java export dummy data generate factory fill pojo dto easy-random

dummymaker's Introduction

DummyMaker

Minimum required Java version GitHub Action Quality Gate Status Coverage Maintainability Rating Lines of Code

DummyMaker is a library that generates random Java Classes / Records / Sealed Interfaces / Sealed Classes for you.

Library can even do simple export in CSV/JSON/XML/SQL formats.

Library have no dependencies.

Dependency ๐Ÿš€

Gradle

implementation "com.github.goodforgod:dummymaker:4.0.0"

Maven

<dependency>
    <groupId>com.github.goodforgod</groupId>
    <artifactId>dummymaker</artifactId>
    <version>4.0.0</version>
</dependency>

Content

When to use?

There are plenty of use cases where DummyMaker is useful:

  • Generating a random data to populate database
  • Generating a random data to for tests
  • Generating a high number of data to load-test a web service
  • Generating a high number of data to text file (CSV, XML, JSON, SQL, etc)
  • etc..

Simple example on how you would create class with random data using constructor manually:

Street street = new Street(12, 1, "Revolution Sq");
Address address = new Address(street, "123456", "Saint-Petersburg");
Person person = new Person("Foo", "Bar", "[email protected]", address);

And if classes do not provide constructors with parameters:

Street street = new Street();
street.setNumber(12);
street.setType(1);
street.setName("Revolution Sq");

Address address = new Address();
address.setStreet(street);
address.setZipCode("123456");
address.setCity("Saint-Petersburg");

Person person = new Person();
person.setFirstName("Foo");
person.setLastName("Bar");
person.setEmail("[email protected]");
person.setAddress(address);

Using DummyMaker library, it is easy to generate Person class with all inner classes with random data for all fields:

GenFactory factory = GenFactory.build();
Person person = factory.build(Person.class);

Factory Examples

GenFactory provides different methods for random class generation.

Given such Java Class as a model:

class User {

  public String name;
  public String surname;
}

Example on how to generate single random Java Class with random field values:

GenFactory factory = GenFactory.build();
User user = factory.build(User.class);

Example on how to generate standard Java Class (can be used with most of the standard Java Classes):

GenFactory factory = GenFactory.build();
Integer integer = factory.build(Integer.class);

Example how to generate list of Java Classes:

GenFactory factory = GenFactory.build();
List<User> users = factory.build(User.class, 1000);

Example how to generate stream of Java Classes:

GenFactory factory = GenFactory.build();
factory.stream(User.class, 1000)
        .forEach(System.out::println);

In case have complex constructor, or it is required to generate on instantiated class, you can provide Supplier for factory:

GenFactory factory = GenFactory.build();
User user = factory.build(() -> new User());

Configuration

GenFactory Builder provides different methods to configure random class generation and generated data specifications.

Example how to configure GenFactory, check its Builder for more settings:

class Account {
    
  public String type = "simple";
  public String name;
}

GenFactory factory = GenFactory.builder()
        .overrideDefaultValues(false)
        .applyCase(NamingCases.UPPER_CASE)
        .build();

Account account = factory.build(Account.class);

Available configurations:

  • Case - apply naming case for String values like SnakeCase, CamelCase, UpperCase, etc.
  • Localisation - choose language for generated String values (available Russian & English)
  • Seed - set seed to use when selecting random generator for fields for constant results across executions
  • AutoByDefault - generate field values for all classes by default (true by default)
  • DepthByDefault - set maximum depth when generating random embedded classes
  • IgnoreExceptions - ignore exceptions while generating field values (false by default)
  • OverrideDefaultValues - generate random values for fields when field have Not Null value (true by default)

GenRules

GenFactory allows to provide rules for configuring class generation for specific fields.

Rules can be used to configure specific generators for specific fields or exclude fields.

GenRule examples will be based on this class:

class Account {

  public Integer number;
  public String type;
  public String name;
}

Example on how to generate specific random value for any field:

List<String> values = Arrays.asList("1", "5", "9");

GenFactory factory = GenFactory.builder()
        .addRule(GenRule.ofClass(Account.class)
                .generateForNames("type", () -> CollectionUtils.random(values)))
        .build();

Account account = factory.build(Account.class);

Class

Class specific Rule is applied only for specific Class.

Example how to add specific Generator for fields by their names:

GenFactory factory = GenFactory.builder()
        .addRule(GenRule.ofClass(Account.class)
                .generateForNames("type", "name", () -> new NameGenerator()))
        .build();

Account account = factory.build(Account.class);

Global

Global Rule is applied for all Classes.

Example how to add specific Generator for all types:

GenFactory factory = GenFactory.builder()
        .addRule(GenRule.ofGlobal()
                .generateForTypes(String.class, () -> new NameGenerator()))
        .build();

Account account = factory.build(Account.class);

GenAnnotation Examples

Library provides lots of annotations to mark out class for random value generation.

This is an alternative to GenRules mechanism for random value generation configuring.

Check io.dummymaker.annotation package for all of them.

Standard

Using annotations like @GenEmail, @GenId, @GenName, etc., it allows mark out which Generator to use for which field.

class Account {

  @GenId
  private String id;
  @GenName
  private String name;
  @GenInt(from = 1, to = 10)
  private long number;
  @GenAddress
  private String address;
  @GenEmail
  private String email;
}

GenFactory factory = GenFactory.build();
Account account = factory.build(Account.class);

Special

Library provides annotations that allow to provide special behavior when generating random values of typically used for complex values generation:

  • @GenSequence - generates sequence number value (when each individual field value should be incremented by 1).
  • @GenArray - generates random array value.
  • @GenArray2D - generates random double array value.
  • @GenEnum - generates random Enum value (should be annotated for Enum fields)
  • @GenList - generates random List value.
  • @GenSet - generates random Set value.
  • @GenMap - generates random Map value.
  • @GenTime - generates random Time value java.time.* package and old Java Data API.
  • @GenUnixTime - generates random UnixTime in millis.

Configuration annotations:

  • @GenIgnore - indicates that field will be excluded from random value generation.
  • @GenAuto - indicates that class should be Auto generated (generators swill be automatically selected if not marked out)
  • @GenDepth - configures maximum Depth when generating embedded class values.
@GenAuto
@GenDepth(2)
class Account {

  @GenSequence
  private Long id;
  @GenTime
  private String timestamp;
  @GenUnixTime
  private long unixTime;
  @GenIgnore
  private String ignored;
  @GenList
  private List<String> emails;
  @GenSet(generator = TypeGenerator.class)
  private Set<String> types;
  @GenMap
  private Map<Integer, String> numbers;
  
  private Account boss;
}

GenFactory factory = GenFactory.build();
Account account = factory.build(Account.class);

GenAnnotations

Library provides lots of GenAnnotations:

String Annotations
@GenAddress
@GenAddressFull
@GenBtcAddress
@GenBtcTxHash
@GenCadastral
@GenCategory
@GenCity
@GenCompany
@GenCountry
@GenCurrency
@GenDescription
@GenDistrict
@GenEmail
@GenEthAddress
@GenEthTxHash
@GenFrequency
@GenFullname
@GenGender
@GenHexData
@GenHexNumber
@GenHouse
@GenId
@GenIdBig
@GenIPv4
@GenIPv6
@GenJob
@GenJson
@GenLevel
@GenLogin
@GenMcc
@GenMerchant
@GenMiddleName
@GenName
@GenNickname
@GenNoun
@GenPass
@GenPassword
@GenPhone
@GenPhoto
@GenProduct
@GenRole
@GenStatus
@GenStreet
@GenString
@GenStringValues
@GenSurname
@GenTag
@GenVersion
Number Annotations
@GenBigDecimal
@GenBigInteger
@GenByte
@GenChar
@GenCharacter
@GenDouble
@GenDoubleSmall
@GenFloat
@GenFloatSmall
@GenInt
@GenLong
@GenMcc
@GenPostal
@GenPrice
@GenSequence
@GenShort
Time Annotations
@GenCalendar
@GenDate
@GenDateSql
@GenDayOfWeek
@GenDuration
@GenInstant
@GenLocalDate
@GenLocalDateTime
@GenLocalTime
@GenMonth
@GenMonthDay
@GenOffsetDateTime
@GenOffsetTime
@GenPeriod
@GenTimeSql
@GenTimestamp
@GenYear
@GenYearMonth
@GenZonedDateTime
@GenZonedOffset
Other Annotations
@GenBoolean
@GenNull
@GenUri
@GenUrl
@GenUuid
Parameterized Generators
@GenArray
@GenArray2D
@GenEnum
@GenList
@GenMap
@GenSet
@GenTime
@GenUnixTime

Generators

Library provides lots of generators:

String Generators
AddressFullGenerator.java
AddressGenerator.java
BtcAddressGenerator.java
BtcTxHashGenerator.java
CadastralGenerator.java
CategoryGenerator.java
CityGenerator.java
CompanyGenerator.java
CountryGenerator.java
CurrencyGenerator.java
DescriptionGenerator.java
DistrictGenerator.java
DocumentGenerator.java
EmailGenerator.java
EthAddressGenerator.java
EthTxHashGenerator.java
ExtensionGenerator.java
FileGenerator.java
FormatGenerator.java
FrequencyGenerator.java
FullnameGenerator.java
GenderGenerator.java
HexDataGenerator.java
HexNumberGenerator.java
HouseGenerator.java
IdBigGenerator.java
IdGenerator.java
IPv4Generator.java
IPv6Generator.java
JobGenerator.java
JsonGenerator.java
LevelGenerator.java
LoginGenerator.java
MccGenerator.java
MerchantGenerator.java
MiddleNameGenerator.java
NameGenerator.java
NounGenerator.java
PasswordGenerator.java
PhoneGenerator.java
PhotoGenerator.java
ProductGenerator.java
RoleGenerator.java
StatusGenerator.java
StreetGenerator.java
StringGenerator.java
StringValuesGenerator.java
SurnameGenerator.java
TagGenerator.java
TypeGenerator.java
VersionGenerator.java
Number Generators
BigDecimalGenerator.java
BigIntegerGenerator.java
ByteGenerator.java
CharacterGenerator.java
CharGenerator.java
DoubleGenerator.java
DoubleSmallGenerator.java
FloatGenerator.java
FloatSmallGenerator.java
IntegerGenerator.java
IntegerSmallGenerator.java
LongGenerator.java
MccGenerator.java
PostalGenerator.java
PriceGenerator.java
SequenceGenerator.java
ShortGenerator.java
UnixTimeGenerator.java
Time Generators
CalendarGenerator.java
DateGenerator.java
DateSqlGenerator.java
DayOfWeekGenerator.java
DurationGenerator.java
InstantGenerator.java
LocalDateGenerator.java
LocalDateTimeGenerator.java
LocalTimeGenerator.java
MonthDayGenerator.java
MonthGenerator.java
OffsetDateTimeGenerator.java
OffsetTimeGenerator.java
PeriodGenerator.java
TimeSqlGenerator.java
TimestampGenerator.java
YearGenerator.java
YearMonthGenerator.java
ZonedDateTimeGenerator.java
ZonedOffsetGenerator.java
Other Generators
BooleanGenerator.java
EmbeddedGenerator.java
NullGenerator.java
ObjectGenerator.java
UriGenerator.java
UrlGenerator.java
UuidGenerator.java
Parameterized Annotations
Array2DParameterizedGenerator.java
ArrayParameterizedGenerator.java
EnumParameterizedGenerator.java
ListParameterizedGenerator.java
MapParameterizedGenerator.java
SetParameterizedGenerator.java
TimeParameterizedGenerator.java

Export

Library provides simple Exporter classes to export objects in CSV, JSON, XML and even SQL formats.

Each Exporter provides different methods to export single Java class, list of classes or stream of classes.

Exporter have different configurations, like naming case for field names, also custom Writer can be supplied for file writing.

Examples will be based on this class:

class Account {

  public Integer number;
  public String type;
  public String name;
}

Annotations

Library provides special export annotations:

  • @GenExportIgnore - allow to ignore object's field during export.
  • @GenExportRename - allow to rename Dummy export Field Name.

JSON

JsonExporter can export Java classes in JSON format.

Example:

GenFactory factory = GenFactory.build();
List<Account> accounts = factory.build(Account.class, 2);

Exporter exporter = JsonExporter.build();
String json = exporter.exportAsString(accounts);

Result:

[
  {"number":1657591124,"type":"invalid","name":"Palmer"},
  {"number":1243742023,"type":"rejected","name":"Cindy"}
]

CSV

CsvExporter can export Java classes in CSV format.

Example:

GenFactory factory = GenFactory.build();
List<Account> accounts = factory.build(Account.class, 2);

Exporter exporter = CsvExporter.build();
String csv = exporter.exportAsString(accounts);

Result:

number,type,name
1032136236,rejected,Mike
338683126,failed,Jesus

XML

XmlExporter can export Java classes in XML format.

Example:

GenFactory factory = GenFactory.build();
List<Account> accounts = factory.build(Account.class, 2);

Exporter exporter = XmlExporter.build();
String xml = exporter.exportAsString(accounts);

Result:

<AccountList>
    <Account>
        <number>189092582</number>
        <type>invalid</type>
        <name>Antonio</name>
    </Account>
    <Account>
        <number>58523878</number>
        <type>failed</type>
        <name>Carlos</name>
    </Account>
</AccountList>

SQL

SqlExporter can export Java classes in SQL format.

This is useful when you need to insert millions rows into SQL database, such insert query is one of the fastest ways.

Example:

GenFactory factory = GenFactory.build();
List<Account> accounts = factory.build(Account.class, 2);

Exporter exporter = SqlExporter.build();
String sql = exporter.exportAsString(accounts);

Result:

CREATE TABLE IF NOT EXISTS account(
	number	INT,
	type	VARCHAR,
	name	VARCHAR,
	PRIMARY KEY (number)
);

INSERT INTO account(number, type, name) VALUES
(1682341022, 'failed', 'Megan'),
(2052081057, 'invalid', 'Tina');

Writer

When exporting to file, you can provide your own Writer implementation.

Example:

GenFactory factory = GenFactory.build();
List<Account> accounts = factory.build(Account.class, 2);

Exporter exporter = JsonExporter.builder().withWriter(name -> new SimpleFileWriter(false, name)).build();
exporter.exportAsFile(accounts);

Customization Examples

Library allows easily create custom Generator or annotations.

Simple Generator

Simple Generator that produce some random value.

Generator can specify pattern that will be used choose where to apply such Generator based on field name.

public class IntegerMyGenerator implements Generator<Integer> {

    private final Pattern pattern = Pattern.compile("age|grade|group", CASE_INSENSITIVE);

    @Override
    public Pattern pattern() {
        return pattern;
    }

    @Override
    public Integer generate() {
        return ThreadLocalRandom.current().nextInt(1, 101);
    }
}

Parameterized Generator

Generator sometimes require more context to use for random value generation, than it is possible to implement ParameterizedGenerator.

public final class MyParameterizedGenerator implements ParameterizedGenerator<String> {

    @Override
    public String get(@NotNull GenParameters parameters) {
        return parameters.namingCase().apply("myValue");
    }

    @Override
    public String get() {
        return "myValue";
    }
}

Custom Annotation

You can apply custom Generator not only using GenRules but also using @GenCustom annotation.

@GenCustom annotation require Generator

class Account {

  @GenCustom(IntegerMyGenerator.class)
  public String type;
}

Custom Annotation Factory

AnnotationGeneratorFactory is used when you need to instantiate generate with arguments from annotation.

AnnotationGeneratorFactory must have zero argument constructor.

@GenCustomFactory is used to indicate which factory for which annotation to use.

Given annotation:

@GenCustomFactory(CustomIntegerAnnotationGeneratorFactory.class)
@Retention(value = RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface GenIntCustom {

    @Range(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE)
    int from() default 0;

    @Range(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE)
    int to() default Integer.MAX_VALUE;
}

Respected AnnotationGeneratorFactory should look like:

public final class IntegerAnnotationGeneratorFactory implements CustomIntegerAnnotationGeneratorFactory<GenIntCustom> {

    @Override
    public @NotNull Generator<Integer> get(GenIntCustom annotation) {
        return new IntegerGenerator(annotation.from(), annotation.to());
    }
}

Previous Versions

Documentation for versions 3.X.X in this document.

Documentation for versions 1.X.X in this document.

License

This project licensed under the MIT - see the LICENSE file for details.

dummymaker's People

Contributors

goodforgod avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

dummymaker's Issues

Add GenConfig class for generator mapping

Create GenConfig class that can map some types to genetaros, like all String fields map to UuidGenerator and etc.
Also add support for fieldName as string -> Generator mapping

Not working with JaCoCo code coverage

Describe the bug
Library is not working properly with JaCoCo code coverage and fails with index out of bound exception when accessing entity fields

To Reproduce
Steps to reproduce the behavior:

  1. Run tests using JaCoCo plugin

Expected behavior
Library not working with JaCoCo, expecting it to work actually

Additional context
Add any other context about the problem here.

Propogate depth level from @GenAuto

Embedded depth level for other classes can be set now only by gen embedded annotations.

It will be useful to add embedded depth level to @GenAuto annotation and propagate such level to all embedded subfields

Global gen rules

Is your feature request related to a problem? Please describe.
Need to create global GenRules that will be applied to all classes and all global fields, such as all fields named "type" should use specific generator

Describe the solution you'd like
GenRule.global() method that will introduce that feature

Static field fill invocation

Describe the bug
factory tries to fill static fields and failes.

To Reproduce
Steps to reproduce the behavior:

  1. Make dummy with status field
  2. Throws exception that can't fill static field

Improve default generator pickup for @GenAuto

Default generators choose method should be improved to support field name scanning and choose automatically NameGenerator for fields that contains name and etc.
At least some basic field choose somehow

Also add some addition generators as Address, MiddleName, etc.

Fixed Resource scanner for JAR files

Describe the bug
Can not load files from JAR

To Reproduce
Steps to reproduce the behavior:

  1. Try load resources from JAR

Expected behavior
Loads resources from JAR
Error is in checking URL from system scanned, should check by converting toString() and not toPath() method

@GenEnum exclude specific enum values

Add enum generation exclude functionality
So you can exclude specific enum values from generating

And rename @GenEnumarate annotation in case of misunderstanding

Rewrite and simplify tests

Its better to rewrite tests, simplify them, separate logically even more, reduce complexity and improve code coverage up to 93%

Invalid graph for Complex fields

Describe the bug
Invalid graph initialization for GenGraphBuilder for complex fields such as list, set, map, arrays...

To Reproduce
Steps to reproduce the behavior:

  1. Make dummy with list and embedded values
  2. Try to populate it
  3. No inner fields were populated

Expected behavior
Fields should be populated

Extend patterns for generators

Is your feature request related to a problem? Please describe.
Extends patterns for generators with like block, house, structure, city, town, country, code, postal, index, type, prefix, postfix, etc

Describe the solution you'd like
Auto generators will be pickup for those patterns and not random ones

Auto generator pickup by patten

Describe the bug
For list\map other fields who pattern collide with string pattern, auto generator picks string generator and can not cast it to complex one while filling values.

For List name; NameGenerator will be picked up and not ListComplexGenerator

Expected behavior
ListComplext generator with NameGenerator inside

SQL Exporter insert statement ending wrong

Describe the bug
SQL exports queries where INSERT statement ends with comma (,) instead of ; symbol.

To Reproduce
Generate SQL with SQLExporter

Expected behavior
Correct ; symbol at the end of INSERT queries

@GenCustom

Create gen custom annotation that consumes any of IGenerator classes \ Complex generators and can be used by factory to pick up desired generator without making custom annotation for such generator

Generate date between 1970 and 2099

Describe the bug
ClickHouse or other databases struggle to work with dates more that 2099.

Expected behavior
Generate dates between 1970 & 2099 only, improve sinse and after date generate intervals

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.