Skip to content

Commit 2e3ae07

Browse files
committed
hardened tests and cascade array
1 parent 2f1069f commit 2e3ae07

File tree

7 files changed

+87
-45
lines changed

7 files changed

+87
-45
lines changed

src/Symfony/Component/Validator/Mapping/ClassMetadata.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,14 @@ public function addConstraint(Constraint $constraint)
204204
}
205205

206206
if ($constraint instanceof Cascade) {
207+
if (\PHP_VERSION_ID < 70400) {
208+
throw new ConstraintDefinitionException(sprintf('The constraint "%s" requires PHP 7.4.', Cascade::class));
209+
}
210+
207211
$this->cascadingStrategy = CascadingStrategy::CASCADE;
208212

209213
foreach ($this->getReflectionClass()->getProperties() as $property) {
210-
if ($property->hasType() && class_exists($property->getType()->getName())) {
214+
if ($property->hasType() && (('array' === $type = $property->getType()->getName()) || class_exists(($type)))) {
211215
$this->addPropertyConstraint($property->getName(), new Valid());
212216
}
213217
}

src/Symfony/Component/Validator/Tests/Fixtures/CascadingEntity.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,16 @@
1313

1414
class CascadingEntity
1515
{
16-
public ?CascadedChild $childOne;
16+
public string $scalar;
1717

18-
public static ?CascadedChild $childTwo;
18+
public CascadedChild $requiredChild;
1919

20-
public $children = [];
20+
public ?CascadedChild $optionalChild;
21+
22+
public static ?CascadedChild $staticChild;
23+
24+
/**
25+
* @var CascadedChild[]
26+
*/
27+
public array $children;
2128
}

src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Validator\Constraint;
16+
use Symfony\Component\Validator\Constraints\Cascade;
1617
use Symfony\Component\Validator\Constraints\Valid;
18+
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
19+
use Symfony\Component\Validator\Mapping\CascadingStrategy;
1720
use Symfony\Component\Validator\Mapping\ClassMetadata;
21+
use Symfony\Component\Validator\Tests\Fixtures\CascadingEntity;
1822
use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
1923
use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
2024
use Symfony\Component\Validator\Tests\Fixtures\PropertyConstraint;
@@ -310,4 +314,36 @@ public function testGetPropertyMetadataReturnsEmptyArrayWithoutConfiguredMetadat
310314
{
311315
$this->assertCount(0, $this->metadata->getPropertyMetadata('foo'), '->getPropertyMetadata() returns an empty collection if no metadata is configured for the given property');
312316
}
317+
318+
/**
319+
* @requires PHP < 7.4
320+
*/
321+
public function testCascadeConstraintIsNotAvailable()
322+
{
323+
$metadata = new ClassMetadata(CascadingEntity::class);
324+
325+
$this->expectException(ConstraintDefinitionException::class);
326+
$this->expectExceptionMessage('The constraint "Symfony\Component\Validator\Constraints\Cascade" requires PHP 7.4.');
327+
328+
$metadata->addConstraint(new Cascade());
329+
}
330+
331+
/**
332+
* @requires PHP 7.4
333+
*/
334+
public function testCascadeConstraint()
335+
{
336+
$metadata = new ClassMetadata(CascadingEntity::class);
337+
338+
$metadata->addConstraint(new Cascade());
339+
340+
$this->assertSame(CascadingStrategy::CASCADE, $metadata->getCascadingStrategy());
341+
$this->assertCount(4, $metadata->properties);
342+
$this->assertSame([
343+
'requiredChild',
344+
'optionalChild',
345+
'staticChild',
346+
'children',
347+
], $metadata->getConstrainedProperties());
348+
}
313349
}

src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Validator\Constraints\All;
1616
use Symfony\Component\Validator\Constraints\Callback;
17-
use Symfony\Component\Validator\Constraints\Cascade;
1817
use Symfony\Component\Validator\Constraints\Choice;
1918
use Symfony\Component\Validator\Constraints\Collection;
2019
use Symfony\Component\Validator\Constraints\IsTrue;
@@ -60,7 +59,6 @@ public function testLoadClassMetadata()
6059
$expected->addConstraint(new Callback('validateMe'));
6160
$expected->addConstraint(new Callback('validateMeStatic'));
6261
$expected->addConstraint(new Callback(['Symfony\Component\Validator\Tests\Fixtures\CallbackClass', 'callback']));
63-
$expected->addConstraint(new Cascade());
6462
$expected->addConstraint(new Traverse(false));
6563
$expected->addPropertyConstraint('firstName', new NotNull());
6664
$expected->addPropertyConstraint('firstName', new Range(['min' => 3]));

src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@
3131
<value>callback</value>
3232
</constraint>
3333

34-
<!-- Cascade -->
35-
<constraint name="Cascade" />
36-
3734
<!-- Traverse with boolean default option -->
3835
<constraint name="Traverse">
3936
false

src/Symfony/Component/Validator/Tests/Validator/AbstractTest.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,9 @@ public function testReferenceCascadeDisabledByDefault()
520520
$this->assertCount(0, $violations);
521521
}
522522

