4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Validator\Tests\Validator;
14 use Symfony\Component\Validator\Constraints\Callback;
15 use Symfony\Component\Validator\Constraints\Valid;
16 use Symfony\Component\Validator\ConstraintViolationInterface;
17 use Symfony\Component\Validator\ExecutionContextInterface;
18 use Symfony\Component\Validator\MetadataFactoryInterface;
19 use Symfony\Component\Validator\Tests\Fixtures\Entity;
20 use Symfony\Component\Validator\Tests\Fixtures\Reference;
21 use Symfony\Component\Validator\ValidatorInterface as LegacyValidatorInterface;
24 * Verifies that a validator satisfies the API of Symfony < 2.5.
26 * @author Bernhard Schussek <bschussek@gmail.com>
29 abstract class AbstractLegacyApiTest extends AbstractValidatorTest
32 * @var LegacyValidatorInterface
37 * @param MetadataFactoryInterface $metadataFactory
39 * @return LegacyValidatorInterface
41 abstract protected function createValidator(MetadataFactoryInterface $metadataFactory, array $objectInitializers = array());
43 protected function setUp()
47 $this->validator = $this->createValidator($this->metadataFactory);
50 protected function validate($value, $constraints = null, $groups = null)
52 if (null === $constraints) {
53 $constraints = new Valid();
56 if ($constraints instanceof Valid) {
57 return $this->validator->validate($value, $groups, $constraints->traverse, $constraints->deep);
60 return $this->validator->validateValue($value, $constraints, $groups);
63 protected function validateProperty($object, $propertyName, $groups = null)
65 return $this->validator->validateProperty($object, $propertyName, $groups);
68 protected function validatePropertyValue($object, $propertyName, $value, $groups = null)
70 return $this->validator->validatePropertyValue($object, $propertyName, $value, $groups);
74 * @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException
76 public function testTraversableTraverseDisabled()
79 $entity = new Entity();
80 $traversable = new \ArrayIterator(array('key' => $entity));
82 $callback = function () use ($test) {
83 $test->fail('Should not be called');
86 $this->metadata->addConstraint(new Callback(array(
87 'callback' => $callback,
91 $this->validator->validate($traversable, 'Group');
95 * @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException
97 public function testRecursiveTraversableRecursiveTraversalDisabled()
100 $entity = new Entity();
101 $traversable = new \ArrayIterator(array(
102 2 => new \ArrayIterator(array('key' => $entity)),
105 $callback = function () use ($test) {
106 $test->fail('Should not be called');
109 $this->metadata->addConstraint(new Callback(array(
110 'callback' => $callback,
114 $this->validator->validate($traversable, 'Group');
117 public function testValidateInContext()
120 $entity = new Entity();
121 $entity->reference = new Reference();
123 $callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
124 $previousValue = $context->getValue();
125 $previousMetadata = $context->getMetadata();
126 $previousPath = $context->getPropertyPath();
127 $previousGroup = $context->getGroup();
129 $context->validate($value->reference, 'subpath');
131 // context changes shouldn't leak out of the validate() call
132 $test->assertSame($previousValue, $context->getValue());
133 $test->assertSame($previousMetadata, $context->getMetadata());
134 $test->assertSame($previousPath, $context->getPropertyPath());
135 $test->assertSame($previousGroup, $context->getGroup());
138 $callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
139 $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
140 $test->assertNull($context->getPropertyName());
141 $test->assertSame('subpath', $context->getPropertyPath());
142 $test->assertSame('Group', $context->getGroup());
143 $test->assertSame($test->referenceMetadata, $context->getMetadata());
144 $test->assertSame($test->metadataFactory, $context->getMetadataFactory());
145 $test->assertSame($entity, $context->getRoot());
146 $test->assertSame($entity->reference, $context->getValue());
147 $test->assertSame($entity->reference, $value);
149 $context->addViolation('Message %param%', array('%param%' => 'value'));
152 $this->metadata->addConstraint(new Callback(array(
153 'callback' => $callback1,
156 $this->referenceMetadata->addConstraint(new Callback(array(
157 'callback' => $callback2,
161 $violations = $this->validator->validate($entity, 'Group');
163 /* @var ConstraintViolationInterface[] $violations */
164 $this->assertCount(1, $violations);
165 $this->assertSame('Message value', $violations[0]->getMessage());
166 $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
167 $this->assertSame(array('%param%' => 'value'), $violations[0]->getParameters());
168 $this->assertSame('subpath', $violations[0]->getPropertyPath());
169 $this->assertSame($entity, $violations[0]->getRoot());
170 $this->assertSame($entity->reference, $violations[0]->getInvalidValue());
171 $this->assertNull($violations[0]->getPlural());
172 $this->assertNull($violations[0]->getCode());
175 public function testValidateArrayInContext()
178 $entity = new Entity();
179 $entity->reference = new Reference();
181 $callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
182 $previousValue = $context->getValue();
183 $previousMetadata = $context->getMetadata();
184 $previousPath = $context->getPropertyPath();
185 $previousGroup = $context->getGroup();
187 $context->validate(array('key' => $value->reference), 'subpath');
189 // context changes shouldn't leak out of the validate() call
190 $test->assertSame($previousValue, $context->getValue());
191 $test->assertSame($previousMetadata, $context->getMetadata());
192 $test->assertSame($previousPath, $context->getPropertyPath());
193 $test->assertSame($previousGroup, $context->getGroup());
196 $callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
197 $test->assertSame($test::REFERENCE_CLASS, $context->getClassName());
198 $test->assertNull($context->getPropertyName());
199 $test->assertSame('subpath[key]', $context->getPropertyPath());
200 $test->assertSame('Group', $context->getGroup());
201 $test->assertSame($test->referenceMetadata, $context->getMetadata());
202 $test->assertSame($test->metadataFactory, $context->getMetadataFactory());
203 $test->assertSame($entity, $context->getRoot());
204 $test->assertSame($entity->reference, $context->getValue());
205 $test->assertSame($entity->reference, $value);
207 $context->addViolation('Message %param%', array('%param%' => 'value'));
210 $this->metadata->addConstraint(new Callback(array(
211 'callback' => $callback1,
214 $this->referenceMetadata->addConstraint(new Callback(array(
215 'callback' => $callback2,
219 $violations = $this->validator->validate($entity, 'Group');
221 /* @var ConstraintViolationInterface[] $violations */
222 $this->assertCount(1, $violations);
223 $this->assertSame('Message value', $violations[0]->getMessage());
224 $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
225 $this->assertSame(array('%param%' => 'value'), $violations[0]->getParameters());
226 $this->assertSame('subpath[key]', $violations[0]->getPropertyPath());
227 $this->assertSame($entity, $violations[0]->getRoot());
228 $this->assertSame($entity->reference, $violations[0]->getInvalidValue());
229 $this->assertNull($violations[0]->getPlural());
230 $this->assertNull($violations[0]->getCode());
233 public function testAddCustomizedViolation()
235 $entity = new Entity();
237 $callback = function ($value, ExecutionContextInterface $context) {
238 $context->addViolation(
240 array('%param%' => 'value'),
247 $this->metadata->addConstraint(new Callback($callback));
249 $violations = $this->validator->validate($entity);
251 /* @var ConstraintViolationInterface[] $violations */
252 $this->assertCount(1, $violations);
253 $this->assertSame('Message value', $violations[0]->getMessage());
254 $this->assertSame('Message %param%', $violations[0]->getMessageTemplate());
255 $this->assertSame(array('%param%' => 'value'), $violations[0]->getParameters());
256 $this->assertSame('', $violations[0]->getPropertyPath());
257 $this->assertSame($entity, $violations[0]->getRoot());
258 $this->assertSame('Invalid value', $violations[0]->getInvalidValue());
259 $this->assertSame(2, $violations[0]->getPlural());
260 $this->assertSame('Code', $violations[0]->getCode());
263 public function testInitializeObjectsOnFirstValidation()
266 $entity = new Entity();
267 $entity->initialized = false;
269 // prepare initializers that set "initialized" to true
270 $initializer1 = $this->getMockBuilder('Symfony\\Component\\Validator\\ObjectInitializerInterface')->getMock();
271 $initializer2 = $this->getMockBuilder('Symfony\\Component\\Validator\\ObjectInitializerInterface')->getMock();
273 $initializer1->expects($this->once())
274 ->method('initialize')
276 ->will($this->returnCallback(function ($object) {
277 $object->initialized = true;
280 $initializer2->expects($this->once())
281 ->method('initialize')
284 $this->validator = $this->createValidator($this->metadataFactory, array(
289 // prepare constraint which
290 // * checks that "initialized" is set to true
291 // * validates the object again
292 $callback = function ($object, ExecutionContextInterface $context) use ($test) {
293 $test->assertTrue($object->initialized);
295 // validate again in same group
296 $context->validate($object);
298 // validate again in other group
299 $context->validate($object, '', 'SomeGroup');
302 $this->metadata->addConstraint(new Callback($callback));
304 $this->validate($entity);
306 $this->assertTrue($entity->initialized);
309 public function testGetMetadataFactory()
311 $this->assertSame($this->metadataFactory, $this->validator->getMetadataFactory());