c2932f81e8b1f54acf3477fa6cce9180f051ff42
[yaffs-website] / vendor / symfony / validator / Test / ConstraintValidatorTestCase.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\Validator\Test;
13
14 use PHPUnit\Framework\Assert;
15 use PHPUnit\Framework\TestCase;
16 use Symfony\Component\Validator\Constraint;
17 use Symfony\Component\Validator\Constraints\NotNull;
18 use Symfony\Component\Validator\ConstraintValidatorInterface;
19 use Symfony\Component\Validator\ConstraintViolation;
20 use Symfony\Component\Validator\Context\ExecutionContext;
21 use Symfony\Component\Validator\Context\ExecutionContextInterface;
22 use Symfony\Component\Validator\Mapping\ClassMetadata;
23 use Symfony\Component\Validator\Mapping\PropertyMetadata;
24
25 /**
26  * A test case to ease testing Constraint Validators.
27  *
28  * @author Bernhard Schussek <bschussek@gmail.com>
29  */
30 abstract class ConstraintValidatorTestCase extends TestCase
31 {
32     /**
33      * @var ExecutionContextInterface
34      */
35     protected $context;
36
37     /**
38      * @var ConstraintValidatorInterface
39      */
40     protected $validator;
41
42     protected $group;
43     protected $metadata;
44     protected $object;
45     protected $value;
46     protected $root;
47     protected $propertyPath;
48     protected $constraint;
49     protected $defaultTimezone;
50
51     protected function setUp()
52     {
53         $this->group = 'MyGroup';
54         $this->metadata = null;
55         $this->object = null;
56         $this->value = 'InvalidValue';
57         $this->root = 'root';
58         $this->propertyPath = 'property.path';
59
60         // Initialize the context with some constraint so that we can
61         // successfully build a violation.
62         $this->constraint = new NotNull();
63
64         $this->context = $this->createContext();
65         $this->validator = $this->createValidator();
66         $this->validator->initialize($this->context);
67
68         \Locale::setDefault('en');
69
70         $this->setDefaultTimezone('UTC');
71     }
72
73     protected function tearDown()
74     {
75         $this->restoreDefaultTimezone();
76     }
77
78     protected function setDefaultTimezone($defaultTimezone)
79     {
80         // Make sure this method can not be called twice before calling
81         // also restoreDefaultTimezone()
82         if (null === $this->defaultTimezone) {
83             $this->defaultTimezone = date_default_timezone_get();
84             date_default_timezone_set($defaultTimezone);
85         }
86     }
87
88     protected function restoreDefaultTimezone()
89     {
90         if (null !== $this->defaultTimezone) {
91             date_default_timezone_set($this->defaultTimezone);
92             $this->defaultTimezone = null;
93         }
94     }
95
96     protected function createContext()
97     {
98         $translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock();
99         $validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock();
100         $contextualValidator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ContextualValidatorInterface')->getMock();
101
102         $context = new ExecutionContext($validator, $this->root, $translator);
103         $context->setGroup($this->group);
104         $context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
105         $context->setConstraint($this->constraint);
106
107         $validator->expects($this->any())
108             ->method('inContext')
109             ->with($context)
110             ->will($this->returnValue($contextualValidator));
111
112         return $context;
113     }
114
115     protected function setGroup($group)
116     {
117         $this->group = $group;
118         $this->context->setGroup($group);
119     }
120
121     protected function setObject($object)
122     {
123         $this->object = $object;
124         $this->metadata = is_object($object)
125             ? new ClassMetadata(get_class($object))
126             : null;
127
128         $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
129     }
130
131     protected function setProperty($object, $property)
132     {
133         $this->object = $object;
134         $this->metadata = is_object($object)
135             ? new PropertyMetadata(get_class($object), $property)
136             : null;
137
138         $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
139     }
140
141     protected function setValue($value)
142     {
143         $this->value = $value;
144         $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
145     }
146
147     protected function setRoot($root)
148     {
149         $this->root = $root;
150         $this->context = $this->createContext();
151         $this->validator->initialize($this->context);
152     }
153
154     protected function setPropertyPath($propertyPath)
155     {
156         $this->propertyPath = $propertyPath;
157         $this->context->setNode($this->value, $this->object, $this->metadata, $this->propertyPath);
158     }
159
160     protected function expectNoValidate()
161     {
162         $validator = $this->context->getValidator()->inContext($this->context);
163         $validator->expects($this->never())
164             ->method('atPath');
165         $validator->expects($this->never())
166             ->method('validate');
167     }
168
169     protected function expectValidateAt($i, $propertyPath, $value, $group)
170     {
171         $validator = $this->context->getValidator()->inContext($this->context);
172         $validator->expects($this->at(2 * $i))
173             ->method('atPath')
174             ->with($propertyPath)
175             ->will($this->returnValue($validator));
176         $validator->expects($this->at(2 * $i + 1))
177             ->method('validate')
178             ->with($value, $this->logicalOr(null, array(), $this->isInstanceOf('\Symfony\Component\Validator\Constraints\Valid')), $group);
179     }
180
181     protected function expectValidateValueAt($i, $propertyPath, $value, $constraints, $group = null)
182     {
183         $contextualValidator = $this->context->getValidator()->inContext($this->context);
184         $contextualValidator->expects($this->at(2 * $i))
185             ->method('atPath')
186             ->with($propertyPath)
187             ->will($this->returnValue($contextualValidator));
188         $contextualValidator->expects($this->at(2 * $i + 1))
189             ->method('validate')
190             ->with($value, $constraints, $group);
191     }
192
193     protected function assertNoViolation()
194     {
195         $this->assertSame(0, $violationsCount = count($this->context->getViolations()), sprintf('0 violation expected. Got %u.', $violationsCount));
196     }
197
198     /**
199      * @param $message
200      *
201      * @return ConstraintViolationAssertion
202      */
203     protected function buildViolation($message)
204     {
205         return new ConstraintViolationAssertion($this->context, $message, $this->constraint);
206     }
207
208     abstract protected function createValidator();
209 }
210
211 /**
212  * @internal
213  */
214 class ConstraintViolationAssertion
215 {
216     /**
217      * @var ExecutionContextInterface
218      */
219     private $context;
220
221     /**
222      * @var ConstraintViolationAssertion[]
223      */
224     private $assertions;
225
226     private $message;
227     private $parameters = array();
228     private $invalidValue = 'InvalidValue';
229     private $propertyPath = 'property.path';
230     private $translationDomain;
231     private $plural;
232     private $code;
233     private $constraint;
234     private $cause;
235
236     public function __construct(ExecutionContextInterface $context, $message, Constraint $constraint = null, array $assertions = array())
237     {
238         $this->context = $context;
239         $this->message = $message;
240         $this->constraint = $constraint;
241         $this->assertions = $assertions;
242     }
243
244     public function atPath($path)
245     {
246         $this->propertyPath = $path;
247
248         return $this;
249     }
250
251     public function setParameter($key, $value)
252     {
253         $this->parameters[$key] = $value;
254
255         return $this;
256     }
257
258     public function setParameters(array $parameters)
259     {
260         $this->parameters = $parameters;
261
262         return $this;
263     }
264
265     public function setTranslationDomain($translationDomain)
266     {
267         $this->translationDomain = $translationDomain;
268
269         return $this;
270     }
271
272     public function setInvalidValue($invalidValue)
273     {
274         $this->invalidValue = $invalidValue;
275
276         return $this;
277     }
278
279     public function setPlural($number)
280     {
281         $this->plural = $number;
282
283         return $this;
284     }
285
286     public function setCode($code)
287     {
288         $this->code = $code;
289
290         return $this;
291     }
292
293     public function setCause($cause)
294     {
295         $this->cause = $cause;
296
297         return $this;
298     }
299
300     public function buildNextViolation($message)
301     {
302         $assertions = $this->assertions;
303         $assertions[] = $this;
304
305         return new self($this->context, $message, $this->constraint, $assertions);
306     }
307
308     public function assertRaised()
309     {
310         $expected = array();
311         foreach ($this->assertions as $assertion) {
312             $expected[] = $assertion->getViolation();
313         }
314         $expected[] = $this->getViolation();
315
316         $violations = iterator_to_array($this->context->getViolations());
317
318         Assert::assertSame($expectedCount = count($expected), $violationsCount = count($violations), sprintf('%u violation(s) expected. Got %u.', $expectedCount, $violationsCount));
319
320         reset($violations);
321
322         foreach ($expected as $violation) {
323             Assert::assertEquals($violation, current($violations));
324             next($violations);
325         }
326     }
327
328     private function getViolation()
329     {
330         return new ConstraintViolation(
331             null,
332             $this->message,
333             $this->parameters,
334             $this->context->getRoot(),
335             $this->propertyPath,
336             $this->invalidValue,
337             $this->plural,
338             $this->code,
339             $this->constraint,
340             $this->cause
341         );
342     }
343 }