[Validator] Refactored ValidatorTest and ValidationVisitorTest into an abstract validator test class
This commit is contained in:
parent
95f8e43205
commit
25cdc68d36
|
@ -60,6 +60,7 @@ Validator
|
|||
valid. This is the default behaviour.
|
||||
|
||||
Strict email validation has to be explicitly activated in the configuration file by adding
|
||||
|
||||
```
|
||||
framework:
|
||||
//...
|
||||
|
@ -68,7 +69,29 @@ Validator
|
|||
//...
|
||||
|
||||
```
|
||||
|
||||
Also you have to add to your composer.json:
|
||||
|
||||
```
|
||||
"egulias/email-validator": "1.1.*"
|
||||
```
|
||||
|
||||
* `ClassMetadata::getGroupSequence()` now returns `GroupSequence` instances
|
||||
instead of an array. The sequence implements `\Traversable`, `\ArrayAccess`
|
||||
and `\Countable`, so in most cases you should be fine. If you however use the
|
||||
sequence with PHP's `array_*()` functions, you should cast it to an array
|
||||
first using `iterator_to_array()`:
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
$sequence = $metadata->getGroupSequence();
|
||||
$result = array_map($callback, $sequence);
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
$sequence = iterator_to_array($metadata->getGroupSequence());
|
||||
$result = array_map($callback, $sequence);
|
||||
```
|
||||
|
|
|
@ -6,6 +6,8 @@ CHANGELOG
|
|||
|
||||
* deprecated `ApcCache` in favor of `DoctrineCache`
|
||||
* added `DoctrineCache` to adapt any Doctrine cache
|
||||
* `GroupSequence` now implements `ArrayAccess`, `Countable` and `Traversable`
|
||||
* changed `ClassMetadata::getGroupSequence()` to return a `GroupSequence` instance instead of an array
|
||||
|
||||
2.4.0
|
||||
-----
|
||||
|
|
|
@ -71,6 +71,6 @@ class Callback extends Constraint
|
|||
*/
|
||||
public function getTargets()
|
||||
{
|
||||
return self::CLASS_CONSTRAINT;
|
||||
return array(self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Symfony\Component\Validator\Constraints;
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
class GroupSequence
|
||||
class GroupSequence implements \ArrayAccess, \IteratorAggregate, \Countable
|
||||
{
|
||||
/**
|
||||
* The members of the sequence
|
||||
|
@ -30,6 +30,43 @@ class GroupSequence
|
|||
|
||||
public function __construct(array $groups)
|
||||
{
|
||||
$this->groups = $groups['value'];
|
||||
// Support for Doctrine annotations
|
||||
$this->groups = isset($groups['value']) ? $groups['value'] : $groups;
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->groups);
|
||||
}
|
||||
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->groups[$offset]);
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->groups[$offset];
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (null !== $offset) {
|
||||
$this->groups[$offset] = $value;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->groups[] = $value;
|
||||
}
|
||||
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->groups[$offset]);
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->groups);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Symfony\Component\Validator\Mapping;
|
||||
|
||||
use Symfony\Component\Validator\Constraints\GroupSequence;
|
||||
use Symfony\Component\Validator\ValidationVisitorInterface;
|
||||
use Symfony\Component\Validator\PropertyMetadataContainerInterface;
|
||||
use Symfony\Component\Validator\ClassBasedInterface;
|
||||
|
@ -330,27 +331,31 @@ class ClassMetadata extends ElementMetadata implements MetadataInterface, ClassB
|
|||
/**
|
||||
* Sets the default group sequence for this class.
|
||||
*
|
||||
* @param array $groups An array of group names
|
||||
* @param array $groupSequence An array of group names
|
||||
*
|
||||
* @return ClassMetadata
|
||||
*
|
||||
* @throws GroupDefinitionException
|
||||
*/
|
||||
public function setGroupSequence(array $groups)
|
||||
public function setGroupSequence($groupSequence)
|
||||
{
|
||||
if ($this->isGroupSequenceProvider()) {
|
||||
throw new GroupDefinitionException('Defining a static group sequence is not allowed with a group sequence provider');
|
||||
}
|
||||
|
||||
if (in_array(Constraint::DEFAULT_GROUP, $groups, true)) {
|
||||
if (is_array($groupSequence)) {
|
||||
$groupSequence = new GroupSequence($groupSequence);
|
||||
}
|
||||
|
||||
if (in_array(Constraint::DEFAULT_GROUP, $groupSequence->groups, true)) {
|
||||
throw new GroupDefinitionException(sprintf('The group "%s" is not allowed in group sequences', Constraint::DEFAULT_GROUP));
|
||||
}
|
||||
|
||||
if (!in_array($this->getDefaultGroup(), $groups, true)) {
|
||||
if (!in_array($this->getDefaultGroup(), $groupSequence->groups, true)) {
|
||||
throw new GroupDefinitionException(sprintf('The group "%s" is missing in the group sequence', $this->getDefaultGroup()));
|
||||
}
|
||||
|
||||
$this->groupSequence = $groups;
|
||||
$this->groupSequence = $groupSequence;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -368,7 +373,7 @@ class ClassMetadata extends ElementMetadata implements MetadataInterface, ClassB
|
|||
/**
|
||||
* Returns the default group sequence for this class.
|
||||
*
|
||||
* @return array An array of group names
|
||||
* @return GroupSequence The group sequence or null
|
||||
*/
|
||||
public function getGroupSequence()
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ExecutionContext;
|
||||
use Symfony\Component\Validator\Constraints\Callback;
|
||||
use Symfony\Component\Validator\Constraints\CallbackValidator;
|
||||
|
@ -320,8 +321,9 @@ class CallbackValidatorTest extends \PHPUnit_Framework_TestCase
|
|||
public function testConstraintGetTargets()
|
||||
{
|
||||
$constraint = new Callback(array('foo'));
|
||||
$targets = array(Constraint::CLASS_CONSTRAINT, Constraint::PROPERTY_CONSTRAINT);
|
||||
|
||||
$this->assertEquals('class', $constraint->getTargets());
|
||||
$this->assertEquals($targets, $constraint->getTargets());
|
||||
}
|
||||
|
||||
// Should succeed. Needed when defining constraints as annotations.
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
<?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\Tests\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraints\GroupSequence;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class GroupSequenceTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testCreate()
|
||||
{
|
||||
$sequence = new GroupSequence(array('Group 1', 'Group 2'));
|
||||
|
||||
$this->assertSame(array('Group 1', 'Group 2'), $sequence->groups);
|
||||
}
|
||||
|
||||
public function testCreateDoctrineStyle()
|
||||
{
|
||||
$sequence = new GroupSequence(array('value' => array('Group 1', 'Group 2')));
|
||||
|
||||
$this->assertSame(array('Group 1', 'Group 2'), $sequence->groups);
|
||||
}
|
||||
|
||||
public function testIterate()
|
||||
{
|
||||
$sequence = new GroupSequence(array('Group 1', 'Group 2'));
|
||||
|
||||
$this->assertSame(array('Group 1', 'Group 2'), iterator_to_array($sequence));
|
||||
}
|
||||
|
||||
public function testCount()
|
||||
{
|
||||
$sequence = new GroupSequence(array('Group 1', 'Group 2'));
|
||||
|
||||
$this->assertCount(2, $sequence);
|
||||
}
|
||||
|
||||
public function testArrayAccess()
|
||||
{
|
||||
$sequence = new GroupSequence(array('Group 1', 'Group 2'));
|
||||
|
||||
$this->assertSame('Group 1', $sequence[0]);
|
||||
$this->assertSame('Group 2', $sequence[1]);
|
||||
$this->assertTrue(isset($sequence[0]));
|
||||
$this->assertFalse(isset($sequence[2]));
|
||||
unset($sequence[0]);
|
||||
$this->assertFalse(isset($sequence[0]));
|
||||
$sequence[] = 'Group 3';
|
||||
$this->assertTrue(isset($sequence[2]));
|
||||
$this->assertSame('Group 3', $sequence[2]);
|
||||
$sequence[0] = 'Group 1';
|
||||
$this->assertTrue(isset($sequence[0]));
|
||||
$this->assertSame('Group 1', $sequence[0]);
|
||||
}
|
||||
}
|
|
@ -32,9 +32,10 @@ class Entity extends EntityParent implements EntityInterface
|
|||
* })
|
||||
* @Assert\Choice(choices={"A", "B"}, message="Must be one of %choices%")
|
||||
*/
|
||||
protected $firstName;
|
||||
public $firstName;
|
||||
protected $lastName;
|
||||
public $reference;
|
||||
public $reference2;
|
||||
private $internal;
|
||||
public $data = 'Overridden data';
|
||||
|
||||
|
@ -48,6 +49,11 @@ class Entity extends EntityParent implements EntityInterface
|
|||
return $this->internal.' from getter';
|
||||
}
|
||||
|
||||
public function setLastName($lastName)
|
||||
{
|
||||
$this->lastName = $lastName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Assert\NotNull
|
||||
*/
|
||||
|
|
|
@ -22,15 +22,15 @@ class GroupSequenceProviderEntity implements GroupSequenceProviderInterface
|
|||
public $firstName;
|
||||
public $lastName;
|
||||
|
||||
protected $groups = array();
|
||||
protected $sequence = array();
|
||||
|
||||
public function setGroups($groups)
|
||||
public function __construct($sequence)
|
||||
{
|
||||
$this->groups = $groups;
|
||||
$this->sequence = $sequence;
|
||||
}
|
||||
|
||||
public function getGroupSequence()
|
||||
{
|
||||
return $this->groups;
|
||||
return $this->sequence;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,4 +13,17 @@ namespace Symfony\Component\Validator\Tests\Fixtures;
|
|||
|
||||
class Reference
|
||||
{
|
||||
public $value;
|
||||
|
||||
private $privateValue;
|
||||
|
||||
public function setPrivateValue($privateValue)
|
||||
{
|
||||
$this->privateValue = $privateValue;
|
||||
}
|
||||
|
||||
public function getPrivateValue()
|
||||
{
|
||||
return $this->privateValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,564 +0,0 @@
|
|||
<?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\Tests;
|
||||
|
||||
use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
|
||||
use Symfony\Component\Validator\Constraints\Valid;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\Reference;
|
||||
use Symfony\Component\Validator\DefaultTranslator;
|
||||
use Symfony\Component\Validator\ConstraintViolation;
|
||||
use Symfony\Component\Validator\ConstraintViolationList;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\ConstraintAValidator;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\Entity;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
use Symfony\Component\Validator\ConstraintValidatorFactory;
|
||||
use Symfony\Component\Validator\ValidationVisitor;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class ValidationVisitorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
const CLASS_NAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
|
||||
|
||||
/**
|
||||
* @var ValidationVisitor
|
||||
*/
|
||||
private $visitor;
|
||||
|
||||
/**
|
||||
* @var FakeMetadataFactory
|
||||
*/
|
||||
private $metadataFactory;
|
||||
|
||||
/**
|
||||
* @var ClassMetadata
|
||||
*/
|
||||
private $metadata;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->metadataFactory = new FakeMetadataFactory();
|
||||
$this->visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator());
|
||||
$this->metadata = new ClassMetadata(self::CLASS_NAME);
|
||||
$this->metadataFactory->addMetadata($this->metadata);
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->metadataFactory = null;
|
||||
$this->visitor = null;
|
||||
$this->metadata = null;
|
||||
}
|
||||
|
||||
public function testValidatePassesCorrectClassAndProperty()
|
||||
{
|
||||
$this->metadata->addConstraint(new ConstraintA());
|
||||
|
||||
$entity = new Entity();
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
$context = ConstraintAValidator::$passedContext;
|
||||
|
||||
$this->assertEquals('Symfony\Component\Validator\Tests\Fixtures\Entity', $context->getClassName());
|
||||
$this->assertNull($context->getPropertyName());
|
||||
}
|
||||
|
||||
public function testValidateConstraints()
|
||||
{
|
||||
$this->metadata->addConstraint(new ConstraintA());
|
||||
|
||||
$this->visitor->validate(new Entity(), 'Default', '');
|
||||
|
||||
$this->assertCount(1, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateTwiceValidatesConstraintsOnce()
|
||||
{
|
||||
$this->metadata->addConstraint(new ConstraintA());
|
||||
|
||||
$entity = new Entity();
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
$this->assertCount(1, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateDifferentObjectsValidatesTwice()
|
||||
{
|
||||
$this->metadata->addConstraint(new ConstraintA());
|
||||
|
||||
$this->visitor->validate(new Entity(), 'Default', '');
|
||||
$this->visitor->validate(new Entity(), 'Default', '');
|
||||
|
||||
$this->assertCount(2, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateTwiceInDifferentGroupsValidatesTwice()
|
||||
{
|
||||
$this->metadata->addConstraint(new ConstraintA());
|
||||
$this->metadata->addConstraint(new ConstraintA(array('groups' => 'Custom')));
|
||||
|
||||
$entity = new Entity();
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
$this->visitor->validate($entity, 'Custom', '');
|
||||
|
||||
$this->assertCount(2, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidatePropertyConstraints()
|
||||
{
|
||||
$this->metadata->addPropertyConstraint('firstName', new ConstraintA());
|
||||
|
||||
$this->visitor->validate(new Entity(), 'Default', '');
|
||||
|
||||
$this->assertCount(1, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateGetterConstraints()
|
||||
{
|
||||
$this->metadata->addGetterConstraint('lastName', new ConstraintA());
|
||||
|
||||
$this->visitor->validate(new Entity(), 'Default', '');
|
||||
|
||||
$this->assertCount(1, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateInDefaultGroupTraversesGroupSequence()
|
||||
{
|
||||
$entity = new Entity();
|
||||
|
||||
$this->metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
|
||||
'groups' => 'First',
|
||||
)));
|
||||
$this->metadata->addGetterConstraint('lastName', new FailingConstraint(array(
|
||||
'groups' => 'Default',
|
||||
)));
|
||||
$this->metadata->setGroupSequence(array('First', $this->metadata->getDefaultGroup()));
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
// After validation of group "First" failed, no more group was
|
||||
// validated
|
||||
$violations = new ConstraintViolationList(array(
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'firstName',
|
||||
''
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateInGroupSequencePropagatesDefaultGroup()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = new Reference();
|
||||
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid());
|
||||
$this->metadata->setGroupSequence(array($this->metadata->getDefaultGroup()));
|
||||
|
||||
$referenceMetadata = new ClassMetadata(get_class($entity->reference));
|
||||
$referenceMetadata->addConstraint(new FailingConstraint(array(
|
||||
// this constraint is only evaluated if group "Default" is
|
||||
// propagated to the reference
|
||||
'groups' => 'Default',
|
||||
)));
|
||||
$this->metadataFactory->addMetadata($referenceMetadata);
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
// The validation of the reference's FailingConstraint in group
|
||||
// "Default" was launched
|
||||
$violations = new ConstraintViolationList(array(
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'reference',
|
||||
$entity->reference
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateInOtherGroupTraversesNoGroupSequence()
|
||||
{
|
||||
$entity = new Entity();
|
||||
|
||||
$this->metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
|
||||
'groups' => 'First',
|
||||
)));
|
||||
$this->metadata->addGetterConstraint('lastName', new FailingConstraint(array(
|
||||
'groups' => $this->metadata->getDefaultGroup(),
|
||||
)));
|
||||
$this->metadata->setGroupSequence(array('First', $this->metadata->getDefaultGroup()));
|
||||
|
||||
$this->visitor->validate($entity, $this->metadata->getDefaultGroup(), '');
|
||||
|
||||
// Only group "Second" was validated
|
||||
$violations = new ConstraintViolationList(array(
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'lastName',
|
||||
''
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateCascadedPropertyValidatesReferences()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = new Entity();
|
||||
|
||||
// add a constraint for the entity that always fails
|
||||
$this->metadata->addConstraint(new FailingConstraint());
|
||||
|
||||
// validate entity when validating the property "reference"
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid());
|
||||
|
||||
// invoke validation on an object
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
$violations = new ConstraintViolationList(array(
|
||||
// generated by the root object
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'',
|
||||
$entity
|
||||
),
|
||||
// generated by the reference
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'reference',
|
||||
$entity->reference
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateCascadedPropertyValidatesArraysByDefault()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = array('key' => new Entity());
|
||||
|
||||
// add a constraint for the entity that always fails
|
||||
$this->metadata->addConstraint(new FailingConstraint());
|
||||
|
||||
// validate array when validating the property "reference"
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid());
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
$violations = new ConstraintViolationList(array(
|
||||
// generated by the root object
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'',
|
||||
$entity
|
||||
),
|
||||
// generated by the reference
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'reference[key]',
|
||||
$entity->reference['key']
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateCascadedPropertyValidatesTraversableByDefault()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = new \ArrayIterator(array('key' => new Entity()));
|
||||
|
||||
// add a constraint for the entity that always fails
|
||||
$this->metadata->addConstraint(new FailingConstraint());
|
||||
|
||||
// validate array when validating the property "reference"
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid());
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
$violations = new ConstraintViolationList(array(
|
||||
// generated by the root object
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'',
|
||||
$entity
|
||||
),
|
||||
// generated by the reference
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'reference[key]',
|
||||
$entity->reference['key']
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateCascadedPropertyDoesNotValidateTraversableIfDisabled()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = new \ArrayIterator(array('key' => new Entity()));
|
||||
|
||||
$this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator'));
|
||||
|
||||
// add a constraint for the entity that always fails
|
||||
$this->metadata->addConstraint(new FailingConstraint());
|
||||
|
||||
// validate array when validating the property "reference"
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid(array(
|
||||
'traverse' => false,
|
||||
)));
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
$violations = new ConstraintViolationList(array(
|
||||
// generated by the root object
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'',
|
||||
$entity
|
||||
),
|
||||
// nothing generated by the reference!
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testMetadataMayNotExistIfTraversalIsEnabled()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = new \ArrayIterator();
|
||||
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid(array(
|
||||
'traverse' => true,
|
||||
)));
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException
|
||||
*/
|
||||
public function testMetadataMustExistIfTraversalIsDisabled()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = new \ArrayIterator();
|
||||
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid(array(
|
||||
'traverse' => false,
|
||||
)));
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
}
|
||||
|
||||
public function testValidateCascadedPropertyDoesNotRecurseByDefault()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = new \ArrayIterator(array(
|
||||
// The inner iterator should not be traversed by default
|
||||
'key' => new \ArrayIterator(array(
|
||||
'nested' => new Entity(),
|
||||
)),
|
||||
));
|
||||
|
||||
$this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator'));
|
||||
|
||||
// add a constraint for the entity that always fails
|
||||
$this->metadata->addConstraint(new FailingConstraint());
|
||||
|
||||
// validate iterator when validating the property "reference"
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid());
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
$violations = new ConstraintViolationList(array(
|
||||
// generated by the root object
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'',
|
||||
$entity
|
||||
),
|
||||
// nothing generated by the reference!
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
// https://github.com/symfony/symfony/issues/6246
|
||||
public function testValidateCascadedPropertyRecursesArraysByDefault()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = array(
|
||||
'key' => array(
|
||||
'nested' => new Entity(),
|
||||
),
|
||||
);
|
||||
|
||||
// add a constraint for the entity that always fails
|
||||
$this->metadata->addConstraint(new FailingConstraint());
|
||||
|
||||
// validate iterator when validating the property "reference"
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid());
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
$violations = new ConstraintViolationList(array(
|
||||
// generated by the root object
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'',
|
||||
$entity
|
||||
),
|
||||
// nothing generated by the reference!
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'reference[key][nested]',
|
||||
$entity->reference['key']['nested']
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateCascadedPropertyRecursesIfDeepIsSet()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = new \ArrayIterator(array(
|
||||
// The inner iterator should now be traversed
|
||||
'key' => new \ArrayIterator(array(
|
||||
'nested' => new Entity(),
|
||||
)),
|
||||
));
|
||||
|
||||
// add a constraint for the entity that always fails
|
||||
$this->metadata->addConstraint(new FailingConstraint());
|
||||
|
||||
// validate iterator when validating the property "reference"
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid(array(
|
||||
'deep' => true,
|
||||
)));
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
$violations = new ConstraintViolationList(array(
|
||||
// generated by the root object
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'',
|
||||
$entity
|
||||
),
|
||||
// nothing generated by the reference!
|
||||
new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Root',
|
||||
'reference[key][nested]',
|
||||
$entity->reference['key']['nested']
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateCascadedPropertyDoesNotValidateNestedScalarValues()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = array('scalar', 'values');
|
||||
|
||||
// validate array when validating the property "reference"
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid());
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
$this->assertCount(0, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
public function testValidateCascadedPropertyDoesNotValidateNullValues()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = null;
|
||||
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid());
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
|
||||
$this->assertCount(0, $this->visitor->getViolations());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException
|
||||
*/
|
||||
public function testValidateCascadedPropertyRequiresObjectOrArray()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$entity->reference = 'no object';
|
||||
|
||||
$this->metadata->addPropertyConstraint('reference', new Valid());
|
||||
|
||||
$this->visitor->validate($entity, 'Default', '');
|
||||
}
|
||||
}
|
|
@ -11,266 +11,15 @@
|
|||
|
||||
namespace Symfony\Component\Validator\Tests;
|
||||
|
||||
use Symfony\Component\Validator\Tests\Fixtures\Entity;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint;
|
||||
use Symfony\Component\Validator\MetadataFactoryInterface;
|
||||
use Symfony\Component\Validator\Validator;
|
||||
use Symfony\Component\Validator\DefaultTranslator;
|
||||
use Symfony\Component\Validator\ConstraintViolation;
|
||||
use Symfony\Component\Validator\ConstraintViolationList;
|
||||
use Symfony\Component\Validator\ConstraintValidatorFactory;
|
||||
use Symfony\Component\Validator\Constraints\Valid;
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||
|
||||
class ValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
class ValidatorTest extends AbstractValidatorTest
|
||||
{
|
||||
/**
|
||||
* @var FakeMetadataFactory
|
||||
*/
|
||||
private $metadataFactory;
|
||||
|
||||
/**
|
||||
* @var Validator
|
||||
*/
|
||||
private $validator;
|
||||
|
||||
protected function setUp()
|
||||
protected function createValidator(MetadataFactoryInterface $metadataFactory)
|
||||
{
|
||||
$this->metadataFactory = new FakeMetadataFactory();
|
||||
$this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator());
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->metadataFactory = null;
|
||||
$this->validator = null;
|
||||
}
|
||||
|
||||
public function testValidateDefaultGroup()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$metadata = new ClassMetadata(get_class($entity));
|
||||
$metadata->addPropertyConstraint('firstName', new FailingConstraint());
|
||||
$metadata->addPropertyConstraint('lastName', new FailingConstraint(array(
|
||||
'groups' => 'Custom',
|
||||
)));
|
||||
$this->metadataFactory->addMetadata($metadata);
|
||||
|
||||
// Only the constraint of group "Default" failed
|
||||
$violations = new ConstraintViolationList();
|
||||
$violations->add(new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
$entity,
|
||||
'firstName',
|
||||
''
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->validator->validate($entity));
|
||||
}
|
||||
|
||||
public function testValidateOneGroup()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$metadata = new ClassMetadata(get_class($entity));
|
||||
$metadata->addPropertyConstraint('firstName', new FailingConstraint());
|
||||
$metadata->addPropertyConstraint('lastName', new FailingConstraint(array(
|
||||
'groups' => 'Custom',
|
||||
)));
|
||||
$this->metadataFactory->addMetadata($metadata);
|
||||
|
||||
// Only the constraint of group "Custom" failed
|
||||
$violations = new ConstraintViolationList();
|
||||
$violations->add(new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
$entity,
|
||||
'lastName',
|
||||
''
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->validator->validate($entity, 'Custom'));
|
||||
}
|
||||
|
||||
public function testValidateMultipleGroups()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$metadata = new ClassMetadata(get_class($entity));
|
||||
$metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
|
||||
'groups' => 'First',
|
||||
)));
|
||||
$metadata->addPropertyConstraint('lastName', new FailingConstraint(array(
|
||||
'groups' => 'Second',
|
||||
)));
|
||||
$this->metadataFactory->addMetadata($metadata);
|
||||
|
||||
// The constraints of both groups failed
|
||||
$violations = new ConstraintViolationList();
|
||||
$violations->add(new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
$entity,
|
||||
'firstName',
|
||||
''
|
||||
));
|
||||
$violations->add(new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
$entity,
|
||||
'lastName',
|
||||
''
|
||||
));
|
||||
|
||||
$result = $this->validator->validate($entity, array('First', 'Second'));
|
||||
|
||||
$this->assertEquals($violations, $result);
|
||||
}
|
||||
|
||||
public function testValidateGroupSequenceProvider()
|
||||
{
|
||||
$entity = new GroupSequenceProviderEntity();
|
||||
$metadata = new ClassMetadata(get_class($entity));
|
||||
$metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
|
||||
'groups' => 'First',
|
||||
)));
|
||||
$metadata->addPropertyConstraint('lastName', new FailingConstraint(array(
|
||||
'groups' => 'Second',
|
||||
)));
|
||||
$metadata->setGroupSequenceProvider(true);
|
||||
$this->metadataFactory->addMetadata($metadata);
|
||||
|
||||
$violations = new ConstraintViolationList();
|
||||
$violations->add(new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
$entity,
|
||||
'firstName',
|
||||
''
|
||||
));
|
||||
|
||||
$entity->setGroups(array('First'));
|
||||
$result = $this->validator->validate($entity);
|
||||
$this->assertEquals($violations, $result);
|
||||
|
||||
$violations = new ConstraintViolationList();
|
||||
$violations->add(new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
$entity,
|
||||
'lastName',
|
||||
''
|
||||
));
|
||||
|
||||
$entity->setGroups(array('Second'));
|
||||
$result = $this->validator->validate($entity);
|
||||
$this->assertEquals($violations, $result);
|
||||
|
||||
$entity->setGroups(array());
|
||||
$result = $this->validator->validate($entity);
|
||||
$this->assertEquals(new ConstraintViolationList(), $result);
|
||||
}
|
||||
|
||||
public function testValidateProperty()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$metadata = new ClassMetadata(get_class($entity));
|
||||
$metadata->addPropertyConstraint('firstName', new FailingConstraint());
|
||||
$this->metadataFactory->addMetadata($metadata);
|
||||
|
||||
$result = $this->validator->validateProperty($entity, 'firstName');
|
||||
|
||||
$this->assertCount(1, $result);
|
||||
|
||||
$result = $this->validator->validateProperty($entity, 'lastName');
|
||||
|
||||
$this->assertCount(0, $result);
|
||||
}
|
||||
|
||||
public function testValidatePropertyValue()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$metadata = new ClassMetadata(get_class($entity));
|
||||
$metadata->addPropertyConstraint('firstName', new FailingConstraint());
|
||||
$this->metadataFactory->addMetadata($metadata);
|
||||
|
||||
$result = $this->validator->validatePropertyValue(get_class($entity), 'firstName', 'Bernhard');
|
||||
|
||||
$this->assertCount(1, $result);
|
||||
}
|
||||
|
||||
public function testValidateValue()
|
||||
{
|
||||
$violations = new ConstraintViolationList();
|
||||
$violations->add(new ConstraintViolation(
|
||||
'Failed',
|
||||
'Failed',
|
||||
array(),
|
||||
'Bernhard',
|
||||
'',
|
||||
'Bernhard'
|
||||
));
|
||||
|
||||
$this->assertEquals($violations, $this->validator->validateValue('Bernhard', new FailingConstraint()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\ValidatorException
|
||||
*/
|
||||
public function testValidateValueRejectsValid()
|
||||
{
|
||||
$entity = new Entity();
|
||||
$metadata = new ClassMetadata(get_class($entity));
|
||||
$this->metadataFactory->addMetadata($metadata);
|
||||
|
||||
$this->validator->validateValue($entity, new Valid());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\ValidatorException
|
||||
*/
|
||||
public function testValidatePropertyFailsIfPropertiesNotSupported()
|
||||
{
|
||||
// $metadata does not implement PropertyMetadataContainerInterface
|
||||
$metadata = $this->getMock('Symfony\Component\Validator\MetadataInterface');
|
||||
$this->metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
|
||||
$this->metadataFactory->expects($this->any())
|
||||
->method('getMetadataFor')
|
||||
->with('VALUE')
|
||||
->will($this->returnValue($metadata));
|
||||
$this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator());
|
||||
|
||||
$this->validator->validateProperty('VALUE', 'someProperty');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Validator\Exception\ValidatorException
|
||||
*/
|
||||
public function testValidatePropertyValueFailsIfPropertiesNotSupported()
|
||||
{
|
||||
// $metadata does not implement PropertyMetadataContainerInterface
|
||||
$metadata = $this->getMock('Symfony\Component\Validator\MetadataInterface');
|
||||
$this->metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
|
||||
$this->metadataFactory->expects($this->any())
|
||||
->method('getMetadataFor')
|
||||
->with('VALUE')
|
||||
->will($this->returnValue($metadata));
|
||||
$this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator());
|
||||
|
||||
$this->validator->validatePropertyValue('VALUE', 'someProperty', 'propertyValue');
|
||||
}
|
||||
|
||||
public function testGetMetadataFactory()
|
||||
{
|
||||
$this->assertInstanceOf(
|
||||
'Symfony\Component\Validator\MetadataFactoryInterface',
|
||||
$this->validator->getMetadataFactory()
|
||||
);
|
||||
return new Validator($metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator());
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue