Skip to content

Commit 409c477

Browse files
committed
regexp => pattern (like in the json spec)
1 parent 6517944 commit 409c477

6 files changed

Lines changed: 99 additions & 11 deletions

File tree

doc/Schema/AssocSchema.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ echo $config['database']['host']; // 'localhost'
158158
$addressSchema = $p->assoc([
159159
'street' => $p->string(),
160160
'city' => $p->string(),
161-
'zipCode' => $p->string()->regexp('/^\d{5}$/'),
161+
'zipCode' => $p->string()->pattern('/^\d{5}$/'),
162162
]);
163163

164164
$personSchema = $p->assoc([

doc/Schema/DiscriminatedUnionSchema.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ $contactSchema = $p->discriminatedUnion([
6363
]),
6464
$p->object([
6565
'_type' => $p->literal('phone'),
66-
'number' => $p->string()->regexp('/^\+\d{10,15}$/'),
66+
'number' => $p->string()->pattern('/^\+\d{10,15}$/'),
6767
'country' => $p->string()->length(2),
6868
]),
6969
$p->object([
@@ -124,9 +124,9 @@ $eventSchema = $p->discriminatedUnion([
124124
$paymentSchema = $p->discriminatedUnion([
125125
$p->object([
126126
'method' => $p->literal('credit_card'),
127-
'cardNumber' => $p->string()->regexp('/^\d{16}$/'),
128-
'expiry' => $p->string()->regexp('/^\d{2}\/\d{2}$/'),
129-
'cvv' => $p->string()->regexp('/^\d{3,4}$/'),
127+
'cardNumber' => $p->string()->pattern('/^\d{16}$/'),
128+
'expiry' => $p->string()->pattern('/^\d{2}\/\d{2}$/'),
129+
'cvv' => $p->string()->pattern('/^\d{3,4}$/'),
130130
]),
131131
$p->object([
132132
'method' => $p->literal('bank_transfer'),

doc/Schema/ObjectSchema.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ $createUserSchema = $p->object([
133133
$addressSchema = $p->object([
134134
'street' => $p->string(),
135135
'city' => $p->string(),
136-
'zipCode' => $p->string()->regexp('/^\d{5}$/'),
136+
'zipCode' => $p->string()->pattern('/^\d{5}$/'),
137137
]);
138138

139139
$personSchema = $p->object([

doc/Schema/StringSchema.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ $schema->maxLength(100); // Maximum 100 characters
3030
$schema->includes('amp'); // Must contain 'amp'
3131
$schema->startsWith('exa'); // Must start with 'exa'
3232
$schema->endsWith('ple'); // Must end with 'ple'
33-
$schema->regexp('/^[a-z]+$/i'); // Must match regex pattern
33+
$schema->pattern('/^[a-z]+$/i'); // Must match regex pattern
3434
```
3535

3636
### Format Validations
@@ -110,7 +110,7 @@ $usernameSchema = $p->string()
110110
->toLowerCase()
111111
->minLength(3)
112112
->maxLength(20)
113-
->regexp('/^[a-z0-9_]+$/');
113+
->pattern('/^[a-z0-9_]+$/');
114114

115115
$usernameSchema->parse(' John_Doe123 '); // Returns: 'john_doe123'
116116
```

src/Schema/StringSchema.php

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ final class StringSchema extends AbstractSchemaInnerParse implements SchemaInter
4646
public const string ERROR_MATCH_CODE = 'string.match';
4747
public const string ERROR_MATCH_TEMPLATE = '{{given}} does not match {{match}}';
4848

49+
public const string ERROR_PATTERN_CODE = 'string.pattern';
50+
public const string ERROR_PATTERN_TEMPLATE = '{{given}} does not pattern {{pattern}}';
51+
4952
public const string ERROR_REGEXP_CODE = 'string.regexp';
5053
public const string ERROR_REGEXP_TEMPLATE = '{{given}} does not regexp {{regexp}}';
5154

@@ -263,11 +266,11 @@ public function mac(): static
263266
}
264267

265268
/**
266-
* @deprecated: use regexp
269+
* @deprecated: use pattern
267270
*/
268271
public function match(string $match): static
269272
{
270-
@trigger_error('Use regexp instead', E_USER_DEPRECATED);
273+
@trigger_error('Use pattern instead', E_USER_DEPRECATED);
271274

272275
if (false === @preg_match($match, '')) {
273276
throw new \InvalidArgumentException(\sprintf('Invalid match "%s" given', $match));
@@ -290,8 +293,36 @@ public function match(string $match): static
290293
});
291294
}
292295

296+
public function pattern(string $pattern): static
297+
{
298+
if (false === @preg_match($pattern, '')) {
299+
throw new \InvalidArgumentException(\sprintf('Invalid pattern "%s" given', $pattern));
300+
}
301+
302+
return $this->postParse(static function (string $string) use ($pattern) {
303+
$doesMatch = filter_var($string, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => $pattern]]);
304+
305+
if (false === $doesMatch) {
306+
throw new ErrorsException(
307+
new Error(
308+
self::ERROR_PATTERN_CODE,
309+
self::ERROR_PATTERN_TEMPLATE,
310+
['pattern' => $pattern, 'given' => $string]
311+
)
312+
);
313+
}
314+
315+
return $string;
316+
});
317+
}
318+
319+
/**
320+
* @deprecated: use pattern
321+
*/
293322
public function regexp(string $regexp): static
294323
{
324+
@trigger_error('Use pattern instead', E_USER_DEPRECATED);
325+
295326
if (false === @preg_match($regexp, '')) {
296327
throw new \InvalidArgumentException(\sprintf('Invalid regexp "%s" given', $regexp));
297328
}

tests/Unit/Schema/StringSchemaTest.php

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ public function testParseWithValidMatch(): void
570570
self::assertArrayHasKey('type', $lastError);
571571
self::assertSame(E_USER_DEPRECATED, $lastError['type']);
572572
self::assertArrayHasKey('message', $lastError);
573-
self::assertSame('Use regexp instead', $lastError['message']);
573+
self::assertSame('Use pattern instead', $lastError['message']);
574574
}
575575

576576
public function testParseWithInvalidMatch(): void
@@ -600,6 +600,53 @@ public function testParseWithInvalidMatch(): void
600600
}
601601
}
602602

603+
public function testParseWithPatternWithInvalidPattern(): void
604+
{
605+
try {
606+
(new StringSchema())->pattern('test');
607+
608+
throw new \Exception('code should not be reached');
609+
} catch (\InvalidArgumentException $e) {
610+
self::assertSame('Invalid pattern "test" given', $e->getMessage());
611+
}
612+
}
613+
614+
public function testParseWithValidPattern(): void
615+
{
616+
$input = 'aBcDeFg';
617+
618+
$schema = (new StringSchema())->pattern('/^[a-z]+$/i');
619+
620+
self::assertSame($input, $schema->parse($input));
621+
}
622+
623+
public function testParseWithInvalidPattern(): void
624+
{
625+
$input = 'a1B2C3d4';
626+
627+
$schema = (new StringSchema())->pattern('/^[a-z]+$/i');
628+
629+
try {
630+
$schema->parse($input);
631+
632+
throw new \Exception('code should not be reached');
633+
} catch (ErrorsException $errorsException) {
634+
self::assertSame([
635+
[
636+
'path' => '',
637+
'error' => [
638+
'code' => 'string.pattern',
639+
'template' => '{{given}} does not pattern {{pattern}}',
640+
'variables' => [
641+
'pattern' => '/^[a-z]+$/i',
642+
'given' => $input,
643+
],
644+
],
645+
],
646+
], $errorsException->errors->jsonSerialize());
647+
}
648+
}
649+
603650
public function testParseWithRegexpWithInvalidPattern(): void
604651
{
605652
try {
@@ -613,11 +660,21 @@ public function testParseWithRegexpWithInvalidPattern(): void
613660

614661
public function testParseWithValidRegexp(): void
615662
{
663+
error_clear_last();
664+
616665
$input = 'aBcDeFg';
617666

618667
$schema = (new StringSchema())->regexp('/^[a-z]+$/i');
619668

620669
self::assertSame($input, $schema->parse($input));
670+
671+
$lastError = error_get_last();
672+
673+
self::assertNotNull($lastError);
674+
self::assertArrayHasKey('type', $lastError);
675+
self::assertSame(E_USER_DEPRECATED, $lastError['type']);
676+
self::assertArrayHasKey('message', $lastError);
677+
self::assertSame('Use pattern instead', $lastError['message']);
621678
}
622679

623680
public function testParseWithInvalidRegexp(): void

0 commit comments

Comments
 (0)