diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToValueTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToValueTransformer.php index 2b4d026db7..ffffddedc3 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToValueTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ChoiceToValueTransformer.php @@ -46,6 +46,10 @@ class ChoiceToValueTransformer implements DataTransformerInterface $choices = $this->choiceList->getChoicesForValues(array((string) $value)); if (1 !== count($choices)) { + if (null === $value || '' === $value) { + return; + } + throw new TransformationFailedException(sprintf('The choice "%s" does not exist or is not unique', $value)); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php index 27d0fbd65a..627f401192 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -240,6 +240,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertEquals('b', $form->getData()); $this->assertEquals('b', $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } public function testSubmitSingleNonExpandedInvalidChoice() @@ -269,6 +270,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertNull($form->getData()); $this->assertSame('', $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } // In edge cases (for example, when choices are loaded dynamically by a @@ -286,6 +288,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertNull($form->getData()); $this->assertSame('', $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } public function testSubmitSingleNonExpandedEmpty() @@ -300,6 +303,27 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertNull($form->getData()); $this->assertSame('', $form->getViewData()); + $this->assertTrue($form->isSynchronized()); + } + + public function testSubmitSingleNonExpandedEmptyExplicitEmptyChoice() + { + $form = $this->factory->create('choice', null, array( + 'multiple' => false, + 'expanded' => false, + 'choices' => array( + 'EMPTY_CHOICE' => 'Empty', + ), + 'choice_value' => function () { + return ''; + }, + )); + + $form->submit(''); + + $this->assertSame('EMPTY_CHOICE', $form->getData()); + $this->assertSame('', $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } // In edge cases (for example, when choices are loaded dynamically by a @@ -317,6 +341,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertNull($form->getData()); $this->assertSame('', $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } public function testSubmitSingleNonExpandedFalse() @@ -331,6 +356,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertNull($form->getData()); $this->assertSame('', $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } // In edge cases (for example, when choices are loaded dynamically by a @@ -348,6 +374,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertNull($form->getData()); $this->assertSame('', $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } public function testSubmitSingleNonExpandedObjectChoices() @@ -366,6 +393,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertEquals($this->objectChoices[1], $form->getData()); $this->assertEquals('2', $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } /** @@ -392,6 +420,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertEquals($this->objectChoices[1], $form->getData()); $this->assertEquals('2', $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } public function testSubmitMultipleNonExpanded() @@ -406,6 +435,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertEquals(array('a', 'b'), $form->getData()); $this->assertEquals(array('a', 'b'), $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } public function testSubmitMultipleNonExpandedEmpty() @@ -420,6 +450,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertSame(array(), $form->getData()); $this->assertSame(array(), $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } // In edge cases (for example, when choices are loaded dynamically by a @@ -437,6 +468,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertSame(array(), $form->getData()); $this->assertSame(array(), $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } public function testSubmitMultipleNonExpandedInvalidScalarChoice() @@ -484,6 +516,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertEquals(array($this->objectChoices[1], $this->objectChoices[2]), $form->getData()); $this->assertEquals(array('2', '3'), $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } /** @@ -509,6 +542,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertEquals(array($this->objectChoices[1], $this->objectChoices[2]), $form->getData()); $this->assertEquals(array('2', '3'), $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } public function testSubmitSingleExpandedRequired() @@ -933,6 +967,8 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $form->submit(''); $this->assertNull($form->getData()); + $this->assertTrue($form->isSynchronized()); + $this->assertTrue($form[0]->getData()); $this->assertFalse($form[1]->getData()); $this->assertSame('', $form[0]->getViewData()); @@ -953,6 +989,8 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $form->submit('2'); $this->assertSame($this->objectChoices[1], $form->getData()); + $this->assertTrue($form->isSynchronized()); + $this->assertFalse($form[0]->getData()); $this->assertTrue($form[1]->getData()); $this->assertFalse($form[2]->getData()); @@ -987,6 +1025,8 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $form->submit('2'); $this->assertSame($this->objectChoices[1], $form->getData()); + $this->assertTrue($form->isSynchronized()); + $this->assertFalse($form[0]->getData()); $this->assertTrue($form[1]->getData()); $this->assertFalse($form[2]->getData()); @@ -1010,6 +1050,8 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $form->submit('1'); $this->assertSame(1, $form->getData()); + $this->assertTrue($form->isSynchronized()); + $this->assertFalse($form[0]->getData()); $this->assertTrue($form[1]->getData()); $this->assertFalse($form[2]->getData()); @@ -1114,6 +1156,8 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $form->submit(array()); $this->assertSame(array(), $form->getData()); + $this->assertTrue($form->isSynchronized()); + $this->assertFalse($form[0]->getData()); $this->assertFalse($form[1]->getData()); $this->assertFalse($form[2]->getData()); @@ -1140,6 +1184,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $form->submit(array()); $this->assertSame(array(), $form->getData()); + $this->assertTrue($form->isSynchronized()); } public function testSubmitMultipleExpandedWithEmptyChild() @@ -1157,6 +1202,8 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $form->submit(array('', '2')); $this->assertSame(array('', 2), $form->getData()); + $this->assertTrue($form->isSynchronized()); + $this->assertTrue($form[0]->getData()); $this->assertFalse($form[1]->getData()); $this->assertTrue($form[2]->getData()); @@ -1179,6 +1226,8 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $form->submit(array('1', '2')); $this->assertSame(array($this->objectChoices[0], $this->objectChoices[1]), $form->getData()); + $this->assertTrue($form->isSynchronized()); + $this->assertTrue($form[0]->getData()); $this->assertTrue($form[1]->getData()); $this->assertFalse($form[2]->getData()); @@ -1213,6 +1262,8 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $form->submit(array('1', '2')); $this->assertSame(array($this->objectChoices[0], $this->objectChoices[1]), $form->getData()); + $this->assertTrue($form->isSynchronized()); + $this->assertTrue($form[0]->getData()); $this->assertTrue($form[1]->getData()); $this->assertFalse($form[2]->getData()); @@ -1236,6 +1287,8 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $form->submit(array('1', '2')); $this->assertSame(array(1, 2), $form->getData()); + $this->assertTrue($form->isSynchronized()); + $this->assertFalse($form[0]->getData()); $this->assertTrue($form[1]->getData()); $this->assertTrue($form[2]->getData()); @@ -1264,6 +1317,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertFalse($form->getData()); $this->assertEquals('0', $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } public function testSetDataMultipleNonExpandedAcceptsBoolean() @@ -1278,6 +1332,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertEquals(array(false, true), $form->getData()); $this->assertEquals(array('0', '1'), $form->getViewData()); + $this->assertTrue($form->isSynchronized()); } public function testPassRequiredToView() @@ -1344,7 +1399,7 @@ class ChoiceTypeTest extends \Symfony\Component\Form\Test\TypeTestCase $this->assertNull($view->vars['choice_translation_domain']); } - public function testDefaulChoiceTranslationDomainIsSameAsTranslationDomainToView() + public function testDefaultChoiceTranslationDomainIsSameAsTranslationDomainToView() { $form = $this->factory->create('choice', null, array( 'choices' => $this->choices,