diff --git a/src/Symfony/Component/Console/Question/ChoiceQuestion.php b/src/Symfony/Component/Console/Question/ChoiceQuestion.php index 020b733f132ac..445630d046532 100644 --- a/src/Symfony/Component/Console/Question/ChoiceQuestion.php +++ b/src/Symfony/Component/Console/Question/ChoiceQuestion.php @@ -169,7 +169,8 @@ private function getDefaultValidator(): callable throw new InvalidArgumentException(sprintf($errorMessage, $value)); } - $multiselectChoices[] = (string) $result; + // For associative choices, consistently return the key as string: + $multiselectChoices[] = $isAssoc ? (string) $result : $result; } if ($multiselect) { diff --git a/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php b/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php index fcba3b3b2fd19..7e3e9963f818b 100644 --- a/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/QuestionHelperTest.php @@ -570,41 +570,6 @@ public function specialCharacterInMultipleChoice() ]; } - /** - * @dataProvider mixedKeysChoiceListAnswerProvider - */ - public function testChoiceFromChoicelistWithMixedKeys($providedAnswer, $expectedValue) - { - $possibleChoices = [ - '0' => 'No environment', - '1' => 'My environment 1', - 'env_2' => 'My environment 2', - 3 => 'My environment 3', - ]; - - $dialog = new QuestionHelper(); - $helperSet = new HelperSet([new FormatterHelper()]); - $dialog->setHelperSet($helperSet); - - $question = new ChoiceQuestion('Please select the environment to load', $possibleChoices); - $question->setMaxAttempts(1); - $answer = $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream($providedAnswer."\n")), $this->createOutputInterface(), $question); - - $this->assertSame($expectedValue, $answer); - } - - public function mixedKeysChoiceListAnswerProvider() - { - return [ - ['0', '0'], - ['No environment', '0'], - ['1', '1'], - ['env_2', 'env_2'], - [3, '3'], - ['My environment 1', '1'], - ]; - } - /** * @dataProvider answerProvider */ diff --git a/src/Symfony/Component/Console/Tests/Question/ChoiceQuestionTest.php b/src/Symfony/Component/Console/Tests/Question/ChoiceQuestionTest.php index 9db12f8528412..18063eaac90d7 100644 --- a/src/Symfony/Component/Console/Tests/Question/ChoiceQuestionTest.php +++ b/src/Symfony/Component/Console/Tests/Question/ChoiceQuestionTest.php @@ -59,6 +59,18 @@ public function selectUseCases() ['First response', 'Second response'], 'When passed multiple answers on MultiSelect, the defaultValidator must return these answers as an array', ], + [ + false, + [0], + 'First response', + 'When passed single answer using choice\'s key, the defaultValidator must return the choice value', + ], + [ + true, + ['0, 2'], + ['First response', 'Third response'], + 'When passed multiple answers using choices\' key, the defaultValidator must return the choice values in an array', + ], ]; } @@ -77,4 +89,64 @@ public function testNonTrimmable() $this->assertSame(['First response ', ' Second response'], $question->getValidator()('First response , Second response')); } + + /** + * @dataProvider selectAssociativeChoicesProvider + */ + public function testSelectAssociativeChoices($providedAnswer, $expectedValue) + { + $question = new ChoiceQuestion('A question', [ + '0' => 'First choice', + 'foo' => 'Foo', + '99' => 'N°99', + 'string object' => new StringChoice('String Object'), + ]); + + $this->assertSame($expectedValue, $question->getValidator()($providedAnswer)); + } + + public function selectAssociativeChoicesProvider() + { + return [ + 'select "0" choice by key' => ['0', '0'], + 'select "0" choice by value' => ['First choice', '0'], + 'select by key' => ['foo', 'foo'], + 'select by value' => ['Foo', 'foo'], + 'select by key, with numeric key' => ['99', '99'], + 'select by value, with numeric key' => ['N°99', '99'], + 'select by key, with string object value' => ['string object', 'string object'], + 'select by value, with string object value' => ['String Object', 'string object'], + ]; + } + + public function testSelectWithNonStringChoices() + { + $question = new ChoiceQuestion('A question', [ + $result1 = new StringChoice('foo'), + $result2 = new StringChoice('bar'), + $result3 = new StringChoice('baz'), + ]); + + $this->assertSame($result1, $question->getValidator()('foo'), 'answer can be selected by its string value'); + $this->assertSame($result1, $question->getValidator()(0), 'answer can be selected by index'); + + $question->setMultiselect(true); + + $this->assertSame([$result3, $result2], $question->getValidator()('baz, bar')); + } +} + +class StringChoice +{ + private $string; + + public function __construct(string $string) + { + $this->string = $string; + } + + public function __toString() + { + return $this->string; + } }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: