Make "Min" always inclusive

Since the rule "GreaterThan" was created, there is no reason to allow
"Min" to not be inclusive.

Also apply contribution guidelines to the rule.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
Henrique Moody 2018-05-31 16:25:00 +02:00
parent 9eb159f3d9
commit 24c2ba8faa
No known key found for this signature in database
GPG key ID: 221E9281655813A6
7 changed files with 154 additions and 72 deletions

View file

@ -1,36 +1,54 @@
# Min
- `Min(mixed $minValue)`
- `Min(mixed $minValue, bool $inclusive)`
- `Min(mixed $compareTo)`
Validates if the input is greater than the minimum value.
Validates whether the input is greater than or equal to a value.
```php
v::intVal()->min(15)->validate(5); // false
v::intVal()->min(5)->validate(5); // false
v::intVal()->min(5, true)->validate(5); // true
v::intVal()->min(10)->validate(9); // false
v::intVal()->min(10)->validate(10); // true
v::intVal()->min(10)->validate(11); // true
```
Also accepts dates:
You can also validate:
```php
v::dateTime()->min('2012-01-01')->validate('2015-01-01'); // true
// Dates
v::dateTime()->max('2010-01-01')->validate('2010-01-01'); // true
v::dateTime()->max('2010-01-01')->validate('2011-01-01'); // false
// DateTimeInterface
v::dateTime()->max(new DateTime('tomorrow'))->validate(new DateTimeImmutable('yesterday')); // true
v::dateTime()->max(new DateTimeImmutable('+1 month'))->validate(new DateTime('today')); // false
// Date intervals
v::dateTime()->max('1988-09-09')->validate('18 years ago'); // true
v::dateTime()->max('+1 minute')->validate('now'); // false
// Single character strings
v::stringType()->lowercase()->max('a')->validate('b'); // true
v::stringType()->uppercase()->max('C')->validate('A'); // false
```
`true` may be passed as a parameter to indicate that inclusive
values must be used.
Message template for this validator includes `{{minValue}}`.
Message template for this validator includes `{{compareTo}}`.
## Changelog
Version | Description
--------|-------------
2.0.0 | Became always inclusive
1.0.0 | Became inclusive by default
0.3.9 | Created
***
See also:
- [GreaterThan](GreaterThan.md)
- [Length](Length.md)
- [LessThan](LessThan.md)
- [Max](Max.md)
- [Between](Between.md)
- [MaxAge](MaxAge.md)
- [MinAge](MinAge.md)

View file

@ -13,23 +13,23 @@ declare(strict_types=1);
namespace Respect\Validation\Exceptions;
class MinException extends ValidationException
/**
* @author Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
* @author Henrique Moody <henriquemoody@gmail.com>
*/
final class MinException extends ValidationException
{
public const INCLUSIVE = 'inclusive';
/**
* {@inheritdoc}
*/
public static $defaultTemplates = [
self::MODE_DEFAULT => [
self::STANDARD => '{{name}} must be greater than {{interval}}',
self::INCLUSIVE => '{{name}} must be greater than or equal to {{interval}}',
self::STANDARD => '{{name}} must be greater than or equal to {{compareTo}}',
],
self::MODE_NEGATIVE => [
self::STANDARD => '{{name}} must not be greater than {{interval}}',
self::INCLUSIVE => '{{name}} must not be greater than or equal to {{interval}}',
self::STANDARD => '{{name}} must not be greater than or equal to {{compareTo}}',
],
];
protected function chooseTemplate(): string
{
return $this->getParam('inclusive') ? static::INCLUSIVE : static::STANDARD;
}
}

View file

