Skip to content

Commit a72b3eb

Browse files
committed
Prevent validators from generating validatorBuilder Ids
When calling `v::validatorName()`, a `ValidatorBuilder` is instantiated to manage the validation chain. However, users generally expect the ID to reflect the specific validator invoked rather than the internal builder class. This commit updates `Id::fromValidator()` to resolve the ID from the underlying validator when it is the sole member of the `ValidatorBuilder`, ensuring more intuitive identification.
1 parent d1d8980 commit a72b3eb

2 files changed

Lines changed: 91 additions & 0 deletions

File tree

src/Id.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace Respect\Validation;
1212

13+
use function count;
1314
use function lcfirst;
1415
use function strrchr;
1516
use function substr;
@@ -24,6 +25,10 @@ public function __construct(
2425

2526
public static function fromValidator(Validator $validator): self
2627
{
28+
if ($validator instanceof ValidatorBuilder && count($validator->getValidators()) === 1) {
29+
return self::fromValidator($validator->getValidators()[0]);
30+
}
31+
2732
return new self(lcfirst(substr((string) strrchr($validator::class, '\\'), 1)));
2833
}
2934

tests/unit/IdTest.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
/*
4+
* SPDX-License-Identifier: MIT
5+
* SPDX-FileCopyrightText: (c) Respect Project Contributors
6+
* SPDX-FileContributor: Henrique Moody <henriquemoody@gmail.com>
7+
*/
8+
9+
declare(strict_types=1);
10+
11+
namespace Respect\Validation;
12+
13+
use PHPUnit\Framework\Attributes\CoversClass;
14+
use PHPUnit\Framework\Attributes\Test;
15+
use Respect\Validation\Test\TestCase;
16+
use Respect\Validation\Validators\AlwaysInvalid;
17+
18+
#[CoversClass(Id::class)]
19+
final class IdTest extends TestCase
20+
{
21+
#[Test]
22+
public function shouldCreateInstanceWithValue(): void
23+
{
24+
$id = new Id('test');
25+
26+
self::assertSame('test', $id->value);
27+
}
28+
29+
#[Test]
30+
public function shouldCreateIdFromSimpleValidator(): void
31+
{
32+
$validator = new AlwaysInvalid();
33+
$id = Id::fromValidator($validator);
34+
35+
self::assertSame('alwaysInvalid', $id->value);
36+
}
37+
38+
#[Test]
39+
public function shouldCreateIdFromNestedValidatorBuilder(): void
40+
{
41+
$validator = ValidatorBuilder::stringType();
42+
43+
$id = Id::fromValidator($validator);
44+
45+
self::assertSame('stringType', $id->value);
46+
}
47+
48+
#[Test]
49+
public function shouldCreateIdFromMultipleValidatorsInBuilder(): void
50+
{
51+
$validator = ValidatorBuilder::stringType()->intType();
52+
53+
$id = Id::fromValidator($validator);
54+
55+
self::assertSame('validatorBuilder', $id->value);
56+
}
57+
58+
#[Test]
59+
public function shouldAddPrefixToValue(): void
60+
{
61+
$id = new Id('test');
62+
$prefixed = $id->withPrefix('my');
63+
64+
self::assertSame('myTest', $prefixed->value);
65+
self::assertNotSame($id, $prefixed);
66+
}
67+
68+
#[Test]
69+
public function shouldHandleEmptyValueWithPrefix(): void
70+
{
71+
$id = new Id('');
72+
$prefixed = $id->withPrefix('prefix');
73+
74+
self::assertSame('prefix', $prefixed->value);
75+
}
76+
77+
#[Test]
78+
public function shouldHandleMultipleRecursionInFromValidator(): void
79+
{
80+
$validator = ValidatorBuilder::init(ValidatorBuilder::stringType());
81+
82+
$id = Id::fromValidator($validator);
83+
84+
self::assertSame('stringType', $id->value);
85+
}
86+
}

0 commit comments

Comments
 (0)