Skip to content

Commit 94970c3

Browse files
authored
add regex argument to string() & nullOrString() (#59)
1 parent a3bf476 commit 94970c3

File tree

3 files changed

+122
-6
lines changed

3 files changed

+122
-6
lines changed

phpstan-baseline.neon

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,18 @@ parameters:
192192
count: 1
193193
path: tests/Unit/Util/ValueObjectTraitTest.php
194194

195+
-
196+
message: '#^Parameter \$regex of static method class@anonymous/tests/Unit/Util/ValueObjectTraitTest\.php\:1133\:\:nullOrString\(\) expects non\-empty\-string\|null, '''' given\.$#'
197+
identifier: argument.type
198+
count: 1
199+
path: tests/Unit/Util/ValueObjectTraitTest.php
200+
201+
-
202+
message: '#^Parameter \$regex of static method class@anonymous/tests/Unit/Util/ValueObjectTraitTest\.php\:1243\:\:string\(\) expects non\-empty\-string\|null, '''' given\.$#'
203+
identifier: argument.type
204+
count: 1
205+
path: tests/Unit/Util/ValueObjectTraitTest.php
206+
195207
-
196208
message: '#^Unable to resolve the template type T in call to method static method class@anonymous/tests/Unit/Util/ValueObjectTraitTest\.php\:332\:\:enum\(\)$#'
197209
identifier: argument.templateType

src/Util/ValueObjectTrait.php

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -362,10 +362,11 @@ final protected static function nullOrMultiLink(array $values, string $key): ?Mu
362362
/**
363363
* Returns null if the value is not set or a trimmed non-empty string.
364364
*
365-
* @param array<mixed> $values
366-
* @param non-empty-string $key
365+
* @param array<mixed> $values
366+
* @param non-empty-string $key
367+
* @param null|non-empty-string $regex
367368
*/
368-
final protected static function nullOrString(array $values, string $key, ?int $maxLength = null): ?string
369+
final protected static function nullOrString(array $values, string $key, ?int $maxLength = null, ?string $regex = null): ?string
369370
{
370371
if (!\array_key_exists($key, $values)) {
371372
return null;
@@ -376,6 +377,11 @@ final protected static function nullOrString(array $values, string $key, ?int $m
376377
Assert::maxLength($values[$key], $maxLength);
377378
}
378379

380+
if (null !== $regex) {
381+
Assert::stringNotEmpty($regex);
382+
Assert::regex($values[$key], $regex);
383+
}
384+
379385
try {
380386
return TrimmedNonEmptyString::from($values[$key])->toString();
381387
} catch (\InvalidArgumentException) {
@@ -386,17 +392,23 @@ final protected static function nullOrString(array $values, string $key, ?int $m
386392
/**
387393
* Returns a trimmed non-empty string.
388394
*
389-
* @param array<mixed> $values
390-
* @param non-empty-string $key
395+
* @param array<mixed> $values
396+
* @param non-empty-string $key
397+
* @param null|non-empty-string $regex
391398
*/
392-
final protected static function string(array $values, string $key, ?int $maxLength = null): string
399+
final protected static function string(array $values, string $key, ?int $maxLength = null, ?string $regex = null): string
393400
{
394401
Assert::keyExists($values, $key);
395402

396403
if (null !== $maxLength) {
397404
Assert::maxLength($values[$key], $maxLength);
398405
}
399406

407+
if (null !== $regex) {
408+
Assert::stringNotEmpty($regex);
409+
Assert::regex($values[$key], $regex);
410+
}
411+
400412
return TrimmedNonEmptyString::fromString($values[$key])->toString();
401413
}
402414

tests/Unit/Util/ValueObjectTraitTest.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,52 @@ public function nullOrStringThrowsExceptionWhenMaxLengthIsLessThenOne(): void
11131113
$class::nullOrString($values, 'key', 0);
11141114
}
11151115

1116+
#[Test]
1117+
public function nullOrStringWithRegex(): void
1118+
{
1119+
$class = new class() {
1120+
use ValueObjectTrait {
1121+
ValueObjectTrait::nullOrString as public;
1122+
}
1123+
};
1124+
1125+
$values = ['key' => 'hello-world'];
1126+
1127+
self::assertSame('hello-world', $class::nullOrString($values, 'key', regex: '/^hello-world$/'));
1128+
}
1129+
1130+
#[Test]
1131+
public function nullOrStringThrowsExceptionWhenRegexEmpty(): void
1132+
{
1133+
$class = new class() {
1134+
use ValueObjectTrait {
1135+
ValueObjectTrait::nullOrString as public;
1136+
}
1137+
};
1138+
1139+
$values = ['key' => 'hello-world'];
1140+
1141+
$this->expectException(\InvalidArgumentException::class);
1142+
1143+
$class::nullOrString($values, 'key', regex: '');
1144+
}
1145+
1146+
#[Test]
1147+
public function nullOrStringThrowsExceptionWhenRegexNotMatch(): void
1148+
{
1149+
$class = new class() {
1150+
use ValueObjectTrait {
1151+
ValueObjectTrait::nullOrString as public;
1152+
}
1153+
};
1154+
1155+
$values = ['key' => 'not-matching'];
1156+
1157+
$this->expectException(\InvalidArgumentException::class);
1158+
1159+
$class::nullOrString($values, 'key', regex: '/^hello-world$/');
1160+
}
1161+
11161162
#[Test]
11171163
public function string(): void
11181164
{
@@ -1177,6 +1223,52 @@ public function stringThrowsExceptionWhenMaxLengthExceeded(): void
11771223
$class::string($values, 'key', 5);
11781224
}
11791225

1226+
#[Test]
1227+
public function stringWithRegex(): void
1228+
{
1229+
$class = new class() {
1230+
use ValueObjectTrait {
1231+
ValueObjectTrait::string as public;
1232+
}
1233+
};
1234+
1235+
$values = ['key' => 'hello-world'];
1236+
1237+
self::assertSame('hello-world', $class::string($values, 'key', regex: '/^hello-world$/'));
1238+
}
1239+
1240+
#[Test]
1241+
public function stringThrowsExceptionWhenRegexEmpty(): void
1242+
{
1243+
$class = new class() {
1244+
use ValueObjectTrait {
1245+
ValueObjectTrait::string as public;
1246+
}
1247+
};
1248+
1249+
$this->expectException(\InvalidArgumentException::class);
1250+
1251+
$values = ['key' => 'hello-world'];
1252+
1253+
$class::string($values, 'key', regex: '');
1254+
}
1255+
1256+
#[Test]
1257+
public function stringThrowsExceptionWhenRegexNotMatch(): void
1258+
{
1259+
$class = new class() {
1260+
use ValueObjectTrait {
1261+
ValueObjectTrait::string as public;
1262+
}
1263+
};
1264+
1265+
$values = ['key' => 'not-matching'];
1266+
1267+
$this->expectException(\InvalidArgumentException::class);
1268+
1269+
$class::string($values, 'key', regex: '/^hello-world$/');
1270+
}
1271+
11801272
#[Test]
11811273
public function nullOrEditable(): void
11821274
{

0 commit comments

Comments
 (0)