Skip to content

Commit

Permalink
Document how to add new data providers in contributing guidelines
Browse files Browse the repository at this point in the history
  • Loading branch information
serpro69 committed May 20, 2022
1 parent bd9fc64 commit 424b362
Showing 1 changed file with 101 additions and 7 deletions.
108 changes: 101 additions & 7 deletions CONTRIBUTING.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ Please note that we can only merge a PR if:
* The code is following the official kotlin codestyle as defined by Jetbrains.
* All tests pass, and the code has 100% test coverage (run `./gradlew clean test` to run the checks).
If it does not make sense to cover a certain line of code, please mention that in the PR.
* Bigger changes and new features are also covered by integration test(s).
* Bigger changes and new features are also covered by integration test(s) which can be run with gradle `integrationTest` task.
* All relevant documentation is updated.
Usually this means updating the KDoc of the code you work on, link:README.md[README] and documentation in link:doc[doc] dir.
* Additional dependencies are only added with a good reason.
* Code was reviewed by one of our regular contributors, taking into consideration code readability, security and whether the addition aligns with the long-term roadmap.
Usually this means updating the KDoc of the code you work on, link:README.md[README] and documentation in link:docs[docs] dir.
* Additional third-party dependencies are only added with a good reason.
* Code was reviewed by one of the regular contributors, taking into consideration code readability, security and whether the addition aligns with the long-term roadmap.

=== Set up instructions

Expand All @@ -53,12 +53,106 @@ Now you can create a new branch describing the change you are about to make, e.g

=== Your First Contribution

If you are interested in contributing, but don't have a specific issue at heart, we would recommend looking through the issues labelled "help wanted".
If you are interested in contributing, but don't have a specific issue at heart, we would recommend looking through the issues labelled /~https://github.com/serpro69/kotlin-faker/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22help+wanted+%3Asos%3A%22[help wanted].

If you are new to contributing to open source, we recommend having a look at a http://makeapullrequest.com/[free tutorial] for this.
Issues labelled "good first issue" are meant specifically to get started in the repository.
Issues labelled /~https://github.com/serpro69/kotlin-faker/issues?q=is%3Aopen+label%3A%22good+first+issue+%3Ahammer%3A%22+sort%3Aupdated-desc[good first issue] are meant specifically to get started in the repository.

If you are stuck at any point, feel free to comment in the issue you chose.
We try to be as helpful to newcomers as possible, and you don't have to be afraid of "dumb" questions.

_If this is your first pull request - please add yourself to the contributors section in /~https://github.com/serpro69/kotlin-faker/blob/master/docs/src/orchid/resources/data.yml[this yaml file] so that you get proper credit in the project's https://kotlin-faker.io/about[About page]._
_If this is your first pull request - please add yourself to the "contributors section" in /~https://github.com/serpro69/kotlin-faker/blob/master/docs/src/orchid/resources/data.yml[data.yml] file so that you get proper credit in the project's https://serpro69.github.io/kotlin-faker/about/[About page]._

== Code Structure

This repository consists of the following modules:

* `link:cli-bot[cli-bot]` - a CLI application that helps to quickly find required kotlin-faker functions right from the terminal
* `link:core[core]` - contains the core functionality of kotlin-faker
* `link:docs[docs]` - documentation for this project, published @ https://serpro69.github.io/kotlin-faker/

== Adding new functionality

This section describes how to add new functionality to kotlin-faker.

=== Basics

Most of the data generated by kotlin-faker comes from `.yml` "dictionary" files located in link:core/src/main/resources/locales[locales] directory.

A **data provider class** - e.g. `Address` - represents a certain "category" of fake data - in this case data related to address information.

Kotlin-faker also generates data in various **locales**, `en` being the default one.
The link:core/src/main/resources/locales/en[locales/en] directory contains `.yml` files for all existing data providers, usually one file per provider, while localized dictionaries usually contain all the data in a single file, e.g. link:core/src/main/resources/locales/uk.yml[locales/uk.yml].

=== Adding a new Data Provider

Adding a new data provider is usually a straightforward process, as most of the "heavy lifting" does not change from one provider to another.
It does involve changes in several places though, which are explained in this section.

==== Add a new `.yml` file to link:core/src/main/resources/locales/en[locales/en]

Let's take the link:core/src/main/resources/locales/en/name.yml[`name.yml`] file for the `Name` provider, as an example:

[source,yml]
----
# core/src/main/resources/locales/en/name.yml
en:
faker:
name:
male_first_name: [Aaron, Abdul, Abe]
female_first_name: [Abbey, Abbie, Abby]
----

.Where:
* `en` is the locale name (in the case of a new data provider it's always going to be `en` as it's the default one)
* `name` is the data category name
* `male_first_name` and `female_first_name` are functions inside the `Name` class which generates random data.

For more details and examples take a look at some of existing `.yml` files.

==== Update the list of default filenames

- the list of `defaultFileNames` needs to be updated in the link:core/src/main/kotlin/io/github/serpro69/kfaker/Constants.kt[Constants] file

==== Create the new data provider class under link:core/src/main/kotlin/io/github/serpro69/kfaker/provider[provider] directory.

The class needs to implement `AbstractFakeDataProvider`, and override a few properties. Expanding on the same data provider example, let's look at the `Name` class implementation:

[source,kotlin]
----
class Name internal constructor(fakerService: FakerService) : AbstractFakeDataProvider<Name>(fakerService) {
override val category = YamlCategory.NAME
override val localUniqueDataProvider = LocalUniqueDataProvider<Name>()
override val unique by UniqueProviderDelegate(localUniqueDataProvider)
fun maleFirstName() = resolve("male_first_name")
fun femaleFirstName() = resolve("female_first_name")
}
----

* the `category` property that uses the `YamlCategory.NAME` enum class, which has to be the same as declared in the `.yml` file. If the enum category does not already exist (Some dictionary files use the same category, which is perfectly fine to do if it makes sense) - new one should be added as well.
* the `AbstractFakeDataProvider` provides a `resolve` function that should be used to get the random value for a given category key, i.e. `female_first_name`.

==== Add the property to `Faker` class

* the entry point for all data generation is the link:core/src/main/kotlin/io/github/serpro69/kfaker/Faker.kt[`Faker`] class, so a new property needs to be added there that calls the data provider class

==== Update native-image link:cli-bot/src/main/resources/META-INF/native-image/io.github.serpro69/cli-bot/reflect-config.json[`reflect-config.json`]

- this is used when building the native-image of the `faker-bot` CLI application and thus needs to be updated, otherwise the `nativeImage` gradle task will fail

==== Next step is to update the documentation

* create a new `.adoc` file under link:docs/src/orchid/resources/pages/data-provider[data-provider] directory
** copy an existing file from that directory and replace the H2 header to reflect the correct faker provider property name, update the code snippet name (should be in the form of `<yml_filename>_provider_dict`) in the `[source,yaml]` section, and update the "available functions" code section as well

==== Add tests

* new tests (usually) don't need to be added since integration tests are dynamically calling all public data provider functions via reflection
* a few changes need to be made to existing tests though if the new category name was added:
** the link:cli-bot/src/test/kotlin/io/github/serpro69/kfaker/app/cli/IntrospectorTest.kt[`IntrospectorTest`] needs to be updated in the `cli-bot` module
** the link:core/src/test/kotlin/io/github/serpro69/kfaker/TestConstants.kt[`TestConstants`] need to be updated as well

==== Example commit

In addition to the above instructions, you can also take a look at /~https://github.com/serpro69/kotlin-faker/commit/0b34d19d77aa728ed87382444908c90a63cc5f52[`0b34d1`] commit, which can be used as an MVP example of all of the above steps.

0 comments on commit 424b362

Please sign in to comment.