Skip to content

Commit 66c2544

Browse files
committed
Add RegexRule validation with evaluation logic and corresponding tests
1 parent 7da3aef commit 66c2544

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed

src/Validation/Rules/RegexRule.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Validation\Rules;
4+
5+
use Nuxtifyts\PhpDto\Exceptions\ValidationRuleException;
6+
7+
class RegexRule implements ValidationRule
8+
{
9+
public string $pattern;
10+
11+
/** @var 0 | 256 | 512 | 768 */
12+
public int $flags = 0;
13+
14+
public int $offset = 0;
15+
16+
public string $name {
17+
get {
18+
return 'regex';
19+
}
20+
}
21+
22+
public function evaluate(mixed $value): bool
23+
{
24+
return is_string($value)
25+
&& preg_match(
26+
pattern: $this->pattern,
27+
subject: $value,
28+
flags: $this->flags,
29+
offset: $this->offset
30+
);
31+
}
32+
33+
/**
34+
* @param ?array<string, mixed> $parameters
35+
*
36+
* @throws ValidationRuleException
37+
*/
38+
public static function make(?array $parameters = null): self
39+
{
40+
$instance = new self();
41+
42+
$pattern = $parameters['pattern'] ?? null;
43+
44+
if (!is_string($pattern) || @preg_match($pattern, '') === false) {
45+
throw ValidationRuleException::invalidParameters();
46+
}
47+
48+
$instance->pattern = $pattern;
49+
50+
return $instance;
51+
}
52+
53+
public function validationMessage(): string
54+
{
55+
return 'The :attribute field does not match the required pattern.';
56+
}
57+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Tests\Unit\Validation;
4+
5+
use Throwable;
6+
use PHPUnit\Framework\Attributes\Test;
7+
use PHPUnit\Framework\Attributes\CoversClass;
8+
use Nuxtifyts\PhpDto\Validation\Rules\RegexRule;
9+
use Nuxtifyts\PhpDto\Validation\Rules\ValidationRule;
10+
use Nuxtifyts\PhpDto\Exceptions\ValidationRuleException;
11+
12+
#[CoversClass(RegexRule::class)]
13+
#[CoversClass(ValidationRuleException::class)]
14+
class RegexRuleTest extends ValidationRuleTestCase
15+
{
16+
/**
17+
* @throws Throwable
18+
*/
19+
#[Test]
20+
public function validate_validation_message(): void
21+
{
22+
$rule = RegexRule::make(['pattern' => '/^test$/']);
23+
24+
self::assertEquals(
25+
'The :attribute field does not match the required pattern.',
26+
$rule->validationMessage()
27+
);
28+
}
29+
30+
/**
31+
* @return array<string, array{
32+
* validationRuleClassString: class-string<ValidationRule>,
33+
* makeParams: ?array<string, mixed>,
34+
* expectedMakeException: ?class-string<ValidationRuleException>,
35+
* valueToBeEvaluated: mixed,
36+
* expectedResult: bool
37+
* }>
38+
*/
39+
public static function data_provider(): array
40+
{
41+
return [
42+
'Will evaluate false when value is not a valid regex string' => [
43+
'validationRuleClassString' => RegexRule::class,
44+
'makeParams' => ['pattern' => '/^test$/'],
45+
'expectedMakeException' => null,
46+
'valueToBeEvaluated' => 'not-a-valid-regex-string',
47+
'expectedResult' => false
48+
],
49+
'Will evaluate true when a valid regex string is provided' => [
50+
'validationRuleClassString' => RegexRule::class,
51+
'makeParams' => ['pattern' => '/^test$/'],
52+
'expectedMakeException' => null,
53+
'valueToBeEvaluated' => 'test',
54+
'expectedResult' => true
55+
],
56+
'Will evaluate false when a non string value is provided' => [
57+
'validationRuleClassString' => RegexRule::class,
58+
'makeParams' => ['pattern' => '/^test$/'],
59+
'expectedMakeException' => null,
60+
'valueToBeEvaluated' => 123,
61+
'expectedResult' => false
62+
],
63+
'Will throw an exception if the pattern is not a valid regex' => [
64+
'validationRuleClassString' => RegexRule::class,
65+
'makeParams' => ['pattern' => '/^test'],
66+
'expectedMakeException' => ValidationRuleException::class,
67+
'valueToBeEvaluated' => 'test',
68+
'expectedResult' => false
69+
],
70+
];
71+
}
72+
}

0 commit comments

Comments
 (0)