From 0f807156557a94b68f81aad8724ec00c70498a60 Mon Sep 17 00:00:00 2001 From: alireza easazade Date: Fri, 15 Sep 2023 20:52:52 +0330 Subject: [PATCH] Update contributing guide --- CONTRIBUTING.md | 59 +++++++++++-------- generate_and_test.sh | 2 +- lib/src/locales/en_us/en_us.dart | 2 +- lib/src/locales/fa_ir/fa_ir.dart | 2 +- lib/src/locales/global/datasources/lorem.dart | 4 +- scripts/generate.dart | 3 +- 6 files changed, 39 insertions(+), 33 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 62beac9..14c6da6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,12 +1,14 @@ # Contribution Guide Reading this document will help you understand: + - Basic structure of the faker_x package - How to add a single new value generator to existing resources. for example adding `cat_image` value generator to resource `image` whether you want to add it `globally` for all existing `locales` or just to a specific locale like `en_us`. -- How to localize global value generators. +- How to localize global value generators. - How to add support for a new locale that doesn't exist for example `en_uk`. ## (TLDR) But First Let's See a Quick Example: + Let's say we want to add a new fake value generator to our `FakerX` class called `pet_name` that generates random pet names . this is going to be done in 3 steps - Define a static String key in `DataKeys` class called `pet_name` @@ -24,11 +26,13 @@ const pet_name = StringDataSource( . . ] -); +); ``` + - run `./generate_and_test.sh` script. this script will create required code, tests & docs and will format, analyze code and run tests at the end. ##### DONE + Now there will be a new getter method that generates fake pet names in our `FakerX` class. ```dart @@ -36,10 +40,12 @@ final myPetName = FakerX.defaultInstance.animal.petName; ``` ### Understanding Package Structure -faker_x contains a `lib/src/locales` directory; this is where changes need to be added. -in `lib/src/locales` you will find different locales like `en_us`, `fa_ir` etc including a `global`. + +faker_x contains a `lib/src/locales` directory; this is where changes need to be added. +in `lib/src/locales` you will find different locales like `en_us`, `fa_ir` etc including a `global`. in each locale directory there is structure like below. a datasources directory that contains a dart file for each `resource` like `job.dart` in each of these resource files there are one or several `DataSource` variables. these datasources are fake value generators. they will generate fake values for that resource. + ``` ├── en_us ├── datasources @@ -82,7 +88,7 @@ final international_phone_number = StringDataSource( ``` -when we run code generation scripts result in our generated `FakerX` class will be seen like below example: +when we run code generation scripts result in our generated `FakerX` class will be seen like below example: ```dart final phoneNumber = FakerX.localized.en_us.phone.phoneNumber; @@ -91,7 +97,7 @@ final international = FakerX.localized.en_us.phone.internationalPhoneNumber; #### Explaining DataSources -a `DataSource` is basically a fake value provider. it either provides a fake value through a list of hardcoded values or a builder method (or a list of `Formats` in case of `StringDataSource`). +a `DataSource` is basically a fake value provider. it either provides a fake value through a list of hardcoded values or a builder method (or a list of `Formats` in case of `StringDataSource`). There are 2 kinds of `DataSources` that we have `StringDataSource`, `TypeDataSource` each `DataSource` must contain a dataKey defined in `DataKeys` class and a locale defined in `Locales` class. @@ -116,7 +122,7 @@ const color_name = StringDataSource( . . ] -); +); ``` - Using StringDataSource to generate fake string values using builder method @@ -156,20 +162,23 @@ final image = StringDataSource.withBuilder( ); ``` -first an `ImageArgs` class is defined then we define our datasource class as `StringDataSource` and then in our builder method parameter we define arguments as `(ImageArgs args, FakerXLocale locale) {...}`. +first an `ImageArgs` class is defined then we define our datasource class as `StringDataSource` and then in our builder method parameter we define arguments as `(ImageArgs args, FakerXLocale locale) {...}`. + +**NOTE:** when defining an `Args` class like `ImageArgs` above -**NOTE:** when defining an `Args` class like `ImageArgs` above +- Make sure to add the arg type as the DataSource arg type + eg: define data source like this `StringDataSource` instead of just `StringDataSource`. if you forget to do this, you will have runtime errors, possibly shown when generated tests for this added data source will run. - make sure to define constructor arguments as named arguments. -- If the argument is required make sure to add `@nonNullable` annotation on that argument. (this is because dart:mirror api does not support null safty) +- If the argument is required make sure to add `@nonNullable` annotation on that argument. (this is because dart:mirror api does not support null safety) - Using StringDataSource to generate fake values using formats. -alternatively you can use `formats` to generate fake values + alternatively you can use `formats` to generate fake values ```dart -// In formats all # characters are converted into random int and all ? characters are converted into random letters and returned for +// In formats all # characters are converted into random int and all ? characters are converted into random letters and returned for // example below format can be used to generate fake values like : 1AL3456 const license_plate = StringDataSource( @@ -188,7 +197,7 @@ const license_plate = StringDataSource( . . ], -); +); ``` @@ -242,7 +251,7 @@ class GeoLocation { - In defining our datasource above `TypeDataSource` we have set the value type to `GeoLocation` and builder method's argument type to `dynamic` since we don't require an argument from the user in our builder method. - type `GeoLocation` must be defined in `lib/src/base/value_types.dart` -Alternatively we can use a list of values +Alternatively we can use a list of values ```dart final product = TypeDataSource( @@ -261,17 +270,14 @@ final product = TypeDataSource( ); ``` +### Add a new DataSource - -### Add a new DataSource -Let's say we want to add a new `DataSource` to generate cat images. we need to add it to the relevent resource. in this case we are going to add a new `cat_image` datasource to the `image` resource, so in our generated `FakerX` class we can have a getter method that generates cat images like below +Let's say we want to add a new `DataSource` to generate cat images. we need to add it to the relevant resource. in this case we are going to add a new `cat_image` datasource to the `image` resource, so in our generated `FakerX` class we can have a getter method that generates cat images like below ```dart final newCatImage = FakerX.defaultInstance.image.catImage; ``` - - Now that we want to add the Datasource we should decide whether we want to add it as a global datasource or only for a specific locale. if we add it as a global DataSource it will be available for all generated locales. all global DataSources are marked green in Resources and Localizations in docs. For example DataSource `ipv4` for resource `internet` is defined globally. That means resource `internet` has a getter method `ipv4`, for all locales. @@ -284,7 +290,7 @@ final i3 = FakerX.localized.es.internet.ipv4; but if we define it only for a specific locale the generator getter method will only appear for that locale. For example, getter method `neighborhood` for resource `address` is only available for `en_us` locale. -Let's add `cat_image` datasource globally +Let's add `cat_image` datasource globally first we define a new datakey called `cat_image` in `DataKeys` class in `lib/src/base/keys.dart` @@ -297,7 +303,8 @@ class DataKeys{ } ``` -Then we add the `cat_image` datasource the resource file in global directory in `lib/src/locales/global/datasources/image.dart` +Then we add the `cat_image` datasource the resource file in global directory in `lib/src/locales/global/datasources/image.dart` + ```dart final cat_image = StringDataSource.withBuilder( dataKey: DataKeys.cat_image, @@ -313,9 +320,9 @@ Now all we need to do is run the command bash script `generate_and_test.sh`. Thi `$ bash generate_and_test.sh` **NOTE:** read the console logs it might tell you to run it again. - ### Add a new locale -Let's say we want to add a new locale that does not exist in our library and so that we can generate fake values localized for that locale. let's try adding `en_uk` locale + +Let's say we want to add a new locale that does not exist in our library and so that we can generate fake values localized for that locale. let's try adding `en_uk` locale - First we need to run a script to create empty resource files and generate basic classes required. run below script @@ -346,8 +353,8 @@ Let's say we want to add a new locale that does not exist in our library and so **NOTE:** read the console logs it might tell you to run it again. ### Side Notes : -**NOTE:** With DataSources that use builder methods to generate the value we can use builder methods of other DataSources in them. for example: +**NOTE:** With DataSources that use builder methods to generate the value we can use builder methods of other DataSources in them. for example: ```dart final uri = StringDataSource.withBuilder( @@ -362,7 +369,7 @@ final https_url = StringDataSource.withBuilder( dataKey: DataKeys.https_url, locale: Locales.en_us, builder: (_, __) { - // here we are calling build method on uri DataSource defined above + // here we are calling build method on uri DataSource defined above // to return an https url // ! NOTE: call build method not builder callback return uri.build(UriArgs(protocol: 'https')), @@ -372,4 +379,4 @@ final https_url = StringDataSource.withBuilder( **NOTE:** There are a lot of warning and error messages to notify you if you have done something wrong and how you should fix them. so if you ever ran the generation command and saw an error or warning in the terminal just fix the code and rerun the command. -**NOTE:** even though a lot of checks have been set in scripts to predict and prevent if code is going to be generated incorrectly or with syntax error messages. this might happen. if you ran a generation command and there was syntax error in generated code in `lib/` directory just silence the syntax error by commenting them out or removing them so you can run generate command again without dart telling you there are syntax errors need to be fixed. doesn't matter if you change generated files manually to silence syntax errors, because they will be regenerated. then change your code if necessary and rerun the generation command. \ No newline at end of file +**NOTE:** even though a lot of checks have been set in scripts to predict and prevent if code is going to be generated incorrectly or with syntax error messages. this might happen. if you ran a generation command and there was syntax error in generated code in `lib/` directory just silence the syntax error by commenting them out or removing them so you can run generate command again without dart telling you there are syntax errors need to be fixed. doesn't matter if you change generated files manually to silence syntax errors, because they will be regenerated. then change your code if necessary and rerun the generation command. diff --git a/generate_and_test.sh b/generate_and_test.sh index c8e4016..aedbf02 100644 --- a/generate_and_test.sh +++ b/generate_and_test.sh @@ -1,7 +1,7 @@ #!/bin/bash dart scripts/regenerate_base_classes.dart -dart scripts/register_data_sources.dart.dart +dart scripts/register_data_sources.dart dart scripts/generate_all.dart && dart scripts/create_tests.dart && dart scripts/generate_example.dart && diff --git a/lib/src/locales/en_us/en_us.dart b/lib/src/locales/en_us/en_us.dart index e735857..fd3ce78 100644 --- a/lib/src/locales/en_us/en_us.dart +++ b/lib/src/locales/en_us/en_us.dart @@ -98,7 +98,7 @@ class EnUsLorem extends Lorem { EnUsLorem(this.locale) : super(locale); String paragraph({ - required int maxSentences, + int maxSentences = 1, }) => provide( DataKeys.paragraph, diff --git a/lib/src/locales/fa_ir/fa_ir.dart b/lib/src/locales/fa_ir/fa_ir.dart index 9808586..003144c 100644 --- a/lib/src/locales/fa_ir/fa_ir.dart +++ b/lib/src/locales/fa_ir/fa_ir.dart @@ -88,7 +88,7 @@ class FaIrLorem extends Lorem { FaIrLorem(this.locale) : super(locale); String paragraph({ - required int maxSentences, + int maxSentences = 1, }) => provide( DataKeys.paragraph, diff --git a/lib/src/locales/global/datasources/lorem.dart b/lib/src/locales/global/datasources/lorem.dart index db17052..349d0d6 100644 --- a/lib/src/locales/global/datasources/lorem.dart +++ b/lib/src/locales/global/datasources/lorem.dart @@ -3,9 +3,7 @@ import 'package:faker_x/src/base/base.dart'; class ParagraphArgs { final int maxSentences; - ParagraphArgs({ - @nonNullable required this.maxSentences, - }); + ParagraphArgs({this.maxSentences = 1}); } final paragraph = StringDataSource.withBuilder( diff --git a/scripts/generate.dart b/scripts/generate.dart index 4c1214b..c2e99d4 100644 --- a/scripts/generate.dart +++ b/scripts/generate.dart @@ -164,7 +164,8 @@ String _createCustomResourceClass({ final argsBuffer = StringBuffer('{'); for (var arg in dsInfo.builderArgTypeFields) { - if (arg.isRequired) argsBuffer.write(' required '); + if (arg.isRequired && arg.defaultValue == null) + argsBuffer.write(' required '); argsBuffer.write(' ${arg.type}'); argsBuffer.write( (arg.isRequired || arg.defaultValue != null) ? ' ' : '? ',