From 1678a3dbdf09c4d5b41e2af627fbd09a1cee0148 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Sat, 28 Jan 2012 15:21:08 +0100 Subject: [PATCH 01/11] [Validator] Fixed: Validator::validateValue() propagates empty validation root instead of the provided value --- src/Symfony/Component/Validator/Validator.php | 2 +- .../Tests/Component/Validator/ValidatorTest.php | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Validator/Validator.php b/src/Symfony/Component/Validator/Validator.php index d20a623256..54ae2f9456 100644 --- a/src/Symfony/Component/Validator/Validator.php +++ b/src/Symfony/Component/Validator/Validator.php @@ -108,7 +108,7 @@ class Validator implements ValidatorInterface return $walker->walkConstraint($constraint, $value, $group, ''); }; - return $this->validateGraph($value, $walk, $groups); + return $this->validateGraph('', $walk, $groups); } protected function validateGraph($root, \Closure $walk, $groups = null) diff --git a/tests/Symfony/Tests/Component/Validator/ValidatorTest.php b/tests/Symfony/Tests/Component/Validator/ValidatorTest.php index 86c8ee98a6..c161a49970 100644 --- a/tests/Symfony/Tests/Component/Validator/ValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/ValidatorTest.php @@ -148,9 +148,16 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase public function testValidateValue() { - $result = $this->validator->validateValue('Bernhard', new FailingConstraint()); + $violations = new ConstraintViolationList(); + $violations->add(new ConstraintViolation( + '', + array(), + '', + '', + 'Bernhard' + )); - $this->assertCount(1, $result); + $this->assertEquals($violations, $this->validator->validateValue('Bernhard', new FailingConstraint())); } public function testGetMetadataFactory() From 1dd302cbea8c48ce38b1712a1c3271b1f9fdcd1e Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Sat, 28 Jan 2012 15:32:24 +0100 Subject: [PATCH 02/11] [Validator] Fixed ConstraintViolationList::__toString() to not include dots in the output if the root is empty --- .../Component/Validator/ConstraintViolationList.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Validator/ConstraintViolationList.php b/src/Symfony/Component/Validator/ConstraintViolationList.php index a66c6040c8..baeaef224b 100644 --- a/src/Symfony/Component/Validator/ConstraintViolationList.php +++ b/src/Symfony/Component/Validator/ConstraintViolationList.php @@ -29,9 +29,13 @@ class ConstraintViolationList implements \IteratorAggregate, \Countable, \ArrayA foreach ($this->violations as $violation) { $root = $violation->getRoot(); - $class = is_object($root) ? get_class($root) : $root; + $class = (string) (is_object($root) ? get_class($root) : $root); + $propertyPath = (string) $violation->getPropertyPath(); + if ('' !== $propertyPath && '[' !== $propertyPath{0} && '' !== $class) { + $class .= '.'; + } $string .= <<getPropertyPath()}: +{$class}{$propertyPath}: {$violation->getMessage()} EOF; From f904a9ed535b0f5536d5a92cd5772d35eb5cc088 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Mon, 30 Jan 2012 20:56:10 +0100 Subject: [PATCH 03/11] [Validator] Fixed: GraphWalker does not add constraint violation if error message is empty --- .../Validator/ConstraintValidator.php | 6 ++++- .../Validator/ConstraintViolationList.php | 21 +++++++++++++++++- .../Component/Validator/GraphWalker.php | 22 +++++++++++-------- .../Validator/ExecutionContextTest.php | 4 ++-- .../Validator/Fixtures/FailingConstraint.php | 2 +- .../Component/Validator/GraphWalkerTest.php | 12 +++++----- .../Component/Validator/ValidatorTest.php | 10 ++++----- 7 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/Symfony/Component/Validator/ConstraintValidator.php b/src/Symfony/Component/Validator/ConstraintValidator.php index 54dafd3be7..2abf92f9c1 100644 --- a/src/Symfony/Component/Validator/ConstraintValidator.php +++ b/src/Symfony/Component/Validator/ConstraintValidator.php @@ -11,7 +11,11 @@ namespace Symfony\Component\Validator; -/* +/** + * Base class for constraint validators + * + * @author Bernhard Schussek + * * @api */ abstract class ConstraintValidator implements ConstraintValidatorInterface diff --git a/src/Symfony/Component/Validator/ConstraintViolationList.php b/src/Symfony/Component/Validator/ConstraintViolationList.php index baeaef224b..808a69a182 100644 --- a/src/Symfony/Component/Validator/ConstraintViolationList.php +++ b/src/Symfony/Component/Validator/ConstraintViolationList.php @@ -12,14 +12,33 @@ namespace Symfony\Component\Validator; /** - * An array-acting object that holds many ConstrainViolation instances. + * An list of ConstrainViolation objects. + * + * @author Bernhard Schussek * * @api */ class ConstraintViolationList implements \IteratorAggregate, \Countable, \ArrayAccess { + /** + * The constraint violations + * + * @var array + */ protected $violations = array(); + /** + * Creates a new constraint violation list + * + * @param array $violations The constraint violations to add to the list + */ + public function __construct(array $violations = array()) + { + foreach ($violations as $violation) { + $this->add($violation); + } + } + /** * @return string */ diff --git a/src/Symfony/Component/Validator/GraphWalker.php b/src/Symfony/Component/Validator/GraphWalker.php index 0acd64d6cf..a88eb8b3a7 100644 --- a/src/Symfony/Component/Validator/GraphWalker.php +++ b/src/Symfony/Component/Validator/GraphWalker.php @@ -174,16 +174,20 @@ class GraphWalker $validator->initialize($this->context); if (!$validator->isValid($value, $constraint)) { - // Resetting the property path. This is needed because some - // validators, like CollectionValidator, use the walker internally - // and so change the context. - $this->context->setPropertyPath($propertyPath); + $messageTemplate = $validator->getMessageTemplate(); + $messageParams = $validator->getMessageParameters(); - $this->context->addViolation( - $validator->getMessageTemplate(), - $validator->getMessageParameters(), - $value - ); + // Somewhat ugly hack: Don't add a violation if no message is set. + // This is required if the validator added its violations directly + // to the context already + if (!empty($messageTemplate)) { + // Resetting the property path. This is needed because some + // validators, like CollectionValidator, use the walker internally + // and so change the context. + $this->context->setPropertyPath($propertyPath); + + $this->context->addViolation($messageTemplate, $messageParams, $value); + } } } } diff --git a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php index 1b47bdf268..a4410b0f0c 100644 --- a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php +++ b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php @@ -98,9 +98,9 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase $violations = $this->context->getViolations(); $expected = <<add(new ConstraintViolation( - '', + 'Failed', array(), 'Root', 'firstName', @@ -175,7 +175,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase // "Default" was launched $violations = new ConstraintViolationList(); $violations->add(new ConstraintViolation( - '', + 'Failed', array(), 'Root', 'reference', @@ -202,7 +202,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase // Only group "Second" was validated $violations = new ConstraintViolationList(); $violations->add(new ConstraintViolation( - '', + 'Failed', array(), 'Root', 'lastName', @@ -254,7 +254,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase $violations = new ConstraintViolationList(); $violations->add(new ConstraintViolation( - '', + 'Failed', array(), 'Root', 'path', @@ -286,7 +286,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase $violations = new ConstraintViolationList(); $violations->add(new ConstraintViolation( - '', + 'Failed', array(), 'Root', 'path[key]', @@ -319,7 +319,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase $violations = new ConstraintViolationList(); $violations->add(new ConstraintViolation( - '', + 'Failed', array(), 'Root', 'path[key]', diff --git a/tests/Symfony/Tests/Component/Validator/ValidatorTest.php b/tests/Symfony/Tests/Component/Validator/ValidatorTest.php index c161a49970..b07e596a10 100644 --- a/tests/Symfony/Tests/Component/Validator/ValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/ValidatorTest.php @@ -55,7 +55,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase // Only the constraint of group "Default" failed $violations = new ConstraintViolationList(); $violations->add(new ConstraintViolation( - '', + 'Failed', array(), $entity, 'firstName', @@ -78,7 +78,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase // Only the constraint of group "Custom" failed $violations = new ConstraintViolationList(); $violations->add(new ConstraintViolation( - '', + 'Failed', array(), $entity, 'lastName', @@ -103,14 +103,14 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase // The constraints of both groups failed $violations = new ConstraintViolationList(); $violations->add(new ConstraintViolation( - '', + 'Failed', array(), $entity, 'firstName', '' )); $violations->add(new ConstraintViolation( - '', + 'Failed', array(), $entity, 'lastName', @@ -150,7 +150,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase { $violations = new ConstraintViolationList(); $violations->add(new ConstraintViolation( - '', + 'Failed', array(), '', '', From a103c28b08e6a60c8e1fdb693976ede4c86f015a Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Mon, 30 Jan 2012 20:57:20 +0100 Subject: [PATCH 04/11] [Validator] The Collection constraint adds "missing" and "extra" errors to the individual fields now --- CHANGELOG-2.1.md | 4 ++ .../Validator/Constraints/Collection.php | 4 +- .../Constraints/CollectionValidator.php | 43 ++++++++----------- .../Constraints/CollectionValidatorTest.php | 27 +++++++++++- .../Component/Validator/GraphWalkerTest.php | 4 +- 5 files changed, 52 insertions(+), 30 deletions(-) diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md index f51c9827ea..a7082b195a 100644 --- a/CHANGELOG-2.1.md +++ b/CHANGELOG-2.1.md @@ -295,6 +295,10 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c * added a SizeLength validator * improved the ImageValidator with min width, max width, min height, and max height constraints * added support for MIME with wildcard in FileValidator + * changed Collection validator to add "missing" and "extra" errors to + individual fields + * changed default value for `extraFieldsMessage` and `missingFieldsMessage` + in Collection constraint ### Yaml diff --git a/src/Symfony/Component/Validator/Constraints/Collection.php b/src/Symfony/Component/Validator/Constraints/Collection.php index d4abc7a8fd..5740b98d34 100644 --- a/src/Symfony/Component/Validator/Constraints/Collection.php +++ b/src/Symfony/Component/Validator/Constraints/Collection.php @@ -23,8 +23,8 @@ class Collection extends Constraint public $fields; public $allowExtraFields = false; public $allowMissingFields = false; - public $extraFieldsMessage = 'The fields {{ fields }} were not expected'; - public $missingFieldsMessage = 'The fields {{ fields }} are missing'; + public $extraFieldsMessage = 'This field was not expected'; + public $missingFieldsMessage = 'This field is missing'; /** * {@inheritDoc} diff --git a/src/Symfony/Component/Validator/Constraints/CollectionValidator.php b/src/Symfony/Component/Validator/Constraints/CollectionValidator.php index f3dd7cbea3..8f6492952d 100644 --- a/src/Symfony/Component/Validator/Constraints/CollectionValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CollectionValidator.php @@ -46,12 +46,7 @@ class CollectionValidator extends ConstraintValidator $group = $this->context->getGroup(); $propertyPath = $this->context->getPropertyPath(); - $missingFields = array(); - $extraFields = array(); - - foreach ($value as $field => $fieldValue) { - $extraFields[$field] = $fieldValue; - } + $valid = true; foreach ($constraint->fields as $field => $fieldConstraint) { if ( @@ -72,29 +67,27 @@ class CollectionValidator extends ConstraintValidator foreach ($constraints as $constr) { $walker->walkConstraint($constr, $value[$field], $group, $propertyPath.'['.$field.']'); } - - unset($extraFields[$field]); - } elseif (!$fieldConstraint instanceof Optional) { - $missingFields[] = $field; + } elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) { + $this->context->setPropertyPath($propertyPath.'['.$field.']'); + $this->context->addViolation($constraint->missingFieldsMessage, array( + '{{ field }}' => '"'.$field.'"' + ), $value); + $valid = false; } } - if (count($extraFields) > 0 && !$constraint->allowExtraFields) { - $this->setMessage($constraint->extraFieldsMessage, array( - '{{ fields }}' => '"'.implode('", "', array_keys($extraFields)).'"' - )); - - return false; + if (!$constraint->allowExtraFields) { + foreach ($value as $field => $fieldValue) { + if (!isset($constraint->fields[$field])) { + $this->context->setPropertyPath($propertyPath.'['.$field.']'); + $this->context->addViolation($constraint->extraFieldsMessage, array( + '{{ field }}' => '"'.$field.'"' + ), $value); + $valid = false; + } + } } - if (count($missingFields) > 0 && !$constraint->allowMissingFields) { - $this->setMessage($constraint->missingFieldsMessage, array( - '{{ fields }}' => '"'.implode('", "', $missingFields).'"' - )); - - return false; - } - - return true; + return $valid; } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php index 19676fb07b..b9a50bf2da 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php @@ -11,6 +11,8 @@ namespace Symfony\Tests\Component\Validator\Constraints; +use Symfony\Component\Validator\ConstraintViolation; +use Symfony\Component\Validator\ConstraintViolationList; use Symfony\Component\Validator\ExecutionContext; use Symfony\Component\Validator\Constraints\Min; use Symfony\Component\Validator\Constraints\NotNull; @@ -125,9 +127,11 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testExtraFieldsDisallowed() { + $this->context->setPropertyPath('bar'); + $data = $this->prepareTestData(array( 'foo' => 5, - 'bar' => 6, + 'baz' => 6, )); $this->assertFalse($this->validator->isValid($data, new Collection(array( @@ -135,6 +139,16 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase 'foo' => new Min(4), ), )))); + + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'This field was not expected', + array('{{ field }}' => '"baz"'), + 'Root', + 'bar[baz]', + $data + ), + )), $this->context->getViolations()); } // bug fix @@ -170,6 +184,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testMissingFieldsDisallowed() { + $this->context->setPropertyPath('bar'); $data = $this->prepareTestData(array()); $this->assertFalse($this->validator->isValid($data, new Collection(array( @@ -177,6 +192,16 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase 'foo' => new Min(4), ), )))); + + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'This field is missing', + array('{{ field }}' => '"foo"'), + 'Root', + 'bar[foo]', + $data + ), + )), $this->context->getViolations()); } public function testMissingFieldsAllowed() diff --git a/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php b/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php index b2c590b020..61740ab6a4 100644 --- a/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php +++ b/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php @@ -441,7 +441,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase $this->walker->walkConstraint($constraint, array('foo' => 'VALID'), 'Default', 'collection'); $violations = $this->walker->getViolations(); - $this->assertEquals('collection', $violations[0]->getPropertyPath()); + $this->assertEquals('collection[bar]', $violations[0]->getPropertyPath()); } public function testWalkObjectUsesCorrectPropertyPathInViolationsWhenUsingNestedCollections() @@ -455,7 +455,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase $this->walker->walkConstraint($constraint, array('foo' => array('foo' => 'VALID')), 'Default', 'collection'); $violations = $this->walker->getViolations(); - $this->assertEquals('collection[foo]', $violations[0]->getPropertyPath()); + $this->assertEquals('collection[foo][bar]', $violations[0]->getPropertyPath()); } protected function getContext() From 1fc615cdcb44b4c99860f2bd58f9a2fe99e9874f Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Tue, 31 Jan 2012 07:39:54 +0100 Subject: [PATCH 05/11] Fixed string access by curly brace to bracket This seems to be the version officially favored by PHP: http://www.php.net/manual/en/language.types.string.php#language.types.string.substr --- src/Symfony/Component/Validator/ConstraintViolationList.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/ConstraintViolationList.php b/src/Symfony/Component/Validator/ConstraintViolationList.php index 808a69a182..55e5acbf1b 100644 --- a/src/Symfony/Component/Validator/ConstraintViolationList.php +++ b/src/Symfony/Component/Validator/ConstraintViolationList.php @@ -50,7 +50,7 @@ class ConstraintViolationList implements \IteratorAggregate, \Countable, \ArrayA $root = $violation->getRoot(); $class = (string) (is_object($root) ? get_class($root) : $root); $propertyPath = (string) $violation->getPropertyPath(); - if ('' !== $propertyPath && '[' !== $propertyPath{0} && '' !== $class) { + if ('' !== $propertyPath && '[' !== $propertyPath[0] && '' !== $class) { $class .= '.'; } $string .= << Date: Tue, 31 Jan 2012 07:45:20 +0100 Subject: [PATCH 06/11] [Form] Fixed typos --- src/Symfony/Component/Validator/ConstraintViolationList.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Validator/ConstraintViolationList.php b/src/Symfony/Component/Validator/ConstraintViolationList.php index 55e5acbf1b..6a0825390a 100644 --- a/src/Symfony/Component/Validator/ConstraintViolationList.php +++ b/src/Symfony/Component/Validator/ConstraintViolationList.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Validator; /** - * An list of ConstrainViolation objects. + * A list of ConstrainViolation objects. * * @author Bernhard Schussek * @@ -28,7 +28,7 @@ class ConstraintViolationList implements \IteratorAggregate, \Countable, \ArrayA protected $violations = array(); /** - * Creates a new constraint violation list + * Creates a new constraint violation list. * * @param array $violations The constraint violations to add to the list */ From fe85bbdb06fa1a9c7cd5c01ba5b28893b4ad0caa Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Tue, 31 Jan 2012 18:42:14 +0100 Subject: [PATCH 07/11] [Validator] Simplified ExecutionContext::addViolation(), added ExecutionContext::addViolationAt() --- .../Constraints/CollectionValidator.php | 10 +- .../Component/Validator/ExecutionContext.php | 32 ++++- .../Component/Validator/GraphWalker.php | 4 +- .../Constraints/CollectionValidatorTest.php | 12 +- .../Validator/ExecutionContextTest.php | 118 +++++++++++++++++- .../Component/Validator/GraphWalkerTest.php | 5 +- 6 files changed, 162 insertions(+), 19 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/CollectionValidator.php b/src/Symfony/Component/Validator/Constraints/CollectionValidator.php index 8f6492952d..2395fd23a7 100644 --- a/src/Symfony/Component/Validator/Constraints/CollectionValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CollectionValidator.php @@ -68,10 +68,9 @@ class CollectionValidator extends ConstraintValidator $walker->walkConstraint($constr, $value[$field], $group, $propertyPath.'['.$field.']'); } } elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) { - $this->context->setPropertyPath($propertyPath.'['.$field.']'); - $this->context->addViolation($constraint->missingFieldsMessage, array( + $this->context->addViolationAt($propertyPath.'['.$field.']', $constraint->missingFieldsMessage, array( '{{ field }}' => '"'.$field.'"' - ), $value); + ), null); $valid = false; } } @@ -79,10 +78,9 @@ class CollectionValidator extends ConstraintValidator if (!$constraint->allowExtraFields) { foreach ($value as $field => $fieldValue) { if (!isset($constraint->fields[$field])) { - $this->context->setPropertyPath($propertyPath.'['.$field.']'); - $this->context->addViolation($constraint->extraFieldsMessage, array( + $this->context->addViolationAt($propertyPath.'['.$field.']', $constraint->extraFieldsMessage, array( '{{ field }}' => '"'.$field.'"' - ), $value); + ), $fieldValue); $valid = false; } } diff --git a/src/Symfony/Component/Validator/ExecutionContext.php b/src/Symfony/Component/Validator/ExecutionContext.php index 5dd58790aa..87fb1c7f99 100644 --- a/src/Symfony/Component/Validator/ExecutionContext.php +++ b/src/Symfony/Component/Validator/ExecutionContext.php @@ -14,13 +14,13 @@ namespace Symfony\Component\Validator; use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface; /** - * The central object representing a single validation process. + * Stores the state of the current node in the validation graph. * * This object is used by the GraphWalker to initialize validation of different * items and keep track of the violations. * * @author Fabien Potencier - * @author Bernhard Schussek + * @author Bernhard Schussek * * @api */ @@ -30,6 +30,7 @@ class ExecutionContext protected $propertyPath; protected $class; protected $property; + protected $value; protected $group; protected $violations; protected $graphWalker; @@ -55,14 +56,27 @@ class ExecutionContext /** * @api */ - public function addViolation($message, array $params, $invalidValue) + public function addViolation($message, array $params = array(), $invalidValue = null) { $this->violations->add(new ConstraintViolation( $message, $params, $this->root, $this->propertyPath, - $invalidValue + // check using func_num_args() to allow passing null values + func_num_args() === 3 ? $invalidValue : $this->value + )); + } + + public function addViolationAt($propertyPath, $message, array $params = array(), $invalidValue = null) + { + $this->violations->add(new ConstraintViolation( + $message, + $params, + $this->root, + $propertyPath, + // check using func_num_args() to allow passing null values + func_num_args() === 4 ? $invalidValue : $this->value )); } @@ -111,6 +125,16 @@ class ExecutionContext return $this->property; } + public function setCurrentValue($value) + { + $this->value = $value; + } + + public function getCurrentValue() + { + return $this->value; + } + public function setGroup($group) { $this->group = $group; diff --git a/src/Symfony/Component/Validator/GraphWalker.php b/src/Symfony/Component/Validator/GraphWalker.php index a88eb8b3a7..7e9047e195 100644 --- a/src/Symfony/Component/Validator/GraphWalker.php +++ b/src/Symfony/Component/Validator/GraphWalker.php @@ -168,6 +168,7 @@ class GraphWalker { $validator = $this->validatorFactory->getInstance($constraint); + $this->context->setCurrentValue($value); $this->context->setPropertyPath($propertyPath); $this->context->setGroup($group); @@ -184,9 +185,10 @@ class GraphWalker // Resetting the property path. This is needed because some // validators, like CollectionValidator, use the walker internally // and so change the context. + $this->context->setCurrentValue($value); $this->context->setPropertyPath($propertyPath); - $this->context->addViolation($messageTemplate, $messageParams, $value); + $this->context->addViolation($messageTemplate, $messageParams); } } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php index b9a50bf2da..9898425b2f 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php @@ -127,13 +127,14 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testExtraFieldsDisallowed() { - $this->context->setPropertyPath('bar'); - $data = $this->prepareTestData(array( 'foo' => 5, 'baz' => 6, )); + $this->context->setCurrentValue($data); + $this->context->setPropertyPath('bar'); + $this->assertFalse($this->validator->isValid($data, new Collection(array( 'fields' => array( 'foo' => new Min(4), @@ -146,7 +147,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase array('{{ field }}' => '"baz"'), 'Root', 'bar[baz]', - $data + 6 ), )), $this->context->getViolations()); } @@ -184,8 +185,9 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testMissingFieldsDisallowed() { - $this->context->setPropertyPath('bar'); $data = $this->prepareTestData(array()); + $this->context->setCurrentValue($data); + $this->context->setPropertyPath('bar'); $this->assertFalse($this->validator->isValid($data, new Collection(array( 'fields' => array( @@ -199,7 +201,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase array('{{ field }}' => '"foo"'), 'Root', 'bar[foo]', - $data + null ), )), $this->context->getViolations()); } diff --git a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php index a4410b0f0c..fa30e76fe6 100644 --- a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php +++ b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php @@ -11,6 +11,10 @@ namespace Symfony\Tests\Component\Validator; +use Symfony\Component\Validator\ConstraintViolation; + +use Symfony\Component\Validator\ConstraintViolationList; + use Symfony\Component\Validator\ExecutionContext; class ExecutionContextTest extends \PHPUnit_Framework_TestCase @@ -43,9 +47,119 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase public function testAddViolation() { $this->assertCount(0, $this->context->getViolations()); - $this->context->addViolation('', array(), ''); - $this->assertCount(1, $this->context->getViolations()); + $this->context->setPropertyPath('foo.bar'); + $this->context->addViolation('Error', array('foo' => 'bar'), 'invalid'); + + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array('foo' => 'bar'), + 'Root', + 'foo.bar', + 'invalid' + ), + )), $this->context->getViolations()); + } + + public function testAddViolationUsesPreconfiguredValueIfNotPassed() + { + $this->assertCount(0, $this->context->getViolations()); + + $this->context->setPropertyPath('foo.bar'); + $this->context->setCurrentValue('invalid'); + $this->context->addViolation('Error'); + + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array(), + 'Root', + 'foo.bar', + 'invalid' + ), + )), $this->context->getViolations()); + } + + public function testAddViolationUsesPassedNulValue() + { + $this->assertCount(0, $this->context->getViolations()); + + $this->context->setPropertyPath('foo.bar'); + $this->context->setCurrentValue('invalid'); + + // passed null value should override preconfigured value "invalid" + $this->context->addViolation('Error', array('foo' => 'bar'), null); + + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array('foo' => 'bar'), + 'Root', + 'foo.bar', + null + ), + )), $this->context->getViolations()); + } + + public function testAddViolationAt() + { + $this->assertCount(0, $this->context->getViolations()); + + $this->context->setPropertyPath('foo.bar'); + + // override preconfigured property path + $this->context->addViolationAt('bar.baz', 'Error', array('foo' => 'bar'), 'invalid'); + + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array('foo' => 'bar'), + 'Root', + 'bar.baz', + 'invalid' + ), + )), $this->context->getViolations()); + } + + public function testAddViolationAtUsesPreconfiguredValueIfNotPassed() + { + $this->assertCount(0, $this->context->getViolations()); + + $this->context->setPropertyPath('foo.bar'); + $this->context->setCurrentValue('invalid'); + $this->context->addViolationAt('bar.baz', 'Error'); + + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array(), + 'Root', + 'bar.baz', + 'invalid' + ), + )), $this->context->getViolations()); + } + + public function testAddViolationAtUsesPassedNulValue() + { + $this->assertCount(0, $this->context->getViolations()); + + $this->context->setPropertyPath('foo.bar'); + $this->context->setCurrentValue('invalid'); + + // passed null value should override preconfigured value "invalid" + $this->context->addViolationAt('bar.baz', 'Error', array('foo' => 'bar'), null); + + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array('foo' => 'bar'), + 'Root', + 'bar.baz', + null + ), + )), $this->context->getViolations()); } public function testGetViolations() diff --git a/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php b/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php index 61740ab6a4..30d2f3dda9 100644 --- a/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php +++ b/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php @@ -58,9 +58,11 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase { $this->metadata->addConstraint(new ConstraintA()); - $this->walker->walkObject($this->metadata, new Entity(), 'Default', ''); + $entity = new Entity(); + $this->walker->walkObject($this->metadata, $entity, 'Default', ''); $this->assertEquals('Symfony\Tests\Component\Validator\Fixtures\Entity', $this->getContext()->getCurrentClass()); + $this->assertEquals($entity, $this->getContext()->getCurrentValue()); } public function testWalkObjectValidatesConstraints() @@ -220,6 +222,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase $this->assertEquals('Symfony\Tests\Component\Validator\Fixtures\Entity', $this->getContext()->getCurrentClass()); $this->assertEquals('firstName', $this->getContext()->getCurrentProperty()); + $this->assertEquals('value', $this->getContext()->getCurrentValue()); } public function testWalkPropertyValueValidatesConstraints() From a30a6791356099513fbda27ecd8a0c6ec5fc984f Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Tue, 31 Jan 2012 21:35:48 +0100 Subject: [PATCH 08/11] [Validator] Made ExecutionContext immutable and introduced new class GlobalExecutionContext A new ExecutionContext is now created everytime that GraphWalker::walkConstraint() is launched. Because of this, a validator B launched from within a validator A can't break A anymore by changing the context. Because we have a new ExecutionContext for every constraint validation, there is no point in modifying its state anymore. Because of this it is now immutable. --- CHANGELOG-2.1.md | 1 + .../Constraints/UniqueEntityValidator.php | 5 +- .../Validator/DelegatingValidator.php | 8 - .../Validator/ConstraintViolationList.php | 6 +- .../Constraints/CallbackValidator.php | 17 +- .../Constraints/CollectionValidator.php | 4 +- .../Component/Validator/ExecutionContext.php | 122 +++++----- .../Validator/GlobalExecutionContext.php | 80 +++++++ .../Component/Validator/GraphWalker.php | 51 ++--- .../Validator/DelegatingValidatorTest.php | 125 ++++------ .../Validator/ConstraintViolationListTest.php | 134 +++++++++++ .../Constraints/AllValidatorTest.php | 11 +- .../Constraints/CallbackValidatorTest.php | 31 +-- .../Constraints/ChoiceValidatorTest.php | 6 +- .../Constraints/CollectionValidatorTest.php | 34 +-- .../Validator/ExecutionContextTest.php | 214 ++++++++---------- .../Fixtures/ConstraintAValidator.php | 10 + .../Validator/GlobalExecutionContextTest.php | 63 ++++++ .../Component/Validator/GraphWalkerTest.php | 23 +- 19 files changed, 558 insertions(+), 387 deletions(-) create mode 100644 src/Symfony/Component/Validator/GlobalExecutionContext.php create mode 100644 tests/Symfony/Tests/Component/Validator/ConstraintViolationListTest.php create mode 100644 tests/Symfony/Tests/Component/Validator/GlobalExecutionContextTest.php diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md index a7082b195a..09d82ce62e 100644 --- a/CHANGELOG-2.1.md +++ b/CHANGELOG-2.1.md @@ -299,6 +299,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c individual fields * changed default value for `extraFieldsMessage` and `missingFieldsMessage` in Collection constraint + * made ExecutionContext immutable ### Yaml diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index 5b70d5927d..2dd1989440 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -102,10 +102,7 @@ class UniqueEntityValidator extends ConstraintValidator return true; } - $oldPath = $this->context->getPropertyPath(); - $this->context->setPropertyPath( empty($oldPath) ? $fields[0] : $oldPath.'.'.$fields[0]); - $this->context->addViolation($constraint->message, array(), $criteria[$fields[0]]); - $this->context->setPropertyPath($oldPath); + $this->context->addNestedViolationAt($fields[0], $constraint->message, array(), $criteria[$fields[0]]); return true; // all true, we added the violation already! } diff --git a/src/Symfony/Component/Form/Extension/Validator/Validator/DelegatingValidator.php b/src/Symfony/Component/Form/Extension/Validator/Validator/DelegatingValidator.php index 431205efc9..8717eb20b3 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Validator/DelegatingValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Validator/DelegatingValidator.php @@ -111,10 +111,6 @@ class DelegatingValidator implements FormValidatorInterface $propertyPath = $context->getPropertyPath(); $graphWalker = $context->getGraphWalker(); - // The Execute constraint is called on class level, so we need to - // set the property manually - $context->setCurrentProperty('data'); - // Adjust the property path accordingly if (!empty($propertyPath)) { $propertyPath .= '.'; @@ -134,10 +130,6 @@ class DelegatingValidator implements FormValidatorInterface $propertyPath = $context->getPropertyPath(); $graphWalker = $context->getGraphWalker(); - // The Execute constraint is called on class level, so we need to - // set the property manually - $context->setCurrentProperty('children'); - // Adjust the property path accordingly if (!empty($propertyPath)) { $propertyPath .= '.'; diff --git a/src/Symfony/Component/Validator/ConstraintViolationList.php b/src/Symfony/Component/Validator/ConstraintViolationList.php index 6a0825390a..96efce4e81 100644 --- a/src/Symfony/Component/Validator/ConstraintViolationList.php +++ b/src/Symfony/Component/Validator/ConstraintViolationList.php @@ -78,13 +78,13 @@ EOF; /** * Merge an existing ConstraintViolationList into this list. * - * @param ConstraintViolationList $violations + * @param ConstraintViolationList $otherList * * @api */ - public function addAll(ConstraintViolationList $violations) + public function addAll(ConstraintViolationList $otherList) { - foreach ($violations->violations as $violation) { + foreach ($otherList->violations as $violation) { $this->violations[] = $violation; } } diff --git a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php index a5df3d2e05..34104c0eac 100644 --- a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php @@ -48,13 +48,6 @@ class CallbackValidator extends ConstraintValidator } $methods = $constraint->methods; - $context = $this->context; - - // save context state - $currentClass = $context->getCurrentClass(); - $currentProperty = $context->getCurrentProperty(); - $group = $context->getGroup(); - $propertyPath = $context->getPropertyPath(); foreach ($methods as $method) { if (is_array($method) || $method instanceof \Closure) { @@ -62,20 +55,14 @@ class CallbackValidator extends ConstraintValidator throw new ConstraintDefinitionException(sprintf('"%s::%s" targeted by Callback constraint is not a valid callable', $method[0], $method[1])); } - call_user_func($method, $object, $context); + call_user_func($method, $object, $this->context); } else { if (!method_exists($object, $method)) { throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist', $method)); } - $object->$method($context); + $object->$method($this->context); } - - // restore context state - $context->setCurrentClass($currentClass); - $context->setCurrentProperty($currentProperty); - $context->setGroup($group); - $context->setPropertyPath($propertyPath); } return true; diff --git a/src/Symfony/Component/Validator/Constraints/CollectionValidator.php b/src/Symfony/Component/Validator/Constraints/CollectionValidator.php index 2395fd23a7..c380041ee6 100644 --- a/src/Symfony/Component/Validator/Constraints/CollectionValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CollectionValidator.php @@ -68,7 +68,7 @@ class CollectionValidator extends ConstraintValidator $walker->walkConstraint($constr, $value[$field], $group, $propertyPath.'['.$field.']'); } } elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) { - $this->context->addViolationAt($propertyPath.'['.$field.']', $constraint->missingFieldsMessage, array( + $this->context->addNestedViolationAt('['.$field.']', $constraint->missingFieldsMessage, array( '{{ field }}' => '"'.$field.'"' ), null); $valid = false; @@ -78,7 +78,7 @@ class CollectionValidator extends ConstraintValidator if (!$constraint->allowExtraFields) { foreach ($value as $field => $fieldValue) { if (!isset($constraint->fields[$field])) { - $this->context->addViolationAt($propertyPath.'['.$field.']', $constraint->extraFieldsMessage, array( + $this->context->addNestedViolationAt('['.$field.']', $constraint->extraFieldsMessage, array( '{{ field }}' => '"'.$field.'"' ), $fieldValue); $valid = false; diff --git a/src/Symfony/Component/Validator/ExecutionContext.php b/src/Symfony/Component/Validator/ExecutionContext.php index 87fb1c7f99..1118d9d90a 100644 --- a/src/Symfony/Component/Validator/ExecutionContext.php +++ b/src/Symfony/Component/Validator/ExecutionContext.php @@ -16,8 +16,10 @@ use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface; /** * Stores the state of the current node in the validation graph. * - * This object is used by the GraphWalker to initialize validation of different - * items and keep track of the violations. + * This class is immutable by design. + * + * It is used by the GraphWalker to initialize validation of different items + * and keep track of the violations. * * @author Fabien Potencier * @author Bernhard Schussek @@ -26,60 +28,97 @@ use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface; */ class ExecutionContext { - protected $root; - protected $propertyPath; - protected $class; - protected $property; - protected $value; - protected $group; - protected $violations; - protected $graphWalker; - protected $metadataFactory; + private $globalContext; + private $propertyPath; + private $value; + private $group; + private $class; + private $property; - public function __construct( - $root, - GraphWalker $graphWalker, - ClassMetadataFactoryInterface $metadataFactory - ) + public function __construct(GlobalExecutionContext $globalContext, $value, $propertyPath, $group, $class = null, $property = null) { - $this->root = $root; - $this->graphWalker = $graphWalker; - $this->metadataFactory = $metadataFactory; - $this->violations = new ConstraintViolationList(); + $this->globalContext = $globalContext; + $this->value = $value; + $this->propertyPath = $propertyPath; + $this->group = $group; + $this->class = $class; + $this->property = $property; } public function __clone() { - $this->violations = clone $this->violations; + $this->globalContext = clone $this->globalContext; } /** + * Adds a violation at the current node of the validation graph. + * + * @param string $message The error message. + * @param array $params The parameters parsed into the error message. + * @param mixed $invalidValue The invalid, validated value. + * * @api */ public function addViolation($message, array $params = array(), $invalidValue = null) { - $this->violations->add(new ConstraintViolation( + $this->globalContext->addViolation(new ConstraintViolation( $message, $params, - $this->root, + $this->globalContext->getRoot(), $this->propertyPath, // check using func_num_args() to allow passing null values func_num_args() === 3 ? $invalidValue : $this->value )); } + /** + * Adds a violation at the validation graph node with the given property + * path. + * + * @param string $propertyPath The property path for the violation. + * @param string $message The error message. + * @param array $params The parameters parsed into the error message. + * @param mixed $invalidValue The invalid, validated value. + */ public function addViolationAt($propertyPath, $message, array $params = array(), $invalidValue = null) { - $this->violations->add(new ConstraintViolation( + $this->globalContext->addViolation(new ConstraintViolation( $message, $params, - $this->root, + $this->globalContext->getRoot(), $propertyPath, // check using func_num_args() to allow passing null values func_num_args() === 4 ? $invalidValue : $this->value )); } + /** + * Adds a violation at the child of the current validation graph node with + * the given property path. + * + * @param string $childPropertyPath The property path of the child node. + * @param string $message The error message. + * @param array $params The parameters parsed into the error message. + * @param mixed $invalidValue The invalid, validated value. + */ + public function addNestedViolationAt($childPropertyPath, $message, array $params = array(), $invalidValue = null) + { + $propertyPath = $this->propertyPath; + + if ('' !== $propertyPath && '' !== $childPropertyPath && '[' !== $childPropertyPath[0]) { + $propertyPath .= '.'; + } + + $this->globalContext->addViolation(new ConstraintViolation( + $message, + $params, + $this->globalContext->getRoot(), + $propertyPath . $childPropertyPath, + // check using func_num_args() to allow passing null values + func_num_args() === 4 ? $invalidValue : $this->value + )); + } + /** * @return ConstraintViolationList * @@ -87,17 +126,12 @@ class ExecutionContext */ public function getViolations() { - return $this->violations; + return $this->globalContext->getViolations(); } public function getRoot() { - return $this->root; - } - - public function setPropertyPath($propertyPath) - { - $this->propertyPath = $propertyPath; + return $this->globalContext->getRoot(); } public function getPropertyPath() @@ -105,41 +139,21 @@ class ExecutionContext return $this->propertyPath; } - public function setCurrentClass($class) - { - $this->class = $class; - } - public function getCurrentClass() { return $this->class; } - public function setCurrentProperty($property) - { - $this->property = $property; - } - public function getCurrentProperty() { return $this->property; } - public function setCurrentValue($value) - { - $this->value = $value; - } - public function getCurrentValue() { return $this->value; } - public function setGroup($group) - { - $this->group = $group; - } - public function getGroup() { return $this->group; @@ -150,7 +164,7 @@ class ExecutionContext */ public function getGraphWalker() { - return $this->graphWalker; + return $this->globalContext->getGraphWalker(); } /** @@ -158,6 +172,6 @@ class ExecutionContext */ public function getMetadataFactory() { - return $this->metadataFactory; + return $this->globalContext->getMetadataFactory(); } } diff --git a/src/Symfony/Component/Validator/GlobalExecutionContext.php b/src/Symfony/Component/Validator/GlobalExecutionContext.php new file mode 100644 index 0000000000..36f71fdf7f --- /dev/null +++ b/src/Symfony/Component/Validator/GlobalExecutionContext.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface; + +/** + * Stores the node-independent information of a validation run. + * + * This class is immutable by design, except for violation tracking. + * + * @author Bernhard Schussek + */ +class GlobalExecutionContext +{ + private $root; + private $graphWalker; + private $metadataFactory; + private $violations; + + public function __construct( + $root, + GraphWalker $graphWalker, + ClassMetadataFactoryInterface $metadataFactory + ) + { + $this->root = $root; + $this->graphWalker = $graphWalker; + $this->metadataFactory = $metadataFactory; + $this->violations = new ConstraintViolationList(); + } + + public function __clone() + { + $this->violations = clone $this->violations; + } + + public function addViolation(ConstraintViolation $violation) + { + $this->violations->add($violation); + } + + /** + * @return ConstraintViolationList + */ + public function getViolations() + { + return $this->violations; + } + + public function getRoot() + { + return $this->root; + } + + /** + * @return GraphWalker + */ + public function getGraphWalker() + { + return $this->graphWalker; + } + + /** + * @return ClassMetadataFactoryInterface + */ + public function getMetadataFactory() + { + return $this->metadataFactory; + } +} \ No newline at end of file diff --git a/src/Symfony/Component/Validator/GraphWalker.php b/src/Symfony/Component/Validator/GraphWalker.php index 7e9047e195..da6e5a0aea 100644 --- a/src/Symfony/Component/Validator/GraphWalker.php +++ b/src/Symfony/Component/Validator/GraphWalker.php @@ -27,15 +27,15 @@ use Symfony\Component\Validator\Mapping\MemberMetadata; */ class GraphWalker { - protected $context; - protected $validatorFactory; - protected $metadataFactory; - protected $validatorInitializers = array(); - protected $validatedObjects = array(); + private $globalContext; + private $validatorFactory; + private $metadataFactory; + private $validatorInitializers = array(); + private $validatedObjects = array(); public function __construct($root, ClassMetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $factory, array $validatorInitializers = array()) { - $this->context = new ExecutionContext($root, $this, $metadataFactory); + $this->globalContext = new GlobalExecutionContext($root, $this, $metadataFactory); $this->validatorFactory = $factory; $this->metadataFactory = $metadataFactory; $this->validatorInitializers = $validatorInitializers; @@ -46,7 +46,7 @@ class GraphWalker */ public function getViolations() { - return $this->context->getViolations(); + return $this->globalContext->getViolations(); } /** @@ -67,8 +67,6 @@ class GraphWalker $initializer->initialize($object); } - $this->context->setCurrentClass($metadata->getClassName()); - if ($group === Constraint::DEFAULT_GROUP && $metadata->hasGroupSequence()) { $groups = $metadata->getGroupSequence(); foreach ($groups as $group) { @@ -100,8 +98,10 @@ class GraphWalker // traversing the object graph $this->validatedObjects[$hash][$group] = true; + $currentClass = $metadata->getClassName(); + foreach ($metadata->findConstraints($group) as $constraint) { - $this->walkConstraint($constraint, $object, $group, $propertyPath); + $this->walkConstraint($constraint, $object, $group, $propertyPath, $currentClass); } if (null !== $object) { @@ -129,11 +129,11 @@ class GraphWalker protected function walkMember(MemberMetadata $metadata, $value, $group, $propertyPath, $propagatedGroup = null) { - $this->context->setCurrentClass($metadata->getClassName()); - $this->context->setCurrentProperty($metadata->getPropertyName()); + $currentClass = $metadata->getClassName(); + $currentProperty = $metadata->getPropertyName(); foreach ($metadata->findConstraints($group) as $constraint) { - $this->walkConstraint($constraint, $value, $group, $propertyPath); + $this->walkConstraint($constraint, $value, $group, $propertyPath, $currentClass, $currentProperty); } if ($metadata->isCascaded()) { @@ -164,15 +164,20 @@ class GraphWalker } } - public function walkConstraint(Constraint $constraint, $value, $group, $propertyPath) + public function walkConstraint(Constraint $constraint, $value, $group, $propertyPath, $currentClass = null, $currentProperty = null) { $validator = $this->validatorFactory->getInstance($constraint); - $this->context->setCurrentValue($value); - $this->context->setPropertyPath($propertyPath); - $this->context->setGroup($group); + $localContext = new ExecutionContext( + $this->globalContext, + $value, + $propertyPath, + $group, + $currentClass, + $currentProperty + ); - $validator->initialize($this->context); + $validator->initialize($localContext); if (!$validator->isValid($value, $constraint)) { $messageTemplate = $validator->getMessageTemplate(); @@ -180,15 +185,9 @@ class GraphWalker // Somewhat ugly hack: Don't add a violation if no message is set. // This is required if the validator added its violations directly - // to the context already + // to the globalContext already if (!empty($messageTemplate)) { - // Resetting the property path. This is needed because some - // validators, like CollectionValidator, use the walker internally - // and so change the context. - $this->context->setCurrentValue($value); - $this->context->setPropertyPath($propertyPath); - - $this->context->addViolation($messageTemplate, $messageParams); + $localContext->addViolation($messageTemplate, $messageParams); } } } diff --git a/tests/Symfony/Tests/Component/Form/Extension/Validator/Validator/DelegatingValidatorTest.php b/tests/Symfony/Tests/Component/Form/Extension/Validator/Validator/DelegatingValidatorTest.php index e1081a2863..27fc1cb27d 100644 --- a/tests/Symfony/Tests/Component/Form/Extension/Validator/Validator/DelegatingValidatorTest.php +++ b/tests/Symfony/Tests/Component/Form/Extension/Validator/Validator/DelegatingValidatorTest.php @@ -11,6 +11,8 @@ namespace Symfony\Tests\Component\Form\Extension\Validator\Validator; +use Symfony\Component\Validator\GlobalExecutionContext; + use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormBuilder; use Symfony\Component\Form\FormError; @@ -63,6 +65,15 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase return $this->getMock('Symfony\Component\Form\DataTransformerInterface', array(), array(), '', false, false); } + protected function getExecutionContext($propertyPath = null) + { + $graphWalker = $this->getMockGraphWalker(); + $metadataFactory = $this->getMockMetadataFactory(); + $globalContext = new GlobalExecutionContext('Root', $graphWalker, $metadataFactory); + + return new ExecutionContext($globalContext, null, $propertyPath, null, null, null); + } + protected function getConstraintViolation($propertyPath) { return new ConstraintViolation($this->message, $this->params, null, $propertyPath, null); @@ -589,9 +600,8 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase public function testValidateFormData() { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); + $context = $this->getExecutionContext(); + $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); $form = $this->getBuilder() ->setAttribute('validation_groups', array('group1', 'group2')) @@ -611,9 +621,8 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase public function testValidateFormDataCanHandleCallbackValidationGroups() { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); + $context = $this->getExecutionContext(); + $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); $form = $this->getBuilder() ->setAttribute('validation_groups', array($this, 'getValidationGroups')) @@ -633,9 +642,8 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase public function testValidateFormDataCanHandleClosureValidationGroups() { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); + $context = $this->getExecutionContext(); + $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); $form = $this->getBuilder() ->setAttribute('validation_groups', function(FormInterface $form){ @@ -657,10 +665,8 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase public function testValidateFormDataUsesInheritedValidationGroup() { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); - $context->setPropertyPath('path'); + $context = $this->getExecutionContext('foo.bar'); + $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); $parent = $this->getBuilder() @@ -675,17 +681,15 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase $graphWalker->expects($this->once()) ->method('walkReference') - ->with($object, 'group', 'path.data', true); + ->with($object, 'group', 'foo.bar.data', true); DelegatingValidator::validateFormData($child, $context); } public function testValidateFormDataUsesInheritedCallbackValidationGroup() { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); - $context->setPropertyPath('path'); + $context = $this->getExecutionContext('foo.bar'); + $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); $parent = $this->getBuilder() @@ -700,20 +704,18 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase $graphWalker->expects($this->at(0)) ->method('walkReference') - ->with($object, 'group1', 'path.data', true); + ->with($object, 'group1', 'foo.bar.data', true); $graphWalker->expects($this->at(1)) ->method('walkReference') - ->with($object, 'group2', 'path.data', true); + ->with($object, 'group2', 'foo.bar.data', true); DelegatingValidator::validateFormData($child, $context); } public function testValidateFormDataUsesInheritedClosureValidationGroup() { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); - $context->setPropertyPath('path'); + $context = $this->getExecutionContext('foo.bar'); + $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); $parent = $this->getBuilder() @@ -730,46 +732,24 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase $graphWalker->expects($this->at(0)) ->method('walkReference') - ->with($object, 'group1', 'path.data', true); + ->with($object, 'group1', 'foo.bar.data', true); $graphWalker->expects($this->at(1)) ->method('walkReference') - ->with($object, 'group2', 'path.data', true); + ->with($object, 'group2', 'foo.bar.data', true); DelegatingValidator::validateFormData($child, $context); } public function testValidateFormDataAppendsPropertyPath() { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); - $context->setPropertyPath('path'); + $context = $this->getExecutionContext('foo.bar'); + $graphWalker = $context->getGraphWalker(); $object = $this->getMock('\stdClass'); $form = $this->getForm(); $graphWalker->expects($this->once()) ->method('walkReference') - ->with($object, 'Default', 'path.data', true); - - $form->setData($object); - - DelegatingValidator::validateFormData($form, $context); - } - - public function testValidateFormDataSetsCurrentPropertyToData() - { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); - $object = $this->getMock('\stdClass'); - $form = $this->getForm(); - $test = $this; - - $graphWalker->expects($this->once()) - ->method('walkReference') - ->will($this->returnCallback(function () use ($context, $test) { - $test->assertEquals('data', $context->getCurrentProperty()); - })); + ->with($object, 'Default', 'foo.bar.data', true); $form->setData($object); @@ -778,9 +758,8 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase public function testValidateFormDataDoesNotWalkScalars() { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); + $context = $this->getExecutionContext(); + $graphWalker = $context->getGraphWalker(); $clientTransformer = $this->getMockTransformer(); $form = $this->getBuilder() @@ -801,9 +780,8 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase public function testValidateFormChildren() { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); + $context = $this->getExecutionContext(); + $graphWalker = $context->getGraphWalker(); $form = $this->getBuilder() ->setAttribute('cascade_validation', true) ->setAttribute('validation_groups', array('group1', 'group2')) @@ -821,10 +799,8 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase public function testValidateFormChildrenAppendsPropertyPath() { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); - $context->setPropertyPath('path'); + $context = $this->getExecutionContext('foo.bar'); + $graphWalker = $context->getGraphWalker(); $form = $this->getBuilder() ->setAttribute('cascade_validation', true) ->getForm(); @@ -832,36 +808,15 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase $graphWalker->expects($this->once()) ->method('walkReference') - ->with($form->getChildren(), 'Default', 'path.children', true); - - DelegatingValidator::validateFormChildren($form, $context); - } - - public function testValidateFormChildrenSetsCurrentPropertyToData() - { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); - $form = $this->getBuilder() - ->setAttribute('cascade_validation', true) - ->getForm(); - $form->add($this->getForm('firstName')); - $test = $this; - - $graphWalker->expects($this->once()) - ->method('walkReference') - ->will($this->returnCallback(function () use ($context, $test) { - $test->assertEquals('children', $context->getCurrentProperty()); - })); + ->with($form->getChildren(), 'Default', 'foo.bar.children', true); DelegatingValidator::validateFormChildren($form, $context); } public function testValidateFormChildrenDoesNothingIfDisabled() { - $graphWalker = $this->getMockGraphWalker(); - $metadataFactory = $this->getMockMetadataFactory(); - $context = new ExecutionContext('Root', $graphWalker, $metadataFactory); + $context = $this->getExecutionContext(); + $graphWalker = $context->getGraphWalker(); $form = $this->getBuilder() ->setAttribute('cascade_validation', false) ->getForm(); diff --git a/tests/Symfony/Tests/Component/Validator/ConstraintViolationListTest.php b/tests/Symfony/Tests/Component/Validator/ConstraintViolationListTest.php new file mode 100644 index 0000000000..37c376fb83 --- /dev/null +++ b/tests/Symfony/Tests/Component/Validator/ConstraintViolationListTest.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Validator; + +use Symfony\Component\Validator\ConstraintViolation; +use Symfony\Component\Validator\ConstraintViolationList; + +class ConstraintViolationListTest extends \PHPUnit_Framework_TestCase +{ + protected $list; + + protected function setUp() + { + $this->list = new ConstraintViolationList(); + } + + protected function tearDown() + { + $this->list = null; + } + + public function testInit() + { + $this->assertCount(0, $this->list); + } + + public function testInitWithViolations() + { + $violation = $this->getViolation('Error'); + $this->list = new ConstraintViolationList(array($violation)); + + $this->assertCount(1, $this->list); + $this->assertSame($violation, $this->list[0]); + } + + public function testAdd() + { + $violation = $this->getViolation('Error'); + $this->list->add($violation); + + $this->assertCount(1, $this->list); + $this->assertSame($violation, $this->list[0]); + } + + public function testAddAll() + { + $violations = array( + 10 => $this->getViolation('Error 1'), + 20 => $this->getViolation('Error 2'), + 30 => $this->getViolation('Error 3'), + ); + $otherList = new ConstraintViolationList($violations); + $this->list->addAll($otherList); + + $this->assertCount(3, $this->list); + + $this->assertSame($violations[10], $this->list[0]); + $this->assertSame($violations[20], $this->list[1]); + $this->assertSame($violations[30], $this->list[2]); + } + + public function testIterator() + { + $violations = array( + 10 => $this->getViolation('Error 1'), + 20 => $this->getViolation('Error 2'), + 30 => $this->getViolation('Error 3'), + ); + + $this->list = new ConstraintViolationList($violations); + + // indices are reset upon adding -> array_values() + $this->assertSame(array_values($violations), iterator_to_array($this->list)); + } + + public function testArrayAccess() + { + $violation = $this->getViolation('Error'); + $this->list[] = $violation; + + $this->assertSame($violation, $this->list[0]); + $this->assertTrue(isset($this->list[0])); + + unset($this->list[0]); + + $this->assertFalse(isset($this->list[0])); + + $this->list[10] = $violation; + + $this->assertSame($violation, $this->list[10]); + $this->assertTrue(isset($this->list[10])); + } + + public function testToString() + { + $this->list = new ConstraintViolationList(array( + $this->getViolation('Error 1', 'Root'), + $this->getViolation('Error 2', 'Root', 'foo.bar'), + $this->getViolation('Error 3', 'Root', '[baz]'), + $this->getViolation('Error 4', '', 'foo.bar'), + $this->getViolation('Error 5', '', '[baz]'), + )); + + $expected = <<assertEquals($expected, (string) $this->list); + } + + protected function getViolation($message, $root = null, $propertyPath = null) + { + return new ConstraintViolation($message, array(), $root, $propertyPath, null); + } +} diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/AllValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/AllValidatorTest.php index 2842f298a5..0649833574 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/AllValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/AllValidatorTest.php @@ -11,6 +11,8 @@ namespace Symfony\Tests\Component\Validator\Constraints; +use Symfony\Component\Validator\GlobalExecutionContext; + use Symfony\Component\Validator\ExecutionContext; use Symfony\Component\Validator\Constraints\Min; use Symfony\Component\Validator\Constraints\All; @@ -26,8 +28,9 @@ class AllValidatorTest extends \PHPUnit_Framework_TestCase { $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); $metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); + $globalContext = new GlobalExecutionContext('Root', $this->walker, $metadataFactory); - $this->context = new ExecutionContext('Root', $this->walker, $metadataFactory); + $this->context = new ExecutionContext($globalContext, null, 'foo', 'MyGroup', null, null); $this->validator = new AllValidator(); $this->validator->initialize($this->context); @@ -57,9 +60,6 @@ class AllValidatorTest extends \PHPUnit_Framework_TestCase */ public function testWalkSingleConstraint($array) { - $this->context->setGroup('MyGroup'); - $this->context->setPropertyPath('foo'); - $constraint = new Min(4); foreach ($array as $key => $value) { @@ -76,9 +76,6 @@ class AllValidatorTest extends \PHPUnit_Framework_TestCase */ public function testWalkMultipleConstraints($array) { - $this->context->setGroup('MyGroup'); - $this->context->setPropertyPath('foo'); - $constraint = new Min(4); // can only test for twice the same constraint because PHPUnits mocking // can't test method calls with different arguments diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/CallbackValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/CallbackValidatorTest.php index 496fb84b11..d8822e5dc5 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/CallbackValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/CallbackValidatorTest.php @@ -11,6 +11,7 @@ namespace Symfony\Tests\Component\Validator\Constraints; +use Symfony\Component\Validator\GlobalExecutionContext; use Symfony\Component\Validator\ExecutionContext; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; @@ -21,11 +22,6 @@ class CallbackValidatorTest_Class { public static function validateStatic($object, ExecutionContext $context) { - $context->setCurrentClass('Foo'); - $context->setCurrentProperty('bar'); - $context->setGroup('mygroup'); - $context->setPropertyPath('foo.bar'); - $context->addViolation('Static message', array('parameter'), 'invalidValue'); } } @@ -34,11 +30,6 @@ class CallbackValidatorTest_Object { public function validateOne(ExecutionContext $context) { - $context->setCurrentClass('Foo'); - $context->setCurrentProperty('bar'); - $context->setGroup('mygroup'); - $context->setPropertyPath('foo.bar'); - $context->addViolation('My message', array('parameter'), 'invalidValue'); } @@ -58,13 +49,9 @@ class CallbackValidatorTest extends \PHPUnit_Framework_TestCase { $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); $metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); + $globalContext = new GlobalExecutionContext('Root', $this->walker, $metadataFactory); - $this->context = new ExecutionContext('Root', $this->walker, $metadataFactory); - $this->context->setCurrentClass('InitialClass'); - $this->context->setCurrentProperty('initialProperty'); - $this->context->setGroup('InitialGroup'); - $this->context->setPropertyPath('initial.property.path'); - + $this->context = new ExecutionContext($globalContext, 'value', 'foo.bar', 'Group', 'ClassName', 'propertyName'); $this->validator = new CallbackValidator(); $this->validator->initialize($this->context); } @@ -97,10 +84,6 @@ class CallbackValidatorTest extends \PHPUnit_Framework_TestCase )); $this->assertEquals($violations, $this->context->getViolations()); - $this->assertEquals('InitialClass', $this->context->getCurrentClass()); - $this->assertEquals('initialProperty', $this->context->getCurrentProperty()); - $this->assertEquals('InitialGroup', $this->context->getGroup()); - $this->assertEquals('initial.property.path', $this->context->getPropertyPath()); } public function testCallbackSingleStaticMethod() @@ -121,10 +104,6 @@ class CallbackValidatorTest extends \PHPUnit_Framework_TestCase )); $this->assertEquals($violations, $this->context->getViolations()); - $this->assertEquals('InitialClass', $this->context->getCurrentClass()); - $this->assertEquals('initialProperty', $this->context->getCurrentProperty()); - $this->assertEquals('InitialGroup', $this->context->getGroup()); - $this->assertEquals('initial.property.path', $this->context->getPropertyPath()); } public function testCallbackMultipleMethods() @@ -143,13 +122,11 @@ class CallbackValidatorTest extends \PHPUnit_Framework_TestCase 'foo.bar', 'invalidValue' )); - - // context was reset $violations->add(new ConstraintViolation( 'Other message', array('other parameter'), 'Root', - 'initial.property.path', + 'foo.bar', 'otherInvalidValue' )); diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/ChoiceValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/ChoiceValidatorTest.php index d2b2659661..54fc6305ef 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/ChoiceValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/ChoiceValidatorTest.php @@ -11,6 +11,8 @@ namespace Symfony\Tests\Component\Validator\Constraints; +use Symfony\Component\Validator\GlobalExecutionContext; + use Symfony\Component\Validator\ExecutionContext; use Symfony\Component\Validator\Constraints\Choice; use Symfony\Component\Validator\Constraints\ChoiceValidator; @@ -33,8 +35,8 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase { $walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); $factory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); - $context = new ExecutionContext('root', $walker, $factory); - $context->setCurrentClass(__CLASS__); + $globalContext = new GlobalExecutionContext('root', $walker, $factory); + $context = new ExecutionContext($globalContext, null, null, null, __CLASS__, null); $this->validator = new ChoiceValidator(); $this->validator->initialize($context); } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php index 9898425b2f..d52b0242a2 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php @@ -11,6 +11,8 @@ namespace Symfony\Tests\Component\Validator\Constraints; +use Symfony\Component\Validator\GlobalExecutionContext; + use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; use Symfony\Component\Validator\ExecutionContext; @@ -25,6 +27,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase { protected $validator; protected $walker; + protected $globalContext; protected $context; protected function setUp() @@ -32,7 +35,8 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); $metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); - $this->context = new ExecutionContext('Root', $this->walker, $metadataFactory); + $this->globalContext = new GlobalExecutionContext('Root', $this->walker, $metadataFactory); + $this->context = new ExecutionContext($this->globalContext, 'value', 'bar', 'MyGroup', 'ClassName', 'propertyName'); $this->validator = new CollectionValidator(); $this->validator->initialize($this->context); @@ -42,6 +46,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase { $this->validator = null; $this->walker = null; + $this->globalContext = null; $this->context = null; } @@ -75,9 +80,6 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testWalkSingleConstraint() { - $this->context->setGroup('MyGroup'); - $this->context->setPropertyPath('foo'); - $constraint = new Min(4); $array = array('foo' => 3); @@ -85,7 +87,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase foreach ($array as $key => $value) { $this->walker->expects($this->once()) ->method('walkConstraint') - ->with($this->equalTo($constraint), $this->equalTo($value), $this->equalTo('MyGroup'), $this->equalTo('foo['.$key.']')); + ->with($this->equalTo($constraint), $this->equalTo($value), $this->equalTo('MyGroup'), $this->equalTo('bar['.$key.']')); } $data = $this->prepareTestData($array); @@ -99,9 +101,6 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testWalkMultipleConstraints() { - $this->context->setGroup('MyGroup'); - $this->context->setPropertyPath('foo'); - $constraints = array( new Min(4), new NotNull(), @@ -112,7 +111,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase foreach ($constraints as $i => $constraint) { $this->walker->expects($this->at($i)) ->method('walkConstraint') - ->with($this->equalTo($constraint), $this->equalTo($value), $this->equalTo('MyGroup'), $this->equalTo('foo['.$key.']')); + ->with($this->equalTo($constraint), $this->equalTo($value), $this->equalTo('MyGroup'), $this->equalTo('bar['.$key.']')); } } @@ -132,9 +131,6 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase 'baz' => 6, )); - $this->context->setCurrentValue($data); - $this->context->setPropertyPath('bar'); - $this->assertFalse($this->validator->isValid($data, new Collection(array( 'fields' => array( 'foo' => new Min(4), @@ -186,8 +182,6 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testMissingFieldsDisallowed() { $data = $this->prepareTestData(array()); - $this->context->setCurrentValue($data); - $this->context->setPropertyPath('bar'); $this->assertFalse($this->validator->isValid($data, new Collection(array( 'fields' => array( @@ -240,9 +234,6 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testOptionalFieldSingleConstraint() { - $this->context->setGroup('MyGroup'); - $this->context->setPropertyPath('bar'); - $array = array( 'foo' => 5, ); @@ -262,9 +253,6 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testOptionalFieldMultipleConstraints() { - $this->context->setGroup('MyGroup'); - $this->context->setPropertyPath('bar'); - $array = array( 'foo' => 5, ); @@ -309,9 +297,6 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testRequiredFieldSingleConstraint() { - $this->context->setGroup('MyGroup'); - $this->context->setPropertyPath('bar'); - $array = array( 'foo' => 5, ); @@ -331,9 +316,6 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testRequiredFieldMultipleConstraints() { - $this->context->setGroup('MyGroup'); - $this->context->setPropertyPath('bar'); - $array = array( 'foo' => 5, ); diff --git a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php index fa30e76fe6..84b4156023 100644 --- a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php +++ b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php @@ -11,6 +11,8 @@ namespace Symfony\Tests\Component\Validator; +use Symfony\Component\Validator\GlobalExecutionContext; + use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; @@ -21,34 +23,44 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase { protected $walker; protected $metadataFactory; + protected $globalContext; protected $context; protected function setUp() { $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); $this->metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); - $this->context = new ExecutionContext('Root', $this->walker, $this->metadataFactory); + $this->globalContext = new GlobalExecutionContext('Root', $this->walker, $this->metadataFactory); + $this->context = new ExecutionContext($this->globalContext, 'currentValue', 'foo.bar', 'Group', 'ClassName', 'propertyName'); } protected function tearDown() { - $this->walker = null; - $this->metadataFactory = null; + $this->globalContext = null; $this->context = null; } + public function testInit() + { + $this->assertCount(0, $this->context->getViolations()); + $this->assertSame('Root', $this->context->getRoot()); + $this->assertSame('foo.bar', $this->context->getPropertyPath()); + $this->assertSame('ClassName', $this->context->getCurrentClass()); + $this->assertSame('propertyName', $this->context->getCurrentProperty()); + $this->assertSame('Group', $this->context->getGroup()); + $this->assertSame($this->walker, $this->context->getGraphWalker()); + $this->assertSame($this->metadataFactory, $this->context->getMetadataFactory()); + } + public function testClone() { $clone = clone $this->context; - $this->assertNotSame($this->context, $clone); + $this->assertNotSame($this->context->getViolations(), $clone->getViolations()); } public function testAddViolation() { - $this->assertCount(0, $this->context->getViolations()); - - $this->context->setPropertyPath('foo.bar'); $this->context->addViolation('Error', array('foo' => 'bar'), 'invalid'); $this->assertEquals(new ConstraintViolationList(array( @@ -64,10 +76,6 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase public function testAddViolationUsesPreconfiguredValueIfNotPassed() { - $this->assertCount(0, $this->context->getViolations()); - - $this->context->setPropertyPath('foo.bar'); - $this->context->setCurrentValue('invalid'); $this->context->addViolation('Error'); $this->assertEquals(new ConstraintViolationList(array( @@ -76,18 +84,13 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase array(), 'Root', 'foo.bar', - 'invalid' + 'currentValue' ), )), $this->context->getViolations()); } public function testAddViolationUsesPassedNulValue() { - $this->assertCount(0, $this->context->getViolations()); - - $this->context->setPropertyPath('foo.bar'); - $this->context->setCurrentValue('invalid'); - // passed null value should override preconfigured value "invalid" $this->context->addViolation('Error', array('foo' => 'bar'), null); @@ -104,10 +107,6 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase public function testAddViolationAt() { - $this->assertCount(0, $this->context->getViolations()); - - $this->context->setPropertyPath('foo.bar'); - // override preconfigured property path $this->context->addViolationAt('bar.baz', 'Error', array('foo' => 'bar'), 'invalid'); @@ -124,10 +123,6 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase public function testAddViolationAtUsesPreconfiguredValueIfNotPassed() { - $this->assertCount(0, $this->context->getViolations()); - - $this->context->setPropertyPath('foo.bar'); - $this->context->setCurrentValue('invalid'); $this->context->addViolationAt('bar.baz', 'Error'); $this->assertEquals(new ConstraintViolationList(array( @@ -136,18 +131,13 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase array(), 'Root', 'bar.baz', - 'invalid' + 'currentValue' ), )), $this->context->getViolations()); } public function testAddViolationAtUsesPassedNulValue() { - $this->assertCount(0, $this->context->getViolations()); - - $this->context->setPropertyPath('foo.bar'); - $this->context->setCurrentValue('invalid'); - // passed null value should override preconfigured value "invalid" $this->context->addViolationAt('bar.baz', 'Error', array('foo' => 'bar'), null); @@ -162,114 +152,100 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testGetViolations() + public function testAddNestedViolationAt() { - $this->context->addViolation('', array(), ''); + // override preconfigured property path + $this->context->addNestedViolationAt('bam.baz', 'Error', array('foo' => 'bar'), 'invalid'); - $violations = $this->context->getViolations(); - - $this->assertCount(1, $violations); - $this->assertInstanceOf('Symfony\Component\Validator\ConstraintViolationList', $violations); - - $this->assertInstanceOf('ArrayIterator', $violations->getIterator()); - - $this->assertTrue(isset($violations[0])); - $this->assertFalse(isset($violations[1])); - - $violations[] = 'fake'; - $this->assertEquals('fake', $violations[1]); - $this->assertTrue(isset($violations[1])); - - unset($violations[1]); - $this->assertFalse(isset($violations[1])); - - $violations[0] = 'fake'; - $this->assertEquals('fake', $violations[0]); + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array('foo' => 'bar'), + 'Root', + 'foo.bar.bam.baz', + 'invalid' + ), + )), $this->context->getViolations()); } - public function testViolationsMerge() + public function testAddNestedViolationAtWithIndexPath() { - $this->context->addViolation('Message 1', array(), ''); - $this->context->addViolation('Message 2', array(), ''); + // override preconfigured property path + $this->context->addNestedViolationAt('[bam]', 'Error', array('foo' => 'bar'), 'invalid'); - $violations1 = $this->context->getViolations(); - - $this->context->addViolation('', array(), ''); - - $violations2 = $this->context->getViolations(); - unset($violations2[1]); - - $violations1->addAll($violations2); - - $this->assertEmpty($violations1[2]->getMessage()); + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array('foo' => 'bar'), + 'Root', + 'foo.bar[bam]', + 'invalid' + ), + )), $this->context->getViolations()); } - public function testViolationsAsString() + public function testAddNestedViolationAtWithEmptyPath() { - $this->context->addViolation('Message 1', array(), ''); - $this->context->addViolation('Message 2', array(), ''); + // override preconfigured property path + $this->context->addNestedViolationAt('', 'Error', array('foo' => 'bar'), 'invalid'); - $violations = $this->context->getViolations(); - - $expected = <<assertEquals($expected, $violations->__toString()); + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array('foo' => 'bar'), + 'Root', + 'foo.bar', + 'invalid' + ), + )), $this->context->getViolations()); } - public function testGetRoot() + public function testAddNestedViolationAtWithEmptyCurrentPropertyPath() { - $this->assertEquals('Root', $this->context->getRoot()); + $this->context = new ExecutionContext($this->globalContext, 'currentValue', '', 'Group', 'ClassName', 'propertyName'); + + // override preconfigured property path + $this->context->addNestedViolationAt('bam.baz', 'Error', array('foo' => 'bar'), 'invalid'); + + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array('foo' => 'bar'), + 'Root', + 'bam.baz', + 'invalid' + ), + )), $this->context->getViolations()); } - public function testSetGetPropertyPath() + public function testAddNestedViolationAtUsesPreconfiguredValueIfNotPassed() { - $this->context->setPropertyPath('property_path'); + $this->context->addNestedViolationAt('bam.baz', 'Error'); - $this->assertEquals('property_path', $this->context->getPropertyPath()); + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array(), + 'Root', + 'foo.bar.bam.baz', + 'currentValue' + ), + )), $this->context->getViolations()); } - public function testSetGetCurrentClass() + public function testAddNestedViolationAtUsesPassedNulValue() { - $this->context->setCurrentClass('current_class'); + // passed null value should override preconfigured value "invalid" + $this->context->addNestedViolationAt('bam.baz', 'Error', array('foo' => 'bar'), null); - $this->assertEquals('current_class', $this->context->getCurrentClass()); - } - - public function testSetGetCurrentProperty() - { - $this->context->setCurrentProperty('current_property'); - - $this->assertEquals('current_property', $this->context->getCurrentProperty()); - } - - public function testSetGetGroup() - { - $this->context->setGroup('group'); - - $this->assertEquals('group', $this->context->getGroup()); - } - - public function testGetGraphWalker() - { - $this->assertSame($this->walker, $this->context->getGraphWalker()); - $this->assertInstanceOf( - 'Symfony\Component\Validator\GraphWalker', - $this->context->getGraphWalker() - ); - } - - public function testGetMetadataFactory() - { - $this->assertSame($this->metadataFactory, $this->context->getMetadataFactory()); - $this->assertInstanceOf( - 'Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface', - $this->context->getMetadataFactory() - ); + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array('foo' => 'bar'), + 'Root', + 'foo.bar.bam.baz', + null + ), + )), $this->context->getViolations()); } } diff --git a/tests/Symfony/Tests/Component/Validator/Fixtures/ConstraintAValidator.php b/tests/Symfony/Tests/Component/Validator/Fixtures/ConstraintAValidator.php index e1c15d3b52..b052081700 100644 --- a/tests/Symfony/Tests/Component/Validator/Fixtures/ConstraintAValidator.php +++ b/tests/Symfony/Tests/Component/Validator/Fixtures/ConstraintAValidator.php @@ -4,9 +4,19 @@ namespace Symfony\Tests\Component\Validator\Fixtures; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\ExecutionContext; class ConstraintAValidator extends ConstraintValidator { + static public $passedContext; + + public function initialize(ExecutionContext $context) + { + parent::initialize($context); + + self::$passedContext = $context; + } + public function isValid($value, Constraint $constraint) { if ('VALID' != $value) { diff --git a/tests/Symfony/Tests/Component/Validator/GlobalExecutionContextTest.php b/tests/Symfony/Tests/Component/Validator/GlobalExecutionContextTest.php new file mode 100644 index 0000000000..0e2e410704 --- /dev/null +++ b/tests/Symfony/Tests/Component/Validator/GlobalExecutionContextTest.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Validator; + +use Symfony\Component\Validator\ConstraintViolation; + +use Symfony\Component\Validator\ConstraintViolationList; + +use Symfony\Component\Validator\GlobalExecutionContext; + +class GlobalExecutionContextTest extends \PHPUnit_Framework_TestCase +{ + protected $walker; + protected $metadataFactory; + protected $context; + + protected function setUp() + { + $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); + $this->metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); + $this->context = new GlobalExecutionContext('Root', $this->walker, $this->metadataFactory); + } + + protected function tearDown() + { + $this->walker = null; + $this->metadataFactory = null; + $this->context = null; + } + + public function testInit() + { + $this->assertCount(0, $this->context->getViolations()); + $this->assertSame('Root', $this->context->getRoot()); + $this->assertSame($this->walker, $this->context->getGraphWalker()); + $this->assertSame($this->metadataFactory, $this->context->getMetadataFactory()); + } + + public function testClone() + { + $clone = clone $this->context; + + $this->assertNotSame($this->context->getViolations(), $clone->getViolations()); + } + + public function testAddViolation() + { + $violation = new ConstraintViolation('Error', array(), 'Root', 'foo.bar', 'invalid'); + + $this->context->addViolation($violation); + + $this->assertEquals(new ConstraintViolationList(array($violation)), $this->context->getViolations()); + } +} diff --git a/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php b/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php index 30d2f3dda9..c89a4e7952 100644 --- a/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php +++ b/tests/Symfony/Tests/Component/Validator/GraphWalkerTest.php @@ -11,6 +11,8 @@ namespace Symfony\Tests\Component\Validator; +use Symfony\Tests\Component\Validator\Fixtures\ConstraintAValidator; + require_once __DIR__.'/Fixtures/Entity.php'; require_once __DIR__.'/Fixtures/Reference.php'; require_once __DIR__.'/Fixtures/ConstraintA.php'; @@ -54,15 +56,17 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase $this->metadata = null; } - public function testWalkObjectUpdatesContext() + public function testWalkObjectPassesCorrectClassAndProperty() { $this->metadata->addConstraint(new ConstraintA()); $entity = new Entity(); $this->walker->walkObject($this->metadata, $entity, 'Default', ''); - $this->assertEquals('Symfony\Tests\Component\Validator\Fixtures\Entity', $this->getContext()->getCurrentClass()); - $this->assertEquals($entity, $this->getContext()->getCurrentValue()); + $context = ConstraintAValidator::$passedContext; + + $this->assertEquals('Symfony\Tests\Component\Validator\Fixtures\Entity', $context->getCurrentClass()); + $this->assertNull($context->getCurrentProperty()); } public function testWalkObjectValidatesConstraints() @@ -214,15 +218,16 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase $this->assertEquals($violations, $this->walker->getViolations()); } - public function testWalkPropertyUpdatesContext() + public function testWalkPropertyPassesCorrectClassAndProperty() { $this->metadata->addPropertyConstraint('firstName', new ConstraintA()); $this->walker->walkPropertyValue($this->metadata, 'firstName', 'value', 'Default', ''); - $this->assertEquals('Symfony\Tests\Component\Validator\Fixtures\Entity', $this->getContext()->getCurrentClass()); - $this->assertEquals('firstName', $this->getContext()->getCurrentProperty()); - $this->assertEquals('value', $this->getContext()->getCurrentValue()); + $context = ConstraintAValidator::$passedContext; + + $this->assertEquals('Symfony\Tests\Component\Validator\Fixtures\Entity', $context->getCurrentClass()); + $this->assertEquals('firstName', $context->getCurrentProperty()); } public function testWalkPropertyValueValidatesConstraints() @@ -461,9 +466,9 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase $this->assertEquals('collection[foo][bar]', $violations[0]->getPropertyPath()); } - protected function getContext() + protected function getProperty($property) { - $p = new \ReflectionProperty($this->walker, 'context'); + $p = new \ReflectionProperty($this->walker, $property); $p->setAccessible(true); return $p->getValue($this->walker); From 041728274033a8f76027e6f624b9ea56d1fa578d Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Wed, 1 Feb 2012 09:21:22 +0100 Subject: [PATCH 09/11] [Validator] Fixed typos --- src/Symfony/Component/Validator/GlobalExecutionContext.php | 6 +----- .../Tests/Component/Validator/ExecutionContextTest.php | 6 +++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/Validator/GlobalExecutionContext.php b/src/Symfony/Component/Validator/GlobalExecutionContext.php index 36f71fdf7f..d234385e40 100644 --- a/src/Symfony/Component/Validator/GlobalExecutionContext.php +++ b/src/Symfony/Component/Validator/GlobalExecutionContext.php @@ -27,11 +27,7 @@ class GlobalExecutionContext private $metadataFactory; private $violations; - public function __construct( - $root, - GraphWalker $graphWalker, - ClassMetadataFactoryInterface $metadataFactory - ) + public function __construct($root, GraphWalker $graphWalker, ClassMetadataFactoryInterface $metadataFactory) { $this->root = $root; $this->graphWalker = $graphWalker; diff --git a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php index 84b4156023..5b15a4d4c9 100644 --- a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php +++ b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php @@ -89,7 +89,7 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testAddViolationUsesPassedNulValue() + public function testAddViolationUsesPassedNullValue() { // passed null value should override preconfigured value "invalid" $this->context->addViolation('Error', array('foo' => 'bar'), null); @@ -136,7 +136,7 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testAddViolationAtUsesPassedNulValue() + public function testAddViolationAtUsesPassedNullValue() { // passed null value should override preconfigured value "invalid" $this->context->addViolationAt('bar.baz', 'Error', array('foo' => 'bar'), null); @@ -233,7 +233,7 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testAddNestedViolationAtUsesPassedNulValue() + public function testAddNestedViolationAtUsesPassedNullValue() { // passed null value should override preconfigured value "invalid" $this->context->addNestedViolationAt('bam.baz', 'Error', array('foo' => 'bar'), null); From 9153f0e5691e67e343222b44f30034828680536c Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Wed, 1 Feb 2012 13:53:45 +0100 Subject: [PATCH 10/11] [Validator] Deprecated ConstraintValidator methods setMessage(), getMessageTemplate() and getMessageParameters() Had to refactor the validation tests at the same time and fixed various small bugs while doing so. --- CHANGELOG-2.1.md | 2 + UPGRADE-2.1.md | 34 +++ .../Constraints/UniqueEntityValidator.php | 2 +- .../Constraint/UserPasswordValidator.php | 2 +- .../Validator/ConstraintValidator.php | 16 +- .../ConstraintValidatorInterface.php | 16 +- .../Validator/ConstraintViolation.php | 25 ++- .../Validator/ConstraintViolationList.php | 12 +- .../Validator/Constraints/BlankValidator.php | 2 +- .../Constraints/CallbackValidator.php | 7 +- .../Validator/Constraints/ChoiceValidator.php | 8 +- .../Constraints/CollectionValidator.php | 8 +- .../Constraints/CountryValidator.php | 2 +- .../Validator/Constraints/DateValidator.php | 6 +- .../Validator/Constraints/EmailValidator.php | 2 +- .../Validator/Constraints/FalseValidator.php | 2 +- .../Validator/Constraints/FileValidator.php | 14 +- .../Validator/Constraints/ImageValidator.php | 10 +- .../Validator/Constraints/IpValidator.php | 2 +- .../Constraints/LanguageValidator.php | 2 +- .../Validator/Constraints/LocaleValidator.php | 2 +- .../Constraints/MaxLengthValidator.php | 2 +- .../Validator/Constraints/MaxValidator.php | 4 +- .../Constraints/MinLengthValidator.php | 2 +- .../Validator/Constraints/MinValidator.php | 4 +- .../Constraints/NotBlankValidator.php | 2 +- .../Constraints/NotNullValidator.php | 2 +- .../Validator/Constraints/NullValidator.php | 2 +- .../Validator/Constraints/RegexValidator.php | 2 +- .../Constraints/SizeLengthValidator.php | 6 +- .../Validator/Constraints/SizeValidator.php | 6 +- .../Validator/Constraints/TimeValidator.php | 2 +- .../Validator/Constraints/TrueValidator.php | 2 +- .../Validator/Constraints/TypeValidator.php | 4 +- .../Validator/Constraints/UrlValidator.php | 2 +- .../Component/Validator/ExecutionContext.php | 27 +-- .../Component/Validator/GraphWalker.php | 13 +- .../Validator/ConstraintViolationTest.php | 35 ++++ .../Constraints/AllValidatorTest.php | 65 ++++-- .../Constraints/BlankValidatorTest.php | 37 ++-- .../Constraints/CallbackValidatorTest.php | 98 ++++----- .../Constraints/ChoiceValidatorTest.php | 131 +++++++++--- .../Constraints/CollectionValidatorTest.php | 163 +++++++++----- .../Constraints/CountryValidatorTest.php | 49 +++-- .../Constraints/DateTimeValidatorTest.php | 52 +++-- .../Constraints/DateValidatorTest.php | 46 ++-- .../Constraints/EmailValidatorTest.php | 43 ++-- ...lidatorTest.php => FalseValidatorTest.php} | 16 +- .../Constraints/FileValidatorObjectTest.php | 22 ++ .../Constraints/FileValidatorPathTest.php | 37 ++++ .../Constraints/FileValidatorTest.php | 134 ++++++------ .../Constraints/ImageValidatorTest.php | 63 ++++-- .../Validator/Constraints/IpValidatorTest.php | 198 ++++++++++++++---- .../Constraints/LanguageValidatorTest.php | 49 +++-- .../Constraints/LocaleValidatorTest.php | 49 +++-- .../Constraints/MaxLengthValidatorTest.php | 72 ++++--- .../Constraints/MaxValidatorTest.php | 39 ++-- .../Constraints/MinLengthValidatorTest.php | 76 ++++--- .../Constraints/MinValidatorTest.php | 38 ++-- .../Constraints/NotBlankValidatorTest.php | 64 ++++-- .../Constraints/NotNullValidatorTest.php | 14 +- .../Constraints/NullValidatorTest.php | 32 +-- .../Constraints/RegexValidatorTest.php | 44 ++-- .../Constraints/SizeLengthValidatorTest.php | 126 +++++++---- .../Constraints/SizeValidatorTest.php | 50 +++-- .../Constraints/TimeValidatorTest.php | 46 ++-- ...alidatorTest.php => TrueValidatorTest.php} | 17 +- ...alidatorTest.php => TypeValidatorTest.php} | 114 +++++----- .../Constraints/UrlValidatorTest.php | 46 ++-- .../Validator/ExecutionContextTest.php | 107 ++++------ .../Fixtures/ConstraintAValidator.php | 2 +- .../Fixtures/FailingConstraintValidator.php | 2 +- 72 files changed, 1554 insertions(+), 880 deletions(-) create mode 100644 tests/Symfony/Tests/Component/Validator/ConstraintViolationTest.php rename tests/Symfony/Tests/Component/Validator/Constraints/{AssertFalseValidatorTest.php => FalseValidatorTest.php} (68%) create mode 100644 tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorObjectTest.php create mode 100644 tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorPathTest.php rename tests/Symfony/Tests/Component/Validator/Constraints/{AssertTrueValidatorTest.php => TrueValidatorTest.php} (67%) rename tests/Symfony/Tests/Component/Validator/Constraints/{AssertTypeValidatorTest.php => TypeValidatorTest.php} (60%) diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md index 09d82ce62e..e29cd3a79a 100644 --- a/CHANGELOG-2.1.md +++ b/CHANGELOG-2.1.md @@ -300,6 +300,8 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c * changed default value for `extraFieldsMessage` and `missingFieldsMessage` in Collection constraint * made ExecutionContext immutable + * deprecated Constraint methods `setMessage`, `getMessageTemplate` and + `getMessageParameters` ### Yaml diff --git a/UPGRADE-2.1.md b/UPGRADE-2.1.md index 9b79eb32ae..dfbfd2f85f 100644 --- a/UPGRADE-2.1.md +++ b/UPGRADE-2.1.md @@ -141,3 +141,37 @@ UPGRADE FROM 2.0 to 2.1 $builder->add('tags', 'collection', array('prototype' => '__proto__')); // results in the name "__proto__" in the template + +* The methods `setMessage`, `getMessageTemplate` and `getMessageParameters` + in Constraint were deprecated + + If you have implemented custom validators, you should use either of the + `addViolation*` methods of the context object instead. + + Before: + + public function isValid($value, Constraint $constraint) + { + // ... + if (!$valid) { + $this->setMessage($constraint->message, array( + '{{ value }}' => $value, + )); + + return false; + } + } + + After: + + public function isValid($value, Constraint $constraint) + { + // ... + if (!$valid) { + $this->context->addViolation($constraint->message, array( + '{{ value }}' => $value, + )); + + return false; + } + } \ No newline at end of file diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index 2dd1989440..8eedb4127c 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -102,7 +102,7 @@ class UniqueEntityValidator extends ConstraintValidator return true; } - $this->context->addNestedViolationAt($fields[0], $constraint->message, array(), $criteria[$fields[0]]); + $this->context->addViolationAtRelativePath($fields[0], $constraint->message, array(), $criteria[$fields[0]]); return true; // all true, we added the violation already! } diff --git a/src/Symfony/Bundle/SecurityBundle/Validator/Constraint/UserPasswordValidator.php b/src/Symfony/Bundle/SecurityBundle/Validator/Constraint/UserPasswordValidator.php index 71208ac789..e817886090 100644 --- a/src/Symfony/Bundle/SecurityBundle/Validator/Constraint/UserPasswordValidator.php +++ b/src/Symfony/Bundle/SecurityBundle/Validator/Constraint/UserPasswordValidator.php @@ -40,7 +40,7 @@ class UserPasswordValidator extends ConstraintValidator $encoder = $this->encoderFactory->getEncoder($user); if (!$encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt())) { - $this->setMessage($constraint->message); + $this->context->addViolation($constraint->message); return false; } diff --git a/src/Symfony/Component/Validator/ConstraintValidator.php b/src/Symfony/Component/Validator/ConstraintValidator.php index 2abf92f9c1..e7c045dfa8 100644 --- a/src/Symfony/Component/Validator/ConstraintValidator.php +++ b/src/Symfony/Component/Validator/ConstraintValidator.php @@ -24,12 +24,18 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface * @var ExecutionContext */ protected $context; + /** * @var string + * + * @deprecated */ private $messageTemplate; + /** * @var array + * + * @deprecated */ private $messageParameters; @@ -46,7 +52,7 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface /** * {@inheritDoc} * - * @api + * @deprecated */ public function getMessageTemplate() { @@ -56,7 +62,7 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface /** * {@inheritDoc} * - * @api + * @deprecated */ public function getMessageParameters() { @@ -64,11 +70,15 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface } /** - * @api + * Wrapper for $this->context->addViolation() + * + * @deprecated */ protected function setMessage($template, array $parameters = array()) { $this->messageTemplate = $template; $this->messageParameters = $parameters; + + $this->context->addViolation($template, $parameters); } } diff --git a/src/Symfony/Component/Validator/ConstraintValidatorInterface.php b/src/Symfony/Component/Validator/ConstraintValidatorInterface.php index 8ef25ada64..a813a67159 100644 --- a/src/Symfony/Component/Validator/ConstraintValidatorInterface.php +++ b/src/Symfony/Component/Validator/ConstraintValidatorInterface.php @@ -12,6 +12,8 @@ namespace Symfony\Component\Validator; /** + * @author Bernhard Schussek + * * @api */ interface ConstraintValidatorInterface @@ -34,18 +36,4 @@ interface ConstraintValidatorInterface * @api */ function isValid($value, Constraint $constraint); - - /** - * @return string - * - * @api - */ - function getMessageTemplate(); - - /** - * @return array - * - * @api - */ - function getMessageParameters(); } diff --git a/src/Symfony/Component/Validator/ConstraintViolation.php b/src/Symfony/Component/Validator/ConstraintViolation.php index e528b3acab..a069dabb17 100644 --- a/src/Symfony/Component/Validator/ConstraintViolation.php +++ b/src/Symfony/Component/Validator/ConstraintViolation.php @@ -33,6 +33,21 @@ class ConstraintViolation $this->invalidValue = $invalidValue; } + /** + * @return string + */ + public function __toString() + { + $class = (string) (is_object($this->root) ? get_class($this->root) : $this->root); + $propertyPath = (string) $this->propertyPath; + + if ('' !== $propertyPath && '[' !== $propertyPath[0] && '' !== $class) { + $class .= '.'; + } + + return $class . $propertyPath . ":\n " . $this->getMessage(); + } + /** * @return string * @@ -62,7 +77,15 @@ class ConstraintViolation */ public function getMessage() { - return strtr($this->messageTemplate, $this->messageParameters); + $parameters = $this->messageParameters; + + foreach ($parameters as $i => $parameter) { + if (is_array($parameter)) { + $parameters[$i] = 'Array'; + } + } + + return strtr($this->messageTemplate, $parameters); } public function getRoot() diff --git a/src/Symfony/Component/Validator/ConstraintViolationList.php b/src/Symfony/Component/Validator/ConstraintViolationList.php index 96efce4e81..7bda2003e9 100644 --- a/src/Symfony/Component/Validator/ConstraintViolationList.php +++ b/src/Symfony/Component/Validator/ConstraintViolationList.php @@ -47,17 +47,7 @@ class ConstraintViolationList implements \IteratorAggregate, \Countable, \ArrayA $string = ''; foreach ($this->violations as $violation) { - $root = $violation->getRoot(); - $class = (string) (is_object($root) ? get_class($root) : $root); - $propertyPath = (string) $violation->getPropertyPath(); - if ('' !== $propertyPath && '[' !== $propertyPath[0] && '' !== $class) { - $class .= '.'; - } - $string .= <<getMessage()} - -EOF; + $string .= $violation . "\n"; } return $string; diff --git a/src/Symfony/Component/Validator/Constraints/BlankValidator.php b/src/Symfony/Component/Validator/Constraints/BlankValidator.php index 7c08b15a35..07212eaa65 100644 --- a/src/Symfony/Component/Validator/Constraints/BlankValidator.php +++ b/src/Symfony/Component/Validator/Constraints/BlankValidator.php @@ -32,7 +32,7 @@ class BlankValidator extends ConstraintValidator public function isValid($value, Constraint $constraint) { if ('' !== $value && null !== $value) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php index 34104c0eac..c7a9fa286e 100644 --- a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php @@ -48,6 +48,7 @@ class CallbackValidator extends ConstraintValidator } $methods = $constraint->methods; + $success = true; foreach ($methods as $method) { if (is_array($method) || $method instanceof \Closure) { @@ -55,16 +56,16 @@ class CallbackValidator extends ConstraintValidator throw new ConstraintDefinitionException(sprintf('"%s::%s" targeted by Callback constraint is not a valid callable', $method[0], $method[1])); } - call_user_func($method, $object, $this->context); + $success = call_user_func($method, $object, $this->context) && $success; } else { if (!method_exists($object, $method)) { throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist', $method)); } - $object->$method($this->context); + $success = $object->$method($this->context) && $success; } } - return true; + return $success; } } diff --git a/src/Symfony/Component/Validator/Constraints/ChoiceValidator.php b/src/Symfony/Component/Validator/Constraints/ChoiceValidator.php index 250fa63ebc..c5401eb4fc 100644 --- a/src/Symfony/Component/Validator/Constraints/ChoiceValidator.php +++ b/src/Symfony/Component/Validator/Constraints/ChoiceValidator.php @@ -66,7 +66,7 @@ class ChoiceValidator extends ConstraintValidator if ($constraint->multiple) { foreach ($value as $_value) { if (!in_array($_value, $choices, $constraint->strict)) { - $this->setMessage($constraint->multipleMessage, array('{{ value }}' => $_value)); + $this->context->addViolation($constraint->multipleMessage, array('{{ value }}' => $_value)); return false; } @@ -75,18 +75,18 @@ class ChoiceValidator extends ConstraintValidator $count = count($value); if ($constraint->min !== null && $count < $constraint->min) { - $this->setMessage($constraint->minMessage, array('{{ limit }}' => $constraint->min)); + $this->context->addViolation($constraint->minMessage, array('{{ limit }}' => $constraint->min)); return false; } if ($constraint->max !== null && $count > $constraint->max) { - $this->setMessage($constraint->maxMessage, array('{{ limit }}' => $constraint->max)); + $this->context->addViolation($constraint->maxMessage, array('{{ limit }}' => $constraint->max)); return false; } } elseif (!in_array($value, $choices, $constraint->strict)) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/CollectionValidator.php b/src/Symfony/Component/Validator/Constraints/CollectionValidator.php index c380041ee6..4697d85761 100644 --- a/src/Symfony/Component/Validator/Constraints/CollectionValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CollectionValidator.php @@ -68,8 +68,8 @@ class CollectionValidator extends ConstraintValidator $walker->walkConstraint($constr, $value[$field], $group, $propertyPath.'['.$field.']'); } } elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) { - $this->context->addNestedViolationAt('['.$field.']', $constraint->missingFieldsMessage, array( - '{{ field }}' => '"'.$field.'"' + $this->context->addViolationAtRelativePath('['.$field.']', $constraint->missingFieldsMessage, array( + '{{ field }}' => $field ), null); $valid = false; } @@ -78,8 +78,8 @@ class CollectionValidator extends ConstraintValidator if (!$constraint->allowExtraFields) { foreach ($value as $field => $fieldValue) { if (!isset($constraint->fields[$field])) { - $this->context->addNestedViolationAt('['.$field.']', $constraint->extraFieldsMessage, array( - '{{ field }}' => '"'.$field.'"' + $this->context->addViolationAtRelativePath('['.$field.']', $constraint->extraFieldsMessage, array( + '{{ field }}' => $field ), $fieldValue); $valid = false; } diff --git a/src/Symfony/Component/Validator/Constraints/CountryValidator.php b/src/Symfony/Component/Validator/Constraints/CountryValidator.php index ca681a32d4..c6de580500 100644 --- a/src/Symfony/Component/Validator/Constraints/CountryValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CountryValidator.php @@ -47,7 +47,7 @@ class CountryValidator extends ConstraintValidator $value = (string) $value; if (!in_array($value, \Symfony\Component\Locale\Locale::getCountries())) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/DateValidator.php b/src/Symfony/Component/Validator/Constraints/DateValidator.php index 89893bbcda..db4ef7c822 100644 --- a/src/Symfony/Component/Validator/Constraints/DateValidator.php +++ b/src/Symfony/Component/Validator/Constraints/DateValidator.php @@ -48,12 +48,12 @@ class DateValidator extends ConstraintValidator $value = (string) $value; - if (!preg_match(static::PATTERN, $value, $matches)) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + if (!preg_match(static::PATTERN, $value, $matches) || !checkdate($matches[2], $matches[3], $matches[1])) { + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } - return checkdate($matches[2], $matches[3], $matches[1]); + return true; } } diff --git a/src/Symfony/Component/Validator/Constraints/EmailValidator.php b/src/Symfony/Component/Validator/Constraints/EmailValidator.php index d4e2adcd48..b26dd55441 100644 --- a/src/Symfony/Component/Validator/Constraints/EmailValidator.php +++ b/src/Symfony/Component/Validator/Constraints/EmailValidator.php @@ -58,7 +58,7 @@ class EmailValidator extends ConstraintValidator } if (!$valid) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/FalseValidator.php b/src/Symfony/Component/Validator/Constraints/FalseValidator.php index bcdaf63db4..f473f7a19a 100644 --- a/src/Symfony/Component/Validator/Constraints/FalseValidator.php +++ b/src/Symfony/Component/Validator/Constraints/FalseValidator.php @@ -39,7 +39,7 @@ class FalseValidator extends ConstraintValidator return true; } - $this->setMessage($constraint->message); + $this->context->addViolation($constraint->message); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/FileValidator.php b/src/Symfony/Component/Validator/Constraints/FileValidator.php index aeccf76837..39d93ed493 100644 --- a/src/Symfony/Component/Validator/Constraints/FileValidator.php +++ b/src/Symfony/Component/Validator/Constraints/FileValidator.php @@ -44,15 +44,15 @@ class FileValidator extends ConstraintValidator case UPLOAD_ERR_INI_SIZE: $maxSize = UploadedFile::getMaxFilesize(); $maxSize = $constraint->maxSize ? min($maxSize, $constraint->maxSize) : $maxSize; - $this->setMessage($constraint->uploadIniSizeErrorMessage, array('{{ limit }}' => $maxSize.' bytes')); + $this->context->addViolation($constraint->uploadIniSizeErrorMessage, array('{{ limit }}' => $maxSize.' bytes')); return false; case UPLOAD_ERR_FORM_SIZE: - $this->setMessage($constraint->uploadFormSizeErrorMessage); + $this->context->addViolation($constraint->uploadFormSizeErrorMessage); return false; default: - $this->setMessage($constraint->uploadErrorMessage); + $this->context->addViolation($constraint->uploadErrorMessage); return false; } @@ -65,13 +65,13 @@ class FileValidator extends ConstraintValidator $path = $value instanceof FileObject ? $value->getPathname() : (string) $value; if (!is_file($path)) { - $this->setMessage($constraint->notFoundMessage, array('{{ file }}' => $path)); + $this->context->addViolation($constraint->notFoundMessage, array('{{ file }}' => $path)); return false; } if (!is_readable($path)) { - $this->setMessage($constraint->notReadableMessage, array('{{ file }}' => $path)); + $this->context->addViolation($constraint->notReadableMessage, array('{{ file }}' => $path)); return false; } @@ -94,7 +94,7 @@ class FileValidator extends ConstraintValidator } if ($size > $limit) { - $this->setMessage($constraint->maxSizeMessage, array( + $this->context->addViolation($constraint->maxSizeMessage, array( '{{ size }}' => $size.$suffix, '{{ limit }}' => $limit.$suffix, '{{ file }}' => $path, @@ -128,7 +128,7 @@ class FileValidator extends ConstraintValidator } if (false === $valid) { - $this->setMessage($constraint->mimeTypesMessage, array( + $this->context->addViolation($constraint->mimeTypesMessage, array( '{{ type }}' => '"'.$mime.'"', '{{ types }}' => '"'.implode('", "', $mimeTypes) .'"', '{{ file }}' => $path, diff --git a/src/Symfony/Component/Validator/Constraints/ImageValidator.php b/src/Symfony/Component/Validator/Constraints/ImageValidator.php index d9cbc678a6..f91113c0fa 100644 --- a/src/Symfony/Component/Validator/Constraints/ImageValidator.php +++ b/src/Symfony/Component/Validator/Constraints/ImageValidator.php @@ -40,7 +40,7 @@ class ImageValidator extends FileValidator $size = @getimagesize($value); if (empty($size) || ($size[0] === 0) || ($size[1] === 0)) { - $this->setMessage($constraint->sizeNotDetectedMessage); + $this->context->addViolation($constraint->sizeNotDetectedMessage); return false; } @@ -54,7 +54,7 @@ class ImageValidator extends FileValidator } if ($width < $constraint->minWidth) { - $this->setMessage($constraint->minWidthMessage, array( + $this->context->addViolation($constraint->minWidthMessage, array( '{{ width }}' => $width, '{{ min_width }}' => $constraint->minWidth )); @@ -69,7 +69,7 @@ class ImageValidator extends FileValidator } if ($width > $constraint->maxWidth) { - $this->setMessage($constraint->maxWidthMessage, array( + $this->context->addViolation($constraint->maxWidthMessage, array( '{{ width }}' => $width, '{{ max_width }}' => $constraint->maxWidth )); @@ -84,7 +84,7 @@ class ImageValidator extends FileValidator } if ($height < $constraint->minHeight) { - $this->setMessage($constraint->minHeightMessage, array( + $this->context->addViolation($constraint->minHeightMessage, array( '{{ height }}' => $height, '{{ min_height }}' => $constraint->minHeight )); @@ -99,7 +99,7 @@ class ImageValidator extends FileValidator } if ($height > $constraint->maxHeight) { - $this->setMessage($constraint->maxHeightMessage, array( + $this->context->addViolation($constraint->maxHeightMessage, array( '{{ height }}' => $height, '{{ max_height }}' => $constraint->maxHeight )); diff --git a/src/Symfony/Component/Validator/Constraints/IpValidator.php b/src/Symfony/Component/Validator/Constraints/IpValidator.php index 724e5fe5cc..4bb3fe547a 100644 --- a/src/Symfony/Component/Validator/Constraints/IpValidator.php +++ b/src/Symfony/Component/Validator/Constraints/IpValidator.php @@ -98,7 +98,7 @@ class IpValidator extends ConstraintValidator } if (!filter_var($value, FILTER_VALIDATE_IP, $flag)) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/LanguageValidator.php b/src/Symfony/Component/Validator/Constraints/LanguageValidator.php index caa5953c89..e5ee7ff6c0 100644 --- a/src/Symfony/Component/Validator/Constraints/LanguageValidator.php +++ b/src/Symfony/Component/Validator/Constraints/LanguageValidator.php @@ -47,7 +47,7 @@ class LanguageValidator extends ConstraintValidator $value = (string) $value; if (!in_array($value, \Symfony\Component\Locale\Locale::getLanguages())) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/LocaleValidator.php b/src/Symfony/Component/Validator/Constraints/LocaleValidator.php index c51b80806e..4ad75447c0 100644 --- a/src/Symfony/Component/Validator/Constraints/LocaleValidator.php +++ b/src/Symfony/Component/Validator/Constraints/LocaleValidator.php @@ -47,7 +47,7 @@ class LocaleValidator extends ConstraintValidator $value = (string) $value; if (!in_array($value, \Symfony\Component\Locale\Locale::getLocales())) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/MaxLengthValidator.php b/src/Symfony/Component/Validator/Constraints/MaxLengthValidator.php index c4485642e8..48bab5fde2 100644 --- a/src/Symfony/Component/Validator/Constraints/MaxLengthValidator.php +++ b/src/Symfony/Component/Validator/Constraints/MaxLengthValidator.php @@ -51,7 +51,7 @@ class MaxLengthValidator extends ConstraintValidator } if ($length > $constraint->limit) { - $this->setMessage($constraint->message, array( + $this->context->addViolation($constraint->message, array( '{{ value }}' => $value, '{{ limit }}' => $constraint->limit, )); diff --git a/src/Symfony/Component/Validator/Constraints/MaxValidator.php b/src/Symfony/Component/Validator/Constraints/MaxValidator.php index 521f5dab95..018f4d0c47 100644 --- a/src/Symfony/Component/Validator/Constraints/MaxValidator.php +++ b/src/Symfony/Component/Validator/Constraints/MaxValidator.php @@ -36,7 +36,7 @@ class MaxValidator extends ConstraintValidator } if (!is_numeric($value)) { - $this->setMessage($constraint->invalidMessage, array( + $this->context->addViolation($constraint->invalidMessage, array( '{{ value }}' => $value, '{{ limit }}' => $constraint->limit, )); @@ -45,7 +45,7 @@ class MaxValidator extends ConstraintValidator } if ($value > $constraint->limit) { - $this->setMessage($constraint->message, array( + $this->context->addViolation($constraint->message, array( '{{ value }}' => $value, '{{ limit }}' => $constraint->limit, )); diff --git a/src/Symfony/Component/Validator/Constraints/MinLengthValidator.php b/src/Symfony/Component/Validator/Constraints/MinLengthValidator.php index 38bb8e8fbf..b148ec794a 100644 --- a/src/Symfony/Component/Validator/Constraints/MinLengthValidator.php +++ b/src/Symfony/Component/Validator/Constraints/MinLengthValidator.php @@ -51,7 +51,7 @@ class MinLengthValidator extends ConstraintValidator } if ($length < $constraint->limit) { - $this->setMessage($constraint->message, array( + $this->context->addViolation($constraint->message, array( '{{ value }}' => $value, '{{ limit }}' => $constraint->limit, )); diff --git a/src/Symfony/Component/Validator/Constraints/MinValidator.php b/src/Symfony/Component/Validator/Constraints/MinValidator.php index 1106258cf5..24e030edbf 100644 --- a/src/Symfony/Component/Validator/Constraints/MinValidator.php +++ b/src/Symfony/Component/Validator/Constraints/MinValidator.php @@ -36,7 +36,7 @@ class MinValidator extends ConstraintValidator } if (!is_numeric($value)) { - $this->setMessage($constraint->invalidMessage, array( + $this->context->addViolation($constraint->invalidMessage, array( '{{ value }}' => $value, '{{ limit }}' => $constraint->limit, )); @@ -45,7 +45,7 @@ class MinValidator extends ConstraintValidator } if ($value < $constraint->limit) { - $this->setMessage($constraint->message, array( + $this->context->addViolation($constraint->message, array( '{{ value }}' => $value, '{{ limit }}' => $constraint->limit, )); diff --git a/src/Symfony/Component/Validator/Constraints/NotBlankValidator.php b/src/Symfony/Component/Validator/Constraints/NotBlankValidator.php index d4706c2313..5fe90ce94d 100644 --- a/src/Symfony/Component/Validator/Constraints/NotBlankValidator.php +++ b/src/Symfony/Component/Validator/Constraints/NotBlankValidator.php @@ -32,7 +32,7 @@ class NotBlankValidator extends ConstraintValidator public function isValid($value, Constraint $constraint) { if (false === $value || (empty($value) && '0' != $value)) { - $this->setMessage($constraint->message); + $this->context->addViolation($constraint->message); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/NotNullValidator.php b/src/Symfony/Component/Validator/Constraints/NotNullValidator.php index d781698e7b..0c8759cefc 100644 --- a/src/Symfony/Component/Validator/Constraints/NotNullValidator.php +++ b/src/Symfony/Component/Validator/Constraints/NotNullValidator.php @@ -32,7 +32,7 @@ class NotNullValidator extends ConstraintValidator public function isValid($value, Constraint $constraint) { if (null === $value) { - $this->setMessage($constraint->message); + $this->context->addViolation($constraint->message); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/NullValidator.php b/src/Symfony/Component/Validator/Constraints/NullValidator.php index ecd87a8030..dc04f9cbab 100644 --- a/src/Symfony/Component/Validator/Constraints/NullValidator.php +++ b/src/Symfony/Component/Validator/Constraints/NullValidator.php @@ -32,7 +32,7 @@ class NullValidator extends ConstraintValidator public function isValid($value, Constraint $constraint) { if (null !== $value) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/RegexValidator.php b/src/Symfony/Component/Validator/Constraints/RegexValidator.php index 30cdbded2a..ebf517bf80 100644 --- a/src/Symfony/Component/Validator/Constraints/RegexValidator.php +++ b/src/Symfony/Component/Validator/Constraints/RegexValidator.php @@ -48,7 +48,7 @@ class RegexValidator extends ConstraintValidator $value = (string) $value; if ($constraint->match xor preg_match($constraint->pattern, $value)) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/SizeLengthValidator.php b/src/Symfony/Component/Validator/Constraints/SizeLengthValidator.php index 916914c039..86de9b4d9e 100644 --- a/src/Symfony/Component/Validator/Constraints/SizeLengthValidator.php +++ b/src/Symfony/Component/Validator/Constraints/SizeLengthValidator.php @@ -51,7 +51,7 @@ class SizeLengthValidator extends ConstraintValidator } if ($constraint->min == $constraint->max && $length != $constraint->max) { - $this->setMessage($constraint->exactMessage, array( + $this->context->addViolation($constraint->exactMessage, array( '{{ value }}' => $value, '{{ limit }}' => $constraint->max, )); @@ -60,7 +60,7 @@ class SizeLengthValidator extends ConstraintValidator } if ($length > $constraint->max) { - $this->setMessage($constraint->maxMessage, array( + $this->context->addViolation($constraint->maxMessage, array( '{{ value }}' => $value, '{{ limit }}' => $constraint->max, )); @@ -69,7 +69,7 @@ class SizeLengthValidator extends ConstraintValidator } if ($length < $constraint->min) { - $this->setMessage($constraint->minMessage, array( + $this->context->addViolation($constraint->minMessage, array( '{{ value }}' => $value, '{{ limit }}' => $constraint->min, )); diff --git a/src/Symfony/Component/Validator/Constraints/SizeValidator.php b/src/Symfony/Component/Validator/Constraints/SizeValidator.php index 51fa5fb962..db8bc65c68 100644 --- a/src/Symfony/Component/Validator/Constraints/SizeValidator.php +++ b/src/Symfony/Component/Validator/Constraints/SizeValidator.php @@ -36,7 +36,7 @@ class SizeValidator extends ConstraintValidator } if (!is_numeric($value)) { - $this->setMessage($constraint->invalidMessage, array( + $this->context->addViolation($constraint->invalidMessage, array( '{{ value }}' => $value, )); @@ -44,7 +44,7 @@ class SizeValidator extends ConstraintValidator } if ($value > $constraint->max) { - $this->setMessage($constraint->maxMessage, array( + $this->context->addViolation($constraint->maxMessage, array( '{{ value }}' => $value, '{{ limit }}' => $constraint->max, )); @@ -53,7 +53,7 @@ class SizeValidator extends ConstraintValidator } if ($value < $constraint->min) { - $this->setMessage($constraint->minMessage, array( + $this->context->addViolation($constraint->minMessage, array( '{{ value }}' => $value, '{{ limit }}' => $constraint->min, )); diff --git a/src/Symfony/Component/Validator/Constraints/TimeValidator.php b/src/Symfony/Component/Validator/Constraints/TimeValidator.php index 4b117b5bd3..6c4b8d538c 100644 --- a/src/Symfony/Component/Validator/Constraints/TimeValidator.php +++ b/src/Symfony/Component/Validator/Constraints/TimeValidator.php @@ -49,7 +49,7 @@ class TimeValidator extends ConstraintValidator $value = (string) $value; if (!preg_match(static::PATTERN, $value)) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/TrueValidator.php b/src/Symfony/Component/Validator/Constraints/TrueValidator.php index 04dcbef8f2..fe58c72eb5 100644 --- a/src/Symfony/Component/Validator/Constraints/TrueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/TrueValidator.php @@ -39,7 +39,7 @@ class TrueValidator extends ConstraintValidator return true; } - $this->setMessage($constraint->message); + $this->context->addViolation($constraint->message); return false; } diff --git a/src/Symfony/Component/Validator/Constraints/TypeValidator.php b/src/Symfony/Component/Validator/Constraints/TypeValidator.php index 84382dd467..71bbed80bd 100644 --- a/src/Symfony/Component/Validator/Constraints/TypeValidator.php +++ b/src/Symfony/Component/Validator/Constraints/TypeValidator.php @@ -48,8 +48,8 @@ class TypeValidator extends ConstraintValidator return true; } - $this->setMessage($constraint->message, array( - '{{ value }}' => is_object($value) ? get_class($value) : is_array($value) ? 'Array' : (string) $value, + $this->context->addViolation($constraint->message, array( + '{{ value }}' => is_object($value) ? get_class($value) : (is_array($value) ? 'Array' : (string) $value), '{{ type }}' => $constraint->type, )); diff --git a/src/Symfony/Component/Validator/Constraints/UrlValidator.php b/src/Symfony/Component/Validator/Constraints/UrlValidator.php index 30021f945a..0514ce661d 100644 --- a/src/Symfony/Component/Validator/Constraints/UrlValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UrlValidator.php @@ -60,7 +60,7 @@ class UrlValidator extends ConstraintValidator $pattern = sprintf(static::PATTERN, implode('|', $constraint->protocols)); if (!preg_match($pattern, $value)) { - $this->setMessage($constraint->message, array('{{ value }}' => $value)); + $this->context->addViolation($constraint->message, array('{{ value }}' => $value)); return false; } diff --git a/src/Symfony/Component/Validator/ExecutionContext.php b/src/Symfony/Component/Validator/ExecutionContext.php index 1118d9d90a..300f3b1c6f 100644 --- a/src/Symfony/Component/Validator/ExecutionContext.php +++ b/src/Symfony/Component/Validator/ExecutionContext.php @@ -80,7 +80,7 @@ class ExecutionContext * @param array $params The parameters parsed into the error message. * @param mixed $invalidValue The invalid, validated value. */ - public function addViolationAt($propertyPath, $message, array $params = array(), $invalidValue = null) + public function addViolationAtPath($propertyPath, $message, array $params = array(), $invalidValue = null) { $this->globalContext->addViolation(new ConstraintViolation( $message, @@ -93,27 +93,21 @@ class ExecutionContext } /** - * Adds a violation at the child of the current validation graph node with - * the given property path. + * Adds a violation at the validation graph node with the given property + * path relative to the current property path. * - * @param string $childPropertyPath The property path of the child node. + * @param string $relativePath The relative property path for the violation. * @param string $message The error message. * @param array $params The parameters parsed into the error message. * @param mixed $invalidValue The invalid, validated value. */ - public function addNestedViolationAt($childPropertyPath, $message, array $params = array(), $invalidValue = null) + public function addViolationAtRelativePath($relativePath, $message, array $params = array(), $invalidValue = null) { - $propertyPath = $this->propertyPath; - - if ('' !== $propertyPath && '' !== $childPropertyPath && '[' !== $childPropertyPath[0]) { - $propertyPath .= '.'; - } - $this->globalContext->addViolation(new ConstraintViolation( $message, $params, $this->globalContext->getRoot(), - $propertyPath . $childPropertyPath, + $this->getAbsolutePropertyPath($relativePath), // check using func_num_args() to allow passing null values func_num_args() === 4 ? $invalidValue : $this->value )); @@ -139,6 +133,15 @@ class ExecutionContext return $this->propertyPath; } + public function getAbsolutePropertyPath($relativePath) + { + if ('' !== $this->propertyPath && '' !== $relativePath && '[' !== $relativePath[0]) { + return $this->propertyPath . '.' . $relativePath; + } + + return $this->propertyPath . $relativePath; + } + public function getCurrentClass() { return $this->class; diff --git a/src/Symfony/Component/Validator/GraphWalker.php b/src/Symfony/Component/Validator/GraphWalker.php index da6e5a0aea..dbdcfdb70e 100644 --- a/src/Symfony/Component/Validator/GraphWalker.php +++ b/src/Symfony/Component/Validator/GraphWalker.php @@ -178,17 +178,6 @@ class GraphWalker ); $validator->initialize($localContext); - - if (!$validator->isValid($value, $constraint)) { - $messageTemplate = $validator->getMessageTemplate(); - $messageParams = $validator->getMessageParameters(); - - // Somewhat ugly hack: Don't add a violation if no message is set. - // This is required if the validator added its violations directly - // to the globalContext already - if (!empty($messageTemplate)) { - $localContext->addViolation($messageTemplate, $messageParams); - } - } + $validator->isValid($value, $constraint); } } diff --git a/tests/Symfony/Tests/Component/Validator/ConstraintViolationTest.php b/tests/Symfony/Tests/Component/Validator/ConstraintViolationTest.php new file mode 100644 index 0000000000..39843f18cd --- /dev/null +++ b/tests/Symfony/Tests/Component/Validator/ConstraintViolationTest.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Validator; + +use Symfony\Component\Validator\ConstraintViolation; + +class ConstraintViolationTest extends \PHPUnit_Framework_TestCase +{ + public function testToStringHandlesArrays() + { + $violation = new ConstraintViolation( + '{{ value }}', + array('{{ value }}' => array(1, 2, 3)), + 'Root', + 'property.path', + null + ); + + $expected = <<assertSame($expected, (string) $violation); + } +} diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/AllValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/AllValidatorTest.php index 0649833574..60f3d3cecb 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/AllValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/AllValidatorTest.php @@ -15,25 +15,32 @@ use Symfony\Component\Validator\GlobalExecutionContext; use Symfony\Component\Validator\ExecutionContext; use Symfony\Component\Validator\Constraints\Min; +use Symfony\Component\Validator\Constraints\Max; use Symfony\Component\Validator\Constraints\All; use Symfony\Component\Validator\Constraints\AllValidator; class AllValidatorTest extends \PHPUnit_Framework_TestCase { - protected $validator; protected $walker; protected $context; + protected $validator; protected function setUp() { $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); - $metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); - $globalContext = new GlobalExecutionContext('Root', $this->walker, $metadataFactory); - - $this->context = new ExecutionContext($globalContext, null, 'foo', 'MyGroup', null, null); - + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new AllValidator(); $this->validator->initialize($this->context); + + $this->context->expects($this->any()) + ->method('getGraphWalker') + ->will($this->returnValue($this->walker)); + $this->context->expects($this->any()) + ->method('getGroup') + ->will($this->returnValue('MyGroup')); + $this->context->expects($this->any()) + ->method('getPropertyPath') + ->will($this->returnValue('foo.bar')); } protected function tearDown() @@ -48,11 +55,13 @@ class AllValidatorTest extends \PHPUnit_Framework_TestCase $this->assertTrue($this->validator->isValid(null, new All(new Min(4)))); } + + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testThrowsExceptionIfNotTraversable() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - - $this->validator->isValid('foobar', new All(new Min(4))); + $this->validator->isValid('foo.barbar', new All(new Min(4))); } /** @@ -62,12 +71,17 @@ class AllValidatorTest extends \PHPUnit_Framework_TestCase { $constraint = new Min(4); + $i = 0; + foreach ($array as $key => $value) { - $this->walker->expects($this->once()) - ->method('walkConstraint') - ->with($this->equalTo($constraint), $this->equalTo($value), $this->equalTo('MyGroup'), $this->equalTo('foo['.$key.']')); + $this->walker->expects($this->at($i++)) + ->method('walkConstraint') + ->with($constraint, $value, 'MyGroup', 'foo.bar['.$key.']'); } + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($array, new All($constraint))); } @@ -76,27 +90,32 @@ class AllValidatorTest extends \PHPUnit_Framework_TestCase */ public function testWalkMultipleConstraints($array) { - $constraint = new Min(4); - // can only test for twice the same constraint because PHPUnits mocking - // can't test method calls with different arguments - $constraints = array($constraint, $constraint); + $constraint1 = new Min(4); + $constraint2 = new Max(6); + + $constraints = array($constraint1, $constraint2); + $i = 0; foreach ($array as $key => $value) { - $this->walker->expects($this->exactly(2)) - ->method('walkConstraint') - ->with($this->equalTo($constraint), $this->equalTo($value), $this->equalTo('MyGroup'), $this->equalTo('foo['.$key.']')); + $this->walker->expects($this->at($i++)) + ->method('walkConstraint') + ->with($constraint1, $value, 'MyGroup', 'foo.bar['.$key.']'); + $this->walker->expects($this->at($i++)) + ->method('walkConstraint') + ->with($constraint2, $value, 'MyGroup', 'foo.bar['.$key.']'); } + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($array, new All($constraints))); } public function getValidArguments() { return array( - // can only test for one entry, because PHPUnits mocking does not allow - // to expect multiple method calls with different arguments - array(array(1)), - array(new \ArrayObject(array(1))), + array(array(5, 6, 7)), + array(new \ArrayObject(array(5, 6, 7))), ); } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/BlankValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/BlankValidatorTest.php index b026a71d61..bca2cad69c 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/BlankValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/BlankValidatorTest.php @@ -16,34 +16,54 @@ use Symfony\Component\Validator\Constraints\BlankValidator; class BlankValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new BlankValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Blank())); } public function testBlankIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Blank())); } /** * @dataProvider getInvalidValues */ - public function testInvalidValues($date) + public function testInvalidValues($value) { - $this->assertFalse($this->validator->isValid($date, new Blank())); + $constraint = new Blank(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $value, + )); + + $this->assertFalse($this->validator->isValid($value, $constraint)); } public function getInvalidValues() @@ -55,17 +75,4 @@ class BlankValidatorTest extends \PHPUnit_Framework_TestCase array(1234), ); } - - public function testMessageIsSet() - { - $constraint = new Blank(array( - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - )); - } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/CallbackValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/CallbackValidatorTest.php index d8822e5dc5..a250325b93 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/CallbackValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/CallbackValidatorTest.php @@ -22,7 +22,9 @@ class CallbackValidatorTest_Class { public static function validateStatic($object, ExecutionContext $context) { - $context->addViolation('Static message', array('parameter'), 'invalidValue'); + $context->addViolation('Static message', array('{{ value }}' => 'foobar'), 'invalidValue'); + + return false; } } @@ -30,107 +32,93 @@ class CallbackValidatorTest_Object { public function validateOne(ExecutionContext $context) { - $context->addViolation('My message', array('parameter'), 'invalidValue'); + $context->addViolation('My message', array('{{ value }}' => 'foobar'), 'invalidValue'); + + return false; } public function validateTwo(ExecutionContext $context) { - $context->addViolation('Other message', array('other parameter'), 'otherInvalidValue'); + $context->addViolation('Other message', array('{{ value }}' => 'baz'), 'otherInvalidValue'); + + return false; } } class CallbackValidatorTest extends \PHPUnit_Framework_TestCase { - protected $validator; - protected $walker; protected $context; + protected $validator; protected function setUp() { - $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); - $metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); - $globalContext = new GlobalExecutionContext('Root', $this->walker, $metadataFactory); - - $this->context = new ExecutionContext($globalContext, 'value', 'foo.bar', 'Group', 'ClassName', 'propertyName'); + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new CallbackValidator(); $this->validator->initialize($this->context); } protected function tearDown() { - $this->validator = null; - $this->walker = null; $this->context = null; + $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Callback(array('foo')))); } public function testCallbackSingleMethod() { $object = new CallbackValidatorTest_Object(); + $constraint = new Callback(array('validateOne')); - $this->assertTrue($this->validator->isValid($object, new Callback(array('validateOne')))); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('My message', array( + '{{ value }}' => 'foobar', + )); - $violations = new ConstraintViolationList(); - $violations->add(new ConstraintViolation( - 'My message', - array('parameter'), - 'Root', - 'foo.bar', - 'invalidValue' - )); - - $this->assertEquals($violations, $this->context->getViolations()); + $this->assertFalse($this->validator->isValid($object, $constraint)); } public function testCallbackSingleStaticMethod() { $object = new CallbackValidatorTest_Object(); - $this->assertTrue($this->validator->isValid($object, new Callback(array( - array(__NAMESPACE__.'\CallbackValidatorTest_Class', 'validateStatic') + $this->context->expects($this->once()) + ->method('addViolation') + ->with('Static message', array( + '{{ value }}' => 'foobar', + )); + + $this->assertFalse($this->validator->isValid($object, new Callback(array( + array(__CLASS__.'_Class', 'validateStatic') )))); - - $violations = new ConstraintViolationList(); - $violations->add(new ConstraintViolation( - 'Static message', - array('parameter'), - 'Root', - 'foo.bar', - 'invalidValue' - )); - - $this->assertEquals($violations, $this->context->getViolations()); } public function testCallbackMultipleMethods() { $object = new CallbackValidatorTest_Object(); - $this->assertTrue($this->validator->isValid($object, new Callback(array( + $this->context->expects($this->at(0)) + ->method('addViolation') + ->with('My message', array( + '{{ value }}' => 'foobar', + )); + $this->context->expects($this->at(1)) + ->method('addViolation') + ->with('Other message', array( + '{{ value }}' => 'baz', + )); + + + $this->assertFalse($this->validator->isValid($object, new Callback(array( 'validateOne', 'validateTwo' )))); - - $violations = new ConstraintViolationList(); - $violations->add(new ConstraintViolation( - 'My message', - array('parameter'), - 'Root', - 'foo.bar', - 'invalidValue' - )); - $violations->add(new ConstraintViolation( - 'Other message', - array('other parameter'), - 'Root', - 'foo.bar', - 'otherInvalidValue' - )); - - $this->assertEquals($violations, $this->context->getViolations()); } /** diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/ChoiceValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/ChoiceValidatorTest.php index 54fc6305ef..9f4bb3e636 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/ChoiceValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/ChoiceValidatorTest.php @@ -24,6 +24,7 @@ function choice_callback() class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; public static function staticCallback() @@ -33,19 +34,24 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); - $factory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); - $globalContext = new GlobalExecutionContext('root', $walker, $factory); - $context = new ExecutionContext($globalContext, null, null, null, __CLASS__, null); + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new ChoiceValidator(); - $this->validator->initialize($context); + $this->validator->initialize($this->context); + + $this->context->expects($this->any()) + ->method('getCurrentClass') + ->will($this->returnValue(__CLASS__)); } protected function tearDown() { + $this->context = null; $this->validator = null; } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectArrayIfMultipleIsTrue() { $constraint = new Choice(array( @@ -53,27 +59,30 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase 'multiple' => true, )); - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid('asdf', $constraint); } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Choice(array('choices' => array('foo', 'bar'))))); } + /** + * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException + */ public function testChoicesOrCallbackExpected() { - $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException'); - $this->validator->isValid('foobar', new Choice()); } + /** + * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException + */ public function testValidCallbackExpected() { - $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException'); - $this->validator->isValid('foobar', new Choice(array('callback' => 'abcd'))); } @@ -81,6 +90,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase { $constraint = new Choice(array('choices' => array('foo', 'bar'))); + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('bar', $constraint)); } @@ -88,6 +100,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase { $constraint = new Choice(array('callback' => __NAMESPACE__.'\choice_callback')); + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('bar', $constraint)); } @@ -97,6 +112,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase return array('foo', 'bar'); })); + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('bar', $constraint)); } @@ -104,6 +122,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase { $constraint = new Choice(array('callback' => array(__CLASS__, 'staticCallback'))); + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('bar', $constraint)); } @@ -111,6 +132,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase { $constraint = new Choice(array('callback' => 'staticCallback')); + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('bar', $constraint)); } @@ -121,6 +145,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase 'multiple' => true, )); + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(array('baz', 'bar'), $constraint)); } @@ -131,11 +158,13 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase 'message' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => 'baz', + )); + $this->assertFalse($this->validator->isValid('baz', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'baz', - )); } public function testInvalidChoiceMultiple() @@ -146,11 +175,13 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase 'multiple' => true, )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => 'baz', + )); + $this->assertFalse($this->validator->isValid(array('foo', 'baz'), $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'baz', - )); } public function testTooFewChoices() @@ -162,11 +193,13 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase 'minMessage' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ limit }}' => 2, + )); + $this->assertFalse($this->validator->isValid(array('foo'), $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ limit }}' => 2, - )); } public function testTooManyChoices() @@ -178,36 +211,60 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase 'maxMessage' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ limit }}' => 2, + )); + $this->assertFalse($this->validator->isValid(array('foo', 'bar', 'moo'), $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ limit }}' => 2, - )); } - public function testStrictIsFalse() + public function testNonStrict() { $constraint = new Choice(array( 'choices' => array(1, 2), 'strict' => false, )); + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('2', $constraint)); $this->assertTrue($this->validator->isValid(2, $constraint)); } - public function testStrictIsTrue() + public function testStrictAllowsExactValue() { $constraint = new Choice(array( 'choices' => array(1, 2), 'strict' => true, )); + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(2, $constraint)); + } + + public function testStrictDisallowsDifferentType() + { + $constraint = new Choice(array( + 'choices' => array(1, 2), + 'strict' => true, + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => '2', + )); + $this->assertFalse($this->validator->isValid('2', $constraint)); } - public function testStrictIsFalseWhenMultipleChoices() + public function testNonStrictWithMultipleChoices() { $constraint = new Choice(array( 'choices' => array(1, 2, 3), @@ -215,17 +272,27 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase 'strict' => false )); + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(array('2', 3), $constraint)); } - public function testStrictIsTrueWhenMultipleChoices() + public function testStrictWithMultipleChoices() { $constraint = new Choice(array( 'choices' => array(1, 2, 3), 'multiple' => true, - 'strict' => true + 'strict' => true, + 'multipleMessage' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => '3', + )); + $this->assertFalse($this->validator->isValid(array(2, '3'), $constraint)); } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php index d52b0242a2..b86ee08e41 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php @@ -25,35 +25,42 @@ use Symfony\Component\Validator\Constraints\CollectionValidator; abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase { - protected $validator; protected $walker; - protected $globalContext; protected $context; + protected $validator; protected function setUp() { $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false); - $metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'); - - $this->globalContext = new GlobalExecutionContext('Root', $this->walker, $metadataFactory); - $this->context = new ExecutionContext($this->globalContext, 'value', 'bar', 'MyGroup', 'ClassName', 'propertyName'); - + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new CollectionValidator(); $this->validator->initialize($this->context); + + $this->context->expects($this->any()) + ->method('getGraphWalker') + ->will($this->returnValue($this->walker)); + $this->context->expects($this->any()) + ->method('getGroup') + ->will($this->returnValue('MyGroup')); + $this->context->expects($this->any()) + ->method('getPropertyPath') + ->will($this->returnValue('foo.bar')); } protected function tearDown() { - $this->validator = null; $this->walker = null; - $this->globalContext = null; $this->context = null; + $this->validator = null; } abstract protected function prepareTestData(array $contents); public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + $this->assertTrue($this->validator->isValid(null, new Collection(array('fields' => array( 'foo' => new Min(4), ))))); @@ -63,6 +70,9 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase { $data = $this->prepareTestData(array('foo' => 'foobar')); + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + $this->assertTrue($this->validator->isValid($data, new Collection(array( 'foo' => new Min(4), )))); @@ -82,19 +92,27 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase { $constraint = new Min(4); - $array = array('foo' => 3); + $array = array( + 'foo' => 3, + 'bar' => 5, + ); + $i = 0; foreach ($array as $key => $value) { - $this->walker->expects($this->once()) + $this->walker->expects($this->at($i++)) ->method('walkConstraint') - ->with($this->equalTo($constraint), $this->equalTo($value), $this->equalTo('MyGroup'), $this->equalTo('bar['.$key.']')); + ->with($constraint, $value, 'MyGroup', 'foo.bar['.$key.']'); } $data = $this->prepareTestData($array); + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + $this->assertTrue($this->validator->isValid($data, new Collection(array( 'fields' => array( 'foo' => $constraint, + 'bar' => $constraint, ), )))); } @@ -105,21 +123,30 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase new Min(4), new NotNull(), ); - $array = array('foo' => 3); + + $array = array( + 'foo' => 3, + 'bar' => 5, + ); + $i = 0; foreach ($array as $key => $value) { - foreach ($constraints as $i => $constraint) { - $this->walker->expects($this->at($i)) + foreach ($constraints as $constraint) { + $this->walker->expects($this->at($i++)) ->method('walkConstraint') - ->with($this->equalTo($constraint), $this->equalTo($value), $this->equalTo('MyGroup'), $this->equalTo('bar['.$key.']')); + ->with($constraint, $value, 'MyGroup', 'foo.bar['.$key.']'); } } $data = $this->prepareTestData($array); + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + $this->assertTrue($this->validator->isValid($data, new Collection(array( 'fields' => array( 'foo' => $constraints, + 'bar' => $constraints, ) )))); } @@ -131,21 +158,18 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase 'baz' => 6, )); + $this->context->expects($this->once()) + ->method('addViolationAtRelativePath') + ->with('[baz]', 'myMessage', array( + '{{ field }}' => 'baz' + )); + $this->assertFalse($this->validator->isValid($data, new Collection(array( 'fields' => array( 'foo' => new Min(4), ), + 'extraFieldsMessage' => 'myMessage', )))); - - $this->assertEquals(new ConstraintViolationList(array( - new ConstraintViolation( - 'This field was not expected', - array('{{ field }}' => '"baz"'), - 'Root', - 'bar[baz]', - 6 - ), - )), $this->context->getViolations()); } // bug fix @@ -154,13 +178,17 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase $data = $this->prepareTestData(array( 'foo' => null, )); - $collection = new Collection(array( + + $constraint = new Collection(array( 'fields' => array( 'foo' => new Min(4), ), )); - $this->assertTrue($this->validator->isValid($data, $collection)); + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + + $this->assertTrue($this->validator->isValid($data, $constraint)); } public function testExtraFieldsAllowed() @@ -169,47 +197,55 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase 'foo' => 5, 'bar' => 6, )); - $collection = new Collection(array( + + $constraint = new Collection(array( 'fields' => array( 'foo' => new Min(4), ), 'allowExtraFields' => true, )); - $this->assertTrue($this->validator->isValid($data, $collection)); + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + + $this->assertTrue($this->validator->isValid($data, $constraint)); } public function testMissingFieldsDisallowed() { $data = $this->prepareTestData(array()); - $this->assertFalse($this->validator->isValid($data, new Collection(array( + $constraint = new Collection(array( 'fields' => array( 'foo' => new Min(4), ), - )))); + 'missingFieldsMessage' => 'myMessage', + )); - $this->assertEquals(new ConstraintViolationList(array( - new ConstraintViolation( - 'This field is missing', - array('{{ field }}' => '"foo"'), - 'Root', - 'bar[foo]', - null - ), - )), $this->context->getViolations()); + $this->context->expects($this->once()) + ->method('addViolationAtRelativePath') + ->with('[foo]', 'myMessage', array( + '{{ field }}' => 'foo', + )); + + $this->assertFalse($this->validator->isValid($data, $constraint)); } public function testMissingFieldsAllowed() { $data = $this->prepareTestData(array()); - $this->assertTrue($this->validator->isValid($data, new Collection(array( + $constraint = new Collection(array( 'fields' => array( 'foo' => new Min(4), ), 'allowMissingFields' => true, - )))); + )); + + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + + $this->assertTrue($this->validator->isValid($data, $constraint)); } public function testOptionalFieldPresent() @@ -218,6 +254,9 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase 'foo' => null, )); + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + $this->assertTrue($this->validator->isValid($data, new Collection(array( 'foo' => new Optional(), )))); @@ -227,6 +266,9 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase { $data = $this->prepareTestData(array()); + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + $this->assertTrue($this->validator->isValid($data, new Collection(array( 'foo' => new Optional(), )))); @@ -242,7 +284,10 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase $this->walker->expects($this->once()) ->method('walkConstraint') - ->with($this->equalTo($constraint), $this->equalTo($array['foo']), $this->equalTo('MyGroup'), $this->equalTo('bar[foo]')); + ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]'); + + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); $data = $this->prepareTestData($array); @@ -265,9 +310,12 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase foreach ($constraints as $i => $constraint) { $this->walker->expects($this->at($i)) ->method('walkConstraint') - ->with($this->equalTo($constraint), $this->equalTo($array['foo']), $this->equalTo('MyGroup'), $this->equalTo('bar[foo]')); + ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]'); } + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + $data = $this->prepareTestData($array); $this->assertTrue($this->validator->isValid($data, new Collection(array( @@ -281,6 +329,9 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase 'foo' => null, )); + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + $this->assertTrue($this->validator->isValid($data, new Collection(array( 'foo' => new Required(), )))); @@ -290,8 +341,17 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase { $data = $this->prepareTestData(array()); + $this->context->expects($this->once()) + ->method('addViolationAtRelativePath') + ->with('[foo]', 'myMessage', array( + '{{ field }}' => 'foo', + )); + $this->assertFalse($this->validator->isValid($data, new Collection(array( - 'foo' => new Required(), + 'fields' => array( + 'foo' => new Required(), + ), + 'missingFieldsMessage' => 'myMessage', )))); } @@ -305,7 +365,10 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase $this->walker->expects($this->once()) ->method('walkConstraint') - ->with($this->equalTo($constraint), $this->equalTo($array['foo']), $this->equalTo('MyGroup'), $this->equalTo('bar[foo]')); + ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]'); + + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); $data = $this->prepareTestData($array); @@ -328,9 +391,12 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase foreach ($constraints as $i => $constraint) { $this->walker->expects($this->at($i)) ->method('walkConstraint') - ->with($this->equalTo($constraint), $this->equalTo($array['foo']), $this->equalTo('MyGroup'), $this->equalTo('bar[foo]')); + ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]'); } + $this->context->expects($this->never()) + ->method('addViolationAtRelativePath'); + $data = $this->prepareTestData($array); $this->assertTrue($this->validator->isValid($array, new Collection(array( @@ -343,6 +409,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase $value = new \ArrayObject(array( 'foo' => 3 )); + $this->validator->isValid($value, new Collection(array( 'fields' => array( 'foo' => new Min(2), diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/CountryValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/CountryValidatorTest.php index 64564e3716..8c6a37a5ad 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/CountryValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/CountryValidatorTest.php @@ -16,43 +16,57 @@ use Symfony\Component\Validator\Constraints\CountryValidator; class CountryValidatorTest extends LocalizedTestCase { + protected $context; protected $validator; protected function setUp() { parent::setUp(); + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new CountryValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Country())); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Country())); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new Country()); } /** * @dataProvider getValidCountries */ - public function testValidCountries($date) + public function testValidCountries($country) { - $this->assertTrue($this->validator->isValid($date, new Country())); + $this->context->expects($this->never()) + ->method('addViolation'); + + $this->assertTrue($this->validator->isValid($country, new Country())); } public function getValidCountries() @@ -67,9 +81,19 @@ class CountryValidatorTest extends LocalizedTestCase /** * @dataProvider getInvalidCountries */ - public function testInvalidCountries($date) + public function testInvalidCountries($country) { - $this->assertFalse($this->validator->isValid($date, new Country())); + $constraint = new Country(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $country, + )); + + $this->assertFalse($this->validator->isValid($country, $constraint)); } public function getInvalidCountries() @@ -79,17 +103,4 @@ class CountryValidatorTest extends LocalizedTestCase array('EN'), ); } - - public function testMessageIsSet() - { - $constraint = new Country(array( - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - )); - } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/DateTimeValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/DateTimeValidatorTest.php index 03bc68ab07..777edcb139 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/DateTimeValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/DateTimeValidatorTest.php @@ -16,46 +16,63 @@ use Symfony\Component\Validator\Constraints\DateTimeValidator; class DateTimeValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new DateTimeValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new DateTime())); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new DateTime())); } public function testDateTimeClassIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(new \DateTime(), new DateTime())); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new DateTime()); } /** * @dataProvider getValidDateTimes */ - public function testValidDateTimes($date) + public function testValidDateTimes($dateTime) { - $this->assertTrue($this->validator->isValid($date, new DateTime())); + $this->context->expects($this->never()) + ->method('addViolation'); + + $this->assertTrue($this->validator->isValid($dateTime, new DateTime())); } public function getValidDateTimes() @@ -70,9 +87,19 @@ class DateTimeValidatorTest extends \PHPUnit_Framework_TestCase /** * @dataProvider getInvalidDateTimes */ - public function testInvalidDateTimes($date) + public function testInvalidDateTimes($dateTime) { - $this->assertFalse($this->validator->isValid($date, new DateTime())); + $constraint = new DateTime(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $dateTime, + )); + + $this->assertFalse($this->validator->isValid($dateTime, $constraint)); } public function getInvalidDateTimes() @@ -90,17 +117,4 @@ class DateTimeValidatorTest extends \PHPUnit_Framework_TestCase array('2010-01-01 00:00:60'), ); } - - public function testMessageIsSet() - { - $constraint = new DateTime(array( - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - )); - } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/DateValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/DateValidatorTest.php index 0e64a6f459..16af8bdccb 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/DateValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/DateValidatorTest.php @@ -16,37 +16,51 @@ use Symfony\Component\Validator\Constraints\DateValidator; class DateValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new DateValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Date())); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Date())); } public function testDateTimeClassIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(new \DateTime(), new Date())); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new Date()); } @@ -55,6 +69,9 @@ class DateValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidDates($date) { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($date, new Date())); } @@ -72,7 +89,17 @@ class DateValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidDates($date) { - $this->assertFalse($this->validator->isValid($date, new Date())); + $constraint = new Date(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $date, + )); + + $this->assertFalse($this->validator->isValid($date, $constraint)); } public function getInvalidDates() @@ -86,17 +113,4 @@ class DateValidatorTest extends \PHPUnit_Framework_TestCase array('2010-02-29'), ); } - - public function testMessageIsSet() - { - $constraint = new Date(array( - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - )); - } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/EmailValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/EmailValidatorTest.php index 32fbd2c34e..70aefb2fa9 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/EmailValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/EmailValidatorTest.php @@ -16,32 +16,43 @@ use Symfony\Component\Validator\Constraints\EmailValidator; class EmailValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new EmailValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Email())); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Email())); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new Email()); } @@ -50,6 +61,9 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidEmails($email) { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($email, new Email())); } @@ -67,7 +81,17 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidEmails($email) { - $this->assertFalse($this->validator->isValid($email, new Email())); + $constraint = new Email(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $email, + )); + + $this->assertFalse($this->validator->isValid($email, $constraint)); } public function getInvalidEmails() @@ -79,17 +103,4 @@ class EmailValidatorTest extends \PHPUnit_Framework_TestCase array('example@example.com@example.com'), ); } - - public function testMessageIsSet() - { - $constraint = new Email(array( - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - )); - } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/AssertFalseValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/FalseValidatorTest.php similarity index 68% rename from tests/Symfony/Tests/Component/Validator/Constraints/AssertFalseValidatorTest.php rename to tests/Symfony/Tests/Component/Validator/Constraints/FalseValidatorTest.php index df95c7c781..7b41e48990 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/AssertFalseValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/FalseValidatorTest.php @@ -16,25 +16,35 @@ use Symfony\Component\Validator\Constraints\FalseValidator; class FalseValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new FalseValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new False())); } public function testFalseIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(false, new False())); } @@ -44,8 +54,10 @@ class FalseValidatorTest extends \PHPUnit_Framework_TestCase 'message' => 'myMessage' )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array()); + $this->assertFalse($this->validator->isValid(true, $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array()); } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorObjectTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorObjectTest.php new file mode 100644 index 0000000000..a331c91497 --- /dev/null +++ b/tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorObjectTest.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Validator\Constraints; + +use Symfony\Component\HttpFoundation\File\File; + +class FileValidatorObjectTest extends FileValidatorTest +{ + protected function getFile($filename) + { + return new File($filename); + } +} diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorPathTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorPathTest.php new file mode 100644 index 0000000000..b0ac0c6672 --- /dev/null +++ b/tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorPathTest.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraints\File; + +class FileValidatorPathTest extends FileValidatorTest +{ + protected function getFile($filename) + { + return $filename; + } + + public function testFileNotFound() + { + $constraint = new File(array( + 'notFoundMessage' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ file }}' => 'foobar', + )); + + $this->assertFalse($this->validator->isValid('foobar', $constraint)); + } +} diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorTest.php index 9b07c2e9e8..fb09e23cfa 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/FileValidatorTest.php @@ -16,15 +16,18 @@ use Symfony\Component\Validator\Constraints\FileValidator; use Symfony\Component\HttpFoundation\File\File as FileObject; use Symfony\Component\HttpFoundation\File\UploadedFile; -class FileValidatorTest extends \PHPUnit_Framework_TestCase +abstract class FileValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected $path; protected $file; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new FileValidator(); + $this->validator->initialize($this->context); $this->path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'FileValidatorTest'; $this->file = fopen($this->path, 'w'); } @@ -33,6 +36,7 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase { fclose($this->file); + $this->context = null; $this->validator = null; $this->path = null; $this->file = null; @@ -40,11 +44,17 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new File())); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new File())); } @@ -58,11 +68,17 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase public function testValidFile() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($this->path, new File())); } public function testValidUploadedfile() { + $this->context->expects($this->never()) + ->method('addViolation'); + $file = new UploadedFile($this->path, 'originalName'); $this->assertTrue($this->validator->isValid($file, new File())); } @@ -76,13 +92,15 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase 'maxSizeMessage' => 'myMessage', )); - $this->assertFileValid($this->path, $constraint, false); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ limit }}' => '10 bytes', - '{{ size }}' => '11 bytes', - '{{ file }}' => $this->path, - )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ limit }}' => '10 bytes', + '{{ size }}' => '11 bytes', + '{{ file }}' => $this->path, + )); + + $this->assertFalse($this->validator->isValid($this->getFile($this->path), $constraint)); } public function testTooLargeKiloBytes() @@ -94,13 +112,15 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase 'maxSizeMessage' => 'myMessage', )); - $this->assertFileValid($this->path, $constraint, false); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ limit }}' => '1 kB', - '{{ size }}' => '1.4 kB', - '{{ file }}' => $this->path, - )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ limit }}' => '1 kB', + '{{ size }}' => '1.4 kB', + '{{ file }}' => $this->path, + )); + + $this->assertFalse($this->validator->isValid($this->getFile($this->path), $constraint)); } public function testTooLargeMegaBytes() @@ -112,13 +132,15 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase 'maxSizeMessage' => 'myMessage', )); - $this->assertFileValid($this->path, $constraint, false); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ limit }}' => '1 MB', - '{{ size }}' => '1.4 MB', - '{{ file }}' => $this->path, - )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ limit }}' => '1 MB', + '{{ size }}' => '1.4 MB', + '{{ file }}' => $this->path, + )); + + $this->assertFalse($this->validator->isValid($this->getFile($this->path), $constraint)); } /** @@ -133,19 +155,6 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase $this->validator->isValid($this->path, $constraint); } - public function testFileNotFound() - { - $constraint = new File(array( - 'notFoundMessage' => 'myMessage', - )); - - $this->assertFileValid('foobar', $constraint, false); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ file }}' => 'foobar', - )); - } - public function testValidMimeType() { $file = $this @@ -164,6 +173,9 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue('image/jpg')) ; + $this->context->expects($this->never()) + ->method('addViolation'); + $constraint = new File(array( 'mimeTypes' => array('image/png', 'image/jpg'), )); @@ -189,6 +201,9 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue('image/jpg')) ; + $this->context->expects($this->never()) + ->method('addViolation'); + $constraint = new File(array( 'mimeTypes' => array('image/*'), )); @@ -219,13 +234,15 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase 'mimeTypesMessage' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ type }}' => '"application/pdf"', + '{{ types }}' => '"image/png", "image/jpg"', + '{{ file }}' => $this->path, + )); + $this->assertFalse($this->validator->isValid($file, $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ type }}' => '"application/pdf"', - '{{ types }}' => '"image/png", "image/jpg"', - '{{ file }}' => $this->path, - )); } public function testInvalidWildcardMimeType() @@ -251,35 +268,40 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase 'mimeTypesMessage' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ type }}' => '"application/pdf"', + '{{ types }}' => '"image/*", "image/jpg"', + '{{ file }}' => $this->path, + )); + $this->assertFalse($this->validator->isValid($file, $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ type }}' => '"application/pdf"', - '{{ types }}' => '"image/*", "image/jpg"', - '{{ file }}' => $this->path, - )); } /** * @dataProvider uploadedFileErrorProvider */ - public function testUploadedFileError($error, $message) + public function testUploadedFileError($error, $message, array $params = array()) { $file = new UploadedFile('/path/to/file', 'originalName', 'mime', 0, $error); - $options[$message] = 'myMessage'; + $constraint = new File(array( + $message => 'myMessage', + )); - $constraint = new File($options); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', $params); $this->assertFalse($this->validator->isValid($file, $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); } public function uploadedFileErrorProvider() { return array( - array(UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage'), + array(UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', array('{{ limit }}' => UploadedFile::getMaxFilesize() . ' bytes')), array(UPLOAD_ERR_FORM_SIZE, 'uploadFormSizeErrorMessage'), array(UPLOAD_ERR_PARTIAL, 'uploadErrorMessage'), array(UPLOAD_ERR_NO_TMP_DIR, 'uploadErrorMessage'), @@ -287,11 +309,5 @@ class FileValidatorTest extends \PHPUnit_Framework_TestCase ); } - protected function assertFileValid($filename, File $constraint, $valid = true) - { - $this->assertEquals($this->validator->isValid($filename, $constraint), $valid); - if (file_exists($filename)) { - $this->assertEquals($this->validator->isValid(new FileObject($filename), $constraint), $valid); - } - } + abstract protected function getFile($filename); } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/ImageValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/ImageValidatorTest.php index 77b465265d..73e5da24e4 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/ImageValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/ImageValidatorTest.php @@ -16,33 +16,48 @@ use Symfony\Component\Validator\Constraints\ImageValidator; class ImageValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected $path; protected $image; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new ImageValidator(); + $this->validator->initialize($this->context); $this->image = __DIR__.'/Fixtures/test.gif'; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Image())); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Image())); } public function testValidImage() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($this->image, new Image())); } public function testValidSize() { + $this->context->expects($this->never()) + ->method('addViolation'); + $constraint = new Image(array( 'minWidth' => 1, 'maxWidth' => 2, @@ -60,12 +75,14 @@ class ImageValidatorTest extends \PHPUnit_Framework_TestCase 'minWidthMessage' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ width }}' => '2', + '{{ min_width }}' => '3', + )); + $this->assertFalse($this->validator->isValid($this->image, $constraint)); - $this->assertEquals('myMessage', $this->validator->getMessageTemplate()); - $this->assertEquals(array( - '{{ width }}' => '2', - '{{ min_width }}' => '3', - ), $this->validator->getMessageParameters()); } public function testWidthTooBig() @@ -75,12 +92,14 @@ class ImageValidatorTest extends \PHPUnit_Framework_TestCase 'maxWidthMessage' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ width }}' => '2', + '{{ max_width }}' => '1', + )); + $this->assertFalse($this->validator->isValid($this->image, $constraint)); - $this->assertEquals('myMessage', $this->validator->getMessageTemplate()); - $this->assertEquals(array( - '{{ width }}' => '2', - '{{ max_width }}' => '1', - ), $this->validator->getMessageParameters()); } public function testHeightTooSmall() @@ -90,12 +109,14 @@ class ImageValidatorTest extends \PHPUnit_Framework_TestCase 'minHeightMessage' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ height }}' => '2', + '{{ min_height }}' => '3', + )); + $this->assertFalse($this->validator->isValid($this->image, $constraint)); - $this->assertEquals('myMessage', $this->validator->getMessageTemplate()); - $this->assertEquals(array( - '{{ height }}' => '2', - '{{ min_height }}' => '3', - ), $this->validator->getMessageParameters()); } public function testHeightTooBig() @@ -105,12 +126,14 @@ class ImageValidatorTest extends \PHPUnit_Framework_TestCase 'maxHeightMessage' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ height }}' => '2', + '{{ max_height }}' => '1', + )); + $this->assertFalse($this->validator->isValid($this->image, $constraint)); - $this->assertEquals('myMessage', $this->validator->getMessageTemplate()); - $this->assertEquals(array( - '{{ height }}' => '2', - '{{ max_height }}' => '1', - ), $this->validator->getMessageParameters()); } /** diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/IpValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/IpValidatorTest.php index 9199a48d01..ee24a4f4e4 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/IpValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/IpValidatorTest.php @@ -16,39 +16,51 @@ use Symfony\Component\Validator\Constraints\IpValidator; class IpValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new IpValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Ip())); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Ip())); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new Ip()); } + /** + * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException + */ public function testInvalidValidatorVersion() { - $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException'); - $ip = new Ip(array( 'version' => 666, )); @@ -59,6 +71,9 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidIpsV4($ip) { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($ip, new Ip(array( 'version' => Ip::V4, )))); @@ -83,6 +98,9 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidIpsV6($ip) { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($ip, new Ip(array( 'version' => Ip::V6, )))); @@ -118,6 +136,9 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidIpsAll($ip) { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($ip, new Ip(array( 'version' => Ip::ALL, )))); @@ -133,9 +154,18 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidIpsV4($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::V4, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidIpsV4() @@ -158,9 +188,18 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidPrivateIpsV4($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::V4_NO_PRIV, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidPrivateIpsV4() @@ -177,9 +216,18 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidReservedIpsV4($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::V4_NO_RES, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidReservedIpsV4() @@ -196,9 +244,18 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidPublicIpsV4($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::V4_ONLY_PUBLIC, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidPublicIpsV4() @@ -211,9 +268,18 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidIpsV6($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::V6, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidIpsV6() @@ -240,9 +306,18 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidPrivateIpsV6($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::V6_NO_PRIV, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidPrivateIpsV6() @@ -259,9 +334,18 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidReservedIpsV6($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::V6_NO_RES, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidReservedIpsV6() @@ -277,9 +361,18 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidPublicIpsV6($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::V6_ONLY_PUBLIC, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidPublicIpsV6() @@ -292,9 +385,18 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidIpsAll($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::ALL, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidIpsAll() @@ -307,9 +409,18 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidPrivateIpsAll($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::ALL_NO_PRIV, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidPrivateIpsAll() @@ -322,9 +433,18 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidReservedIpsAll($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::ALL_NO_RES, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidReservedIpsAll() @@ -337,26 +457,22 @@ class IpValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidPublicIpsAll($ip) { - $this->assertFalse($this->validator->isValid($ip, new Ip(array( + $constraint = new Ip(array( 'version' => Ip::ALL_ONLY_PUBLIC, - )))); + 'message' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $ip, + )); + + $this->assertFalse($this->validator->isValid($ip, $constraint)); } public function getInvalidPublicIpsAll() { return array_merge($this->getInvalidPublicIpsV4(), $this->getInvalidPublicIpsV6()); } - - public function testMessageIsSet() - { - $constraint = new Ip(array( - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - )); - } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/LanguageValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/LanguageValidatorTest.php index 3c68dfc989..0f0064df1e 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/LanguageValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/LanguageValidatorTest.php @@ -16,43 +16,57 @@ use Symfony\Component\Validator\Constraints\LanguageValidator; class LanguageValidatorTest extends LocalizedTestCase { + protected $context; protected $validator; protected function setUp() { parent::setUp(); + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new LanguageValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Language())); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Language())); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new Language()); } /** * @dataProvider getValidLanguages */ - public function testValidLanguages($date) + public function testValidLanguages($language) { - $this->assertTrue($this->validator->isValid($date, new Language())); + $this->context->expects($this->never()) + ->method('addViolation'); + + $this->assertTrue($this->validator->isValid($language, new Language())); } public function getValidLanguages() @@ -67,9 +81,19 @@ class LanguageValidatorTest extends LocalizedTestCase /** * @dataProvider getInvalidLanguages */ - public function testInvalidLanguages($date) + public function testInvalidLanguages($language) { - $this->assertFalse($this->validator->isValid($date, new Language())); + $constraint = new Language(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $language, + )); + + $this->assertFalse($this->validator->isValid($language, $constraint)); } public function getInvalidLanguages() @@ -79,17 +103,4 @@ class LanguageValidatorTest extends LocalizedTestCase array('foobar'), ); } - - public function testMessageIsSet() - { - $constraint = new Language(array( - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - )); - } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/LocaleValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/LocaleValidatorTest.php index 1e6de9e949..ad05aaf6a7 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/LocaleValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/LocaleValidatorTest.php @@ -16,43 +16,57 @@ use Symfony\Component\Validator\Constraints\LocaleValidator; class LocaleValidatorTest extends LocalizedTestCase { + protected $context; protected $validator; protected function setUp() { parent::setUp(); + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new LocaleValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Locale())); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Locale())); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new Locale()); } /** * @dataProvider getValidLocales */ - public function testValidLocales($date) + public function testValidLocales($locale) { - $this->assertTrue($this->validator->isValid($date, new Locale())); + $this->context->expects($this->never()) + ->method('addViolation'); + + $this->assertTrue($this->validator->isValid($locale, new Locale())); } public function getValidLocales() @@ -68,9 +82,19 @@ class LocaleValidatorTest extends LocalizedTestCase /** * @dataProvider getInvalidLocales */ - public function testInvalidLocales($date) + public function testInvalidLocales($locale) { - $this->assertFalse($this->validator->isValid($date, new Locale())); + $constraint = new Locale(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $locale, + )); + + $this->assertFalse($this->validator->isValid($locale, $constraint)); } public function getInvalidLocales() @@ -80,17 +104,4 @@ class LocaleValidatorTest extends LocalizedTestCase array('foobar'), ); } - - public function testMessageIsSet() - { - $constraint = new Locale(array( - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - )); - } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/MaxLengthValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/MaxLengthValidatorTest.php index 57fcf75888..2be5b4fb6a 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/MaxLengthValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/MaxLengthValidatorTest.php @@ -16,44 +16,60 @@ use Symfony\Component\Validator\Constraints\MaxLengthValidator; class MaxLengthValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new MaxLengthValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new MaxLength(array('limit' => 5)))); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new MaxLength(array('limit' => 5)))); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new MaxLength(array('limit' => 5))); } /** * @dataProvider getValidValues */ - public function testValidValues($value, $skip = false) + public function testValidValues($value, $mbOnly = false) { - if (!$skip) { - $constraint = new MaxLength(array('limit' => 5)); - $this->assertTrue($this->validator->isValid($value, $constraint)); + if ($mbOnly && !function_exists('mb_strlen')) { + return $this->markTestSkipped('mb_strlen does not exist'); } + + $this->context->expects($this->never()) + ->method('addViolation'); + + $constraint = new MaxLength(array('limit' => 5)); + $this->assertTrue($this->validator->isValid($value, $constraint)); } public function getValidValues() @@ -61,20 +77,33 @@ class MaxLengthValidatorTest extends \PHPUnit_Framework_TestCase return array( array(12345), array('12345'), - array('üüüüü', !function_exists('mb_strlen')), - array('ééééé', !function_exists('mb_strlen')), + array('üüüüü', true), + array('ééééé', true), ); } /** * @dataProvider getInvalidValues */ - public function testInvalidValues($value, $skip = false) + public function testInvalidValues($value, $mbOnly = false) { - if (!$skip) { - $constraint = new MaxLength(array('limit' => 5)); - $this->assertFalse($this->validator->isValid($value, $constraint)); + if ($mbOnly && !function_exists('mb_strlen')) { + return $this->markTestSkipped('mb_strlen does not exist'); } + + $constraint = new MaxLength(array( + 'limit' => 5, + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $value, + '{{ limit }}' => 5, + )); + + $this->assertFalse($this->validator->isValid($value, $constraint)); } public function getInvalidValues() @@ -82,26 +111,11 @@ class MaxLengthValidatorTest extends \PHPUnit_Framework_TestCase return array( array(123456), array('123456'), - array('üüüüüü', !function_exists('mb_strlen')), - array('éééééé', !function_exists('mb_strlen')), + array('üüüüüü', true), + array('éééééé', true), ); } - public function testMessageIsSet() - { - $constraint = new MaxLength(array( - 'limit' => 5, - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('123456', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => '123456', - '{{ limit }}' => 5, - )); - } - public function testConstraintGetDefaultOption() { $constraint = new MaxLength(array( diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/MaxValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/MaxValidatorTest.php index 4d05ee79b0..04304cb65b 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/MaxValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/MaxValidatorTest.php @@ -16,20 +16,27 @@ use Symfony\Component\Validator\Constraints\MaxValidator; class MaxValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new MaxValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Max(array('limit' => 10)))); } @@ -38,6 +45,9 @@ class MaxValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidValues($value) { + $this->context->expects($this->never()) + ->method('addViolation'); + $constraint = new Max(array('limit' => 10)); $this->assertTrue($this->validator->isValid($value, $constraint)); } @@ -57,7 +67,19 @@ class MaxValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidValues($value) { - $constraint = new Max(array('limit' => 10)); + $constraint = new Max(array( + 'limit' => 10, + 'message' => 'myMessage', + 'invalidMessage' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $value, + '{{ limit }}' => 10, + )); + $this->assertFalse($this->validator->isValid($value, $constraint)); } @@ -70,21 +92,6 @@ class MaxValidatorTest extends \PHPUnit_Framework_TestCase ); } - public function testMessageIsSet() - { - $constraint = new Max(array( - 'limit' => 10, - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid(11, $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 11, - '{{ limit }}' => 10, - )); - } - public function testConstraintGetDefaultOption() { $constraint = new Max(array( diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/MinLengthValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/MinLengthValidatorTest.php index 6cfa963dc2..43066704d8 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/MinLengthValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/MinLengthValidatorTest.php @@ -16,44 +16,60 @@ use Symfony\Component\Validator\Constraints\MinLengthValidator; class MinLengthValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new MinLengthValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new MinLength(array('limit' => 6)))); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new MinLength(array('limit' => 6)))); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new MinLength(array('limit' => 5))); } /** * @dataProvider getValidValues */ - public function testValidValues($value, $skip = false) + public function testValidValues($value, $mbOnly = false) { - if (!$skip) { - $constraint = new MinLength(array('limit' => 6)); - $this->assertTrue($this->validator->isValid($value, $constraint)); + if ($mbOnly && !function_exists('mb_strlen')) { + return $this->markTestSkipped('mb_strlen does not exist'); } + + $this->context->expects($this->never()) + ->method('addViolation'); + + $constraint = new MinLength(array('limit' => 6)); + $this->assertTrue($this->validator->isValid($value, $constraint)); } public function getValidValues() @@ -61,47 +77,45 @@ class MinLengthValidatorTest extends \PHPUnit_Framework_TestCase return array( array(123456), array('123456'), - array('üüüüüü', !function_exists('mb_strlen')), - array('éééééé', !function_exists('mb_strlen')), + array('üüüüüü', true), + array('éééééé', true), ); } /** * @dataProvider getInvalidValues */ - public function testInvalidValues($value, $skip = false) + public function testInvalidValues($value, $mbOnly = false) { - if (!$skip) { - $constraint = new MinLength(array('limit' => 6)); - $this->assertFalse($this->validator->isValid($value, $constraint)); + if ($mbOnly && !function_exists('mb_strlen')) { + return $this->markTestSkipped('mb_strlen does not exist'); } + + $constraint = new MinLength(array( + 'limit' => 5, + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $value, + '{{ limit }}' => 5, + )); + + $this->assertFalse($this->validator->isValid($value, $constraint)); } public function getInvalidValues() { return array( - array(12345), - array('12345'), - array('üüüüü', !function_exists('mb_strlen')), - array('ééééé', !function_exists('mb_strlen')), + array(1234), + array('1234'), + array('üüüü', true), + array('éééé', true), ); } - public function testMessageIsSet() - { - $constraint = new MinLength(array( - 'limit' => 5, - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('1234', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => '1234', - '{{ limit }}' => 5, - )); - } - public function testConstraintGetDefaultOption() { $constraint = new MinLength(array( diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/MinValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/MinValidatorTest.php index 8306ce43ca..2e93627fbd 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/MinValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/MinValidatorTest.php @@ -16,15 +16,21 @@ use Symfony\Component\Validator\Constraints\MinValidator; class MinValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new MinValidator(); + $this->validator->initialize($this->context); } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Min(array('limit' => 10)))); } @@ -33,6 +39,9 @@ class MinValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidValues($value) { + $this->context->expects($this->never()) + ->method('addViolation'); + $constraint = new Min(array('limit' => 10)); $this->assertTrue($this->validator->isValid($value, $constraint)); } @@ -52,7 +61,19 @@ class MinValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidValues($value) { - $constraint = new Min(array('limit' => 10)); + $constraint = new Min(array( + 'limit' => 10, + 'message' => 'myMessage', + 'invalidMessage' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $value, + '{{ limit }}' => 10, + )); + $this->assertFalse($this->validator->isValid($value, $constraint)); } @@ -65,21 +86,6 @@ class MinValidatorTest extends \PHPUnit_Framework_TestCase ); } - public function testMessageIsSet() - { - $constraint = new Min(array( - 'limit' => 10, - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid(9, $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 9, - '{{ limit }}' => 10, - )); - } - public function testConstraintGetDefaultOption() { $constraint = new Min(array( diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/NotBlankValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/NotBlankValidatorTest.php index 27dbc43a13..e9c46758dd 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/NotBlankValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/NotBlankValidatorTest.php @@ -16,15 +16,19 @@ use Symfony\Component\Validator\Constraints\NotBlankValidator; class NotBlankValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new NotBlankValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } @@ -33,6 +37,9 @@ class NotBlankValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidValues($date) { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($date, new NotBlank())); } @@ -49,33 +56,54 @@ class NotBlankValidatorTest extends \PHPUnit_Framework_TestCase public function testNullIsInvalid() { - $this->assertFalse($this->validator->isValid(null, new NotBlank())); + $constraint = new NotBlank(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage'); + + $this->assertFalse($this->validator->isValid(null, $constraint)); } public function testBlankIsInvalid() - { - $this->assertFalse($this->validator->isValid('', new NotBlank())); - } - - public function testFalseIsInvalid() - { - $this->assertFalse($this->validator->isValid(false, new NotBlank())); - } - - public function testEmptyArrayIsInvalid() - { - $this->assertFalse($this->validator->isValid(array(), new NotBlank())); - } - - public function testSetMessage() { $constraint = new NotBlank(array( 'message' => 'myMessage' )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage'); + $this->assertFalse($this->validator->isValid('', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array()); + } + + public function testFalseIsInvalid() + { + $constraint = new NotBlank(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage'); + + $this->assertFalse($this->validator->isValid(false, $constraint)); + } + + public function testEmptyArrayIsInvalid() + { + $constraint = new NotBlank(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage'); + + $this->assertFalse($this->validator->isValid(array(), $constraint)); } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/NotNullValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/NotNullValidatorTest.php index 0f46e11109..6643ce5065 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/NotNullValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/NotNullValidatorTest.php @@ -16,15 +16,19 @@ use Symfony\Component\Validator\Constraints\NotNullValidator; class NotNullValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new NotNullValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } @@ -33,6 +37,9 @@ class NotNullValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidValues($value) { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($value, new NotNull())); } @@ -52,8 +59,11 @@ class NotNullValidatorTest extends \PHPUnit_Framework_TestCase 'message' => 'myMessage' )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + )); + $this->assertFalse($this->validator->isValid(null, $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array()); } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/NullValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/NullValidatorTest.php index ebb3a61e9e..4fd5d70388 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/NullValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/NullValidatorTest.php @@ -16,20 +16,27 @@ use Symfony\Component\Validator\Constraints\NullValidator; class NullValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new NullValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Null())); } @@ -38,7 +45,17 @@ class NullValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidValues($value) { - $this->assertFalse($this->validator->isValid($value, new Null())); + $constraint = new Null(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $value, + )); + + $this->assertFalse($this->validator->isValid($value, $constraint)); } public function getInvalidValues() @@ -50,17 +67,4 @@ class NullValidatorTest extends \PHPUnit_Framework_TestCase array(''), ); } - - public function testSetMessage() - { - $constraint = new Null(array( - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid(1, $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 1, - )); - } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/RegexValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/RegexValidatorTest.php index d87e793167..e157ad3e67 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/RegexValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/RegexValidatorTest.php @@ -16,32 +16,43 @@ use Symfony\Component\Validator\Constraints\RegexValidator; class RegexValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new RegexValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Regex(array('pattern' => '/^[0-9]+$/')))); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Regex(array('pattern' => '/^[0-9]+$/')))); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new Regex(array('pattern' => '/^[0-9]+$/'))); } @@ -50,6 +61,9 @@ class RegexValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidValues($value) { + $this->context->expects($this->never()) + ->method('addViolation'); + $constraint = new Regex(array('pattern' => '/^[0-9]+$/')); $this->assertTrue($this->validator->isValid($value, $constraint)); } @@ -69,7 +83,17 @@ class RegexValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidValues($value) { - $constraint = new Regex(array('pattern' => '/^[0-9]+$/')); + $constraint = new Regex(array( + 'pattern' => '/^[0-9]+$/', + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $value, + )); + $this->assertFalse($this->validator->isValid($value, $constraint)); } @@ -81,20 +105,6 @@ class RegexValidatorTest extends \PHPUnit_Framework_TestCase ); } - public function testMessageIsSet() - { - $constraint = new Regex(array( - 'pattern' => '/^[0-9]+$/', - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - )); - } - public function testConstraintGetDefaultOption() { $constraint = new Regex(array( diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/SizeLengthValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/SizeLengthValidatorTest.php index e2a1ee2cab..610bf91766 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/SizeLengthValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/SizeLengthValidatorTest.php @@ -2,12 +2,12 @@ /* * This file is part of the Symfony package. - * - * (c) Fabien Potencier - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ +* +* (c) Fabien Potencier +* +* For the full copyright and license information, please view the LICENSE +* file that was distributed with this source code. +*/ namespace Symfony\Tests\Component\Validator\Constraints; @@ -16,44 +16,60 @@ use Symfony\Component\Validator\Constraints\SizeLengthValidator; class SizeLengthValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new SizeLengthValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new SizeLength(array('min' => 6, 'max' => 10)))); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new SizeLength(array('min' => 6, 'max' => 10)))); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new SizeLength(array('min' => 6, 'max' => 10))); } /** * @dataProvider getValidValues */ - public function testValidValues($value, $skip = false) + public function testValidValues($value, $mbOnly = false) { - if (!$skip) { - $constraint = new SizeLength(array('min' => 6, 'max' => 10)); - $this->assertTrue($this->validator->isValid($value, $constraint)); + if ($mbOnly && !function_exists('mb_strlen')) { + return $this->markTestSkipped('mb_strlen does not exist'); } + + $this->context->expects($this->never()) + ->method('addViolation'); + + $constraint = new SizeLength(array('min' => 6, 'max' => 10)); + $this->assertTrue($this->validator->isValid($value, $constraint)); } public function getValidValues() @@ -63,22 +79,27 @@ class SizeLengthValidatorTest extends \PHPUnit_Framework_TestCase array(1234567890), array('123456'), array('1234567890'), - array('üüüüüü', !function_exists('mb_strlen')), - array('üüüüüüüüüü', !function_exists('mb_strlen')), - array('éééééé', !function_exists('mb_strlen')), - array('éééééééééé', !function_exists('mb_strlen')), + array('üüüüüü', true), + array('üüüüüüüüüü', true), + array('éééééé', true), + array('éééééééééé', true), ); } /** * @dataProvider getInvalidValues */ - public function testInvalidValues($value, $skip = false) + public function testInvalidValues($value, $mbOnly = false) { - if (!$skip) { - $constraint = new SizeLength(array('min' => 6, 'max' => 10)); - $this->assertFalse($this->validator->isValid($value, $constraint)); + if ($mbOnly && !function_exists('mb_strlen')) { + return $this->markTestSkipped('mb_strlen does not exist'); } + + $this->context->expects($this->once()) + ->method('addViolation'); + + $constraint = new SizeLength(array('min' => 6, 'max' => 10)); + $this->assertFalse($this->validator->isValid($value, $constraint)); } public function getInvalidValues() @@ -88,49 +109,64 @@ class SizeLengthValidatorTest extends \PHPUnit_Framework_TestCase array(12345678901), array('12345'), array('12345678901'), - array('üüüüü', !function_exists('mb_strlen')), - array('üüüüüüüüüüü', !function_exists('mb_strlen')), - array('ééééé', !function_exists('mb_strlen')), - array('ééééééééééé', !function_exists('mb_strlen')), + array('üüüüü', true), + array('üüüüüüüüüüü', true), + array('ééééé', true), + array('ééééééééééé', true), ); } - public function testMessageIsSet() + public function testMinMessageIsSet() { $constraint = new SizeLength(array( 'min' => 5, 'max' => 10, - 'minMessage' => 'myMinMessage', - 'maxMessage' => 'myMaxMessage', + 'minMessage' => 'myMessage', )); - $this->assertFalse($this->validator->isValid('1234', $constraint)); - $this->assertEquals('myMinMessage', $this->validator->getMessageTemplate()); - $this->assertEquals(array( - '{{ value }}' => '1234', - '{{ limit }}' => 5, - ), $this->validator->getMessageParameters()); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => '1234', + '{{ limit }}' => 5, + )); - $this->assertFalse($this->validator->isValid('12345678901', $constraint)); - $this->assertEquals('myMaxMessage', $this->validator->getMessageTemplate()); - $this->assertEquals(array( - '{{ value }}' => '12345678901', - '{{ limit }}' => 10, - ), $this->validator->getMessageParameters()); + $this->assertFalse($this->validator->isValid('1234', $constraint)); } - public function testExactErrorMessage() + public function testMaxMessageIsSet() + { + $constraint = new SizeLength(array( + 'min' => 5, + 'max' => 10, + 'maxMessage' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => '12345678901', + '{{ limit }}' => 10, + )); + + $this->assertFalse($this->validator->isValid('12345678901', $constraint)); + } + + public function testExactMessageIsSet() { $constraint = new SizeLength(array( 'min' => 5, 'max' => 5, + 'exactMessage' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => '1234', + '{{ limit }}' => 5, + )); + $this->assertFalse($this->validator->isValid('1234', $constraint)); - $this->assertEquals('This value should have exactly {{ limit }} characters', $this->validator->getMessageTemplate()); - $this->assertEquals(array( - '{{ value }}' => '1234', - '{{ limit }}' => 5, - ), $this->validator->getMessageParameters()); } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/SizeValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/SizeValidatorTest.php index 49c39f37f4..48a448f17f 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/SizeValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/SizeValidatorTest.php @@ -16,15 +16,21 @@ use Symfony\Component\Validator\Constraints\SizeValidator; class SizeValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new SizeValidator(); + $this->validator->initialize($this->context); } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Size(array('min' => 10, 'max' => 20)))); } @@ -33,6 +39,9 @@ class SizeValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidValues($value) { + $this->context->expects($this->never()) + ->method('addViolation'); + $constraint = new Size(array('min' => 10, 'max' => 20)); $this->assertTrue($this->validator->isValid($value, $constraint)); } @@ -56,6 +65,9 @@ class SizeValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidValues($value) { + $this->context->expects($this->once()) + ->method('addViolation'); + $constraint = new Size(array('min' => 10, 'max' => 20)); $this->assertFalse($this->validator->isValid($value, $constraint)); } @@ -71,27 +83,39 @@ class SizeValidatorTest extends \PHPUnit_Framework_TestCase ); } - public function testMessageIsSet() + public function testMinMessageIsSet() { $constraint = new Size(array( 'min' => 10, 'max' => 20, - 'minMessage' => 'myMinMessage', - 'maxMessage' => 'myMaxMessage', + 'minMessage' => 'myMessage', )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => 9, + '{{ limit }}' => 10, + )); + $this->assertFalse($this->validator->isValid(9, $constraint)); - $this->assertEquals('myMinMessage', $this->validator->getMessageTemplate()); - $this->assertEquals(array( - '{{ value }}' => 9, - '{{ limit }}' => 10, - ), $this->validator->getMessageParameters()); + } + + public function testMaxMessageIsSet() + { + $constraint = new Size(array( + 'min' => 10, + 'max' => 20, + 'maxMessage' => 'myMessage', + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => 21, + '{{ limit }}' => 20, + )); $this->assertFalse($this->validator->isValid(21, $constraint)); - $this->assertEquals('myMaxMessage', $this->validator->getMessageTemplate()); - $this->assertEquals(array( - '{{ value }}' => 21, - '{{ limit }}' => 20, - ), $this->validator->getMessageParameters()); } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/TimeValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/TimeValidatorTest.php index 77089419c8..a97ec0f5d6 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/TimeValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/TimeValidatorTest.php @@ -16,37 +16,51 @@ use Symfony\Component\Validator\Constraints\TimeValidator; class TimeValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new TimeValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Time())); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Time())); } public function testDateTimeClassIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(new \DateTime(), new Time())); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new Time()); } @@ -55,6 +69,9 @@ class TimeValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidTimes($time) { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($time, new Time())); } @@ -72,7 +89,17 @@ class TimeValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidTimes($time) { - $this->assertFalse($this->validator->isValid($time, new Time())); + $constraint = new Time(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $time, + )); + + $this->assertFalse($this->validator->isValid($time, $constraint)); } public function getInvalidTimes() @@ -87,17 +114,4 @@ class TimeValidatorTest extends \PHPUnit_Framework_TestCase array('00:00:60'), ); } - - public function testMessageIsSet() - { - $constraint = new Time(array( - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - )); - } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/AssertTrueValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/TrueValidatorTest.php similarity index 67% rename from tests/Symfony/Tests/Component/Validator/Constraints/AssertTrueValidatorTest.php rename to tests/Symfony/Tests/Component/Validator/Constraints/TrueValidatorTest.php index 5045667449..d512aea88f 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/AssertTrueValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/TrueValidatorTest.php @@ -16,25 +16,35 @@ use Symfony\Component\Validator\Constraints\TrueValidator; class TrueValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new TrueValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new True())); } public function testTrueIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(true, new True())); } @@ -44,8 +54,11 @@ class TrueValidatorTest extends \PHPUnit_Framework_TestCase 'message' => 'myMessage' )); + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + )); + $this->assertFalse($this->validator->isValid(false, $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array()); } } diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/AssertTypeValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/TypeValidatorTest.php similarity index 60% rename from tests/Symfony/Tests/Component/Validator/Constraints/AssertTypeValidatorTest.php rename to tests/Symfony/Tests/Component/Validator/Constraints/TypeValidatorTest.php index 193a327c98..9e4d964195 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/AssertTypeValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/TypeValidatorTest.php @@ -19,25 +19,35 @@ class TypeValidatorTest extends \PHPUnit_Framework_TestCase { protected static $file; + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new TypeValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Type(array('type' => 'integer')))); } public function testEmptyIsValidIfString() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Type(array('type' => 'string')))); } @@ -51,6 +61,9 @@ class TypeValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidValues($value, $type) { + $this->context->expects($this->never()) + ->method('addViolation'); + $constraint = new Type(array('type' => $type)); $this->assertTrue($this->validator->isValid($value, $constraint)); @@ -96,81 +109,60 @@ class TypeValidatorTest extends \PHPUnit_Framework_TestCase /** * @dataProvider getInvalidValues */ - public function testInvalidValues($value, $type) + public function testInvalidValues($value, $type, $valueAsString) { - $constraint = new Type(array('type' => $type)); + $constraint = new Type(array( + 'type' => $type, + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $valueAsString, + '{{ type }}' => $type, + )); $this->assertFalse($this->validator->isValid($value, $constraint)); } - public function testConstraintViolationCanHandleArrayValue() - { - $constraint = new Type(array('type' => 'string')); - $this->validator->isValid(array(0 => "Test"), $constraint); - - $violation = new ConstraintViolation( - '{{ value }}', - $this->validator->getMessageParameters(), - '', - '', - '' - ); - - $this->assertEquals('Array', $violation->getMessage()); - } - public function getInvalidValues() { $object = new \stdClass(); $file = $this->createFile(); return array( - array('foobar', 'numeric'), - array('foobar', 'boolean'), - array('0', 'integer'), - array('1.5', 'float'), - array(12345, 'string'), - array($object, 'boolean'), - array($object, 'numeric'), - array($object, 'integer'), - array($object, 'float'), - array($object, 'string'), - array($object, 'resource'), - array($file, 'boolean'), - array($file, 'numeric'), - array($file, 'integer'), - array($file, 'float'), - array($file, 'string'), - array($file, 'object'), - array('12a34', 'digit'), - array('1a#23', 'alnum'), - array('abcd1', 'alpha'), - array("\nabc", 'cntrl'), - array("abc\n", 'graph'), - array('abCDE', 'lower'), - array('ABcde', 'upper'), - array("\nabc", 'print'), - array('abc&$!', 'punct'), - array("\nabc", 'space'), - array('AR1012', 'xdigit'), + array('foobar', 'numeric', 'foobar'), + array('foobar', 'boolean', 'foobar'), + array('0', 'integer', '0'), + array('1.5', 'float', '1.5'), + array(12345, 'string', '12345'), + array($object, 'boolean', 'stdClass'), + array($object, 'numeric', 'stdClass'), + array($object, 'integer', 'stdClass'), + array($object, 'float', 'stdClass'), + array($object, 'string', 'stdClass'), + array($object, 'resource', 'stdClass'), + array($file, 'boolean', (string) $file), + array($file, 'numeric', (string) $file), + array($file, 'integer', (string) $file), + array($file, 'float', (string) $file), + array($file, 'string', (string) $file), + array($file, 'object', (string) $file), + array('12a34', 'digit', '12a34'), + array('1a#23', 'alnum', '1a#23'), + array('abcd1', 'alpha', 'abcd1'), + array("\nabc", 'cntrl', "\nabc"), + array("abc\n", 'graph', "abc\n"), + array('abCDE', 'lower', 'abCDE'), + array('ABcde', 'upper', 'ABcde'), + array("\nabc", 'print', "\nabc"), + array('abc&$!', 'punct', 'abc&$!'), + array("\nabc", 'space', "\nabc"), + array('AR1012', 'xdigit', 'AR1012'), ); } - public function testMessageIsSet() - { - $constraint = new Type(array( - 'type' => 'numeric', - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - '{{ type }}' => 'numeric', - )); - } - protected function createFile() { if (!self::$file) { diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/UrlValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/UrlValidatorTest.php index f0c809fb2c..af44621baf 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/UrlValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/UrlValidatorTest.php @@ -16,32 +16,43 @@ use Symfony\Component\Validator\Constraints\UrlValidator; class UrlValidatorTest extends \PHPUnit_Framework_TestCase { + protected $context; protected $validator; protected function setUp() { + $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false); $this->validator = new UrlValidator(); + $this->validator->initialize($this->context); } protected function tearDown() { + $this->context = null; $this->validator = null; } public function testNullIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid(null, new Url())); } public function testEmptyStringIsValid() { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid('', new Url())); } + /** + * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException + */ public function testExpectsStringCompatibleType() { - $this->setExpectedException('Symfony\Component\Validator\Exception\UnexpectedTypeException'); - $this->validator->isValid(new \stdClass(), new Url()); } @@ -50,6 +61,9 @@ class UrlValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidUrls($url) { + $this->context->expects($this->never()) + ->method('addViolation'); + $this->assertTrue($this->validator->isValid($url, new Url())); } @@ -92,7 +106,17 @@ class UrlValidatorTest extends \PHPUnit_Framework_TestCase */ public function testInvalidUrls($url) { - $this->assertFalse($this->validator->isValid($url, new Url())); + $constraint = new Url(array( + 'message' => 'myMessage' + )); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('myMessage', array( + '{{ value }}' => $url, + )); + + $this->assertFalse($this->validator->isValid($url, $constraint)); } public function getInvalidUrls() @@ -118,6 +142,9 @@ class UrlValidatorTest extends \PHPUnit_Framework_TestCase */ public function testCustomProtocolIsValid($url) { + $this->context->expects($this->never()) + ->method('addViolation'); + $constraint = new Url(array( 'protocols' => array('ftp', 'file', 'git') )); @@ -133,17 +160,4 @@ class UrlValidatorTest extends \PHPUnit_Framework_TestCase array('git://[::1]/'), ); } - - public function testMessageIsSet() - { - $constraint = new Url(array( - 'message' => 'myMessage' - )); - - $this->assertFalse($this->validator->isValid('foobar', $constraint)); - $this->assertEquals($this->validator->getMessageTemplate(), 'myMessage'); - $this->assertEquals($this->validator->getMessageParameters(), array( - '{{ value }}' => 'foobar', - )); - } } diff --git a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php index 5b15a4d4c9..266a7aa759 100644 --- a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php +++ b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php @@ -105,10 +105,10 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testAddViolationAt() + public function testAddViolationAtPath() { // override preconfigured property path - $this->context->addViolationAt('bar.baz', 'Error', array('foo' => 'bar'), 'invalid'); + $this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), 'invalid'); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -121,9 +121,9 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testAddViolationAtUsesPreconfiguredValueIfNotPassed() + public function testAddViolationAtPathUsesPreconfiguredValueIfNotPassed() { - $this->context->addViolationAt('bar.baz', 'Error'); + $this->context->addViolationAtPath('bar.baz', 'Error'); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -136,10 +136,10 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testAddViolationAtUsesPassedNullValue() + public function testAddViolationAtPathUsesPassedNullValue() { // passed null value should override preconfigured value "invalid" - $this->context->addViolationAt('bar.baz', 'Error', array('foo' => 'bar'), null); + $this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), null); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -152,10 +152,10 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testAddNestedViolationAt() + public function testAddViolationAtRelativePath() { // override preconfigured property path - $this->context->addNestedViolationAt('bam.baz', 'Error', array('foo' => 'bar'), 'invalid'); + $this->context->addViolationAtRelativePath('bam.baz', 'Error', array('foo' => 'bar'), 'invalid'); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -168,84 +168,51 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testAddNestedViolationAtWithIndexPath() + public function testAddViolationAtRelativePathUsesPreconfiguredValueIfNotPassed() { - // override preconfigured property path - $this->context->addNestedViolationAt('[bam]', 'Error', array('foo' => 'bar'), 'invalid'); + $this->context->addViolationAtRelativePath('bam.baz', 'Error'); + + $this->assertEquals(new ConstraintViolationList(array( + new ConstraintViolation( + 'Error', + array(), + 'Root', + 'foo.bar.bam.baz', + 'currentValue' + ), + )), $this->context->getViolations()); + } + + public function testAddViolationAtRelativePathUsesPassedNullValue() + { + // passed null value should override preconfigured value "invalid" + $this->context->addViolationAtRelativePath('bam.baz', 'Error', array('foo' => 'bar'), null); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( 'Error', array('foo' => 'bar'), 'Root', - 'foo.bar[bam]', - 'invalid' + 'foo.bar.bam.baz', + null ), )), $this->context->getViolations()); } - public function testAddNestedViolationAtWithEmptyPath() + public function testGetAbsolutePropertyPathWithIndexPath() { - // override preconfigured property path - $this->context->addNestedViolationAt('', 'Error', array('foo' => 'bar'), 'invalid'); - - $this->assertEquals(new ConstraintViolationList(array( - new ConstraintViolation( - 'Error', - array('foo' => 'bar'), - 'Root', - 'foo.bar', - 'invalid' - ), - )), $this->context->getViolations()); + $this->assertEquals('foo.bar[bam]', $this->context->getAbsolutePropertyPath('[bam]')); } - public function testAddNestedViolationAtWithEmptyCurrentPropertyPath() + public function testGetAbsolutePropertyPathWithEmptyPath() + { + $this->assertEquals('foo.bar', $this->context->getAbsolutePropertyPath('')); + } + + public function testGetAbsolutePropertyPathWithEmptyCurrentPropertyPath() { $this->context = new ExecutionContext($this->globalContext, 'currentValue', '', 'Group', 'ClassName', 'propertyName'); - // override preconfigured property path - $this->context->addNestedViolationAt('bam.baz', 'Error', array('foo' => 'bar'), 'invalid'); - - $this->assertEquals(new ConstraintViolationList(array( - new ConstraintViolation( - 'Error', - array('foo' => 'bar'), - 'Root', - 'bam.baz', - 'invalid' - ), - )), $this->context->getViolations()); - } - - public function testAddNestedViolationAtUsesPreconfiguredValueIfNotPassed() - { - $this->context->addNestedViolationAt('bam.baz', 'Error'); - - $this->assertEquals(new ConstraintViolationList(array( - new ConstraintViolation( - 'Error', - array(), - 'Root', - 'foo.bar.bam.baz', - 'currentValue' - ), - )), $this->context->getViolations()); - } - - public function testAddNestedViolationAtUsesPassedNullValue() - { - // passed null value should override preconfigured value "invalid" - $this->context->addNestedViolationAt('bam.baz', 'Error', array('foo' => 'bar'), null); - - $this->assertEquals(new ConstraintViolationList(array( - new ConstraintViolation( - 'Error', - array('foo' => 'bar'), - 'Root', - 'foo.bar.bam.baz', - null - ), - )), $this->context->getViolations()); + $this->assertEquals('bam.baz', $this->context->getAbsolutePropertyPath('bam.baz')); } } diff --git a/tests/Symfony/Tests/Component/Validator/Fixtures/ConstraintAValidator.php b/tests/Symfony/Tests/Component/Validator/Fixtures/ConstraintAValidator.php index b052081700..148d3df6d4 100644 --- a/tests/Symfony/Tests/Component/Validator/Fixtures/ConstraintAValidator.php +++ b/tests/Symfony/Tests/Component/Validator/Fixtures/ConstraintAValidator.php @@ -20,7 +20,7 @@ class ConstraintAValidator extends ConstraintValidator public function isValid($value, Constraint $constraint) { if ('VALID' != $value) { - $this->setMessage('message', array('param' => 'value')); + $this->context->addViolation('message', array('param' => 'value')); return false; } diff --git a/tests/Symfony/Tests/Component/Validator/Fixtures/FailingConstraintValidator.php b/tests/Symfony/Tests/Component/Validator/Fixtures/FailingConstraintValidator.php index 920ffe177e..444c1b095b 100644 --- a/tests/Symfony/Tests/Component/Validator/Fixtures/FailingConstraintValidator.php +++ b/tests/Symfony/Tests/Component/Validator/Fixtures/FailingConstraintValidator.php @@ -9,7 +9,7 @@ class FailingConstraintValidator extends ConstraintValidator { public function isValid($value, Constraint $constraint) { - $this->setMessage($constraint->message, array()); + $this->context->addViolation($constraint->message, array()); return false; } From 2e4ebe444f8deb17907f50e1e130efc9dee6b364 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Thu, 2 Feb 2012 10:13:41 +0100 Subject: [PATCH 11/11] [Validator] Renamed methods addViolationAtRelativePath() and getAbsolutePropertyPath() in ExecutionContext --- .../Constraints/UniqueEntityValidator.php | 2 +- .../Constraints/CollectionValidator.php | 4 +-- .../Component/Validator/ExecutionContext.php | 19 ++++------- .../Constraints/CollectionValidatorTest.php | 34 +++++++++---------- .../Validator/ExecutionContextTest.php | 29 +++++++++------- 5 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index 8eedb4127c..1783a5a250 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -102,7 +102,7 @@ class UniqueEntityValidator extends ConstraintValidator return true; } - $this->context->addViolationAtRelativePath($fields[0], $constraint->message, array(), $criteria[$fields[0]]); + $this->context->addViolationAtSubPath($fields[0], $constraint->message, array(), $criteria[$fields[0]]); return true; // all true, we added the violation already! } diff --git a/src/Symfony/Component/Validator/Constraints/CollectionValidator.php b/src/Symfony/Component/Validator/Constraints/CollectionValidator.php index 4697d85761..ab537c2319 100644 --- a/src/Symfony/Component/Validator/Constraints/CollectionValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CollectionValidator.php @@ -68,7 +68,7 @@ class CollectionValidator extends ConstraintValidator $walker->walkConstraint($constr, $value[$field], $group, $propertyPath.'['.$field.']'); } } elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) { - $this->context->addViolationAtRelativePath('['.$field.']', $constraint->missingFieldsMessage, array( + $this->context->addViolationAtSubPath('['.$field.']', $constraint->missingFieldsMessage, array( '{{ field }}' => $field ), null); $valid = false; @@ -78,7 +78,7 @@ class CollectionValidator extends ConstraintValidator if (!$constraint->allowExtraFields) { foreach ($value as $field => $fieldValue) { if (!isset($constraint->fields[$field])) { - $this->context->addViolationAtRelativePath('['.$field.']', $constraint->extraFieldsMessage, array( + $this->context->addViolationAtSubPath('['.$field.']', $constraint->extraFieldsMessage, array( '{{ field }}' => $field ), $fieldValue); $valid = false; diff --git a/src/Symfony/Component/Validator/ExecutionContext.php b/src/Symfony/Component/Validator/ExecutionContext.php index 300f3b1c6f..a84e2e1811 100644 --- a/src/Symfony/Component/Validator/ExecutionContext.php +++ b/src/Symfony/Component/Validator/ExecutionContext.php @@ -96,18 +96,18 @@ class ExecutionContext * Adds a violation at the validation graph node with the given property * path relative to the current property path. * - * @param string $relativePath The relative property path for the violation. + * @param string $subPath The relative property path for the violation. * @param string $message The error message. * @param array $params The parameters parsed into the error message. * @param mixed $invalidValue The invalid, validated value. */ - public function addViolationAtRelativePath($relativePath, $message, array $params = array(), $invalidValue = null) + public function addViolationAtSubPath($subPath, $message, array $params = array(), $invalidValue = null) { $this->globalContext->addViolation(new ConstraintViolation( $message, $params, $this->globalContext->getRoot(), - $this->getAbsolutePropertyPath($relativePath), + $this->getPropertyPath($subPath), // check using func_num_args() to allow passing null values func_num_args() === 4 ? $invalidValue : $this->value )); @@ -128,18 +128,13 @@ class ExecutionContext return $this->globalContext->getRoot(); } - public function getPropertyPath() + public function getPropertyPath($subPath = null) { - return $this->propertyPath; - } - - public function getAbsolutePropertyPath($relativePath) - { - if ('' !== $this->propertyPath && '' !== $relativePath && '[' !== $relativePath[0]) { - return $this->propertyPath . '.' . $relativePath; + if (null !== $subPath && '' !== $this->propertyPath && '' !== $subPath && '[' !== $subPath[0]) { + return $this->propertyPath . '.' . $subPath; } - return $this->propertyPath . $relativePath; + return $this->propertyPath . $subPath; } public function getCurrentClass() diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php index b86ee08e41..8524af1a9c 100644 --- a/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/Constraints/CollectionValidatorTest.php @@ -59,7 +59,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase public function testNullIsValid() { $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $this->assertTrue($this->validator->isValid(null, new Collection(array('fields' => array( 'foo' => new Min(4), @@ -71,7 +71,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase $data = $this->prepareTestData(array('foo' => 'foobar')); $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $this->assertTrue($this->validator->isValid($data, new Collection(array( 'foo' => new Min(4), @@ -107,7 +107,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase $data = $this->prepareTestData($array); $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $this->assertTrue($this->validator->isValid($data, new Collection(array( 'fields' => array( @@ -141,7 +141,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase $data = $this->prepareTestData($array); $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $this->assertTrue($this->validator->isValid($data, new Collection(array( 'fields' => array( @@ -159,7 +159,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase )); $this->context->expects($this->once()) - ->method('addViolationAtRelativePath') + ->method('addViolationAtSubPath') ->with('[baz]', 'myMessage', array( '{{ field }}' => 'baz' )); @@ -186,7 +186,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase )); $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $this->assertTrue($this->validator->isValid($data, $constraint)); } @@ -206,7 +206,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase )); $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $this->assertTrue($this->validator->isValid($data, $constraint)); } @@ -223,7 +223,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase )); $this->context->expects($this->once()) - ->method('addViolationAtRelativePath') + ->method('addViolationAtSubPath') ->with('[foo]', 'myMessage', array( '{{ field }}' => 'foo', )); @@ -243,7 +243,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase )); $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $this->assertTrue($this->validator->isValid($data, $constraint)); } @@ -255,7 +255,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase )); $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $this->assertTrue($this->validator->isValid($data, new Collection(array( 'foo' => new Optional(), @@ -267,7 +267,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase $data = $this->prepareTestData(array()); $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $this->assertTrue($this->validator->isValid($data, new Collection(array( 'foo' => new Optional(), @@ -287,7 +287,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]'); $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $data = $this->prepareTestData($array); @@ -314,7 +314,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase } $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $data = $this->prepareTestData($array); @@ -330,7 +330,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase )); $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $this->assertTrue($this->validator->isValid($data, new Collection(array( 'foo' => new Required(), @@ -342,7 +342,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase $data = $this->prepareTestData(array()); $this->context->expects($this->once()) - ->method('addViolationAtRelativePath') + ->method('addViolationAtSubPath') ->with('[foo]', 'myMessage', array( '{{ field }}' => 'foo', )); @@ -368,7 +368,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]'); $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $data = $this->prepareTestData($array); @@ -395,7 +395,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase } $this->context->expects($this->never()) - ->method('addViolationAtRelativePath'); + ->method('addViolationAtSubPath'); $data = $this->prepareTestData($array); diff --git a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php index 266a7aa759..1d86dd9822 100644 --- a/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php +++ b/tests/Symfony/Tests/Component/Validator/ExecutionContextTest.php @@ -152,10 +152,10 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testAddViolationAtRelativePath() + public function testAddViolationAtSubPath() { // override preconfigured property path - $this->context->addViolationAtRelativePath('bam.baz', 'Error', array('foo' => 'bar'), 'invalid'); + $this->context->addViolationAtSubPath('bam.baz', 'Error', array('foo' => 'bar'), 'invalid'); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -168,9 +168,9 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testAddViolationAtRelativePathUsesPreconfiguredValueIfNotPassed() + public function testAddViolationAtSubPathUsesPreconfiguredValueIfNotPassed() { - $this->context->addViolationAtRelativePath('bam.baz', 'Error'); + $this->context->addViolationAtSubPath('bam.baz', 'Error'); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -183,10 +183,10 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testAddViolationAtRelativePathUsesPassedNullValue() + public function testAddViolationAtSubPathUsesPassedNullValue() { // passed null value should override preconfigured value "invalid" - $this->context->addViolationAtRelativePath('bam.baz', 'Error', array('foo' => 'bar'), null); + $this->context->addViolationAtSubPath('bam.baz', 'Error', array('foo' => 'bar'), null); $this->assertEquals(new ConstraintViolationList(array( new ConstraintViolation( @@ -199,20 +199,25 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase )), $this->context->getViolations()); } - public function testGetAbsolutePropertyPathWithIndexPath() + public function testGetPropertyPath() { - $this->assertEquals('foo.bar[bam]', $this->context->getAbsolutePropertyPath('[bam]')); + $this->assertEquals('foo.bar', $this->context->getPropertyPath()); } - public function testGetAbsolutePropertyPathWithEmptyPath() + public function testGetPropertyPathWithIndexPath() { - $this->assertEquals('foo.bar', $this->context->getAbsolutePropertyPath('')); + $this->assertEquals('foo.bar[bam]', $this->context->getPropertyPath('[bam]')); } - public function testGetAbsolutePropertyPathWithEmptyCurrentPropertyPath() + public function testGetPropertyPathWithEmptyPath() + { + $this->assertEquals('foo.bar', $this->context->getPropertyPath('')); + } + + public function testGetPropertyPathWithEmptyCurrentPropertyPath() { $this->context = new ExecutionContext($this->globalContext, 'currentValue', '', 'Group', 'ClassName', 'propertyName'); - $this->assertEquals('bam.baz', $this->context->getAbsolutePropertyPath('bam.baz')); + $this->assertEquals('bam.baz', $this->context->getPropertyPath('bam.baz')); } }