Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Form] Fixed ValidatorExtension to work with the 2.5 Validation API #11645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 15, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\Form\Extension\Validator;

use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
use Symfony\Component\Form\AbstractExtension;
use Symfony\Component\Validator\Constraints\Valid;
Expand All @@ -29,37 +30,42 @@ class ValidatorExtension extends AbstractExtension

/**
* @param ValidatorInterface|LegacyValidatorInterface $validator
*
* @throws UnexpectedTypeException If $validator is invalid
*/
public function __construct($validator)
{
// since validator apiVersion 2.5
// 2.5 API
if ($validator instanceof ValidatorInterface) {
$this->validator = $validator;

/** @var $metadata ClassMetadata */
$metadata = $this->validator->getMetadataFor('Symfony\Component\Form\Form');
// until validator apiVersion 2.4
$metadata = $validator->getMetadataFor('Symfony\Component\Form\Form');
// 2.4 API
} elseif ($validator instanceof LegacyValidatorInterface) {
$this->validator = $validator;

/** @var $metadata ClassMetadata */
$metadata = $this->validator->getMetadataFactory()->getMetadataFor('Symfony\Component\Form\Form');
$metadata = $validator->getMetadataFactory()->getMetadataFor('Symfony\Component\Form\Form');
} else {
throw new \InvalidArgumentException('Validator must be instance of Symfony\Component\Validator\Validator\ValidatorInterface or Symfony\Component\Validator\ValidatorInterface');
throw new UnexpectedTypeException($validator, 'Symfony\Component\Validator\Validator\ValidatorInterface or Symfony\Component\Validator\ValidatorInterface');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Symfony, we use the SPL InvalidArgumentException directly in places were we had to remove the typehint to support several classes because of a BC layer. I'm not sure we should switch to the Validator UnexpectedTypeException here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what you mean.. UnexpectedTypeException extends InvalidArgumentException, what's the problem?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, what I mean is that we generally don't use component exceptions for these cases (we use exception just because we cannot reproduce the behavior of PHP for unsatisfied typehints)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do use UnexpectedTypeExceptions quite often for that. At least in a couple of components (including Validator).

}

// Register the form constraints in the validator programmatically.
// This functionality is required when using the Form component without
// the DIC, where the XML file is loaded automatically. Thus the following
// code must be kept synchronized with validation.xml

/** @var $metadata ClassMetadata */
$metadata->addConstraint(new Form());
$metadata->addPropertyConstraint('children', new Valid());

$this->validator = $validator;
}

public function loadTypeGuesser()
{
return new ValidatorTypeGuesser($this->validator->getMetadataFactory());
// 2.4 API
if ($this->validator instanceof LegacyValidatorInterface) {
return new ValidatorTypeGuesser($this->validator->getMetadataFactory());
}

// 2.5 API - ValidatorInterface extends MetadataFactoryInterface
return new ValidatorTypeGuesser($this->validator);
}

protected function loadTypeExtensions()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,79 +15,70 @@

class ValidatorExtensionTest extends \PHPUnit_Framework_TestCase
{
public function testValidatorInterfaceSinceSymfony25()
public function test2Dot5ValidationApi()
{
$classMetaData = $this->createClassMetaDataMock();

// Mock of ValidatorInterface since apiVersion 2.5
$validator = $this->getMock('Symfony\Component\Validator\Validator\ValidatorInterface');
$metadata = $this->getMockBuilder('Symfony\Component\Validator\Mapping\ClassMetadata')
->disableOriginalConstructor()
->getMock();

$validator
->expects($this->once())
$validator->expects($this->once())
->method('getMetadataFor')
->with($this->identicalTo('Symfony\Component\Form\Form'))
->will($this->returnValue($classMetaData))
;
->will($this->returnValue($metadata));

// Verify that the constraints are added
$metadata->expects($this->once())
->method('addConstraint')
->with($this->isInstanceOf('Symfony\Component\Form\Extension\Validator\Constraints\Form'));

$metadata->expects($this->once())
->method('addPropertyConstraint')
->with('children', $this->isInstanceOf('Symfony\Component\Validator\Constraints\Valid'));

$validatorExtension = new ValidatorExtension($validator);
$this->assertAttributeSame($validator, 'validator', $validatorExtension);
$extension = new ValidatorExtension($validator);
$guesser = $extension->loadTypeGuesser();

$this->assertInstanceOf('Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser', $guesser);
}

public function testValidatorInterfaceUntilSymfony24()
public function test2Dot4ValidationApi()
{
$classMetaData = $this->createClassMetaDataMock();
$factory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
$validator = $this->getMock('Symfony\Component\Validator\ValidatorInterface');
$metadata = $this->getMockBuilder('Symfony\Component\Validator\Mapping\ClassMetadata')
->disableOriginalConstructor()
->getMock();

$metaDataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
$validator->expects($this->any())
->method('getMetadataFactory')
->will($this->returnValue($factory));

$metaDataFactory
->expects($this->once())
$factory->expects($this->once())
->method('getMetadataFor')
->with($this->identicalTo('Symfony\Component\Form\Form'))
->will($this->returnValue($classMetaData))
;
->will($this->returnValue($metadata));

// Mock of ValidatorInterface until apiVersion 2.4
$validator = $this->getMock('Symfony\Component\Validator\ValidatorInterface');
// Verify that the constraints are added
$metadata->expects($this->once())
->method('addConstraint')
->with($this->isInstanceOf('Symfony\Component\Form\Extension\Validator\Constraints\Form'));

$validator
->expects($this->once())
->method('getMetadataFactory')
->will($this->returnValue($metaDataFactory))
;
$metadata->expects($this->once())
->method('addPropertyConstraint')
->with('children', $this->isInstanceOf('Symfony\Component\Validator\Constraints\Valid'));

$validatorExtension = new ValidatorExtension($validator);
$this->assertAttributeSame($validator, 'validator', $validatorExtension);
$extension = new ValidatorExtension($validator);
$guesser = $extension->loadTypeGuesser();

$this->assertInstanceOf('Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser', $guesser);
}

/**
* @expectedException \InvalidArgumentException
* @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
*/
public function testInvalidValidatorInterface()
{
new ValidatorExtension(null);
}

/**
* @return mixed
*/
private function createClassMetaDataMock()
{
$classMetaData = $this->getMockBuilder('Symfony\Component\Validator\Mapping\ClassMetadata')
->disableOriginalConstructor()
->getMock();

$classMetaData
->expects($this->once())
->method('addConstraint')
->with($this->isInstanceOf('Symfony\Component\Form\Extension\Validator\Constraints\Form'));
$classMetaData
->expects($this->once())
->method('addPropertyConstraint')
->with(
$this->identicalTo('children'),
$this->isInstanceOf('Symfony\Component\Validator\Constraints\Valid')
);

return $classMetaData;
}
}