diff --git a/library/Exceptions/BaseException.php b/library/Exceptions/BaseException.php index e026d141..1a888b7b 100644 --- a/library/Exceptions/BaseException.php +++ b/library/Exceptions/BaseException.php @@ -13,6 +13,22 @@ declare(strict_types=1); namespace Respect\Validation\Exceptions; -class BaseException extends ValidationException +/** + * @author Carlos André Ferrari + * @author Henrique Moody + * @author William Espindola + */ +final class BaseException extends ValidationException { + /** + * {@inheritdoc} + */ + public static $defaultTemplates = [ + self::MODE_DEFAULT => [ + self::STANDARD => '{{name}} must be a number in the base {{base}}', + ], + self::MODE_NEGATIVE => [ + self::STANDARD => '{{name}} must not be a number in the base {{base}}', + ], + ]; } diff --git a/library/Rules/Base.php b/library/Rules/Base.php index b671af08..85a90b40 100644 --- a/library/Rules/Base.php +++ b/library/Rules/Base.php @@ -14,25 +14,52 @@ declare(strict_types=1); namespace Respect\Validation\Rules; use Respect\Validation\Exceptions\ComponentException; +use function is_null; +use function mb_strlen; +use function preg_match; +use function sprintf; -class Base extends AbstractRule +/** + * Validate numbers in any base, even with non regular bases. + * + * @author Carlos André Ferrari + * @author Henrique Moody + * @author William Espindola + */ +final class Base extends AbstractRule { - public $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - public $base; + /** + * @var string + */ + private $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - public function __construct($base = null, $chars = null) + /** + * @var int + */ + private $base; + + /** + * Initializes the Base rule. + * + * @param int $base + * @param string $chars + */ + public function __construct(int $base, $chars = null) { if (!is_null($chars)) { $this->chars = $chars; } $max = mb_strlen($this->chars); - if (!is_numeric($base) || $base > $max) { + if ($base > $max) { throw new ComponentException(sprintf('a base between 1 and %s is required', $max)); } $this->base = $base; } + /** + * {@inheritdoc} + */ public function validate($input): bool { $valid = mb_substr($this->chars, 0, $this->base); diff --git a/tests/integration/rules/base.phpt b/tests/integration/rules/base.phpt new file mode 100644 index 00000000..6d916a0c --- /dev/null +++ b/tests/integration/rules/base.phpt @@ -0,0 +1,38 @@ +--FILE-- +check('Z01xSsg5675hic20dj'); +} catch (BaseException $exception) { + echo $exception->getMessage().PHP_EOL; +} + +try { + v::base(2)->assert(''); +} catch (NestedValidationException $exception) { + echo $exception->getFullMessage().PHP_EOL; +} + +try { + v::not(v::base(2))->check('011010001'); +} catch (BaseException $exception) { + echo $exception->getMessage().PHP_EOL; +} + +try { + v::not(v::base(2))->assert('011010001'); +} catch (NestedValidationException $exception) { + echo $exception->getFullMessage().PHP_EOL; +} +?> +--EXPECTF-- +"Z01xSsg5675hic20dj" must be a number in the base 61 +- "" must be a number in the base 2 +"011010001" must not be a number in the base 2 +- "011010001" must not be a number in the base 2 diff --git a/tests/unit/Rules/BaseTest.php b/tests/unit/Rules/BaseTest.php index cf74a097..e8018a1a 100644 --- a/tests/unit/Rules/BaseTest.php +++ b/tests/unit/Rules/BaseTest.php @@ -13,105 +13,58 @@ declare(strict_types=1); namespace Respect\Validation\Rules; -use PHPUnit\Framework\TestCase; +use Respect\Validation\Test\RuleTestCase; /** - * @group rule + * @group rule + * * @covers \Respect\Validation\Rules\Base - * @covers \Respect\Validation\Exceptions\BaseException + * + * @author Carlos André Ferrari + * @author Gabriel Caruso + * @author Henrique Moody + * @author William Espindola */ -class BaseTest extends TestCase +final class BaseTest extends RuleTestCase { - protected $object; - /** - * @dataProvider providerForBase + * {@inheritdoc} */ - public function testBase($base, $input): void - { - $object = new Base($base); - self::assertTrue($object->__invoke($input)); - $object->check($input); - $object->assert($input); - } - - /** - * @dataProvider providerForInvalidBase - */ - public function testInvalidBase($base, $input): void - { - $object = new Base($base); - self::assertFalse($object->__invoke($input)); - } - - /** - * @dataProvider providerForExceptionBase - * @expectedException \Respect\Validation\Exceptions\ComponentException - */ - public function testExceptionBase($base, $input): void - { - $object = new Base($base); - self::assertTrue($object->__invoke($input)); - $object->assert($input); - } - - /** - * @dataProvider providerForCustomBase - */ - public function testCustomBase($base, $custom, $input): void - { - $object = new Base($base, $custom); - self::assertTrue($object->__invoke($input)); - $object->check($input); - $object->assert($input); - } - - public function providerForBase() + public function providerForValidInput(): array { return [ - [2, '011010001'], - [3, '0120122001'], - [8, '01234567520'], - [16, '012a34f5675c20d'], - [20, '012ah34f5675hic20dj'], - [50, '012ah34f56A75FGhic20dj'], - [62, 'Z01xSsg5675hic20dj'], + [new Base(2), '011010001'], + [new Base(3), '0120122001'], + [new Base(8), '01234567520'], + [new Base(16), '012a34f5675c20d'], + [new Base(20), '012ah34f5675hic20dj'], + [new Base(50), '012ah34f56A75FGhic20dj'], + [new Base(62), 'Z01xSsg5675hic20dj'], + [new Base(2, 'xy'), 'xyyxyxxy'], + [new Base(3, 'pfg'), 'gfpffp'], ]; } - public function providerForInvalidBase() + /** + * {@inheritdoc} + */ + public function providerForInvalidInput(): array { return [ - [2, ''], - [3, ''], - [8, ''], - [16, ''], - [20, ''], - [50, ''], - [62, ''], - [2, '01210103001'], - [3, '0120125f2001'], - [8, '01234dfZ567520'], - [16, '012aXS34f5675c20d'], - [20, '012ahZX34f5675hic20dj'], - [50, '012ahGZ34f56A75FGhic20dj'], - [61, 'Z01xSsg5675hic20dj'], - ]; - } - - public function providerForCustomBase() - { - return [ - [2, 'xy', 'xyyxyxxy'], - [3, 'pfg', 'gfpffp'], - ]; - } - - public function providerForExceptionBase() - { - return [ - [63, '01210103001'], - [125, '0120125f2001'], + [new Base(2), ''], + [new Base(3), ''], + [new Base(8), ''], + [new Base(16), ''], + [new Base(20), ''], + [new Base(50), ''], + [new Base(62), ''], + [new Base(2), '01210103001'], + [new Base(3), '0120125f2001'], + [new Base(8), '01234dfZ567520'], + [new Base(16), '012aXS34f5675c20d'], + [new Base(20), '012ahZX34f5675hic20dj'], + [new Base(50), '012ahGZ34f56A75FGhic20dj'], + [new Base(61), 'Z01xSsg5675hic20dj'], ]; } }