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

Commit 599fc42

Browse files
committed
feat: added LessThan rule
1 parent d5f272f commit 599fc42

7 files changed

Lines changed: 122 additions & 5 deletions

File tree

src/ChainedValidatorInterface.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ public function validate(mixed $value): bool;
1515

1616
// --- Rules ---
1717

18-
public function notBlank(string $message = null): ChainedValidatorInterface;
18+
public function notBlank(array $options = []): ChainedValidatorInterface;
1919

20-
public function greaterThan(mixed $constraint, string $message = null): ChainedValidatorInterface;
20+
public function greaterThan(mixed $constraint, array $options = []): ChainedValidatorInterface;
21+
22+
public function lessThan(mixed $constraint, array $options = []): ChainedValidatorInterface;
2123
}
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 LessThanException extends ValidationException {}

src/Factory.php renamed to src/Factory/Factory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace ProgrammatorDev\YetAnotherPhpValidator;
3+
namespace ProgrammatorDev\YetAnotherPhpValidator\Factory;
44

55
use ProgrammatorDev\YetAnotherPhpValidator\Exception\RuleNotFoundException;
66
use ProgrammatorDev\YetAnotherPhpValidator\Rule\RuleInterface;

src/Rule/LessThan.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace ProgrammatorDev\YetAnotherPhpValidator\Rule;
4+
5+
use ProgrammatorDev\YetAnotherPhpValidator\Exception\LessThanException;
6+
use ProgrammatorDev\YetAnotherPhpValidator\Rule\Util\AssertComparableTrait;
7+
use Symfony\Component\OptionsResolver\OptionsResolver;
8+
9+
class LessThan extends AbstractRule implements RuleInterface
10+
{
11+
use AssertComparableTrait;
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 "{{ constraint }}", "{{ value }}" given.']);
20+
21+
$resolver->setAllowedTypes('message', 'string');
22+
23+
$this->options = $resolver->resolve($options);
24+
}
25+
26+
/**
27+
* @throws LessThanException
28+
*/
29+
public function assert(mixed $value, string $name): void
30+
{
31+
// Assert if constraint and value can be compared
32+
$this->assertComparable($this->constraint, $value, LessThanException::class);
33+
34+
if (!($value < $this->constraint)) {
35+
throw new LessThanException(
36+
message: $this->options['message'],
37+
parameters: [
38+
'name' => $name,
39+
'constraint' => $this->constraint,
40+
'value' => $value
41+
]
42+
);
43+
}
44+
}
45+
}

src/StaticValidatorInterface.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
interface StaticValidatorInterface
66
{
7-
public static function notBlank(string $message = null): ChainedValidatorInterface;
7+
public static function notBlank(array $options = []): ChainedValidatorInterface;
88

9-
public static function greaterThan(mixed $constraint, string $message = null): ChainedValidatorInterface;
9+
public static function greaterThan(mixed $constraint, array $options = []): ChainedValidatorInterface;
10+
11+
public static function lessThan(mixed $constraint, array $options = []): ChainedValidatorInterface;
1012
}

src/Validator.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use ProgrammatorDev\YetAnotherPhpValidator\Exception\RuleNotFoundException;
66
use ProgrammatorDev\YetAnotherPhpValidator\Exception\ValidationException;
7+
use ProgrammatorDev\YetAnotherPhpValidator\Factory\Factory;
78
use ProgrammatorDev\YetAnotherPhpValidator\Rule\RuleInterface;
89

910
/**

tests/LessThanTest.php

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

0 commit comments

Comments
 (0)