mirror of
https://github.com/Respect/Validation.git
synced 2024-05-15 04:36:40 +02:00
Allow to customise messages while asserting
Because we now have a single "assert()" method, we have more freedom to add more customizations to it. This specific one is handy if someone wants to use the library to validate but wants to use their own exceptions. Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
parent
d7dc0f2b4e
commit
2ae1df177a
|
@ -199,15 +199,13 @@ method as well by passing the templates as an argument:
|
|||
|
||||
```php
|
||||
try {
|
||||
$usernameValidator->assert('really messed up screen#name');
|
||||
$usernameValidator->assert('really messed up screen#name', [
|
||||
'alnum' => '{{name}} must contain only letters and digits',
|
||||
'noWhitespace' => '{{name}} cannot contain spaces',
|
||||
'length' => '{{name}} must not have more than 15 chars',
|
||||
]);
|
||||
} catch(NestedValidationException $exception) {
|
||||
print_r(
|
||||
$exception->getMessages([
|
||||
'alnum' => '{{name}} must contain only letters and digits',
|
||||
'noWhitespace' => '{{name}} cannot contain spaces',
|
||||
'length' => '{{name}} must not have more than 15 chars',
|
||||
])
|
||||
);
|
||||
print_r($exception->getMessages());
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -16,15 +16,17 @@ use Respect\Validation\Message\StandardFormatter;
|
|||
use Respect\Validation\Message\StandardRenderer;
|
||||
use Respect\Validation\Mixins\StaticValidator;
|
||||
use Respect\Validation\Rules\AllOf;
|
||||
use Respect\Validation\Rules\Core\Standard;
|
||||
use Throwable;
|
||||
|
||||
use function count;
|
||||
use function current;
|
||||
use function is_array;
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
* @mixin StaticValidator
|
||||
*/
|
||||
final class Validator extends Standard
|
||||
final class Validator implements Validatable
|
||||
{
|
||||
use CanBindEvaluateRule;
|
||||
|
||||
|
@ -34,6 +36,10 @@ final class Validator extends Standard
|
|||
/** @var array<string, mixed> */
|
||||
private array $templates = [];
|
||||
|
||||
private ?string $name = null;
|
||||
|
||||
private ?string $template = null;
|
||||
|
||||
public function __construct(
|
||||
private readonly Factory $factory,
|
||||
private readonly Formatter $formatter,
|
||||
|
@ -66,15 +72,24 @@ final class Validator extends Standard
|
|||
return $this->evaluate($input)->isValid;
|
||||
}
|
||||
|
||||
public function assert(mixed $input): void
|
||||
/** @param array<string, mixed>|string|Throwable|null $template */
|
||||
public function assert(mixed $input, array|string|Throwable|null $template = null): void
|
||||
{
|
||||
$result = $this->evaluate($input);
|
||||
if ($result->isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($template instanceof Throwable) {
|
||||
throw $template;
|
||||
}
|
||||
|
||||
$templates = $this->templates;
|
||||
if (count($templates) === 0 && $this->getTemplate() != null) {
|
||||
if (is_array($template)) {
|
||||
$templates = $template;
|
||||
} elseif (is_string($template)) {
|
||||
$templates = ['__root__' => $template];
|
||||
} elseif ($this->getTemplate() != null) {
|
||||
$templates = ['__root__' => $this->getTemplate()];
|
||||
}
|
||||
|
||||
|
@ -115,6 +130,30 @@ final class Validator extends Standard
|
|||
$this->assert($input);
|
||||
}
|
||||
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): static
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTemplate(): ?string
|
||||
{
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
public function setTemplate(string $template): static
|
||||
{
|
||||
$this->template = $template;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function rule(): Validatable
|
||||
{
|
||||
if (count($this->rules) === 1) {
|
||||
|
|
|
@ -26,25 +26,27 @@ exceptionMessages(
|
|||
->key('password', v::stringType())
|
||||
->key('schema', v::stringType())
|
||||
)
|
||||
->setTemplates([
|
||||
'mysql' => [
|
||||
'user' => 'Value should be a MySQL username',
|
||||
'host' => '`{{name}}` should be a MySQL host',
|
||||
->assert(
|
||||
[
|
||||
'mysql' => [
|
||||
'host' => 42,
|
||||
'schema' => 42,
|
||||
],
|
||||
'postgresql' => [
|
||||
'user' => 42,
|
||||
'password' => 42,
|
||||
],
|
||||
],
|
||||
'postgresql' => [
|
||||
'schema' => 'You must provide a valid PostgreSQL schema',
|
||||
],
|
||||
])
|
||||
->assert([
|
||||
'mysql' => [
|
||||
'host' => 42,
|
||||
'schema' => 42,
|
||||
],
|
||||
'postgresql' => [
|
||||
'user' => 42,
|
||||
'password' => 42,
|
||||
],
|
||||
]);
|
||||
[
|
||||
'mysql' => [
|
||||
'user' => 'Value should be a MySQL username',
|
||||
'host' => '`{{name}}` should be a MySQL host',
|
||||
],
|
||||
'postgresql' => [
|
||||
'schema' => 'You must provide a valid PostgreSQL schema',
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
);
|
||||
?>
|
||||
|
|
|
@ -51,19 +51,11 @@ function run(array $scenarios): void
|
|||
echo $description . PHP_EOL;
|
||||
echo str_repeat('⎺', strlen($description)) . PHP_EOL;
|
||||
|
||||
if (is_string($template)) {
|
||||
$rule->setTemplate($template);
|
||||
}
|
||||
|
||||
if (is_array($template)) {
|
||||
$rule->setTemplates($template);
|
||||
}
|
||||
|
||||
$fallbackMessage = 'No exception was thrown with: ' . stringify($input);
|
||||
|
||||
exceptionMessage(static fn() => $rule->check($input), $fallbackMessage);
|
||||
exceptionFullMessage(static fn() => $rule->assert($input), $fallbackMessage);
|
||||
exceptionMessages(static fn() => $rule->assert($input), $fallbackMessage);
|
||||
exceptionMessage(static fn() => $rule->assert($input, $template), $fallbackMessage);
|
||||
exceptionFullMessage(static fn() => $rule->assert($input, $template), $fallbackMessage);
|
||||
exceptionMessages(static fn() => $rule->assert($input, $template), $fallbackMessage);
|
||||
echo PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,11 @@ exceptionMessages(
|
|||
static fn() => v::alnum()
|
||||
->noWhitespace()
|
||||
->length(v::between(1, 15))
|
||||
->setTemplates([
|
||||
->assert('really messed up screen#name', [
|
||||
'alnum' => '{{name}} must contain only letters and digits',
|
||||
'noWhitespace' => '{{name}} cannot contain spaces',
|
||||
'length' => '{{name}} must not have more than 15 chars',
|
||||
])
|
||||
->assert('really messed up screen#name')
|
||||
);
|
||||
?>
|
||||
--EXPECT--
|
||||
|
@ -25,4 +24,4 @@ exceptionMessages(
|
|||
'alnum' => '"really messed up screen#name" must contain only letters and digits',
|
||||
'noWhitespace' => '"really messed up screen#name" cannot contain spaces',
|
||||
'lengthBetween' => 'The length of "really messed up screen#name" must be between 1 and 15',
|
||||
]
|
||||
]
|
||||
|
|
|
@ -9,7 +9,9 @@ declare(strict_types=1);
|
|||
|
||||
namespace Respect\Validation;
|
||||
|
||||
use Exception;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use Respect\Validation\Exceptions\ComponentException;
|
||||
use Respect\Validation\Test\Rules\Stub;
|
||||
|
@ -49,4 +51,77 @@ final class ValidatorTest extends TestCase
|
|||
|
||||
self::assertFalse($validator->isValid('whatever'));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function itShouldAssertUsingTheGivingExceptionEvenWhenRuleAlreadyHasTemplate(): void
|
||||
{
|
||||
$template = new Exception('This is a test');
|
||||
|
||||
$this->expectExceptionObject($template);
|
||||
|
||||
$validator = Validator::create(Stub::fail(1));
|
||||
$validator->setTemplate('This wont be used');
|
||||
$validator->assert('whatever', $template);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function itShouldAssertUsingTheGivingStringTemplate(): void
|
||||
{
|
||||
$template = 'This is my new template';
|
||||
|
||||
$this->expectExceptionMessage($template);
|
||||
|
||||
$validator = Validator::create(Stub::fail(1));
|
||||
$validator->assert('whatever', $template);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function itShouldAssertUsingTheGivingArrayTemplateWithTheRuleNameAsKey(): void
|
||||
{
|
||||
$template = ['stub' => 'This is my new template'];
|
||||
|
||||
$this->expectExceptionMessage($template['stub']);
|
||||
|
||||
$validator = Validator::create(Stub::fail(1));
|
||||
$validator->setTemplates(['stub' => 'This is my pre-defined template']);
|
||||
$validator->assert('whatever', $template);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function itShouldAssertUsingTheGivingArrayTemplateWithRootKey(): void
|
||||
{
|
||||
$template = ['__root__' => 'This is my new template'];
|
||||
|
||||
$this->expectExceptionMessage($template['__root__']);
|
||||
|
||||
$validator = Validator::create(Stub::fail(1));
|
||||
$validator->setTemplates(['__root__' => 'This is my pre-defined template']);
|
||||
$validator->assert('whatever', $template);
|
||||
}
|
||||
|
||||
/** @param string|array<string, mixed> $template */
|
||||
#[Test]
|
||||
#[DataProvider('providerForTemplates')]
|
||||
public function itShouldAssertNotOverwritingThePreDefinedTemplate(array|string $template): void
|
||||
{
|
||||
$preDefinedTemplate = 'This is my pre-defined template';
|
||||
|
||||
$this->expectExceptionMessage($preDefinedTemplate);
|
||||
|
||||
$validator = Validator::create(Stub::fail(1));
|
||||
$validator->setTemplate($preDefinedTemplate);
|
||||
$validator->assert('whatever', $template);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array{string|array<string, mixed>}>
|
||||
*/
|
||||
public static function providerForTemplates(): array
|
||||
{
|
||||
return [
|
||||
'string' => ['This is my new template'],
|
||||
'array key named key' => [['stub' => 'This is my new template']],
|
||||
'array key __root__ key' => [['__root__' => 'This is my new template']],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue