From 5ed4d91bb864e5209938270918af95aaee5d900d Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Thu, 3 Feb 2011 10:40:53 +0100 Subject: [PATCH] [Validator] Implemented Execute constraint --- .../Validator/Constraints/Execute.php | 41 +++++++ .../Constraints/ExecuteValidator.php | 56 +++++++++ .../Constraints/ExecuteValidatorTest.php | 114 ++++++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 src/Symfony/Component/Validator/Constraints/Execute.php create mode 100644 src/Symfony/Component/Validator/Constraints/ExecuteValidator.php create mode 100644 tests/Symfony/Tests/Component/Validator/Constraints/ExecuteValidatorTest.php diff --git a/src/Symfony/Component/Validator/Constraints/Execute.php b/src/Symfony/Component/Validator/Constraints/Execute.php new file mode 100644 index 0000000000..8a366c406c --- /dev/null +++ b/src/Symfony/Component/Validator/Constraints/Execute.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +class Execute extends \Symfony\Component\Validator\Constraint +{ + public $methods; + + /** + * {@inheritDoc} + */ + public function requiredOptions() + { + return array('methods'); + } + + /** + * {@inheritDoc} + */ + public function defaultOption() + { + return 'methods'; + } + + /** + * {@inheritDoc} + */ + public function targets() + { + return self::CLASS_CONSTRAINT; + } +} diff --git a/src/Symfony/Component/Validator/Constraints/ExecuteValidator.php b/src/Symfony/Component/Validator/Constraints/ExecuteValidator.php new file mode 100644 index 0000000000..ac800ac1b4 --- /dev/null +++ b/src/Symfony/Component/Validator/Constraints/ExecuteValidator.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\UnexpectedTypeException; + +/** + * Validator for Execute constraint + * + * @author Bernhard Schussek + */ +class ExecuteValidator extends ConstraintValidator +{ + public function isValid($object, Constraint $constraint) + { + if (null === $object) { + return true; + } + + $methods = (array)$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 (!method_exists($object, $method)) { + throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Execute constraint does not exist', $method)); + } + + $object->$method($context); + + // restore context state + $context->setCurrentClass($currentClass); + $context->setCurrentProperty($currentProperty); + $context->setGroup($group); + $context->setPropertyPath($propertyPath); + } + + return true; + } +} \ No newline at end of file diff --git a/tests/Symfony/Tests/Component/Validator/Constraints/ExecuteValidatorTest.php b/tests/Symfony/Tests/Component/Validator/Constraints/ExecuteValidatorTest.php new file mode 100644 index 0000000000..5d50429c47 --- /dev/null +++ b/tests/Symfony/Tests/Component/Validator/Constraints/ExecuteValidatorTest.php @@ -0,0 +1,114 @@ + + * + * 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\ExecutionContext; +use Symfony\Component\Validator\ConstraintViolation; +use Symfony\Component\Validator\ConstraintViolationList; +use Symfony\Component\Validator\Constraints\Execute; +use Symfony\Component\Validator\Constraints\ExecuteValidator; + +class ExecuteValidatorTest_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'); + } + + public function validateTwo(ExecutionContext $context) + { + $context->addViolation('Other message', array('other parameter'), 'otherInvalidValue'); + } +} + +class ExecuteValidatorTest extends \PHPUnit_Framework_TestCase +{ + protected $validator; + protected $walker; + protected $context; + + protected function setUp() + { + $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->context->setCurrentClass('InitialClass'); + $this->context->setCurrentProperty('initialProperty'); + $this->context->setGroup('InitialGroup'); + $this->context->setPropertyPath('initial.property.path'); + + $this->validator = new ExecuteValidator(); + $this->validator->initialize($this->context); + } + + public function testNullIsValid() + { + $this->assertTrue($this->validator->isValid(null, new Execute('foo'))); + } + + public function testExecuteSingleMethod() + { + $object = new ExecuteValidatorTest_Object(); + + $this->assertTrue($this->validator->isValid($object, new Execute('validateOne'))); + + $violations = new ConstraintViolationList(); + $violations->add(new ConstraintViolation( + 'My message', + array('parameter'), + 'Root', + 'foo.bar', + 'invalidValue' + )); + + $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 testExecuteMultipleMethods() + { + $object = new ExecuteValidatorTest_Object(); + + $this->assertTrue($this->validator->isValid($object, new Execute(array( + 'validateOne', 'validateTwo' + )))); + + $violations = new ConstraintViolationList(); + $violations->add(new ConstraintViolation( + 'My message', + array('parameter'), + 'Root', + 'foo.bar', + 'invalidValue' + )); + + // context was reset + $violations->add(new ConstraintViolation( + 'Other message', + array('other parameter'), + 'Root', + 'initial.property.path', + 'otherInvalidValue' + )); + + $this->assertEquals($violations, $this->context->getViolations()); + } +} \ No newline at end of file