523+
/**
524+
* @requires PHP 7.4
525+
*/
523526
public function testReferenceCascadeEnabledIgnoresUntyped()
524527
{
525528
$entity = new Entity();
@@ -548,7 +551,7 @@ public function testReferenceCascadeEnabledIgnoresUntyped()
548551
public function testTypedReferenceCascadeEnabled()
549552
{
550553
$entity = new CascadingEntity();
551-
$entity->childOne = new CascadedChild();
554+
$entity->requiredChild = new CascadedChild();
552555

553556
$callback = function ($value, ExecutionContextInterface $context) {
554557
$context->buildViolation('Invalid child')

src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -168,51 +168,33 @@ public function testAllConstraintValidateAllGroupsForNestedConstraints()
168168
/**
169169
* @requires PHP 7.4
170170
*/
171-
public function testValidateDoNotCascadeNestedObjectsByDefault()
172-
{
173-
$this->metadataFactory->addMetadata(new ClassMetadata(CascadingEntity::class));
174-
$this->metadataFactory->addMetadata((new ClassMetadata(CascadedChild::class))
175-
->addPropertyConstraint('name', new NotNull())
176-
);
177-
178-
$entity = new CascadingEntity();
179-
$entity->childOne = new CascadedChild();
180-
CascadingEntity::$childTwo = new CascadedChild();
181-
182-
$violations = $this->validator->validate($entity);
183-
184-
$this->assertCount(0, $violations);
185-
186-
CascadingEntity::$childTwo = null;
187-
}
188-
189-
/**
190-
* @requires PHP 7.4
191-
*/
192-
public function testValidateDoNotCascadeNestedArrayByDefault()
171+
public function testValidateDoNotCascadeNestedObjectsAndArraysByDefault()
193172
{
194173
$this->metadataFactory->addMetadata(new ClassMetadata(CascadingEntity::class));
195174
$this->metadataFactory->addMetadata((new ClassMetadata(CascadedChild::class))
196175
->addPropertyConstraint('name', new NotNull())
197176
);
198177

199178
$entity = new CascadingEntity();
179+
$entity->requiredChild = new CascadedChild();
180+
$entity->optionalChild = new CascadedChild();
200181
$entity->children[] = new CascadedChild();
201-
$entity->children[] = new CascadedChild();
182+
CascadingEntity::$staticChild = new CascadedChild();
202183

203184
$violations = $this->validator->validate($entity);
204185

205186
$this->assertCount(0, $violations);
187+
188+
CascadingEntity::$staticChild = null;
206189
}
207190

208191
/**
209192
* @requires PHP 7.4
210193
*/
211-
public function testValidateCascadeNestedArrayByDefaultIfConstrained()
194+
public function testValidateTraverseNestedArrayByDefaultIfConstrainedWithoutCascading()
212195
{
213196
$this->metadataFactory->addMetadata((new ClassMetadata(CascadingEntity::class))
214197
->addPropertyConstraint('children', new All([
215-
new NotNull(),
216198
new Type(CascadedChild::class),
217199
]))
218200
);
@@ -222,6 +204,7 @@ public function testValidateCascadeNestedArrayByDefaultIfConstrained()
222204

223205
$entity = new CascadingEntity();
224206
$entity->children[] = new \stdClass();
207+
$entity->children[] = new CascadedChild();
225208

226209
$violations = $this->validator->validate($entity);
227210

@@ -235,24 +218,32 @@ public function testValidateCascadeNestedArrayByDefaultIfConstrained()
235218
public function testValidateCascadeWithValid()
236219
{
237220
$this->metadataFactory->addMetadata((new ClassMetadata(CascadingEntity::class))
238-
->addPropertyConstraint('childOne', new Valid())
239-
->addPropertyConstraint('childTwo', new Valid())
221+
->addPropertyConstraint('requiredChild', new Valid())
222+
->addPropertyConstraint('optionalChild', new Valid())
223+
->addPropertyConstraint('staticChild', new Valid())
224+
->addPropertyConstraint('children', new Valid())
240225
);
241226
$this->metadataFactory->addMetadata((new ClassMetadata(CascadedChild::class))
242227
->addPropertyConstraint('name', new NotNull())
243228
);
244229

245230
$entity = new CascadingEntity();
246-
$entity->childOne = new CascadedChild();
247-
CascadingEntity::$childTwo = new CascadedChild();
231+
$entity->requiredChild = new CascadedChild();
232+
$entity->children[] = new CascadedChild();
233+
$entity->children[] = null;
234+
CascadingEntity::$staticChild = new CascadedChild();
248235

249236
$violations = $this->validator->validate($entity);
250237

251-
$this->assertCount(2, $violations);
238+
$this->assertCount(3, $violations);
252239
$this->assertInstanceOf(NotNull::class, $violations->get(0)->getConstraint());
253240
$this->assertInstanceOf(NotNull::class, $violations->get(1)->getConstraint());
241+
$this->assertInstanceOf(NotNull::class, $violations->get(2)->getConstraint());
242+
$this->assertSame('requiredChild.name', $violations->get(0)->getPropertyPath());
243+
$this->assertSame('staticChild.name', $violations->get(1)->getPropertyPath());
244+
$this->assertSame('children[0].name', $violations->get(2)->getPropertyPath());
254245

255-
CascadingEntity::$childTwo = null;
246+
CascadingEntity::$staticChild = null;
256247
}
257248

258249
/**
@@ -268,15 +259,21 @@ public function testValidateWithExplicitCascade()
268259
);
269260

270261
$entity = new CascadingEntity();
271-
$entity->childOne = new CascadedChild();
272-
CascadingEntity::$childTwo = new CascadedChild();
262+
$entity->requiredChild = new CascadedChild();
263+
$entity->children[] = new CascadedChild();
264+
$entity->children[] = null;
265+
CascadingEntity::$staticChild = new CascadedChild();
273266

274267
$violations = $this->validator->validate($entity);
275268

276-
$this->assertCount(2, $violations);
269+
$this->assertCount(3, $violations);
277270
$this->assertInstanceOf(NotNull::class, $violations->get(0)->getConstraint());
278271
$this->assertInstanceOf(NotNull::class, $violations->get(1)->getConstraint());
272+
$this->assertInstanceOf(NotNull::class, $violations->get(2)->getConstraint());
273+
$this->assertSame('requiredChild.name', $violations->get(0)->getPropertyPath());
274+
$this->assertSame('staticChild.name', $violations->get(1)->getPropertyPath());
275+
$this->assertSame('children[0].name', $violations->get(2)->getPropertyPath());
279276

280-
CascadingEntity::$childTwo = null;
277+
CascadingEntity::$staticChild = null;
281278
}
282279
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy