Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit a83c11e

Browse files
committed
feat: added LessThanOrEqual rule
1 parent 486263f commit a83c11e

File tree

5 files changed

+122
-0
lines changed

5 files changed

+122
-0
lines changed

src/ChainedValidatorInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public function greaterThanOrEqual(mixed $constraint, array $options = []): Chai
2323

2424
public function lessThan(mixed $constraint, array $options = []): ChainedValidatorInterface;
2525

26+
public function lessThanOrEqual(mixed $constraint, array $options = []): ChainedValidatorInterface;
27+
2628
public function choice(array $constraints, bool $multiple = false, ?int $minConstraint = null, ?int $maxConstraint = null, array $options = []): ChainedValidatorInterface;
2729

2830
public function range(mixed $minConstraint, mixed $maxConstraint, array $options = []): ChainedValidatorInterface;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
namespace ProgrammatorDev\YetAnotherPhpValidator\Exception;
4+
5+
class LessThanOrEqualException extends ValidationException {}

src/Rule/LessThanOrEqual.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace ProgrammatorDev\YetAnotherPhpValidator\Rule;
4+
5+
use ProgrammatorDev\YetAnotherPhpValidator\Exception\LessThanOrEqualException;
6+
use ProgrammatorDev\YetAnotherPhpValidator\Rule\Util\AssertIsComparableTrait;
7+
use Symfony\Component\OptionsResolver\OptionsResolver;
8+
9+
class LessThanOrEqual extends AbstractRule implements RuleInterface
10+
{
11+
use AssertIsComparableTrait;
12+
13+
private array $options;
14+
15+
public function __construct(private readonly mixed $constraint, array $options = [])
16+
{
17+
$resolver = new OptionsResolver();
18+
19+
$resolver->setDefaults(['message' => 'The "{{ name }}" value should be less than or equal to "{{ constraint }}", "{{ value }}" given.']);
20+
21+
$resolver->setAllowedTypes('message', 'string');
22+
23+
$this->options = $resolver->resolve($options);
24+
}
25+
26+
/**
27+
* @throws LessThanOrEqualException
28+
*/
29+
public function assert(mixed $value, string $name): void
30+
{
31+
$this->assertIsComparable($this->constraint, $value);
32+
33+
if (!($value <= $this->constraint)) {
34+
throw new LessThanOrEqualException(
35+
message: $this->options['message'],
36+
parameters: [
37+
'value' => $value,
38+
'name' => $name,
39+
'constraint' => $this->constraint
40+
]
41+
);
42+
}
43+
}
44+
}

src/StaticValidatorInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public static function greaterThanOrEqual(mixed $constraint, array $options = []
1212

1313
public static function lessThan(mixed $constraint, array $options = []): ChainedValidatorInterface;
1414

15+
public static function lessThanOrEqual(mixed $constraint, array $options = []): ChainedValidatorInterface;
16+
1517
public static function choice(array $constraints, bool $multiple = false, ?int $minConstraint = null, ?int $maxConstraint = null, array $options = []): ChainedValidatorInterface;
1618

1719
public static function range(mixed $minConstraint, mixed $maxConstraint, array $options = []): ChainedValidatorInterface;

tests/LessThanOrEqualTest.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace ProgrammatorDev\YetAnotherPhpValidator\Test;
4+
5+
use ProgrammatorDev\YetAnotherPhpValidator\Exception\LessThanOrEqualException;
6+
use ProgrammatorDev\YetAnotherPhpValidator\Rule\LessThanOrEqual;
7+
use ProgrammatorDev\YetAnotherPhpValidator\Test\Util\TestRuleFailureConditionTrait;
8+
use ProgrammatorDev\YetAnotherPhpValidator\Test\Util\TestRuleMessageOptionTrait;
9+
use ProgrammatorDev\YetAnotherPhpValidator\Test\Util\TestRuleSuccessConditionTrait;
10+
use ProgrammatorDev\YetAnotherPhpValidator\Test\Util\TestRuleUnexpectedValueTrait;
11+
12+
class LessThanOrEqualTest extends AbstractTest
13+
{
14+
use TestRuleUnexpectedValueTrait;
15+
use TestRuleFailureConditionTrait;
16+
use TestRuleSuccessConditionTrait;
17+
use TestRuleMessageOptionTrait;
18+
19+
public static function provideRuleUnexpectedValueData(): \Generator
20+
{
21+
$message = '/Cannot compare a type "(.*)" with a type "(.*)"/';
22+
23+
yield 'datetime constraint with int value' => [new LessThanOrEqual(new \DateTime()), 10, $message];
24+
yield 'datetime constraint with float value' => [new LessThanOrEqual(new \DateTime()), 1.0, $message];
25+
yield 'datetime constraint with string value' => [new LessThanOrEqual(new \DateTime()), 'a', $message];
26+
yield 'int constraint with string value' => [new LessThanOrEqual(10), 'a', $message];
27+
yield 'float constraint with string value' => [new LessThanOrEqual(1.0), 'a', $message];
28+
yield 'array constraint' => [new LessThanOrEqual([10]), 10, $message];
29+
yield 'null constraint' => [new LessThanOrEqual(null), 10, $message];
30+
}
31+
32+
public static function provideRuleFailureConditionData(): \Generator
33+
{
34+
$exception = LessThanOrEqualException::class;
35+
$message = '/The "(.*)" value should be less than or equal to "(.*)", "(.*)" given./';
36+
37+
yield 'datetime' => [new LessThanOrEqual(new \DateTime('today')), new \DateTime('tomorrow'), $exception, $message];
38+
yield 'int' => [new LessThanOrEqual(10), 20, $exception, $message];
39+
yield 'float' => [new LessThanOrEqual(10.0), 20.0, $exception, $message];
40+
yield 'int with float' => [new LessThanOrEqual(10), 20.0, $exception, $message];
41+
yield 'string' => [new LessThanOrEqual('a'), 'z', $exception, $message];
42+
}
43+
44+
public static function provideRuleSuccessConditionData(): \Generator
45+
{
46+
yield 'datetime' => [new LessThanOrEqual(new \DateTime('today')), new \DateTime('yesterday')];
47+
yield 'same datetime' => [new LessThanOrEqual(new \DateTime('today')), new \DateTime('today')];
48+
yield 'int' => [new LessThanOrEqual(10), 1];
49+
yield 'same int' => [new LessThanOrEqual(10), 10];
50+
yield 'float' => [new LessThanOrEqual(10.0), 1.0];
51+
yield 'same float' => [new LessThanOrEqual(10.0), 10.0];
52+
yield 'int with float' => [new LessThanOrEqual(10), 1.0];
53+
yield 'same int with float' => [new LessThanOrEqual(10), 10.0];
54+
yield 'string' => [new LessThanOrEqual('z'), 'a'];
55+
yield 'same string' => [new LessThanOrEqual('a'), 'a'];
56+
}
57+
58+
public static function provideRuleMessageOptionData(): \Generator
59+
{
60+
yield 'message' => [
61+
new LessThanOrEqual(
62+
constraint: 10,
63+
options: [
64+
'message' => 'The "{{ name }}" value "{{ value }}" is not less than or equal to "{{ constraint }}".'
65+
]
66+
), 20, 'The "test" value "20" is not less than or equal to "10".'
67+
];
68+
}
69+
}

0 commit comments

Comments
 (0)