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\Form\Tests\Extension\Core\Type
;
14 use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList
;
15 use Symfony\Component\Form\Extension\Core\View\ChoiceView
;
17 class ChoiceTypeTest
extends \Symfony\Component\Form\Test\TypeTestCase
19 private $choices = array(
27 private $numericChoices = array(
35 private $objectChoices;
37 protected $groupedChoices = array(
49 protected function setUp()
53 $this->objectChoices
= array(
54 (object) array('id' => 1, 'name' => 'Bernhard'),
55 (object) array('id' => 2, 'name' => 'Fabien'),
56 (object) array('id' => 3, 'name' => 'Kris'),
57 (object) array('id' => 4, 'name' => 'Jon'),
58 (object) array('id' => 5, 'name' => 'Roman'),
62 protected function tearDown()
66 $this->objectChoices
= null;
70 * @expectedException \PHPUnit_Framework_Error
72 public function testChoicesOptionExpectsArray()
74 $this->factory
->create('choice', null, array(
75 'choices' => new \
ArrayObject(),
80 * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
82 public function testChoiceListOptionExpectsChoiceListInterface()
84 $this->factory
->create('choice', null, array(
85 'choice_list' => array('foo' => 'foo'),
89 public function testChoiceListAndChoicesCanBeEmpty()
91 $this->factory
->create('choice');
94 public function testExpandedChoicesOptionsTurnIntoChildren()
96 $form = $this->factory
->create('choice', null, array(
98 'choices' => $this->choices
,
101 $this->assertCount(count($this->choices
), $form, 'Each choice should become a new field');
104 public function testPlaceholderPresentOnNonRequiredExpandedSingleChoice()
106 $form = $this->factory
->create('choice', null, array(
110 'choices' => $this->choices
,
113 $this->assertTrue(isset($form['placeholder']));
114 $this->assertCount(count($this->choices
) +
1, $form, 'Each choice should become a new field');
117 public function testPlaceholderNotPresentIfRequired()
119 $form = $this->factory
->create('choice', null, array(
123 'choices' => $this->choices
,
126 $this->assertFalse(isset($form['placeholder']));
127 $this->assertCount(count($this->choices
), $form, 'Each choice should become a new field');
130 public function testPlaceholderNotPresentIfMultiple()
132 $form = $this->factory
->create('choice', null, array(
136 'choices' => $this->choices
,
139 $this->assertFalse(isset($form['placeholder']));
140 $this->assertCount(count($this->choices
), $form, 'Each choice should become a new field');
143 public function testPlaceholderNotPresentIfEmptyChoice()
145 $form = $this->factory
->create('choice', null, array(
155 $this->assertFalse(isset($form['placeholder']));
156 $this->assertCount(2, $form, 'Each choice should become a new field');
159 public function testExpandedChoicesOptionsAreFlattened()
161 $form = $this->factory
->create('choice', null, array(
163 'choices' => $this->groupedChoices
,
166 $flattened = array();
167 foreach ($this->groupedChoices
as $choices) {
168 $flattened = array_merge($flattened, array_keys($choices));
171 $this->assertCount($form->count(), $flattened, 'Each nested choice should become a new field, not the groups');
173 foreach ($flattened as $value => $choice) {
174 $this->assertTrue($form->has($value), 'Flattened choice is named after it\'s value');
178 public function testExpandedCheckboxesAreNeverRequired()
180 $form = $this->factory
->create('choice', null, array(
184 'choices' => $this->choices
,
187 foreach ($form as $child) {
188 $this->assertFalse($child->isRequired());
192 public function testExpandedRadiosAreRequiredIfChoiceChildIsRequired()
194 $form = $this->factory
->create('choice', null, array(
198 'choices' => $this->choices
,
201 foreach ($form as $child) {
202 $this->assertTrue($child->isRequired());
206 public function testExpandedRadiosAreNotRequiredIfChoiceChildIsNotRequired()
208 $form = $this->factory
->create('choice', null, array(
212 'choices' => $this->choices
,
215 foreach ($form as $child) {
216 $this->assertFalse($child->isRequired());
220 public function testSubmitSingleNonExpanded()
222 $form = $this->factory
->create('choice', null, array(
225 'choices' => $this->choices
,
230 $this->assertEquals('b', $form->getData());
231 $this->assertEquals('b', $form->getViewData());
234 public function testSubmitSingleNonExpandedObjectChoices()
236 $form = $this->factory
->create('choice', null, array(
239 'choice_list' => new ObjectChoiceList(
240 $this->objectChoices
,
250 // "id" value of the second entry
253 $this->assertEquals($this->objectChoices
[1], $form->getData());
254 $this->assertEquals('2', $form->getViewData());
257 public function testSubmitMultipleNonExpanded()
259 $form = $this->factory
->create('choice', null, array(
262 'choices' => $this->choices
,
265 $form->submit(array('a', 'b'));
267 $this->assertEquals(array('a', 'b'), $form->getData());
268 $this->assertEquals(array('a', 'b'), $form->getViewData());
271 public function testSubmitMultipleNonExpandedObjectChoices()
273 $form = $this->factory
->create('choice', null, array(
276 'choice_list' => new ObjectChoiceList(
277 $this->objectChoices
,
287 $form->submit(array('2', '3'));
289 $this->assertEquals(array($this->objectChoices
[1], $this->objectChoices
[2]), $form->getData());
290 $this->assertEquals(array('2', '3'), $form->getViewData());
293 public function testSubmitSingleExpandedRequired()
295 $form = $this->factory
->create('choice', null, array(
299 'choices' => $this->choices
,
304 $this->assertSame('b', $form->getData());
305 $this->assertSame(array(
311 ), $form->getViewData());
313 $this->assertFalse($form[0]->getData());
314 $this->assertTrue($form[1]->getData());
315 $this->assertFalse($form[2]->getData());
316 $this->assertFalse($form[3]->getData());
317 $this->assertFalse($form[4]->getData());
318 $this->assertNull($form[0]->getViewData());
319 $this->assertSame('b', $form[1]->getViewData());
320 $this->assertNull($form[2]->getViewData());
321 $this->assertNull($form[3]->getViewData());
322 $this->assertNull($form[4]->getViewData());
325 public function testSubmitSingleExpandedNonRequired()
327 $form = $this->factory
->create('choice', null, array(
331 'choices' => $this->choices
,
336 $this->assertSame('b', $form->getData());
337 $this->assertSame(array(
343 'placeholder' => false,
344 ), $form->getViewData());
346 $this->assertFalse($form['placeholder']->getData());
347 $this->assertFalse($form[0]->getData());
348 $this->assertTrue($form[1]->getData());
349 $this->assertFalse($form[2]->getData());
350 $this->assertFalse($form[3]->getData());
351 $this->assertFalse($form[4]->getData());
352 $this->assertNull($form['placeholder']->getViewData());
353 $this->assertNull($form[0]->getViewData());
354 $this->assertSame('b', $form[1]->getViewData());
355 $this->assertNull($form[2]->getViewData());
356 $this->assertNull($form[3]->getViewData());
357 $this->assertNull($form[4]->getViewData());
360 public function testSubmitSingleExpandedRequiredNothingChecked()
362 $form = $this->factory
->create('choice', null, array(
366 'choices' => $this->choices
,
371 $this->assertNull($form->getData());
372 $this->assertSame(array(
378 ), $form->getViewData());
380 $this->assertFalse($form[0]->getData());
381 $this->assertFalse($form[1]->getData());
382 $this->assertFalse($form[2]->getData());
383 $this->assertFalse($form[3]->getData());
384 $this->assertFalse($form[4]->getData());
385 $this->assertNull($form[0]->getViewData());
386 $this->assertNull($form[1]->getViewData());
387 $this->assertNull($form[2]->getViewData());
388 $this->assertNull($form[3]->getViewData());
389 $this->assertNull($form[4]->getViewData());
392 public function testSubmitSingleExpandedNonRequiredNothingChecked()
394 $form = $this->factory
->create('choice', null, array(
398 'choices' => $this->choices
,
403 $this->assertNull($form->getData());
404 $this->assertSame(array(
410 'placeholder' => true,
411 ), $form->getViewData());
413 $this->assertTrue($form['placeholder']->getData());
414 $this->assertFalse($form[0]->getData());
415 $this->assertFalse($form[1]->getData());
416 $this->assertFalse($form[2]->getData());
417 $this->assertFalse($form[3]->getData());
418 $this->assertFalse($form[4]->getData());
419 $this->assertSame('', $form['placeholder']->getViewData());
420 $this->assertNull($form[0]->getViewData());
421 $this->assertNull($form[1]->getViewData());
422 $this->assertNull($form[2]->getViewData());
423 $this->assertNull($form[3]->getViewData());
424 $this->assertNull($form[4]->getViewData());
427 public function testSubmitFalseToSingleExpandedRequiredDoesNotProduceExtraChildrenError()
429 $form = $this->factory
->create('choice', null, array(
433 'choices' => $this->choices
,
436 $form->submit(false);
438 $this->assertEmpty($form->getExtraData());
439 $this->assertNull($form->getData());
442 public function testSubmitFalseToSingleExpandedNonRequiredDoesNotProduceExtraChildrenError()
444 $form = $this->factory
->create('choice', null, array(
448 'choices' => $this->choices
,
451 $form->submit(false);
453 $this->assertEmpty($form->getExtraData());
454 $this->assertNull($form->getData());
457 public function testSubmitSingleExpandedWithEmptyChild()
459 $form = $this->factory
->create('choice', null, array(
470 $this->assertNull($form->getData());
471 $this->assertTrue($form[0]->getData());
472 $this->assertFalse($form[1]->getData());
473 $this->assertSame('', $form[0]->getViewData());
474 $this->assertNull($form[1]->getViewData());
477 public function testSubmitSingleExpandedObjectChoices()
479 $form = $this->factory
->create('choice', null, array(
482 'choice_list' => new ObjectChoiceList(
483 $this->objectChoices
,
495 $this->assertSame($this->objectChoices
[1], $form->getData());
496 $this->assertFalse($form[0]->getData());
497 $this->assertTrue($form[1]->getData());
498 $this->assertFalse($form[2]->getData());
499 $this->assertFalse($form[3]->getData());
500 $this->assertFalse($form[4]->getData());
501 $this->assertNull($form[0]->getViewData());
502 $this->assertSame('2', $form[1]->getViewData());
503 $this->assertNull($form[2]->getViewData());
504 $this->assertNull($form[3]->getViewData());
505 $this->assertNull($form[4]->getViewData());
508 public function testSubmitSingleExpandedNumericChoices()
510 $form = $this->factory
->create('choice', null, array(
513 'choices' => $this->numericChoices
,
518 $this->assertSame(1, $form->getData());
519 $this->assertFalse($form[0]->getData());
520 $this->assertTrue($form[1]->getData());
521 $this->assertFalse($form[2]->getData());
522 $this->assertFalse($form[3]->getData());
523 $this->assertFalse($form[4]->getData());
524 $this->assertNull($form[0]->getViewData());
525 $this->assertSame('1', $form[1]->getViewData());
526 $this->assertNull($form[2]->getViewData());
527 $this->assertNull($form[3]->getViewData());
528 $this->assertNull($form[4]->getViewData());
531 public function testSubmitMultipleExpanded()
533 $form = $this->factory
->create('choice', null, array(
536 'choices' => $this->choices
,
539 $form->submit(array('a', 'c'));
541 $this->assertSame(array('a', 'c'), $form->getData());
542 $this->assertTrue($form[0]->getData());
543 $this->assertFalse($form[1]->getData());
544 $this->assertTrue($form[2]->getData());
545 $this->assertFalse($form[3]->getData());
546 $this->assertFalse($form[4]->getData());
547 $this->assertSame('a', $form[0]->getViewData());
548 $this->assertNull($form[1]->getViewData());
549 $this->assertSame('c', $form[2]->getViewData());
550 $this->assertNull($form[3]->getViewData());
551 $this->assertNull($form[4]->getViewData());
554 public function testSubmitMultipleExpandedEmpty()
556 $form = $this->factory
->create('choice', null, array(
559 'choices' => $this->choices
,
562 $form->submit(array());
564 $this->assertSame(array(), $form->getData());
565 $this->assertFalse($form[0]->getData());
566 $this->assertFalse($form[1]->getData());
567 $this->assertFalse($form[2]->getData());
568 $this->assertFalse($form[3]->getData());
569 $this->assertFalse($form[4]->getData());
570 $this->assertNull($form[0]->getViewData());
571 $this->assertNull($form[1]->getViewData());
572 $this->assertNull($form[2]->getViewData());
573 $this->assertNull($form[3]->getViewData());
574 $this->assertNull($form[4]->getViewData());
577 public function testSubmitMultipleExpandedWithEmptyChild()
579 $form = $this->factory
->create('choice', null, array(
589 $form->submit(array('', '2'));
591 $this->assertSame(array('', 2), $form->getData());
592 $this->assertTrue($form[0]->getData());
593 $this->assertFalse($form[1]->getData());
594 $this->assertTrue($form[2]->getData());
595 $this->assertSame('', $form[0]->getViewData());
596 $this->assertNull($form[1]->getViewData());
597 $this->assertSame('2', $form[2]->getViewData());
600 public function testSubmitMultipleExpandedObjectChoices()
602 $form = $this->factory
->create('choice', null, array(
605 'choice_list' => new ObjectChoiceList(
606 $this->objectChoices
,
616 $form->submit(array('1', '2'));
618 $this->assertSame(array($this->objectChoices
[0], $this->objectChoices
[1]), $form->getData());
619 $this->assertTrue($form[0]->getData());
620 $this->assertTrue($form[1]->getData());
621 $this->assertFalse($form[2]->getData());
622 $this->assertFalse($form[3]->getData());
623 $this->assertFalse($form[4]->getData());
624 $this->assertSame('1', $form[0]->getViewData());
625 $this->assertSame('2', $form[1]->getViewData());
626 $this->assertNull($form[2]->getViewData());
627 $this->assertNull($form[3]->getViewData());
628 $this->assertNull($form[4]->getViewData());
631 public function testSubmitMultipleExpandedNumericChoices()
633 $form = $this->factory
->create('choice', null, array(
636 'choices' => $this->numericChoices
,
639 $form->submit(array('1', '2'));
641 $this->assertSame(array(1, 2), $form->getData());
642 $this->assertFalse($form[0]->getData());
643 $this->assertTrue($form[1]->getData());
644 $this->assertTrue($form[2]->getData());
645 $this->assertFalse($form[3]->getData());
646 $this->assertFalse($form[4]->getData());
647 $this->assertNull($form[0]->getViewData());
648 $this->assertSame('1', $form[1]->getViewData());
649 $this->assertSame('2', $form[2]->getViewData());
650 $this->assertNull($form[3]->getViewData());
651 $this->assertNull($form[4]->getViewData());
655 * We need this functionality to create choice fields for Boolean types,
656 * e.g. false => 'No', true => 'Yes'
658 public function testSetDataSingleNonExpandedAcceptsBoolean()
660 $form = $this->factory
->create('choice', null, array(
663 'choices' => $this->numericChoices
,
666 $form->setData(false);
668 $this->assertFalse($form->getData());
669 $this->assertEquals('0', $form->getViewData());
672 public function testSetDataMultipleNonExpandedAcceptsBoolean()
674 $form = $this->factory
->create('choice', null, array(
677 'choices' => $this->numericChoices
,
680 $form->setData(array(false, true));
682 $this->assertEquals(array(false, true), $form->getData());
683 $this->assertEquals(array('0', '1'), $form->getViewData());
686 public function testPassRequiredToView()
688 $form = $this->factory
->create('choice', null, array(
689 'choices' => $this->choices
,
691 $view = $form->createView();
693 $this->assertTrue($view->vars
['required']);
696 public function testPassNonRequiredToView()
698 $form = $this->factory
->create('choice', null, array(
700 'choices' => $this->choices
,
702 $view = $form->createView();
704 $this->assertFalse($view->vars
['required']);
707 public function testPassMultipleToView()
709 $form = $this->factory
->create('choice', null, array(
711 'choices' => $this->choices
,
713 $view = $form->createView();
715 $this->assertTrue($view->vars
['multiple']);
718 public function testPassExpandedToView()
720 $form = $this->factory
->create('choice', null, array(
722 'choices' => $this->choices
,
724 $view = $form->createView();
726 $this->assertTrue($view->vars
['expanded']);
729 public function testEmptyValueIsNullByDefaultIfRequired()
731 $form = $this->factory
->create('choice', null, array(
734 'choices' => $this->choices
,
736 $view = $form->createView();
738 $this->assertNull($view->vars
['empty_value']);
741 public function testEmptyValueIsEmptyStringByDefaultIfNotRequired()
743 $form = $this->factory
->create('choice', null, array(
746 'choices' => $this->choices
,
748 $view = $form->createView();
750 $this->assertSame('', $view->vars
['empty_value']);
754 * @dataProvider getOptionsWithEmptyValue
756 public function testPassEmptyValueToView($multiple, $expanded, $required, $emptyValue, $viewValue)
758 $form = $this->factory
->create('choice', null, array(
759 'multiple' => $multiple,
760 'expanded' => $expanded,
761 'required' => $required,
762 'empty_value' => $emptyValue,
763 'choices' => $this->choices
,
765 $view = $form->createView();
767 $this->assertEquals($viewValue, $view->vars
['empty_value']);
771 * @dataProvider getOptionsWithEmptyValue
773 public function testDontPassEmptyValueIfContainedInChoices($multiple, $expanded, $required, $emptyValue, $viewValue)
775 $form = $this->factory
->create('choice', null, array(
776 'multiple' => $multiple,
777 'expanded' => $expanded,
778 'required' => $required,
779 'empty_value' => $emptyValue,
780 'choices' => array('a' => 'A', '' => 'Empty'),
782 $view = $form->createView();
784 $this->assertNull($view->vars
['empty_value']);
787 public function getOptionsWithEmptyValue()
790 // single non-expanded
791 array(false, false, false, 'foobar', 'foobar'),
792 array(false, false, false, '', ''),
793 array(false, false, false, null, null),
794 array(false, false, false, false, null),
795 array(false, false, true, 'foobar', 'foobar'),
796 array(false, false, true, '', ''),
797 array(false, false, true, null, null),
798 array(false, false, true, false, null),
800 array(false, true, false, 'foobar', 'foobar'),
801 // radios should never have an empty label
802 array(false, true, false, '', 'None'),
803 array(false, true, false, null, null),
804 array(false, true, false, false, null),
805 array(false, true, true, 'foobar', 'foobar'),
806 // radios should never have an empty label
807 array(false, true, true, '', 'None'),
808 array(false, true, true, null, null),
809 array(false, true, true, false, null),
810 // multiple non-expanded
811 array(true, false, false, 'foobar', null),
812 array(true, false, false, '', null),
813 array(true, false, false, null, null),
814 array(true, false, false, false, null),
815 array(true, false, true, 'foobar', null),
816 array(true, false, true, '', null),
817 array(true, false, true, null, null),
818 array(true, false, true, false, null),
820 array(true, true, false, 'foobar', null),
821 array(true, true, false, '', null),
822 array(true, true, false, null, null),
823 array(true, true, false, false, null),
824 array(true, true, true, 'foobar', null),
825 array(true, true, true, '', null),
826 array(true, true, true, null, null),
827 array(true, true, true, false, null),
831 public function testPassChoicesToView()
833 $choices = array('a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D');
834 $form = $this->factory
->create('choice', null, array(
835 'choices' => $choices,
837 $view = $form->createView();
839 $this->assertEquals(array(
840 new ChoiceView('a', 'a', 'A'),
841 new ChoiceView('b', 'b', 'B'),
842 new ChoiceView('c', 'c', 'C'),
843 new ChoiceView('d', 'd', 'D'),
844 ), $view->vars
['choices']);
847 public function testPassPreferredChoicesToView()
849 $choices = array('a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D');
850 $form = $this->factory
->create('choice', null, array(
851 'choices' => $choices,
852 'preferred_choices' => array('b', 'd'),
854 $view = $form->createView();
856 $this->assertEquals(array(
857 0 => new ChoiceView('a', 'a', 'A'),
858 2 => new ChoiceView('c', 'c', 'C'),
859 ), $view->vars
['choices']);
860 $this->assertEquals(array(
861 1 => new ChoiceView('b', 'b', 'B'),
862 3 => new ChoiceView('d', 'd', 'D'),
863 ), $view->vars
['preferred_choices']);
866 public function testPassHierarchicalChoicesToView()
868 $form = $this->factory
->create('choice', null, array(
869 'choices' => $this->groupedChoices
,
870 'preferred_choices' => array('b', 'd'),
872 $view = $form->createView();
874 $this->assertEquals(array(
876 0 => new ChoiceView('a', 'a', 'Bernhard'),
877 2 => new ChoiceView('c', 'c', 'Kris'),
880 4 => new ChoiceView('e', 'e', 'Roman'),
882 ), $view->vars
['choices']);
883 $this->assertEquals(array(
885 1 => new ChoiceView('b', 'b', 'Fabien'),
888 3 => new ChoiceView('d', 'd', 'Jon'),
890 ), $view->vars
['preferred_choices']);
893 public function testPassChoiceDataToView()
895 $obj1 = (object) array('value' => 'a', 'label' => 'A');
896 $obj2 = (object) array('value' => 'b', 'label' => 'B');
897 $obj3 = (object) array('value' => 'c', 'label' => 'C');
898 $obj4 = (object) array('value' => 'd', 'label' => 'D');
899 $form = $this->factory
->create('choice', null, array(
900 'choice_list' => new ObjectChoiceList(array($obj1, $obj2, $obj3, $obj4), 'label', array(), null, 'value'),
902 $view = $form->createView();
904 $this->assertEquals(array(
905 new ChoiceView($obj1, 'a', 'A'),
906 new ChoiceView($obj2, 'b', 'B'),
907 new ChoiceView($obj3, 'c', 'C'),
908 new ChoiceView($obj4, 'd', 'D'),
909 ), $view->vars
['choices']);
912 public function testAdjustFullNameForMultipleNonExpanded()
914 $form = $this->factory
->createNamed('name', 'choice', null, array(
917 'choices' => $this->choices
,
919 $view = $form->createView();
921 $this->assertSame('name[]', $view->vars
['full_name']);
924 // https://github.com/symfony/symfony/issues/3298
925 public function testInitializeWithEmptyChoices()
927 $this->factory
->createNamed('name', 'choice', null, array(
928 'choices' => array(),
932 public function testInitializeWithDefaultObjectChoice()
934 $obj1 = (object) array('value' => 'a', 'label' => 'A');
935 $obj2 = (object) array('value' => 'b', 'label' => 'B');
936 $obj3 = (object) array('value' => 'c', 'label' => 'C');
937 $obj4 = (object) array('value' => 'd', 'label' => 'D');
939 $form = $this->factory
->create('choice', null, array(
940 'choice_list' => new ObjectChoiceList(array($obj1, $obj2, $obj3, $obj4), 'label', array(), null, 'value'),
941 // Used to break because "data_class" was inferred, which needs to
942 // remain null in every case (because it refers to the view format)
946 // Trigger data initialization
947 $form->getViewData();