Skip to content

Add annotation support for data classes based on JavaObjectTransformer #754

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 13, 2023

Conversation

RVRhub
Copy link
Contributor

@RVRhub RVRhub commented Apr 2, 2023

PR adds annotation support for data class based on issue: #675
After some discussion, the idea came up to:

  • implement only one annotation: @Fake("defaultSchema") to specify the default schema
  • add two methods to BaseFaker for populating objects that use the JavaObjectTransformer.
    An example of usage

Data class definition:

@FakeForSchema("net.datafaker.annotations.FakeAnnotationTest#defaultSchema")
public class Person {
    private String fullName;

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
}

If a schema is defined in the same class as the population call, the full path with the class name is not required. Example: @FakeForSchema("defaultSchema")

Schema definition:

 public static Schema<Object, ?> defaultSchema() {
        var faker = new Faker(Locale.forLanguageTag("fr-en"), new RandomService(new Random(1)));
        return Schema.of(field("fullName", () -> faker.name().fullName()));
    }

Object generation with default schema:

var person = Faker.populate(Person.class);

Object generation with custom schema:

var person = Faker.populate(Person.class, customSchema());

@codecov-commenter
Copy link

codecov-commenter commented Apr 2, 2023

Codecov Report

Merging #754 (fbc82ca) into main (55e3a7c) will decrease coverage by 0.02%.
The diff coverage is 82.85%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

@@             Coverage Diff              @@
##               main     #754      +/-   ##
============================================
- Coverage     92.86%   92.85%   -0.02%     
- Complexity     2595     2606      +11     
============================================
  Files           281      282       +1     
  Lines          5127     5161      +34     
  Branches        530      533       +3     
============================================
+ Hits           4761     4792      +31     
- Misses          240      243       +3     
  Partials        126      126              
Impacted Files Coverage Δ
...n/java/net/datafaker/annotations/FakeResolver.java 77.77% <77.77%> (ø)
...in/java/net/datafaker/providers/base/Aviation.java 100.00% <100.00%> (ø)
...n/java/net/datafaker/providers/base/BaseFaker.java 91.45% <100.00%> (+1.18%) ⬆️

... and 5 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@RVRhub RVRhub force-pushed the annotation_with_schema branch 3 times, most recently from 0972cd4 to 06738a7 Compare April 2, 2023 19:48
@RVRhub RVRhub force-pushed the annotation_with_schema branch 2 times, most recently from 68e66bb to 448bce3 Compare April 2, 2023 19:53
@RVRhub RVRhub force-pushed the annotation_with_schema branch from 1d5bafb to 9f8125f Compare April 3, 2023 08:26
@snuyanzin
Copy link
Collaborator

thanks for your contribution @RVRhub
lgtm from one side
however it would be great to have some documentation for that

//cc @bodiam since you mentioning something about that
with this PR it will be possible to make calls like

var person = Faker.populate(Person.class);
// or
var person2 = Faker.populate(Person.class, customSchema());

schema could be defined separately

@bodiam
Copy link
Contributor

bodiam commented Apr 3, 2023

@snuyanzin's sorry, I missed some of the conversions on this. Is the annotation support now dropped in favor of some schema method?

I'm not a huge fan of that schema support. I find it too hard to get the syntax correct, and I struggled to get the generics work. With the schema support it seems the connection between the fields and the generator is gone, as in I can't see which fields are using which generator, something which could be easily seen when you have annotated fields.

So, what was the reason to pick an option like this over the annotation approach?

@snuyanzin
Copy link
Collaborator

snuyanzin commented Apr 3, 2023

There are 2 reasons

After having several chats and POCs with @RVRhub we faced 2 issues:

  1. it looks like the code is becoming polluted with annotations especially for classes with multiple fields
  2. it's impossible to have several objects generated in different ways.

To address these issues we decided to have only one annotation @FakeForSchema which is a reference to a method providing a default schema to generate objects similar to junit's @MethodSource.

The idea is to build the solution based on java transformers approach #513 which already can generate objects.

So the objects could be generated in 2 ways:
1.

MyClass object = Faker.populate(MyClass.class);

this will generate an object with usage of default schema mentioned by @FakeForSchema
2.

MyClass object = Faker.populate(MyClass.class, myschema);

this will allow to generate objects based on others schemas.

In this way it's possible to have a number of different schemas and generate objects based on them.
At the same time schemas and objects generations are decoupled

@bodiam
Copy link
Contributor

bodiam commented Apr 3, 2023

Okay, makes sense. Thanks for the clarification!

Comment on lines 463 to 464
Then you can use `net.datafaker.providers.base.BaseFaker.populate(java.lang.Class<T>)` to populate object with default predefined schema.
Or you can use `net.datafaker.providers.base.BaseFaker.populate(java.lang.Class<T>, net.datafaker.schema.Schema<java.lang.Object, ?>)` to populate object with custom schema.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably need code snippets for both cases

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added one more snippet of object template population with custom schema

RVRhub and others added 2 commits April 13, 2023 11:17
Co-authored-by: Sergey Nuyanzin <sergey.nuyanzin@aiven.io>
@snuyanzin snuyanzin merged commit e64dfa8 into datafaker-net:main Apr 13, 2023
@snuyanzin snuyanzin mentioned this pull request Apr 13, 2023
@RVRhub RVRhub deleted the annotation_with_schema branch April 13, 2023 21:45
snuyanzin added a commit to snuyanzin/datafaker that referenced this pull request Apr 17, 2023
datafaker-net#754)

---------

Co-authored-by: Sergey Nuyanzin <sergey.nuyanzin@aiven.io>
snuyanzin added a commit that referenced this pull request Apr 17, 2023
#754) (#773)

---------

Co-authored-by: Roman <r.romanv1@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants