8000 [Validator] Add `CompoundConstraintTestCase` to ease testing Compound… · symfony/symfony@cd080f1 · GitHub
[go: up one dir, main page]

Skip to content

Commit cd080f1

Browse files
[Validator] Add CompoundConstraintTestCase to ease testing Compound Constraint
1 parent 3d380c9 commit cd080f1

File tree

6 files changed

+263
-14
lines changed

6 files changed

+263
-14
lines changed

src/Symfony/Component/Validator/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
* Add a `NoSuspiciousCharacters` constraint to validate a string is not a spoofing attempt
1111
* Add the `countUnit` option to the `Length` constraint to allow counting the string length either by code points (like before, now the default setting `Length::COUNT_CODEPOINTS`), bytes (`Length::COUNT_BYTES`) or graphemes (`Length::COUNT_GRAPHEMES`)
1212
* Add the `filenameMaxLength` option to the `File` constraint
13+
* Add `CompoundConstraintTestCase` to ease testing Compound Constraint
1314

1415
6.2
1516
---
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Test;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Validator\Constraints\Compound;
16+
use Symfony\Component\Validator\Constraints\GroupSequence;
17+
use Symfony\Component\Validator\ConstraintViolationInterface;
18+
use Symfony\Component\Validator\ConstraintViolationListInterface;
19+
use Symfony\Component\Validator\Validation;
20+
use Symfony\Component\Validator\Validator\ValidatorInterface;
21+
22+
/**
23+
* A test case to ease testing Compound Constraint.
24+
*
25+
* @author Alexandre Daubois <alex.daubois@gmail.com>
26+
*/
27+
abstract class CompoundConstraintTestCase extends TestCase
28+
{
29+
protected ValidatorInterface $validator;
30+
31+
protected ?ConstraintViolationListInterface $violationList = null;
32+
33+
protected function setUp(): void
34+
{
35+
$this->validator = Validation::createValidator();
36+
}
37+
38+
protected function validateValue(mixed $value, array|string|GroupSequence $groups = null): void
39+
{
40+
$this->violationList = $this->validator->validate($value, $this->createCompound(), $groups);
41+
}
42+
43+
protected function assertViolationIsRaisedByCompound(string $code): void
44+
{
45+
if (null === $this->violationList) {
46+
throw new \LogicException('Value must be validated with the "validateValue()" method before asserting on compound violations.');
47+
}
48+
49+
$this->assertTrue($this->isViolationRaised($code), sprintf('Expected violation with code "%s" to be raised.', $code));
50+
}
51+
52+
protected function assertViolationIsNotRaisedByCompound(string $code): void
53+
{
54+
if (null === $this->violationList) {
55+
throw new \LogicException('Value must be validated with the "validateValue()" method before asserting on compound violations.');
56+
}
57+
58+
$this->assertFalse($this->isViolationRaised($code), sprintf('Expected violation with code "%s" to be raised.', $code));
59+
}
60+
61+
protected function assertViolationsAreRaisedByCompound(array $codes): void
62+
{
63+
if (null === $this->violationList) {
64+
throw new \LogicException('Value must be validated with the "validateValue()" method before asserting on compound violations.');
65+
}
66+
67+
$violationCodes = array_map(static fn (ConstraintViolationInterface $violation): ?string => $violation->getCode(), iterator_to_array($this->violationList));
68+
69+
$violationCodes = array_filter($violationCodes, static fn (string $violationCode): bool => !\in_array($violationCode, $codes, true));
70+
71+
$this->assertEmpty($violationCodes, sprintf('Some violations code have not been raised: %s.', implode(', ', $violationCodes)));
72+
}
73+
74+
protected function assertViolationCountRaisedByCompound(int $count): void
75+
{
76+
if (null === $this->violationList) {
77+
throw new \LogicException('Value must be validated with the "validateValue()" method before asserting on compound violations.');
78+
}
79+
80+
$this->assertCount($count, $this->violationList, sprintf('Expected %d violation to be raised, got %d.', $count, \count($this->violationList)));
81+
}
82+
83+
protected function assertNoViolation(): void
84+
{
85+
if (null === $this->violationList) {
86+
throw new \LogicException('Value must be validated with the "validateValue()" method before asserting on compound violations.');
87+
}
88+
89+
$this->assertCount(0, $this->violationList, sprintf('Expected no violations to be raised, got %d.', \count($this->violationList)));
90+
}
91+
92+
private function isViolationRaised(string $code): bool
93+
{
94+
foreach ($this->violationList as $violation) {
95+
if ($violation->getCode() === $code) {
96+
return true;
97+
}
98+
}
99+
100+
return false;
101+
}
102+
103+
abstract public function createCompound(): Compound;
104+
}

src/Symfony/Component/Validator/Tests/Constraints/CompoundValidatorTest.php

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@
1111

1212
namespace Symfony\Component\Validator\Tests\Constraints;
1313

14-
use Symfony\Component\Validator\Constraints\Compound;
1514
use Symfony\Component\Validator\Constraints\CompoundValidator;
16-
use Symfony\Component\Validator\Constraints\Length;
17-
use Symfony\Component\Validator\Constraints\NotBlank;
1815
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
16+
use Symfony\Component\Validator\Tests\Fixtures\DummyCompoundConstraint;
1917

2018
class CompoundValidatorTest extends ConstraintValidatorTestCase
2119
{
@@ -43,14 +41,3 @@ public function testValidateWithConstraints()
4341
$this->assertNoViolation();
4442
}
4543
}
46-
47-
class DummyCompoundConstraint extends Compound
48-
{
49-
protected function getConstraints(array $options): array
50-
{
51-
return [
52-
new NotBlank(),
53-
new Length(['max' => 3]),
54-
];
55-
}
56-
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Tests\Fixtures;
13+
14+
use Symfony\Component\Validator\Constraints\Compound;
15+
use Symfony\Component\Validator\Constraints\Length;
16+
use Symfony\Component\Validator\Constraints\NotBlank;
17+
use Symfony\Component\Validator\Constraints\Regex;
18+
19+
class DummyCompoundConstraint extends Compound
20+
{
21+
protected function getConstraints(array $options): array
22+
{
23+
return [
24+
new NotBlank(),
25+
new Length(['max' => 3]),
26+
new Regex('/[a-z]+/'),
27+
];
28+
}
29+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Tests\Fixtures;
13+
14+
use Symfony\Component\Validator\Constraints\Compound;
15+
use Symfony\Component\Validator\Constraints\Length;
16+
use Symfony\Component\Validator\Constraints\NotBlank;
17+
use Symfony\Component\Validator\Constraints\Regex;
18+
19+
class DummyCompoundConstraintWithGroups extends Compound
20+
{
21+
protected function getConstraints(array $options): array
22+
{
23+
return [
24+
new NotBlank(groups: ['not_blank']),
25+
new Length(['max' => 3], groups: ['max_length']),
26+
];
27+
}
28+
}
Lines changed: 100 additions & 0 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Tests\Test;
13+
14+
use Symfony\Component\Validator\Constraints\Compound;
15+
use Symfony\Component\Validator\Constraints\Length;
16+
use Symfony\Component\Validator\Constraints\NotBlank;
17+
use Symfony\Component\Validator\Constraints\Regex;
18+
use Symfony\Component\Validator\Test\CompoundConstraintTestCase;
19+
use Symfony\Component\Validator\Tests\Fixtures\DummyCompoundConstraint;
20+
21+
class CompoundConstraintTestCaseTest extends CompoundConstraintTestCase
22+
{
23+
public function createCompound(): Compound
24+
{
25+
return new DummyCompoundConstraint();
26+
}
27+
28+
public function testAssertNoViolation()
29+
{
30+
$this->validateValue('abc');
31+
32+
$this->assertNoViolation();
33+
}
34+
35+
public function testAssertIsRaisedByCompound()
36+
{
37+
$this->validateValue('');
38+
39+
$this->assertViolationIsRaisedByCompound(NotBlank::IS_BLANK_ERROR);
40+
$this->assertViolationCountRaisedByCompound(1);
41+
}
42+
43+
public function testAssertIsNotRaisedByCompound()
44+
{
45+
$this->validateValue('abc');
46+
47+
$this->assertViolationIsNotRaisedByCompound(NotBlank::IS_BLANK_ERROR);
48+
}
49+
50+
public function testMultipleAssertAreRaisedByCompound()
51+
{
52+
$this->validateValue('1245');
53+
54+
$this->assertViolationsAreRaisedByCompound([
55+
Length::TOO_LONG_ERROR,
56+
Regex::REGEX_FAILED_ERROR,
57+
]);
58+
$this->assertViolationCountRaisedByCompound(2);
59+
}
60+
61+
public function testAssertIsRaisedByCompoundWithGroups()
62+
{
63+
$this->validateValue('', ['max_length']);
64+
65+
$this->assertViolationIsNotRaisedByCompound(NotBlank::IS_BLANK_ERROR);
66+
$this->assertViolationCountRaisedByCompound(0);
67+
}
68+
69+
public function testAssertViolationIsRaisedByCompoundWithoutValidate()
70+
{
71+
$this->expectException(\LogicException::class);
72+
$this->expectExceptionMessage('Value must be validated with the "validateValue()" method before asserting on compound violations.');
73+
74+
$this->assertViolationIsRaisedByCompound('code');
75+
}
76+
77+
public function testAssertViolationAreRaisedByCompoundWithoutValidate()
78+
{
79+
$this->expectException(\LogicException::class);
80+
$this->expectExceptionMessage('Value must be validated with the "validateValue()" method before asserting on compound violations.');
81+
82+
$this->assertViolationsAreRaisedByCompound(['code']);
83+
}
84+
85+
public function testAssertViolationCountRaisedByCompoundWithoutValidate()
86+
{
87+
$this->expectException(\LogicException::class);
88+
$this->expectExceptionMessage('Value must be validated with the "validateValue()" method before asserting on compound violations.');
89+
90+
$this->assertViolationCountRaisedByCompound(1);
91+
}
92+
93+
public function testAssertNoViolationWithoutValidate()
94+
{
95+
$this->expectException(\LogicException::class);
96+
$this->expectExceptionMessage('Value must be validated with the "validateValue()" method before asserting on compound violations.');
97+
98+
$this->assertNoViolation();
99+
}
100+
}

0 commit comments

Comments
 (0)
0