Skip to content

Commit

Permalink
Create BetweenExclusive rule
Browse files Browse the repository at this point in the history
Signed-off-by: Henrique Moody <[email protected]>
  • Loading branch information
henriquemoody committed Mar 11, 2024
1 parent 1e2c1bf commit 52b75bc
Show file tree
Hide file tree
Showing 16 changed files with 231 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/08-list-of-rules-by-category.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
## Comparisons

- [Between](rules/Between.md)
- [BetweenExclusive](rules/BetweenExclusive.md)
- [Equals](rules/Equals.md)
- [Equivalent](rules/Equivalent.md)
- [GreaterThan](rules/GreaterThan.md)
Expand Down Expand Up @@ -297,6 +298,7 @@
- [Base](rules/Base.md)
- [Base64](rules/Base64.md)
- [Between](rules/Between.md)
- [BetweenExclusive](rules/BetweenExclusive.md)
- [BoolType](rules/BoolType.md)
- [BoolVal](rules/BoolVal.md)
- [Bsn](rules/Bsn.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/Between.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Version | Description
***
See also:

- [BetweenExclusive](BetweenExclusive.md)
- [DateTime](DateTime.md)
- [GreaterThan](GreaterThan.md)
- [GreaterThanOrEqual](GreaterThanOrEqual.md)
Expand Down
39 changes: 39 additions & 0 deletions docs/rules/BetweenExclusive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# BetweenExclusive

- `BetweenExclusive(mixed $minimum, mixed $maximum)`

Validates whether the input is between two other values, exclusively.

```php
v::betweenExclusive(10, 20)->validate(10); // true
v::betweenExclusive('a', 'e')->validate('c'); // true
v::betweenExclusive(new DateTime('yesterday'), new DateTime('tomorrow'))->validate(new DateTime('today')); // true

v::betweenExclusive(0, 100)->validate(100); // false
v::betweenExclusive('a', 'z')->validate('a'); // false
```

Validation makes comparison easier, check out our supported [comparable values](../07-comparable-values.md).

## Categorization

- Comparisons

## Changelog

| Version | Description |
|--------:|-----------------------------|
| 3.0.0 | Created |

***
See also:

- [Between](Between.md)
- [DateTime](DateTime.md)
- [GreaterThan](GreaterThan.md)
- [GreaterThanOrEqual](GreaterThanOrEqual.md)
- [Length](Length.md)
- [LessThan](LessThan.md)
- [LessThanOrEqual](LessThanOrEqual.md)
- [Max](Max.md)
- [Min](Min.md)
1 change: 1 addition & 0 deletions docs/rules/DateTime.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ v::dateTime(DateTime::RFC3339_EXTENDED)->validate($input); // false
See also:

- [Between](Between.md)
- [BetweenExclusive](BetweenExclusive.md)
- [Callback](Callback.md)
- [Date](Date.md)
- [LeapDate](LeapDate.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/GreaterThan.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Version | Description
See also:

- [Between](Between.md)
- [BetweenExclusive](BetweenExclusive.md)
- [GreaterThanOrEqual](GreaterThanOrEqual.md)
- [LessThanOrEqual](LessThanOrEqual.md)
- [Max](Max.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/GreaterThanOrEqual.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Message template for this validator includes `{{compareTo}}`.
See also:

- [Between](Between.md)
- [BetweenExclusive](BetweenExclusive.md)
- [GreaterThan](GreaterThan.md)
- [Length](Length.md)
- [LessThan](LessThan.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/Length.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@ Version | Description
See also:

- [Between](Between.md)
- [BetweenExclusive](BetweenExclusive.md)
- [GreaterThanOrEqual](GreaterThanOrEqual.md)
1 change: 1 addition & 0 deletions docs/rules/LessThan.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Version | Description
See also:

- [Between](Between.md)
- [BetweenExclusive](BetweenExclusive.md)
- [GreaterThanOrEqual](GreaterThanOrEqual.md)
- [LessThanOrEqual](LessThanOrEqual.md)
- [Max](Max.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/LessThanOrEqual.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Message template for this validator includes `{{compareTo}}`.
See also:

- [Between](Between.md)
- [BetweenExclusive](BetweenExclusive.md)
- [GreaterThan](GreaterThan.md)
- [GreaterThanOrEqual](GreaterThanOrEqual.md)
- [LessThan](LessThan.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/Max.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ empty, the validation will fail.
See also:

- [Between](Between.md)
- [BetweenExclusive](BetweenExclusive.md)
- [GreaterThan](GreaterThan.md)
- [GreaterThanOrEqual](GreaterThanOrEqual.md)
- [IterableType](IterableType.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/Min.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ empty, the validation will fail.
See also:

- [Between](Between.md)
- [BetweenExclusive](BetweenExclusive.md)
- [Each](Each.md)
- [GreaterThan](GreaterThan.md)
- [GreaterThanOrEqual](GreaterThanOrEqual.md)
Expand Down
2 changes: 2 additions & 0 deletions library/Mixins/ChainedValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public function base64(): ChainedValidator;

public function between(mixed $minimum, mixed $maximum): ChainedValidator;

public function betweenExclusive(mixed $minimum, mixed $maximum): ChainedValidator;

public function boolType(): ChainedValidator;

public function boolVal(): ChainedValidator;
Expand Down
2 changes: 2 additions & 0 deletions library/Mixins/StaticValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public static function base64(): ChainedValidator;

public static function between(mixed $minimum, mixed $maximum): ChainedValidator;

public static function betweenExclusive(mixed $minimum, mixed $maximum): ChainedValidator;

public static function bic(string $countryCode): ChainedValidator;

public static function boolType(): ChainedValidator;
Expand Down
36 changes: 36 additions & 0 deletions library/Rules/BetweenExclusive.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/*
* Copyright (c) Alexandre Gomes Gaigalas <[email protected]>
* SPDX-License-Identifier: MIT
*/

declare(strict_types=1);

namespace Respect\Validation\Rules;

use Respect\Validation\Exceptions\InvalidRuleConstructorException;
use Respect\Validation\Helpers\CanCompareValues;
use Respect\Validation\Message\Template;
use Respect\Validation\Rules\Core\Envelope;

#[Template(
'{{name}} must be greater than {{minValue}} and less than {{maxValue}}',
'{{name}} must not be greater than {{minValue}} and less than {{maxValue}}',
)]
final class BetweenExclusive extends Envelope
{
use CanCompareValues;

public function __construct(mixed $minimum, mixed $maximum)
{
if ($this->toComparable($minimum) >= $this->toComparable($maximum)) {
throw new InvalidRuleConstructorException('Minimum cannot be less than or equals to maximum');
}

parent::__construct(
new AllOf(new GreaterThan($minimum), new LessThan($maximum)),
['minValue' => $minimum, 'maxValue' => $maximum]
);
}
}
49 changes: 49 additions & 0 deletions tests/integration/rules/betweenExclusive.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
--FILE--
<?php

declare(strict_types=1);

require 'vendor/autoload.php';

use Respect\Validation\Validator as v;

run([
'Default' => [v::betweenExclusive(1, 10), 12],
'Negative' => [v::not(v::betweenExclusive(1, 10)), 5],
'With template' => [v::betweenExclusive(1, 10), 12, 'Bewildered bees buzzed between blooming begonias'],
'With name' => [v::betweenExclusive(1, 10)->setName('Range'), 10],
]);
?>
--EXPECT--
Default
⎺⎺⎺⎺⎺⎺⎺
12 must be greater than 1 and less than 10
- 12 must be greater than 1 and less than 10
[
'betweenExclusive' => '12 must be greater than 1 and less than 10',
]

Negative
⎺⎺⎺⎺⎺⎺⎺⎺
5 must not be greater than 1 and less than 10
- 5 must not be greater than 1 and less than 10
[
'betweenExclusive' => '5 must not be greater than 1 and less than 10',
]

With template
⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺
Bewildered bees buzzed between blooming begonias
- Bewildered bees buzzed between blooming begonias
[
'betweenExclusive' => 'Bewildered bees buzzed between blooming begonias',
]

With name
⎺⎺⎺⎺⎺⎺⎺⎺⎺
Range must be greater than 1 and less than 10
- Range must be greater than 1 and less than 10
[
'Range' => 'Range must be greater than 1 and less than 10',
]

92 changes: 92 additions & 0 deletions tests/unit/Rules/BetweenExclusiveTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

/*
* Copyright (c) Alexandre Gomes Gaigalas <[email protected]>
* SPDX-License-Identifier: MIT
*/

declare(strict_types=1);

namespace Respect\Validation\Rules;

use DateTime;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\Test;
use Respect\Validation\Exceptions\InvalidRuleConstructorException;
use Respect\Validation\Test\Stubs\CountableStub;
use Respect\Validation\Test\TestCase;

#[Group('rule')]
#[CoversClass(BetweenExclusive::class)]
final class BetweenExclusiveTest extends TestCase
{
#[Test]
public function minimumValueShouldNotBeGreaterThanMaximumValue(): void
{
$this->expectExceptionObject(
new InvalidRuleConstructorException('Minimum cannot be less than or equals to maximum')
);

new BetweenExclusive(10, 5);
}

#[Test]
public function minimumValueShouldNotBeEqualsToMaximumValue(): void
{
$this->expectExceptionObject(
new InvalidRuleConstructorException('Minimum cannot be less than or equals to maximum')
);

new BetweenExclusive(5, 5);
}

#[Test]
#[DataProvider('providerForValidInput')]
public function shouldValidateValidInput(mixed $minValue, mixed $maxValue, mixed $input): void
{
self::assertValidInput(new BetweenExclusive($minValue, $maxValue), $input);
}

#[Test]
#[DataProvider('providerForInvalidInput')]
public function shouldValidateInvalidInput(mixed $minValue, mixed $maxValue, mixed $input): void
{
self::assertInvalidInput(new BetweenExclusive($minValue, $maxValue), $input);
}

/** @return array<array{mixed, mixed, mixed}> */
public static function providerForValidInput(): array
{
return [
'positive numbers' => [10, 20, 15],
'negative numbers' => [-10, 20, -5],
'positive and negative numbers' => [-10, 20, 0],
'letters' => ['a', 'z', 'j'],
'date time objects' => [new DateTime('yesterday'), new DateTime('tomorrow'), new DateTime('now')],
'countable objects' => [new CountableStub(1), new CountableStub(10), 5],
'countable objects against integer' => [new CountableStub(1), new CountableStub(10), 5],
];
}

/** @return array<array{mixed, mixed, mixed}> */
public static function providerForInvalidInput(): iterable
{
return [
'equals to the max value' => [10, 20, 20],
'equals to the min value' => [10, 20, 10],
'equals to the max value without a gap' => [0, 1, 1],
'equals to the min value without a gap' => [0, 1, 0],
'empty string' => [10, 20, ''],
'greater than max value' => [0, 1, 2],
'less than min value' => [0, 1, -1],
'letters greater than max value' => ['a', 'j', 'z'],
'datetime greater than max value' => [
new DateTime('yesterday'),
new DateTime('now'),
new DateTime('tomorrow'),
],
];
}
}

0 comments on commit 52b75bc

Please sign in to comment.