Browse Source

[FrameworkBundle] updated constraint validator factory to work with non-DIC validators

Kris Wallsmith 14 years ago
parent
commit
7639fde3f2

+ 24 - 15
src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php

@@ -13,10 +13,33 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Validator;
 
 use Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory;
 use Symfony\Component\DependencyInjection\Container;
+use Symfony\Component\Validator\Constraints\Blank as BlankConstraint;
 
 class ConstraintValidatorFactoryTest extends \PHPUnit_Framework_TestCase
 {
-    public function testLoadTaggedServiceIdsSetsValidators()
+    public function testGetInstanceCreatesValidator()
+    {
+        $class = get_class($this->getMockForAbstractClass('Symfony\\Component\\Validator\\ConstraintValidator'));
+
+        $constraint = $this->getMock('Symfony\\Component\\Validator\\Constraint');
+        $constraint
+            ->expects($this->once())
+            ->method('validatedBy')
+            ->will($this->returnValue($class));
+
+        $factory = new ConstraintValidatorFactory(new Container());
+        $this->assertInstanceOf($class, $factory->getInstance($constraint));
+    }
+
+    public function testGetInstanceReturnsExistingValidator()
+    {
+        $factory = new ConstraintValidatorFactory(new Container());
+        $v1 = $factory->getInstance(new BlankConstraint());
+        $v2 = $factory->getInstance(new BlankConstraint());
+        $this->assertSame($v1, $v2);
+    }
+
+    public function testGetInstanceReturnsService()
     {
         $service = 'validator_constraint_service';
         $alias = 'validator_constraint_alias';
@@ -47,18 +70,4 @@ class ConstraintValidatorFactoryTest extends \PHPUnit_Framework_TestCase
         $factory->loadTaggedServiceIds($container);
         $this->assertSame($validator, $factory->getInstance($constraint));
     }
-
-    public function testGetInstanceException()
-    {
-        $this->setExpectedException('InvalidArgumentException');
-
-        $constraint = $this->getMock('Symfony\\Component\\Validator\\Constraint');
-        $constraint
-            ->expects($this->once())
-            ->method('validatedBy')
-            ->will($this->returnValue('foo'));
-
-        $factory = new ConstraintValidatorFactory(new Container());
-        $factory->getInstance($constraint);
-    }
 }

+ 17 - 6
src/Symfony/Bundle/FrameworkBundle/Validator/ConstraintValidatorFactory.php

@@ -19,6 +19,21 @@ use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
 /**
  * Uses a service container to create constraint validators.
  *
+ * A constraint validator should be tagged as "validator.constraint_validator"
+ * in the service container and include an "alias" attribute:
+ *
+ *     <service id="some_doctrine_validator">
+ *         <argument type="service" id="doctrine.orm.some_entity_manager" />
+ *         <tag name="validator.constraint_validator" alias="some_alias" />
+ *     </service>
+ *
+ * A constraint may then return this alias in its validatedBy() method:
+ *
+ *     public function validatedBy()
+ *     {
+ *         return 'some_alias';
+ *     }
+ *
  * @author Kris Wallsmith <kris.wallsmith@symfony-project.com>
  */
 class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
@@ -56,18 +71,14 @@ class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
      * @param Constraint $constraint A constraint
      *
      * @return Symfony\Component\Validator\ConstraintValidator A validator for the supplied constraint
-     *
-     * @throws InvalidArgumentException If no validator for the supplied constraint is found
      */
     public function getInstance(Constraint $constraint)
     {
         $name = $constraint->validatedBy();
 
         if (!isset($this->validators[$name])) {
-            throw new \InvalidArgumentException(sprintf('There is no "%s" constraint validator.', $name));
-        }
-
-        if (is_string($this->validators[$name])) {
+            $this->validators[$name] = new $name();
+        } elseif (is_string($this->validators[$name])) {
             $this->validators[$name] = $this->container->get($this->validators[$name]);
         }