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;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\Validator\Constraints\Collection;
16 use Symfony\Component\Validator\Constraints\All;
17 use Symfony\Component\Validator\ConstraintValidatorFactory;
18 use Symfony\Component\Validator\ConstraintViolation;
19 use Symfony\Component\Validator\ConstraintViolationList;
20 use Symfony\Component\Validator\ExecutionContext;
21 use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
22 use Symfony\Component\Validator\ValidationVisitor;
27 class LegacyExecutionContextTest extends TestCase
29 const TRANS_DOMAIN = 'trans_domain';
34 private $metadataFactory;
35 private $globalContext;
39 * @var ExecutionContext
43 protected function setUp()
45 $this->visitor = $this->getMockBuilder('Symfony\Component\Validator\ValidationVisitor')
46 ->disableOriginalConstructor()
48 $this->violations = new ConstraintViolationList();
49 $this->metadata = $this->getMockBuilder('Symfony\Component\Validator\MetadataInterface')->getMock();
50 $this->metadataFactory = $this->getMockBuilder('Symfony\Component\Validator\MetadataFactoryInterface')->getMock();
51 $this->globalContext = $this->getMockBuilder('Symfony\Component\Validator\GlobalExecutionContextInterface')->getMock();
52 $this->globalContext->expects($this->any())
54 ->will($this->returnValue('Root'));
55 $this->globalContext->expects($this->any())
56 ->method('getViolations')
57 ->will($this->returnValue($this->violations));
58 $this->globalContext->expects($this->any())
59 ->method('getVisitor')
60 ->will($this->returnValue($this->visitor));
61 $this->globalContext->expects($this->any())
62 ->method('getMetadataFactory')
63 ->will($this->returnValue($this->metadataFactory));
64 $this->translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock();
65 $this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', 'foo.bar');
68 protected function tearDown()
70 $this->globalContext = null;
71 $this->context = null;
74 public function testInit()
76 $this->assertCount(0, $this->context->getViolations());
77 $this->assertSame('Root', $this->context->getRoot());
78 $this->assertSame('foo.bar', $this->context->getPropertyPath());
79 $this->assertSame('Group', $this->context->getGroup());
82 public function testClone()
84 $clone = clone $this->context;
86 // Cloning the context keeps the reference to the original violation
87 // list. This way we can efficiently duplicate context instances during
88 // the validation run and only modify the properties that need to be
90 $this->assertSame($this->context->getViolations(), $clone->getViolations());
93 public function testAddViolation()
95 $this->translator->expects($this->once())
97 ->with('Error', array('foo' => 'bar'))
98 ->will($this->returnValue('Translated error'));
100 $this->context->addViolation('Error', array('foo' => 'bar'), 'invalid');
102 $this->assertEquals(new ConstraintViolationList(array(
103 new ConstraintViolation(
106 array('foo' => 'bar'),
111 )), $this->context->getViolations());
114 public function testAddViolationUsesPreconfiguredValueIfNotPassed()
116 $this->translator->expects($this->once())
118 ->with('Error', array())
119 ->will($this->returnValue('Translated error'));
121 $this->context->addViolation('Error');
123 $this->assertEquals(new ConstraintViolationList(array(
124 new ConstraintViolation(
132 )), $this->context->getViolations());
135 public function testAddViolationUsesPassedNullValue()
137 $this->translator->expects($this->once())
139 ->with('Error', array('foo1' => 'bar1'))
140 ->will($this->returnValue('Translated error'));
141 $this->translator->expects($this->once())
142 ->method('transChoice')
143 ->with('Choice error', 1, array('foo2' => 'bar2'))
144 ->will($this->returnValue('Translated choice error'));
146 // passed null value should override preconfigured value "invalid"
147 $this->context->addViolation('Error', array('foo1' => 'bar1'), null);
148 $this->context->addViolation('Choice error', array('foo2' => 'bar2'), null, 1);
150 $this->assertEquals(new ConstraintViolationList(array(
151 new ConstraintViolation(
154 array('foo1' => 'bar1'),
159 new ConstraintViolation(
160 'Translated choice error',
162 array('foo2' => 'bar2'),
168 )), $this->context->getViolations());
171 public function testAddViolationAt()
173 $this->translator->expects($this->once())
175 ->with('Error', array('foo' => 'bar'))
176 ->will($this->returnValue('Translated error'));
178 // override preconfigured property path
179 $this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), 'invalid');
181 $this->assertEquals(new ConstraintViolationList(array(
182 new ConstraintViolation(
185 array('foo' => 'bar'),
190 )), $this->context->getViolations());
193 public function testAddViolationAtUsesPreconfiguredValueIfNotPassed()
195 $this->translator->expects($this->once())
197 ->with('Error', array())
198 ->will($this->returnValue('Translated error'));
200 $this->context->addViolationAt('bam.baz', 'Error');
202 $this->assertEquals(new ConstraintViolationList(array(
203 new ConstraintViolation(
211 )), $this->context->getViolations());
214 public function testAddViolationAtUsesPassedNullValue()
216 $this->translator->expects($this->once())
218 ->with('Error', array('foo' => 'bar'))
219 ->will($this->returnValue('Translated error'));
220 $this->translator->expects($this->once())
221 ->method('transChoice')
222 ->with('Choice error', 2, array('foo' => 'bar'))
223 ->will($this->returnValue('Translated choice error'));
225 // passed null value should override preconfigured value "invalid"
226 $this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), null);
227 $this->context->addViolationAt('bam.baz', 'Choice error', array('foo' => 'bar'), null, 2);
229 $this->assertEquals(new ConstraintViolationList(array(
230 new ConstraintViolation(
233 array('foo' => 'bar'),
238 new ConstraintViolation(
239 'Translated choice error',
241 array('foo' => 'bar'),
247 )), $this->context->getViolations());
250 public function testAddViolationPluralTranslationError()
252 $this->translator->expects($this->once())
253 ->method('transChoice')
255 ->will($this->throwException(new \InvalidArgumentException()));
256 $this->translator->expects($this->once())
260 $this->context->addViolation('foo', array(), null, 2);
263 public function testGetPropertyPath()
265 $this->assertEquals('foo.bar', $this->context->getPropertyPath());
268 public function testGetPropertyPathWithIndexPath()
270 $this->assertEquals('foo.bar[bam]', $this->context->getPropertyPath('[bam]'));
273 public function testGetPropertyPathWithEmptyPath()
275 $this->assertEquals('foo.bar', $this->context->getPropertyPath(''));
278 public function testGetPropertyPathWithEmptyCurrentPropertyPath()
280 $this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', '');
282 $this->assertEquals('bam.baz', $this->context->getPropertyPath('bam.baz'));
285 public function testGetPropertyPathWithNestedCollectionsAndAllMixed()
287 $constraints = new Collection(array(
288 'shelves' => new All(array('constraints' => array(
289 new Collection(array(
290 'name' => new ConstraintA(),
291 'books' => new All(array('constraints' => array(
296 'name' => new ConstraintA(),
301 'name' => 'Research',
302 'books' => array('foo', 'bar'),
306 'books' => array('foozy', 'VALID', 'bazzy'),
311 $expectedViolationPaths = array(
312 '[shelves][0][name]',
313 '[shelves][0][books][0]',
314 '[shelves][0][books][1]',
315 '[shelves][1][books][0]',
316 '[shelves][1][books][2]',
320 $visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory(), $this->translator);
321 $context = new ExecutionContext($visitor, $this->translator, self::TRANS_DOMAIN);
322 $context->validateValue($data, $constraints);
324 foreach ($context->getViolations() as $violation) {
325 $violationPaths[] = $violation->getPropertyPath();
328 $this->assertEquals($expectedViolationPaths, $violationPaths);
332 class ExecutionContextTest_TestClass