130 lines
4.3 KiB
PHP
130 lines
4.3 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the Symfony package.
|
|
*
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Symfony\Component\Validator\Test;
|
|
|
|
use PHPUnit\Framework\ExpectationFailedException;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Symfony\Component\Validator\Constraint;
|
|
use Symfony\Component\Validator\Constraints\Compound;
|
|
use Symfony\Component\Validator\Constraints\CompoundValidator;
|
|
use Symfony\Component\Validator\ConstraintViolationListInterface;
|
|
use Symfony\Component\Validator\Context\ExecutionContext;
|
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
|
use Symfony\Component\Validator\Validation;
|
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
|
|
/**
|
|
* A test case to ease testing Compound Constraints.
|
|
*
|
|
* @author Alexandre Daubois <alex.daubois@gmail.com>
|
|
*
|
|
* @template T of Compound
|
|
*/
|
|
abstract class CompoundConstraintTestCase extends TestCase
|
|
{
|
|
protected ValidatorInterface $validator;
|
|
protected ?ConstraintViolationListInterface $violationList = null;
|
|
protected ExecutionContextInterface $context;
|
|
protected mixed $root;
|
|
|
|
private mixed $validatedValue;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->root = 'root';
|
|
$this->validator = $this->createValidator();
|
|
$this->context = $this->createContext($this->validator);
|
|
}
|
|
|
|
protected function validateValue(mixed $value): void
|
|
{
|
|
$this->validator->inContext($this->context)->validate($this->validatedValue = $value, $this->createCompound());
|
|
}
|
|
|
|
protected function createValidator(): ValidatorInterface
|
|
{
|
|
return Validation::createValidator();
|
|
}
|
|
|
|
protected function createContext(?ValidatorInterface $validator = null): ExecutionContextInterface
|
|
{
|
|
$translator = $this->createMock(TranslatorInterface::class);
|
|
$translator->expects($this->any())->method('trans')->willReturnArgument(0);
|
|
|
|
return new ExecutionContext($validator ?? $this->createValidator(), $this->root, $translator);
|
|
}
|
|
|
|
public function assertViolationsRaisedByCompound(Constraint|array $constraints): void
|
|
{
|
|
if ($constraints instanceof Constraint) {
|
|
$constraints = [$constraints];
|
|
}
|
|
|
|
$validator = new CompoundValidator();
|
|
$context = $this->createContext();
|
|
$validator->initialize($context);
|
|
|
|
$validator->validate($this->validatedValue, new class($constraints) extends Compound {
|
|
public function __construct(private array $testedConstraints)
|
|
{
|
|
parent::__construct();
|
|
}
|
|
|
|
protected function getConstraints(array $options): array
|
|
{
|
|
return $this->testedConstraints;
|
|
}
|
|
});
|
|
|
|
$expectedViolations = iterator_to_array($context->getViolations());
|
|
|
|
if (!$expectedViolations) {
|
|
throw new ExpectationFailedException(\sprintf('Expected at least one violation for constraint(s) "%s", got none raised.', implode(', ', array_map(fn ($constraint) => $constraint::class, $constraints))));
|
|
}
|
|
|
|
$failedToAssertViolations = [];
|
|
reset($expectedViolations);
|
|
foreach ($this->context->getViolations() as $violation) {
|
|
if ($violation != current($expectedViolations)) {
|
|
$failedToAssertViolations[] = $violation;
|
|
}
|
|
|
|
next($expectedViolations);
|
|
}
|
|
|
|
$this->assertSame(
|
|
[],
|
|
$failedToAssertViolations,
|
|
\sprintf('Expected violation(s) for constraint(s) %s to be raised by compound.',
|
|
implode(', ', array_map(fn ($violation) => ($violation->getConstraint())::class, $failedToAssertViolations))
|
|
)
|
|
);
|
|
}
|
|
|
|
public function assertViolationsCount(int $count): void
|
|
{
|
|
$this->assertCount($count, $this->context->getViolations());
|
|
}
|
|
|
|
protected function assertNoViolation(): void
|
|
{
|
|
$violationsCount = \count($this->context->getViolations());
|
|
$this->assertSame(0, $violationsCount, \sprintf('No violation expected. Got %d.', $violationsCount));
|
|
}
|
|
|
|
/**
|
|
* @return T
|
|
*/
|
|
abstract protected function createCompound(): Compound;
|
|
}
|