@ -42,7 +42,7 @@ final class Between extends AbstractEnvelope
parent::__construct(
new AllOf(
new Min($minValue, true),
new Min($minValue),
new Max($maxValue)
),
[

View file

@ -13,14 +13,38 @@ declare(strict_types=1);
namespace Respect\Validation\Rules;
class Min extends AbstractInterval
use Respect\Validation\Helpers\ComparisonHelper;
/**
* Validates whether the input is greater than or equal to a value.
*
* @author Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
* @author Henrique Moody <henriquemoody@gmail.com>
*/
final class Min extends AbstractRule
{
use ComparisonHelper;
/**
* @var mixed
*/
private $compareTo;
/**
* Initializes the rule by setting the value to be compared to the input.
*
* @param mixed $compareTo
*/
public function __construct($compareTo)
{
$this->compareTo = $compareTo;
}
/**
* {@inheritdoc}
*/
public function validate($input): bool
{
if ($this->inclusive) {
return $this->filterInterval($input) >= $this->filterInterval($this->interval);
}
return $this->filterInterval($input) > $this->filterInterval($this->interval);
return $this->toComparable($input) >= $this->toComparable($this->compareTo);
}
}

View file

@ -101,8 +101,8 @@ use Respect\Validation\Rules\Key;
* @method static Validator max($compareTo)
* @method static Validator maxAge(int $age, string $format = null)
* @method static Validator mimetype(string $mimetype)
* @method static Validator min($minValue, bool $inclusive = true)
* @method static Validator minAge(int $age, bool $format = null)
* @method static Validator min($compareTo)
* @method static Validator minAge(int $age, string $format = null)
* @method static Validator multiple(int $multipleOf)
* @method static Validator negative()
* @method static Validator nif()

View file

@ -0,0 +1,37 @@
--FILE--
<?php
require 'vendor/autoload.php';
use Respect\Validation\Exceptions\MinException;
use Respect\Validation\Exceptions\NestedValidationException;
use Respect\Validation\Validator as v;
try {
v::min(INF)->check(10);
} catch (MinException $exception) {
echo $exception->getMessage().PHP_EOL;
}
try {
v::not(v::min(5))->check(INF);
} catch (MinException $exception) {
echo $exception->getMessage().PHP_EOL;
}
try {
v::min('today')->assert('yesterday');
} catch (NestedValidationException $exception) {
echo $exception->getFullMessage().PHP_EOL;
}
try {
v::not(v::min('a'))->assert('z');
} catch (NestedValidationException $exception) {
echo $exception->getFullMessage().PHP_EOL;
}
?>
--EXPECTF--
10 must be greater than or equal to `INF`
`INF` must not be greater than or equal to 5
- "yesterday" must be greater than or equal to "today"
- "z" must not be greater than or equal to "a"

View file

@ -14,65 +14,68 @@ declare(strict_types=1);
namespace Respect\Validation\Rules;
use DateTime;
use PHPUnit\Framework\TestCase;
use DateTimeImmutable;
use Respect\Validation\Test\RuleTestCase;
/**
* @group rule
* @group rule
*
* @covers \Respect\Validation\Rules\Min
* @covers \Respect\Validation\Exceptions\MinException
*
* @author Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
* @author Gabriel Caruso <carusogabriel34@gmail.com>
* @author Henrique Moody <henriquemoody@gmail.com>
*/
class MinTest extends TestCase
final class MinTest extends RuleTestCase
{
/**
* @dataProvider providerForValidMin
* {@inheritdoc}
*/
public function testValidMinShouldReturnTrue($minValue, $inclusive, $input): void
{
$min = new Min($minValue, $inclusive);
self::assertTrue($min->__invoke($input));
$min->check($input);
$min->assert($input);
}
/**
* @dataProvider providerForInvalidMin
* @expectedException \Respect\Validation\Exceptions\MinException
*/
public function testInvalidMinShouldThrowMinException($minValue, $inclusive, $input): void
{
$min = new Min($minValue, $inclusive);
self::assertFalse($min->__invoke($input));
$min->assert($input);
}
public function providerForValidMin()
public function providerForValidInput(): array
{
return [
[100, false, 165.0],
[-100, false, 200],
[200, true, 200],
[200, false, 300],
['a', true, 'a'],
['a', true, 'c'],
['yesterday', true, 'now'],
// From documentation
[new Min(10), 10],
[new Min(10), 11],
[new Min('2010-01-01'), '2010-01-01'],
[new Min(new DateTime('yesterday')), new DateTimeImmutable('tomorrow')],
[new Min('1988-09-09'), '18 years ago'],
[new Min('a'), 'b'],
[new Min(100), 165.0],
[new Min(-100), 200],
[new Min(200), 200],
[new Min(200), 300],
[new Min('a'), 'a'],
[new Min('a'), 'c'],
[new Min('yesterday'), 'now'],
// Samples from issue #178
['13-05-2014 03:16', true, '20-05-2014 03:16'],
[new DateTime('13-05-2014 03:16'), true, new DateTime('20-05-2014 03:16')],
['13-05-2014 03:16', true, new DateTime('20-05-2014 03:16')],
[new DateTime('13-05-2014 03:16'), true, '20-05-2014 03:16'],
[new Min('13-05-2014 03:16'), '20-05-2014 03:16'],
[new Min(new DateTime('13-05-2014 03:16')), new DateTime('20-05-2014 03:16')],
[new Min('13-05-2014 03:16'), new DateTime('20-05-2014 03:16')],
[new Min(new DateTime('13-05-2014 03:16')), '20-05-2014 03:16'],
[new Min(50), 50],
];
}
public function providerForInvalidMin()
/**
* {@inheritdoc}
*/
public function providerForInvalidInput(): array
{
return [
[100, true, ''],
[100, false, ''],
[500, false, 300],
[0, false, -250],
[0, false, -50],
[50, false, 50],
// From documentation
[new Min(10), 9],
[new Min('2011-01-01'), '2009-01-01'],
[new Min(new DateTimeImmutable('+1 month')), new DateTime('today')],
[new Min('+1 minute'), new DateTime('now')],
[new Min('C'), 'A'],
[new Min(100), ''],
[new Min(100), ''],
[new Min(500), 300],
[new Min(0), -250],
[new Min(0), -50],
];
}
}