Use PHP ISO Codes in the "SubdivisionCode" rule

Since we now have PHP ISO Codes as a dependency[1], it doesn't make
sense to keep dealing with this data ourselves.

[1]: 04b2722d02

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
Henrique Moody 2024-02-13 23:41:51 +01:00
parent 4c99cbf433
commit 44e769a271
No known key found for this signature in database
GPG key ID: 221E9281655813A6
3 changed files with 31 additions and 74 deletions

View file

@ -6,13 +6,13 @@ Validates subdivision country codes according to [ISO 3166-2][].
The `$countryCode` must be a country in [ISO 3166-1 alpha-2][] format.
**This rule requires [sokil/php-isocodes][] and [php-isocodes-db-only][] to be installed.**
```php
v::subdivisionCode('BR')->validate('SP'); // true
v::subdivisionCode('US')->validate('CA'); // true
```
This rules uses data from [iso-codes][].
## Categorization
- ISO codes
@ -22,6 +22,7 @@ This rules uses data from [iso-codes][].
Version | Description
--------|-------------
3.0.0 | Require [sokil/php-isocodes][] and [sokil/php-isocodes-db-only][]
1.0.0 | Created
***
@ -36,6 +37,7 @@ See also:
- [PublicDomainSuffix](PublicDomainSuffix.md)
- [Tld](Tld.md)
[iso-codes]: https://salsa.debian.org/iso-codes-team/iso-codes
[ISO 3166-1 alpha-2]: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 "ISO 3166-1 alpha-2"
[ISO 3166-2]: http://en.wikipedia.org/wiki/ISO_3166-2 "ISO 3166-2"
[sokil/php-isocodes]: https://github.com/sokil/php-isocodes
[sokil/php-isocodes-db-only]: https://github.com/sokil/php-isocodes-db-only

View file

@ -11,20 +11,22 @@ namespace Respect\Validation\Rules;
use Respect\Validation\Exceptions\InvalidRuleConstructorException;
use Respect\Validation\Exceptions\MissingComposerDependencyException;
use Respect\Validation\Helpers\CanValidateUndefined;
use Respect\Validation\Message\Template;
use Respect\Validation\Result;
use Sokil\IsoCodes\Database\Countries;
use Sokil\IsoCodes\Database\Subdivisions;
use function array_map;
use function class_exists;
use function str_replace;
#[Template(
'{{name}} must be a subdivision code of {{countryName|trans}}',
'{{name}} must not be a subdivision code of {{countryName|trans}}',
)]
final class SubdivisionCode extends AbstractSearcher
final class SubdivisionCode extends Standard
{
use CanValidateUndefined;
private readonly Countries\Country $country;
private readonly Subdivisions $subdivisions;
@ -49,26 +51,14 @@ final class SubdivisionCode extends AbstractSearcher
$this->subdivisions = $subdivisions ?? new Subdivisions();
}
/**
* @return array<string, mixed>
*/
public function getParams(): array
public function evaluate(mixed $input): Result
{
return ['countryName' => $this->country->getName()];
}
$parameters = ['countryName' => $this->country->getName()];
$subdivision = $this->subdivisions->getByCode($this->country->getAlpha2() . '-' . $input);
if ($this->isUndefined($input) && $subdivision === null) {
return Result::passed($input, $this)->withParameters($parameters);
}
/**
* @return array<int, string>
*/
protected function getDataSource(mixed $input = null): array
{
return array_map(
fn (Subdivisions\Subdivision $subdivision): string => str_replace(
$this->country->getAlpha2() . '-',
'',
$subdivision->getCode(),
),
$this->subdivisions->getAllByCountryCode($this->country->getAlpha2()),
);
return (new Result($subdivision !== null, $input, $this))->withParameters($parameters);
}
}

View file

@ -10,16 +10,14 @@ declare(strict_types=1);
namespace Respect\Validation\Rules;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\Test;
use Respect\Validation\Exceptions\ComponentException;
use Respect\Validation\Exceptions\ValidationException;
use Respect\Validation\Test\TestCase;
use Respect\Validation\Test\RuleTestCase;
#[Group('rule')]
#[CoversClass(SubdivisionCode::class)]
final class SubdivisionCodeTest extends TestCase
final class SubdivisionCodeTest extends RuleTestCase
{
#[Test]
public function shouldThrowsExceptionWhenInvalidFormat(): void
@ -39,58 +37,25 @@ final class SubdivisionCodeTest extends TestCase
new SubdivisionCode('JK');
}
#[Test]
#[DataProvider('providerForValidSubdivisionCodeInformation')]
public function shouldValidateValidSubdivisionCodeInformation(string $countryCode, ?string $input): void
{
$countrySubdivision = new SubdivisionCode($countryCode);
self::assertTrue($countrySubdivision->validate($input));
}
#[Test]
#[DataProvider('providerForInvalidSubdivisionCodeInformation')]
public function shouldNotValidateInvalidSubdivisionCodeInformation(string $countryCode, mixed $input): void
{
$countrySubdivision = new SubdivisionCode($countryCode);
self::assertFalse($countrySubdivision->validate($input));
}
#[Test]
public function shouldThrowsValidationException(): void
{
$countrySubdivision = new SubdivisionCode('BR');
$this->expectException(ValidationException::class);
$this->expectExceptionMessage('"CA" must be a subdivision code of Brazil');
$countrySubdivision->assert('CA');
}
/**
* @return mixed[][]
*/
public static function providerForValidSubdivisionCodeInformation(): array
/** @return iterable<array{SubdivisionCode, mixed}> */
public static function providerForValidInput(): iterable
{
return [
['AQ', null],
['BR', 'SP'],
['MV', '00'],
['US', 'CA'],
['YT', ''],
[new SubdivisionCode('AQ'), null],
[new SubdivisionCode('BR'), 'SP'],
[new SubdivisionCode('MV'), '00'],
[new SubdivisionCode('US'), 'CA'],
[new SubdivisionCode('YT'), ''],
];
}
/**
* @return mixed[][]
*/
public static function providerForInvalidSubdivisionCodeInformation(): array
/** @return iterable<array{SubdivisionCode, mixed}> */
public static function providerForInvalidInput(): iterable
{
return [
['BR', 'CA'],
['MV', 0],
['US', 'CE'],
[new SubdivisionCode('BR'), 'CA'],
[new SubdivisionCode('MV'), 0],
[new SubdivisionCode('US'), 'CE'],
];
}
}