From 66dfe69791345547b624f5eaedced802db49fc53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Pimpa=CC=83o?= Date: Mon, 29 Apr 2024 18:50:59 +0100 Subject: [PATCH 1/5] chore: changed default country error message --- src/Rule/Country.php | 6 +++--- tests/CountryTest.php | 14 +++++++------- tests/TimezoneTest.php | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Rule/Country.php b/src/Rule/Country.php index 410e570..657cc9f 100644 --- a/src/Rule/Country.php +++ b/src/Rule/Country.php @@ -17,7 +17,7 @@ class Country extends AbstractRule implements RuleInterface self::ALPHA_3_CODE ]; - private string $message = 'The {{ name }} value is not a valid {{ code }} country code, {{ value }} given.'; + private string $message = 'The {{ name }} value is not a valid country, {{ value }} given.'; public function __construct( private readonly string $code = self::ALPHA_2_CODE, @@ -37,8 +37,8 @@ public function assert(mixed $value, ?string $name = null): void throw new UnexpectedTypeException('string', get_debug_type($value)); } - // Keep original value for parameters - $input = strtoupper($value); + // keep original value for parameters + $input = \strtoupper($value); if ( ($this->code === self::ALPHA_2_CODE && !Countries::exists($input)) diff --git a/tests/CountryTest.php b/tests/CountryTest.php index e0519c7..07ad197 100644 --- a/tests/CountryTest.php +++ b/tests/CountryTest.php @@ -21,26 +21,26 @@ public static function provideRuleUnexpectedValueData(): \Generator $unexpectedCodeMessage = '/Invalid code "(.*)"\. Accepted values are\: "(.*)"\./'; $unexpectedTypeMessage = '/Expected value of type "string", (.*) given\./'; - yield 'invalid code' => [new Country('invalid'), 'PT', $unexpectedCodeMessage]; + yield 'invalid code' => [new Country('invalid'), 'pt', $unexpectedCodeMessage]; yield 'invalid type' => [new Country(), 123, $unexpectedTypeMessage]; } public static function provideRuleFailureConditionData(): \Generator { $exception = CountryException::class; - $message = '/The (.*) value is not a valid (.*) country code, (.*) given\./'; + $message = '/The (.*) value is not a valid country, (.*) given\./'; yield 'default' => [new Country(), 'PRT', $exception, $message]; - yield 'alpha2' => [new Country(code: 'alpha-2'), 'PRT', $exception, $message]; - yield 'alpha3' => [new Country(code: 'alpha-3'), 'PT', $exception, $message]; + yield 'alpha2' => [new Country(code: 'alpha-2'), 'prt', $exception, $message]; + yield 'alpha3' => [new Country(code: 'alpha-3'), 'pt', $exception, $message]; } public static function provideRuleSuccessConditionData(): \Generator { - yield 'default' => [new Country(), 'PT']; - yield 'alpha2' => [new Country(code: 'alpha-2'), 'PT']; + yield 'default' => [new Country(), 'pt']; + yield 'alpha2' => [new Country(code: 'alpha-2'), 'pt']; yield 'alpha2 lowercase' => [new Country(code: 'alpha-2'), 'pt']; - yield 'alpha3' => [new Country(code: 'alpha-3'), 'PRT']; + yield 'alpha3' => [new Country(code: 'alpha-3'), 'prt']; yield 'alpha3 lowercase' => [new Country(code: 'alpha-3'), 'prt']; } diff --git a/tests/TimezoneTest.php b/tests/TimezoneTest.php index da0d7d3..1ab718b 100644 --- a/tests/TimezoneTest.php +++ b/tests/TimezoneTest.php @@ -19,7 +19,7 @@ class TimezoneTest extends AbstractTest public static function provideRuleUnexpectedValueData(): \Generator { $unexpectedMissingCountryCodeMessage = '/A country code is required when timezone group is "\\\DateTimeZone::PER_COUNTRY"\./'; - $unexpectedCountryCodeMessage = '/The (.*) value is not a valid (.*) country code, (.*) given\./'; + $unexpectedCountryCodeMessage = '/The (.*) value is not a valid country, (.*) given\./'; yield 'missing country code' => [ new Timezone(\DateTimeZone::PER_COUNTRY), @@ -27,7 +27,7 @@ public static function provideRuleUnexpectedValueData(): \Generator $unexpectedMissingCountryCodeMessage ]; yield 'invalid country code' => [ - new Timezone(\DateTimeZone::PER_COUNTRY, 'PRT'), + new Timezone(\DateTimeZone::PER_COUNTRY, 'prt'), 'Europe/Lisbon', $unexpectedCountryCodeMessage ]; From c7d716b928edf613ae3cfd3305f5f5181a533259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Pimpa=CC=83o?= Date: Mon, 29 Apr 2024 18:56:19 +0100 Subject: [PATCH 2/5] tests: improved country tests --- tests/CountryTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/CountryTest.php b/tests/CountryTest.php index 07ad197..6dad72b 100644 --- a/tests/CountryTest.php +++ b/tests/CountryTest.php @@ -30,7 +30,7 @@ public static function provideRuleFailureConditionData(): \Generator $exception = CountryException::class; $message = '/The (.*) value is not a valid country, (.*) given\./'; - yield 'default' => [new Country(), 'PRT', $exception, $message]; + yield 'default' => [new Country(), 'prt', $exception, $message]; yield 'alpha2' => [new Country(code: 'alpha-2'), 'prt', $exception, $message]; yield 'alpha3' => [new Country(code: 'alpha-3'), 'pt', $exception, $message]; } @@ -39,9 +39,7 @@ public static function provideRuleSuccessConditionData(): \Generator { yield 'default' => [new Country(), 'pt']; yield 'alpha2' => [new Country(code: 'alpha-2'), 'pt']; - yield 'alpha2 lowercase' => [new Country(code: 'alpha-2'), 'pt']; yield 'alpha3' => [new Country(code: 'alpha-3'), 'prt']; - yield 'alpha3 lowercase' => [new Country(code: 'alpha-3'), 'prt']; } public static function provideRuleMessageOptionData(): \Generator From 084427f2f1f2b1c3860e5d4797f450e523dab137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Pimpa=CC=83o?= Date: Mon, 29 Apr 2024 18:56:55 +0100 Subject: [PATCH 3/5] feat: added language rule --- src/ChainedValidatorInterface.php | 5 +++ src/Exception/LanguageException.php | 5 +++ src/Rule/Language.php | 57 +++++++++++++++++++++++++++++ src/StaticValidatorInterface.php | 5 +++ tests/LanguageTest.php | 55 ++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+) create mode 100644 src/Exception/LanguageException.php create mode 100644 src/Rule/Language.php create mode 100644 tests/LanguageTest.php diff --git a/src/ChainedValidatorInterface.php b/src/ChainedValidatorInterface.php index 9a0f928..10995de 100644 --- a/src/ChainedValidatorInterface.php +++ b/src/ChainedValidatorInterface.php @@ -70,6 +70,11 @@ public function greaterThanOrEqual( ?string $message = null ): ChainedValidatorInterface&Validator; + public function language( + string $code = 'alpha-2', + ?string $message = null + ): ChainedValidatorInterface&Validator; + public function length( ?int $min = null, ?int $max = null, diff --git a/src/Exception/LanguageException.php b/src/Exception/LanguageException.php new file mode 100644 index 0000000..f1bf19e --- /dev/null +++ b/src/Exception/LanguageException.php @@ -0,0 +1,5 @@ +message = $message ?? $this->message; + } + + public function assert(mixed $value, ?string $name = null): void + { + if (!\in_array($this->code, self::CODE_OPTIONS)) { + throw new UnexpectedOptionException('code', self::CODE_OPTIONS, $this->code); + } + + if (!\is_string($value)) { + throw new UnexpectedTypeException('string', get_debug_type($value)); + } + + // keep original value for parameters + $input = \strtolower($value); + + if ( + ($this->code === self::ALPHA_2_CODE && !Languages::exists($input)) + || ($this->code === self::ALPHA_3_CODE && !Languages::alpha3CodeExists($input)) + ) { + throw new LanguageException( + message: $this->message, + parameters: [ + 'name' => $name, + 'value' => $value, + 'code' => $this->code + ] + ); + } + } +} \ No newline at end of file diff --git a/src/StaticValidatorInterface.php b/src/StaticValidatorInterface.php index a43dfff..154db90 100644 --- a/src/StaticValidatorInterface.php +++ b/src/StaticValidatorInterface.php @@ -69,6 +69,11 @@ public static function greaterThanOrEqual( ?string $message = null ): ChainedValidatorInterface&Validator; + public static function language( + string $code = 'alpha-2', + ?string $message = null + ): ChainedValidatorInterface&Validator; + public static function length( ?int $min = null, ?int $max = null, diff --git a/tests/LanguageTest.php b/tests/LanguageTest.php new file mode 100644 index 0000000..a05da7d --- /dev/null +++ b/tests/LanguageTest.php @@ -0,0 +1,55 @@ + [new Language('invalid'), 'pt', $unexpectedCodeMessage]; + yield 'invalid type' => [new Language(), 123, $unexpectedTypeMessage]; + } + + public static function provideRuleFailureConditionData(): \Generator + { + $exception = LanguageException::class; + $message = '/The (.*) value is not a valid language, (.*) given\./'; + + yield 'default' => [new Language(), 'prt', $exception, $message]; + yield 'alpha2' => [new Language(code: 'alpha-2'), 'por', $exception, $message]; + yield 'alpha3' => [new Language(code: 'alpha-3'), 'pt', $exception, $message]; + } + + public static function provideRuleSuccessConditionData(): \Generator + { + yield 'default' => [new Language(), 'pt']; + yield 'alpha2' => [new Language(code: 'alpha-2'), 'pt']; + yield 'alpha3' => [new Language(code: 'alpha-3'), 'por']; + } + + public static function provideRuleMessageOptionData(): \Generator + { + yield 'message' => [ + new Language( + message: 'The {{ name }} value {{ value }} is not a valid {{ code }} language code.' + ), + 'invalid', + 'The test value "invalid" is not a valid "alpha-2" language code.' + ]; + } +} \ No newline at end of file From 3833400c61177fe354f620cb8ce0d055025941a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Pimpa=CC=83o?= Date: Mon, 29 Apr 2024 19:01:24 +0100 Subject: [PATCH 4/5] docs: updated default country error message --- docs/03-rules_country.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/03-rules_country.md b/docs/03-rules_country.md index adc984c..3b83684 100644 --- a/docs/03-rules_country.md +++ b/docs/03-rules_country.md @@ -41,7 +41,7 @@ Available options: ### `message` -type: `?string` default: `The {{ name }} value is not a valid {{ code }} country code, {{ value }} given.` +type: `?string` default: `The {{ name }} value is not a valid country, {{ value }} given.` Message that will be shown if the input value is not a valid country code. From 0b63426f7b44a7848c274a10577917101d23c285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Pimpa=CC=83o?= Date: Mon, 29 Apr 2024 19:02:05 +0100 Subject: [PATCH 5/5] docs: added language rule --- docs/03-rules.md | 1 + docs/03-rules_language.md | 58 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 docs/03-rules_language.md diff --git a/docs/03-rules.md b/docs/03-rules.md index 4481196..944b879 100644 --- a/docs/03-rules.md +++ b/docs/03-rules.md @@ -39,6 +39,7 @@ - [Choice](03-rules_choice.md) - [Country](03-rules_country.md) +- [Language](03-rules_language.md) ## Iterable Rules diff --git a/docs/03-rules_language.md b/docs/03-rules_language.md new file mode 100644 index 0000000..f50427d --- /dev/null +++ b/docs/03-rules_language.md @@ -0,0 +1,58 @@ +# Language + +Validates that a value is a valid language code. + +```php +Language( + string $code = 'alpha-2', + ?string $message = null +); +``` + +## Basic Usage + +```php +// default alpha-2 code +Validator::language()->validate('pt'); // true + +// alpha-3 code +Validator::language(code: 'alpha-3')->validate('por'); // true +``` + +> [!NOTE] +> An `UnexpectedValueException` will be thrown when the `code` value is not a valid option. + +> [!NOTE] +> An `UnexpectedValueException` will be thrown when the input value is not a `string`. + +## Options + +### `code` + +type: `string` default: `alpha-2` + +Set code type to validate the language. +Check the [official language codes](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) list for more information. + +Available options: + +- `alpha-2`: two-letter code +- `alpha-3`: three-letter code + +### `message` + +type: `?string` default: `The {{ name }} value is not a valid language, {{ value }} given.` + +Message that will be shown if the input value is not a valid language code. + +The following parameters are available: + +| Parameter | Description | +|---------------|---------------------------| +| `{{ value }}` | The current invalid value | +| `{{ name }}` | Name of the invalid value | +| `{{ code }}` | Selected code type | + +## Changelog + +- `1.1.0` Created \ No newline at end of file