]> git.immae.eu Git - github/wallabag/wallabag.git/blob - vendor/symfony/form/Symfony/Component/Form/Tests/SimpleFormTest.php
twig implementation
[github/wallabag/wallabag.git] / vendor / symfony / form / Symfony / Component / Form / Tests / SimpleFormTest.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\Form\Tests;
13
14 use Symfony\Component\Form\Form;
15 use Symfony\Component\Form\FormEvent;
16 use Symfony\Component\Form\FormEvents;
17 use Symfony\Component\PropertyAccess\PropertyPath;
18 use Symfony\Component\Form\FormConfigBuilder;
19 use Symfony\Component\Form\FormError;
20 use Symfony\Component\Form\Exception\TransformationFailedException;
21 use Symfony\Component\EventDispatcher\EventDispatcher;
22 use Symfony\Component\Form\Tests\Fixtures\FixedDataTransformer;
23 use Symfony\Component\Form\Tests\Fixtures\FixedFilterListener;
24
25 class SimpleFormTest_Countable implements \Countable
26 {
27 private $count;
28
29 public function __construct($count)
30 {
31 $this->count = $count;
32 }
33
34 public function count()
35 {
36 return $this->count;
37 }
38 }
39
40 class SimpleFormTest_Traversable implements \IteratorAggregate
41 {
42 private $iterator;
43
44 public function __construct($count)
45 {
46 $this->iterator = new \ArrayIterator($count > 0 ? array_fill(0, $count, 'Foo') : array());
47 }
48
49 public function getIterator()
50 {
51 return $this->iterator;
52 }
53 }
54
55 class SimpleFormTest extends AbstractFormTest
56 {
57 public function testDataIsInitializedToConfiguredValue()
58 {
59 $model = new FixedDataTransformer(array(
60 'default' => 'foo',
61 ));
62 $view = new FixedDataTransformer(array(
63 'foo' => 'bar',
64 ));
65
66 $config = new FormConfigBuilder('name', null, $this->dispatcher);
67 $config->addViewTransformer($view);
68 $config->addModelTransformer($model);
69 $config->setData('default');
70 $form = new Form($config);
71
72 $this->assertSame('default', $form->getData());
73 $this->assertSame('foo', $form->getNormData());
74 $this->assertSame('bar', $form->getViewData());
75 }
76
77 // https://github.com/symfony/symfony/commit/d4f4038f6daf7cf88ca7c7ab089473cce5ebf7d8#commitcomment-1632879
78 public function testDataIsInitializedFromSubmit()
79 {
80 $mock = $this->getMockBuilder('\stdClass')
81 ->setMethods(array('preSetData', 'preSubmit'))
82 ->getMock();
83 $mock->expects($this->at(0))
84 ->method('preSetData');
85 $mock->expects($this->at(1))
86 ->method('preSubmit');
87
88 $config = new FormConfigBuilder('name', null, $this->dispatcher);
89 $config->addEventListener(FormEvents::PRE_SET_DATA, array($mock, 'preSetData'));
90 $config->addEventListener(FormEvents::PRE_SUBMIT, array($mock, 'preSubmit'));
91 $form = new Form($config);
92
93 // no call to setData() or similar where the object would be
94 // initialized otherwise
95
96 $form->submit('foobar');
97 }
98
99 // https://github.com/symfony/symfony/pull/7789
100 public function testFalseIsConvertedToNull()
101 {
102 $mock = $this->getMockBuilder('\stdClass')
103 ->setMethods(array('preBind'))
104 ->getMock();
105 $mock->expects($this->once())
106 ->method('preBind')
107 ->with($this->callback(function ($event) {
108 return null === $event->getData();
109 }));
110
111 $config = new FormConfigBuilder('name', null, $this->dispatcher);
112 $config->addEventListener(FormEvents::PRE_BIND, array($mock, 'preBind'));
113 $form = new Form($config);
114
115 $form->bind(false);
116
117 $this->assertTrue($form->isValid());
118 $this->assertNull($form->getData());
119 }
120
121 /**
122 * @expectedException \Symfony\Component\Form\Exception\AlreadySubmittedException
123 */
124 public function testSubmitThrowsExceptionIfAlreadySubmitted()
125 {
126 $this->form->submit(array());
127 $this->form->submit(array());
128 }
129
130 public function testSubmitIsIgnoredIfDisabled()
131 {
132 $form = $this->getBuilder()
133 ->setDisabled(true)
134 ->setData('initial')
135 ->getForm();
136
137 $form->submit('new');
138
139 $this->assertEquals('initial', $form->getData());
140 $this->assertTrue($form->isSubmitted());
141 }
142
143 public function testNeverRequiredIfParentNotRequired()
144 {
145 $parent = $this->getBuilder()->setRequired(false)->getForm();
146 $child = $this->getBuilder()->setRequired(true)->getForm();
147
148 $child->setParent($parent);
149
150 $this->assertFalse($child->isRequired());
151 }
152
153 public function testRequired()
154 {
155 $parent = $this->getBuilder()->setRequired(true)->getForm();
156 $child = $this->getBuilder()->setRequired(true)->getForm();
157
158 $child->setParent($parent);
159
160 $this->assertTrue($child->isRequired());
161 }
162
163 public function testNotRequired()
164 {
165 $parent = $this->getBuilder()->setRequired(true)->getForm();
166 $child = $this->getBuilder()->setRequired(false)->getForm();
167
168 $child->setParent($parent);
169
170 $this->assertFalse($child->isRequired());
171 }
172
173 public function testAlwaysDisabledIfParentDisabled()
174 {
175 $parent = $this->getBuilder()->setDisabled(true)->getForm();
176 $child = $this->getBuilder()->setDisabled(false)->getForm();
177
178 $child->setParent($parent);
179
180 $this->assertTrue($child->isDisabled());
181 }
182
183 public function testDisabled()
184 {
185 $parent = $this->getBuilder()->setDisabled(false)->getForm();
186 $child = $this->getBuilder()->setDisabled(true)->getForm();
187
188 $child->setParent($parent);
189
190 $this->assertTrue($child->isDisabled());
191 }
192
193 public function testNotDisabled()
194 {
195 $parent = $this->getBuilder()->setDisabled(false)->getForm();
196 $child = $this->getBuilder()->setDisabled(false)->getForm();
197
198 $child->setParent($parent);
199
200 $this->assertFalse($child->isDisabled());
201 }
202
203 public function testGetRootReturnsRootOfParent()
204 {
205 $parent = $this->getMockForm();
206 $parent->expects($this->once())
207 ->method('getRoot')
208 ->will($this->returnValue('ROOT'));
209
210 $this->form->setParent($parent);
211
212 $this->assertEquals('ROOT', $this->form->getRoot());
213 }
214
215 public function testGetRootReturnsSelfIfNoParent()
216 {
217 $this->assertSame($this->form, $this->form->getRoot());
218 }
219
220 public function testEmptyIfEmptyArray()
221 {
222 $this->form->setData(array());
223
224 $this->assertTrue($this->form->isEmpty());
225 }
226
227 public function testEmptyIfEmptyCountable()
228 {
229 $this->form = new Form(new FormConfigBuilder('name', __NAMESPACE__.'\SimpleFormTest_Countable', $this->dispatcher));
230
231 $this->form->setData(new SimpleFormTest_Countable(0));
232
233 $this->assertTrue($this->form->isEmpty());
234 }
235
236 public function testNotEmptyIfFilledCountable()
237 {
238 $this->form = new Form(new FormConfigBuilder('name', __NAMESPACE__.'\SimpleFormTest_Countable', $this->dispatcher));
239
240 $this->form->setData(new SimpleFormTest_Countable(1));
241
242 $this->assertFalse($this->form->isEmpty());
243 }
244
245 public function testEmptyIfEmptyTraversable()
246 {
247 $this->form = new Form(new FormConfigBuilder('name', __NAMESPACE__.'\SimpleFormTest_Traversable', $this->dispatcher));
248
249 $this->form->setData(new SimpleFormTest_Traversable(0));
250
251 $this->assertTrue($this->form->isEmpty());
252 }
253
254 public function testNotEmptyIfFilledTraversable()
255 {
256 $this->form = new Form(new FormConfigBuilder('name', __NAMESPACE__.'\SimpleFormTest_Traversable', $this->dispatcher));
257
258 $this->form->setData(new SimpleFormTest_Traversable(1));
259
260 $this->assertFalse($this->form->isEmpty());
261 }
262
263 public function testEmptyIfNull()
264 {
265 $this->form->setData(null);
266
267 $this->assertTrue($this->form->isEmpty());
268 }
269
270 public function testEmptyIfEmptyString()
271 {
272 $this->form->setData('');
273
274 $this->assertTrue($this->form->isEmpty());
275 }
276
277 public function testNotEmptyIfText()
278 {
279 $this->form->setData('foobar');
280
281 $this->assertFalse($this->form->isEmpty());
282 }
283
284 public function testValidIfSubmitted()
285 {
286 $form = $this->getBuilder()->getForm();
287 $form->submit('foobar');
288
289 $this->assertTrue($form->isValid());
290 }
291
292 public function testValidIfSubmittedAndDisabled()
293 {
294 $form = $this->getBuilder()->setDisabled(true)->getForm();
295 $form->submit('foobar');
296
297 $this->assertTrue($form->isValid());
298 }
299
300 public function testNotValidIfNotSubmitted()
301 {
302 $this->assertFalse($this->form->isValid());
303 }
304
305 public function testNotValidIfErrors()
306 {
307 $form = $this->getBuilder()->getForm();
308 $form->submit('foobar');
309 $form->addError(new FormError('Error!'));
310
311 $this->assertFalse($form->isValid());
312 }
313
314 public function testHasErrors()
315 {
316 $this->form->addError(new FormError('Error!'));
317
318 $this->assertCount(1, $this->form->getErrors());
319 }
320
321 public function testHasNoErrors()
322 {
323 $this->assertCount(0, $this->form->getErrors());
324 }
325
326 /**
327 * @expectedException \Symfony\Component\Form\Exception\AlreadySubmittedException
328 */
329 public function testSetParentThrowsExceptionIfAlreadySubmitted()
330 {
331 $this->form->submit(array());
332 $this->form->setParent($this->getBuilder('parent')->getForm());
333 }
334
335 public function testSubmitted()
336 {
337 $form = $this->getBuilder()->getForm();
338 $form->submit('foobar');
339
340 $this->assertTrue($form->isSubmitted());
341 }
342
343 public function testNotSubmitted()
344 {
345 $this->assertFalse($this->form->isSubmitted());
346 }
347
348 /**
349 * @expectedException \Symfony\Component\Form\Exception\AlreadySubmittedException
350 */
351 public function testSetDataThrowsExceptionIfAlreadySubmitted()
352 {
353 $this->form->submit(array());
354 $this->form->setData(null);
355 }
356
357 public function testSetDataClonesObjectIfNotByReference()
358 {
359 $data = new \stdClass();
360 $form = $this->getBuilder('name', null, '\stdClass')->setByReference(false)->getForm();
361 $form->setData($data);
362
363 $this->assertNotSame($data, $form->getData());
364 $this->assertEquals($data, $form->getData());
365 }
366
367 public function testSetDataDoesNotCloneObjectIfByReference()
368 {
369 $data = new \stdClass();
370 $form = $this->getBuilder('name', null, '\stdClass')->setByReference(true)->getForm();
371 $form->setData($data);
372
373 $this->assertSame($data, $form->getData());
374 }
375
376 public function testSetDataExecutesTransformationChain()
377 {
378 // use real event dispatcher now
379 $form = $this->getBuilder('name', new EventDispatcher())
380 ->addEventSubscriber(new FixedFilterListener(array(
381 'preSetData' => array(
382 'app' => 'filtered',
383 ),
384 )))
385 ->addModelTransformer(new FixedDataTransformer(array(
386 '' => '',
387 'filtered' => 'norm',
388 )))
389 ->addViewTransformer(new FixedDataTransformer(array(
390 '' => '',
391 'norm' => 'client',
392 )))
393 ->getForm();
394
395 $form->setData('app');
396
397 $this->assertEquals('filtered', $form->getData());
398 $this->assertEquals('norm', $form->getNormData());
399 $this->assertEquals('client', $form->getViewData());
400 }
401
402 public function testSetDataExecutesViewTransformersInOrder()
403 {
404 $form = $this->getBuilder()
405 ->addViewTransformer(new FixedDataTransformer(array(
406 '' => '',
407 'first' => 'second',
408 )))
409 ->addViewTransformer(new FixedDataTransformer(array(
410 '' => '',
411 'second' => 'third',
412 )))
413 ->getForm();
414
415 $form->setData('first');
416
417 $this->assertEquals('third', $form->getViewData());
418 }
419
420 public function testSetDataExecutesModelTransformersInReverseOrder()
421 {
422 $form = $this->getBuilder()
423 ->addModelTransformer(new FixedDataTransformer(array(
424 '' => '',
425 'second' => 'third',
426 )))
427 ->addModelTransformer(new FixedDataTransformer(array(
428 '' => '',
429 'first' => 'second',
430 )))
431 ->getForm();
432
433 $form->setData('first');
434
435 $this->assertEquals('third', $form->getNormData());
436 }
437
438 /*
439 * When there is no data transformer, the data must have the same format
440 * in all three representations
441 */
442 public function testSetDataConvertsScalarToStringIfNoTransformer()
443 {
444 $form = $this->getBuilder()->getForm();
445
446 $form->setData(1);
447
448 $this->assertSame('1', $form->getData());
449 $this->assertSame('1', $form->getNormData());
450 $this->assertSame('1', $form->getViewData());
451 }
452
453 /*
454 * Data in client format should, if possible, always be a string to
455 * facilitate differentiation between '0' and ''
456 */
457 public function testSetDataConvertsScalarToStringIfOnlyModelTransformer()
458 {
459 $form = $this->getBuilder()
460 ->addModelTransformer(new FixedDataTransformer(array(
461 '' => '',
462 1 => 23,
463 )))
464 ->getForm();
465
466 $form->setData(1);
467
468 $this->assertSame(1, $form->getData());
469 $this->assertSame(23, $form->getNormData());
470 $this->assertSame('23', $form->getViewData());
471 }
472
473 /*
474 * NULL remains NULL in app and norm format to remove the need to treat
475 * empty values and NULL explicitly in the application
476 */
477 public function testSetDataConvertsNullToStringIfNoTransformer()
478 {
479 $form = $this->getBuilder()->getForm();
480
481 $form->setData(null);
482
483 $this->assertNull($form->getData());
484 $this->assertNull($form->getNormData());
485 $this->assertSame('', $form->getViewData());
486 }
487
488 public function testSetDataIsIgnoredIfDataIsLocked()
489 {
490 $form = $this->getBuilder()
491 ->setData('default')
492 ->setDataLocked(true)
493 ->getForm();
494
495 $form->setData('foobar');
496
497 $this->assertSame('default', $form->getData());
498 }
499
500 public function testSubmitConvertsEmptyToNullIfNoTransformer()
501 {
502 $form = $this->getBuilder()->getForm();
503
504 $form->submit('');
505
506 $this->assertNull($form->getData());
507 $this->assertNull($form->getNormData());
508 $this->assertSame('', $form->getViewData());
509 }
510
511 public function testSubmitExecutesTransformationChain()
512 {
513 // use real event dispatcher now
514 $form = $this->getBuilder('name', new EventDispatcher())
515 ->addEventSubscriber(new FixedFilterListener(array(
516 'preSubmit' => array(
517 'client' => 'filteredclient',
518 ),
519 'onSubmit' => array(
520 'norm' => 'filterednorm',
521 ),
522 )))
523 ->addViewTransformer(new FixedDataTransformer(array(
524 '' => '',
525 // direction is reversed!
526 'norm' => 'filteredclient',
527 'filterednorm' => 'cleanedclient'
528 )))
529 ->addModelTransformer(new FixedDataTransformer(array(
530 '' => '',
531 // direction is reversed!
532 'app' => 'filterednorm',
533 )))
534 ->getForm();
535
536 $form->submit('client');
537
538 $this->assertEquals('app', $form->getData());
539 $this->assertEquals('filterednorm', $form->getNormData());
540 $this->assertEquals('cleanedclient', $form->getViewData());
541 }
542
543 public function testSubmitExecutesViewTransformersInReverseOrder()
544 {
545 $form = $this->getBuilder()
546 ->addViewTransformer(new FixedDataTransformer(array(
547 '' => '',
548 'third' => 'second',
549 )))
550 ->addViewTransformer(new FixedDataTransformer(array(
551 '' => '',
552 'second' => 'first',
553 )))
554 ->getForm();
555
556 $form->submit('first');
557
558 $this->assertEquals('third', $form->getNormData());
559 }
560
561 public function testSubmitExecutesModelTransformersInOrder()
562 {
563 $form = $this->getBuilder()
564 ->addModelTransformer(new FixedDataTransformer(array(
565 '' => '',
566 'second' => 'first',
567 )))
568 ->addModelTransformer(new FixedDataTransformer(array(
569 '' => '',
570 'third' => 'second',
571 )))
572 ->getForm();
573
574 $form->submit('first');
575
576 $this->assertEquals('third', $form->getData());
577 }
578
579 public function testSynchronizedByDefault()
580 {
581 $this->assertTrue($this->form->isSynchronized());
582 }
583
584 public function testSynchronizedAfterSubmission()
585 {
586 $this->form->submit('foobar');
587
588 $this->assertTrue($this->form->isSynchronized());
589 }
590
591 public function testNotSynchronizedIfViewReverseTransformationFailed()
592 {
593 $transformer = $this->getDataTransformer();
594 $transformer->expects($this->once())
595 ->method('reverseTransform')
596 ->will($this->throwException(new TransformationFailedException()));
597
598 $form = $this->getBuilder()
599 ->addViewTransformer($transformer)
600 ->getForm();
601
602 $form->submit('foobar');
603
604 $this->assertFalse($form->isSynchronized());
605 }
606
607 public function testNotSynchronizedIfModelReverseTransformationFailed()
608 {
609 $transformer = $this->getDataTransformer();
610 $transformer->expects($this->once())
611 ->method('reverseTransform')
612 ->will($this->throwException(new TransformationFailedException()));
613
614 $form = $this->getBuilder()
615 ->addModelTransformer($transformer)
616 ->getForm();
617
618 $form->submit('foobar');
619
620 $this->assertFalse($form->isSynchronized());
621 }
622
623 public function testEmptyDataCreatedBeforeTransforming()
624 {
625 $form = $this->getBuilder()
626 ->setEmptyData('foo')
627 ->addViewTransformer(new FixedDataTransformer(array(
628 '' => '',
629 // direction is reversed!
630 'bar' => 'foo',
631 )))
632 ->getForm();
633
634 $form->submit('');
635
636 $this->assertEquals('bar', $form->getData());
637 }
638
639 public function testEmptyDataFromClosure()
640 {
641 $test = $this;
642 $form = $this->getBuilder()
643 ->setEmptyData(function ($form) use ($test) {
644 // the form instance is passed to the closure to allow use
645 // of form data when creating the empty value
646 $test->assertInstanceOf('Symfony\Component\Form\FormInterface', $form);
647
648 return 'foo';
649 })
650 ->addViewTransformer(new FixedDataTransformer(array(
651 '' => '',
652 // direction is reversed!
653 'bar' => 'foo',
654 )))
655 ->getForm();
656
657 $form->submit('');
658
659 $this->assertEquals('bar', $form->getData());
660 }
661
662 public function testSubmitResetsErrors()
663 {
664 $this->form->addError(new FormError('Error!'));
665 $this->form->submit('foobar');
666
667 $this->assertSame(array(), $this->form->getErrors());
668 }
669
670 public function testCreateView()
671 {
672 $type = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
673 $view = $this->getMock('Symfony\Component\Form\FormView');
674 $form = $this->getBuilder()->setType($type)->getForm();
675
676 $type->expects($this->once())
677 ->method('createView')
678 ->with($form)
679 ->will($this->returnValue($view));
680
681 $this->assertSame($view, $form->createView());
682 }
683
684 public function testCreateViewWithParent()
685 {
686 $type = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
687 $view = $this->getMock('Symfony\Component\Form\FormView');
688 $parentForm = $this->getMock('Symfony\Component\Form\Test\FormInterface');
689 $parentView = $this->getMock('Symfony\Component\Form\FormView');
690 $form = $this->getBuilder()->setType($type)->getForm();
691 $form->setParent($parentForm);
692
693 $parentForm->expects($this->once())
694 ->method('createView')
695 ->will($this->returnValue($parentView));
696
697 $type->expects($this->once())
698 ->method('createView')
699 ->with($form, $parentView)
700 ->will($this->returnValue($view));
701
702 $this->assertSame($view, $form->createView());
703 }
704
705 public function testCreateViewWithExplicitParent()
706 {
707 $type = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
708 $view = $this->getMock('Symfony\Component\Form\FormView');
709 $parentView = $this->getMock('Symfony\Component\Form\FormView');
710 $form = $this->getBuilder()->setType($type)->getForm();
711
712 $type->expects($this->once())
713 ->method('createView')
714 ->with($form, $parentView)
715 ->will($this->returnValue($view));
716
717 $this->assertSame($view, $form->createView($parentView));
718 }
719
720 public function testGetErrorsAsString()
721 {
722 $this->form->addError(new FormError('Error!'));
723
724 $this->assertEquals("ERROR: Error!\n", $this->form->getErrorsAsString());
725 }
726
727 public function testFormCanHaveEmptyName()
728 {
729 $form = $this->getBuilder('')->getForm();
730
731 $this->assertEquals('', $form->getName());
732 }
733
734 public function testSetNullParentWorksWithEmptyName()
735 {
736 $form = $this->getBuilder('')->getForm();
737 $form->setParent(null);
738
739 $this->assertNull($form->getParent());
740 }
741
742 /**
743 * @expectedException \Symfony\Component\Form\Exception\LogicException
744 * @expectedExceptionMessage A form with an empty name cannot have a parent form.
745 */
746 public function testFormCannotHaveEmptyNameNotInRootLevel()
747 {
748 $this->getBuilder()
749 ->setCompound(true)
750 ->setDataMapper($this->getDataMapper())
751 ->add($this->getBuilder(''))
752 ->getForm();
753 }
754
755 public function testGetPropertyPathReturnsConfiguredPath()
756 {
757 $form = $this->getBuilder()->setPropertyPath('address.street')->getForm();
758
759 $this->assertEquals(new PropertyPath('address.street'), $form->getPropertyPath());
760 }
761
762 // see https://github.com/symfony/symfony/issues/3903
763 public function testGetPropertyPathDefaultsToNameIfParentHasDataClass()
764 {
765 $parent = $this->getBuilder(null, null, 'stdClass')
766 ->setCompound(true)
767 ->setDataMapper($this->getDataMapper())
768 ->getForm();
769 $form = $this->getBuilder('name')->getForm();
770 $parent->add($form);
771
772 $this->assertEquals(new PropertyPath('name'), $form->getPropertyPath());
773 }
774
775 // see https://github.com/symfony/symfony/issues/3903
776 public function testGetPropertyPathDefaultsToIndexedNameIfParentDataClassIsNull()
777 {
778 $parent = $this->getBuilder()
779 ->setCompound(true)
780 ->setDataMapper($this->getDataMapper())
781 ->getForm();
782 $form = $this->getBuilder('name')->getForm();
783 $parent->add($form);
784
785 $this->assertEquals(new PropertyPath('[name]'), $form->getPropertyPath());
786 }
787
788 public function testGetPropertyPathDefaultsToNameIfFirstParentWithoutInheritDataHasDataClass()
789 {
790 $grandParent = $this->getBuilder(null, null, 'stdClass')
791 ->setCompound(true)
792 ->setDataMapper($this->getDataMapper())
793 ->getForm();
794 $parent = $this->getBuilder()
795 ->setCompound(true)
796 ->setDataMapper($this->getDataMapper())
797 ->setInheritData(true)
798 ->getForm();
799 $form = $this->getBuilder('name')->getForm();
800 $grandParent->add($parent);
801 $parent->add($form);
802
803 $this->assertEquals(new PropertyPath('name'), $form->getPropertyPath());
804 }
805
806 public function testGetPropertyPathDefaultsToIndexedNameIfDataClassOfFirstParentWithoutInheritDataIsNull()
807 {
808 $grandParent = $this->getBuilder()
809 ->setCompound(true)
810 ->setDataMapper($this->getDataMapper())
811 ->getForm();
812 $parent = $this->getBuilder()
813 ->setCompound(true)
814 ->setDataMapper($this->getDataMapper())
815 ->setInheritData(true)
816 ->getForm();
817 $form = $this->getBuilder('name')->getForm();
818 $grandParent->add($parent);
819 $parent->add($form);
820
821 $this->assertEquals(new PropertyPath('[name]'), $form->getPropertyPath());
822 }
823
824 /**
825 * @expectedException \Symfony\Component\Form\Exception\LogicException
826 */
827 public function testViewDataMustNotBeObjectIfDataClassIsNull()
828 {
829 $config = new FormConfigBuilder('name', null, $this->dispatcher);
830 $config->addViewTransformer(new FixedDataTransformer(array(
831 '' => '',
832 'foo' => new \stdClass(),
833 )));
834 $form = new Form($config);
835
836 $form->setData('foo');
837 }
838
839 public function testViewDataMayBeArrayAccessIfDataClassIsNull()
840 {
841 $arrayAccess = $this->getMock('\ArrayAccess');
842 $config = new FormConfigBuilder('name', null, $this->dispatcher);
843 $config->addViewTransformer(new FixedDataTransformer(array(
844 '' => '',
845 'foo' => $arrayAccess,
846 )));
847 $form = new Form($config);
848
849 $form->setData('foo');
850
851 $this->assertSame($arrayAccess, $form->getViewData());
852 }
853
854 /**
855 * @expectedException \Symfony\Component\Form\Exception\LogicException
856 */
857 public function testViewDataMustBeObjectIfDataClassIsSet()
858 {
859 $config = new FormConfigBuilder('name', 'stdClass', $this->dispatcher);
860 $config->addViewTransformer(new FixedDataTransformer(array(
861 '' => '',
862 'foo' => array('bar' => 'baz'),
863 )));
864 $form = new Form($config);
865
866 $form->setData('foo');
867 }
868
869 /**
870 * @expectedException \Symfony\Component\Form\Exception\RuntimeException
871 */
872 public function testSetDataCannotInvokeItself()
873 {
874 // Cycle detection to prevent endless loops
875 $config = new FormConfigBuilder('name', 'stdClass', $this->dispatcher);
876 $config->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
877 $event->getForm()->setData('bar');
878 });
879 $form = new Form($config);
880
881 $form->setData('foo');
882 }
883
884 public function testSubmittingWrongDataIsIgnored()
885 {
886 $test = $this;
887
888 $child = $this->getBuilder('child', $this->dispatcher);
889 $child->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($test) {
890 // child form doesn't receive the wrong data that is submitted on parent
891 $test->assertNull($event->getData());
892 });
893
894 $parent = $this->getBuilder('parent', new EventDispatcher())
895 ->setCompound(true)
896 ->setDataMapper($this->getDataMapper())
897 ->add($child)
898 ->getForm();
899
900 $parent->submit('not-an-array');
901 }
902
903 public function testHandleRequestForwardsToRequestHandler()
904 {
905 $handler = $this->getMock('Symfony\Component\Form\RequestHandlerInterface');
906
907 $form = $this->getBuilder()
908 ->setRequestHandler($handler)
909 ->getForm();
910
911 $handler->expects($this->once())
912 ->method('handleRequest')
913 ->with($this->identicalTo($form), 'REQUEST');
914
915 $this->assertSame($form, $form->handleRequest('REQUEST'));
916 }
917
918 public function testFormInheritsParentData()
919 {
920 $child = $this->getBuilder('child')
921 ->setInheritData(true);
922
923 $parent = $this->getBuilder('parent')
924 ->setCompound(true)
925 ->setDataMapper($this->getDataMapper())
926 ->setData('foo')
927 ->addModelTransformer(new FixedDataTransformer(array(
928 'foo' => 'norm[foo]',
929 )))
930 ->addViewTransformer(new FixedDataTransformer(array(
931 'norm[foo]' => 'view[foo]',
932 )))
933 ->add($child)
934 ->getForm();
935
936 $this->assertSame('foo', $parent->get('child')->getData());
937 $this->assertSame('norm[foo]', $parent->get('child')->getNormData());
938 $this->assertSame('view[foo]', $parent->get('child')->getViewData());
939 }
940
941 /**
942 * @expectedException \Symfony\Component\Form\Exception\RuntimeException
943 */
944 public function testInheritDataDisallowsSetData()
945 {
946 $form = $this->getBuilder()
947 ->setInheritData(true)
948 ->getForm();
949
950 $form->setData('foo');
951 }
952
953 /**
954 * @expectedException \Symfony\Component\Form\Exception\RuntimeException
955 */
956 public function testGetDataRequiresParentToBeSetIfInheritData()
957 {
958 $form = $this->getBuilder()
959 ->setInheritData(true)
960 ->getForm();
961
962 $form->getData();
963 }
964
965 /**
966 * @expectedException \Symfony\Component\Form\Exception\RuntimeException
967 */
968 public function testGetNormDataRequiresParentToBeSetIfInheritData()
969 {
970 $form = $this->getBuilder()
971 ->setInheritData(true)
972 ->getForm();
973
974 $form->getNormData();
975 }
976
977 /**
978 * @expectedException \Symfony\Component\Form\Exception\RuntimeException
979 */
980 public function testGetViewDataRequiresParentToBeSetIfInheritData()
981 {
982 $form = $this->getBuilder()
983 ->setInheritData(true)
984 ->getForm();
985
986 $form->getViewData();
987 }
988
989 public function testPostSubmitDataIsNullIfInheritData()
990 {
991 $test = $this;
992 $form = $this->getBuilder()
993 ->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($test) {
994 $test->assertNull($event->getData());
995 })
996 ->setInheritData(true)
997 ->getForm();
998
999 $form->submit('foo');
1000 }
1001
1002 public function testSubmitIsNeverFiredIfInheritData()
1003 {
1004 $test = $this;
1005 $form = $this->getBuilder()
1006 ->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) use ($test) {
1007 $test->fail('The SUBMIT event should not be fired');
1008 })
1009 ->setInheritData(true)
1010 ->getForm();
1011
1012 $form->submit('foo');
1013 }
1014
1015 public function testInitializeSetsDefaultData()
1016 {
1017 $config = $this->getBuilder()->setData('DEFAULT')->getFormConfig();
1018 $form = $this->getMock('Symfony\Component\Form\Form', array('setData'), array($config));
1019
1020 $form->expects($this->once())
1021 ->method('setData')
1022 ->with($this->identicalTo('DEFAULT'));
1023
1024 /* @var Form $form */
1025 $form->initialize();
1026 }
1027
1028 /**
1029 * @expectedException \Symfony\Component\Form\Exception\RuntimeException
1030 */
1031 public function testInitializeFailsIfParent()
1032 {
1033 $parent = $this->getBuilder()->setRequired(false)->getForm();
1034 $child = $this->getBuilder()->setRequired(true)->getForm();
1035
1036 $child->setParent($parent);
1037
1038 $child->initialize();
1039 }
1040
1041 protected function createForm()
1042 {
1043 return $this->getBuilder()->getForm();
1044 }
1045 }