Make some improvements to the "Roman" rule

The rule validates any empty string as a valid input, its exception
message states Roman with lower-case "R" and refers to numbers instead
of numerals, which is the most common usage.

This commit will fix both behaviors and also improve the tests for the
rule.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
Henrique Moody 2019-04-05 20:10:13 +02:00
parent cb528ae612
commit 22f3f80f4c
No known key found for this signature in database
GPG key ID: 221E9281655813A6
5 changed files with 81 additions and 65 deletions

View file

@ -2,7 +2,7 @@
- `Roman()`
Validates roman numbers
Validates if the input is a Roman numeral.
```php
v::roman()->validate('IV'); // true
@ -12,6 +12,8 @@ v::roman()->validate('IV'); // true
Version | Description
--------|-------------
2.0.0 | Exception message refers to Roman "numerals" instead of "numbers"
2.0.0 | Do not consider empty strings as valid
0.3.9 | Created
***

View file

@ -24,10 +24,10 @@ final class RomanException extends ValidationException
*/
public static $defaultTemplates = [
self::MODE_DEFAULT => [
self::STANDARD => '{{name}} must be a valid roman number',
self::STANDARD => '{{name}} must be a valid Roman numeral',
],
self::MODE_NEGATIVE => [
self::STANDARD => '{{name}} must not be a valid roman number',
self::STANDARD => '{{name}} must not be a valid Roman numeral',
],
];
}

View file

@ -14,6 +14,8 @@ declare(strict_types=1);
namespace Respect\Validation\Rules;
/**
* Validates if the input is a Roman numeral.
*
* @author Alexander Wühr <wuehr@sc-networks.com>
* @author Henrique Moody <henriquemoody@gmail.com>
* @author Jean Pimentel <jeanfap@gmail.com>
@ -22,6 +24,6 @@ final class Roman extends AbstractEnvelope
{
public function __construct()
{
parent::__construct(new Regex('/^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/'));
parent::__construct(new Regex('/^(?=[MDCLXVI])M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$/'));
}
}

View file

@ -0,0 +1,42 @@
--CREDITS--
Henrique Moody <henriquemoody@gmail.com>
--FILE--
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use Respect\Validation\Exceptions\NestedValidationException;
use Respect\Validation\Exceptions\RomanException;
use Respect\Validation\Validator as v;
try {
v::roman()->check(1234);
} catch (RomanException $exception) {
echo $exception->getMessage().PHP_EOL;
}
try {
v::not(v::roman())->check('XL');
} catch (RomanException $exception) {
echo $exception->getMessage().PHP_EOL;
}
try {
v::roman()->assert('e2');
} catch (NestedValidationException $exception) {
echo $exception->getFullMessage().PHP_EOL;
}
try {
v::not(v::roman())->assert('IV');
} catch (NestedValidationException $exception) {
echo $exception->getFullMessage().PHP_EOL;
}
?>
--EXPECT--
1234 must be a valid Roman numeral
"XL" must not be a valid Roman numeral
- "e2" must be a valid Roman numeral
- "IV" must not be a valid Roman numeral

View file

@ -13,88 +13,58 @@ declare(strict_types=1);
namespace Respect\Validation\Rules;
use Respect\Validation\Test\TestCase;
use Respect\Validation\Test\RuleTestCase;
/**
* @group rule
* @covers \Respect\Validation\Exceptions\RomanException
* @group rule
*
* @covers \Respect\Validation\Rules\Roman
*
* @author Gabriel Caruso <carusogabriel34@gmail.com>
* @author Henrique Moody <henriquemoody@gmail.com>
* @author Jean Pimentel <jeanfap@gmail.com>
*/
final class RomanTest extends TestCase
final class RomanTest extends RuleTestCase
{
/**
* @var Roman
* {@inheritDoc}
*/
protected $romanValidator;
protected function setUp(): void
public function providerForValidInput(): array
{
$this->romanValidator = new Roman();
}
$sut = new Roman();
/**
* @dataProvider providerForRoman
*
* @test
*/
public function validRomansShouldReturnTrue(string $input): void
{
self::assertTrue($this->romanValidator->__invoke($input));
$this->romanValidator->assert($input);
$this->romanValidator->check($input);
}
/**
* @dataProvider providerForNotRoman
* @expectedException \Respect\Validation\Exceptions\RomanException
*
* @test
*/
public function invalidRomansShouldThrowRomanException(string $input): void
{
self::assertFalse($this->romanValidator->__invoke($input));
$this->romanValidator->assert($input);
}
/**
* @return string[][]
*/
public function providerForRoman(): array
{
return [
[''],
['III'],
['IV'],
['VI'],
['XIX'],
['XLII'],
['LXII'],
['CXLIX'],
['CLIII'],
['MCCXXXIV'],
['MMXXIV'],
['MCMLXXV'],
['MMMMCMXCIX'],
[$sut, 'III'],
[$sut, 'IV'],
[$sut, 'VI'],
[$sut, 'XIX'],
[$sut, 'XLII'],
[$sut, 'LXII'],
[$sut, 'CXLIX'],
[$sut, 'CLIII'],
[$sut, 'MCCXXXIV'],
[$sut, 'MMXXIV'],
[$sut, 'MCMLXXV'],
[$sut, 'MMMMCMXCIX'],
];
}
/**
* @return string[][]
* {@inheritDoc}
*/
public function providerForNotRoman(): array
public function providerForInvalidInput(): array
{
$sut = new Roman();
return [
[' '],
['IIII'],
['IVVVX'],
['CCDC'],
['MXM'],
['XIIIIIIII'],
['MIMIMI'],
[$sut, ''],
[$sut, ' '],
[$sut, 'IIII'],
[$sut, 'IVVVX'],
[$sut, 'CCDC'],
[$sut, 'MXM'],
[$sut, 'XIIIIIIII'],
[$sut, 'MIMIMI'],
];
}
}