Просмотр исходного кода

[Form] Fixed: ThemeRenderer::isChoiceSelected() works correctly for boolean choices

Bernhard Schussek 14 лет назад
Родитель
Сommit
fc59936740

+ 19 - 7
src/Symfony/Component/Form/Renderer/ThemeRenderer.php

@@ -250,16 +250,28 @@ class ThemeRenderer implements ThemeRendererInterface, \ArrayAccess, \IteratorAg
 
     public function isChoiceSelected($choice)
     {
-        $choice = $this->toChoice($choice);
-        $choices = array_map(array($this, 'toChoice'), (array)$this->vars['value']);
+        $choice = $this->toValidArrayKey($choice);
+        $choices = array_flip((array)$this->vars['value']);
 
-        return in_array($choice, $choices, true);
+        return array_key_exists($choice, $choices);
     }
 
-    private function toChoice($choice)
+    /**
+     * Returns a valid array key for the given value
+     *
+     * @return integer|string $value  An integer if the value can be transformed
+     *                                to one, a string otherwise
+     */
+    private function toValidArrayKey($value)
     {
-        return (string)(int)$choice === (string)$choice
-            ? (int)$choice
-            : (string)$choice;
+        if ((string)(int)$value === (string)$value) {
+            return (int)$value;
+        }
+
+        if (is_bool($value)) {
+            return (int)$value;
+        }
+
+        return (string)$value;
     }
 }

+ 33 - 30
tests/Symfony/Tests/Component/Form/Renderer/ThemeRendererTest.php

@@ -53,53 +53,56 @@ class ThemeRendererTest extends \PHPUnit_Framework_TestCase
         $this->assertTrue($this->renderer->isRendered());
     }
 
-    public function testIsChoiceSelected_intZeroIsNotEmptyString()
+    public function considersEqualProvider()
     {
-        $this->renderer->setVar('choices', array(
-            0 => 'foo',
-            '' => 'bar',
-        ));
-
-        $this->renderer->setVar('value', 0);
-
-        $this->assertTrue($this->renderer->isChoiceSelected(0));
-        $this->assertFalse($this->renderer->isChoiceSelected(''));
+        return array(
+            // the first argument given here must be a valid array key
+            //     = integers and non-integer strings
+            array(0, '0'),
+            array(0, false),
+            array(1, true),
+        );
     }
 
-    public function testIsChoiceSelected_emptyStringIsNotIntZero()
+    public function considersUnequalProvider()
     {
-        $this->renderer->setVar('choices', array(
-            0 => 'foo',
-            '' => 'bar',
-        ));
-
-        $this->renderer->setVar('value', '');
-
-        $this->assertFalse($this->renderer->isChoiceSelected(0));
-        $this->assertTrue($this->renderer->isChoiceSelected(''));
+        return array(
+            // the first argument given here must be a valid array key
+            //     = integers and non-integer strings
+            array(0, ''),
+            array('', 0),
+            array('', false),
+            array('', '0'),
+        );
     }
 
-    public function testIsChoiceSelected_intZeroEqualsStringZero()
+    /**
+     * @dataProvider considersEqualProvider
+     */
+    public function testIsChoiceConsidersEqual($choice, $otherChoice)
     {
         $this->renderer->setVar('choices', array(
-            0 => 'foo',
+            $choice => 'foo',
         ));
 
-        $this->renderer->setVar('value', 0);
+        $this->renderer->setVar('value', $choice);
 
-        $this->assertTrue($this->renderer->isChoiceSelected(0));
-        $this->assertTrue($this->renderer->isChoiceSelected('0'));
+        $this->assertTrue($this->renderer->isChoiceSelected($choice));
+        $this->assertTrue($this->renderer->isChoiceSelected($otherChoice));
     }
 
-    public function testIsChoiceSelected_stringZeroEqualsIntZero()
+    /**
+     * @dataProvider considersUnequalProvider
+     */
+    public function testIsChoiceConsidersUnequal($choice, $otherChoice)
     {
         $this->renderer->setVar('choices', array(
-            0 => 'foo',
+            $choice => 'foo',
         ));
 
-        $this->renderer->setVar('value', '0');
+        $this->renderer->setVar('value', $choice);
 
-        $this->assertTrue($this->renderer->isChoiceSelected(0));
-        $this->assertTrue($this->renderer->isChoiceSelected('0'));
+        $this->assertTrue($this->renderer->isChoiceSelected($choice));
+        $this->assertFalse($this->renderer->isChoiceSelected($otherChoice));
     }
 }