feature #34790 [Console] Remove restriction for choices to be strings (LordZardeck, YaFou, ogizanagi)
This PR was merged into the 5.2-dev branch. Discussion ---------- [Console] Remove restriction for choices to be strings | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fix #34789 | License | MIT When using choice, selected answers are forced into strings, preventing us from using complex values such as a class with a custom __toString. This is a problem, as I need the ability to present the user with a list of display strings to choose from, but need the ID associated with that display string in order to do anything useful. Commits -------d276cc9ca3
[Console] Cast associative choices questions keys to stringa0223088a0
[Console] Add tests for removing restriction for choices to be strings3349d3ce89
Remove restriction for choices to be strings
This commit is contained in:
commit
d6468a9634
@ -169,7 +169,8 @@ class ChoiceQuestion extends Question
|
|||||||
throw new InvalidArgumentException(sprintf($errorMessage, $value));
|
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) {
|
if ($multiselect) {
|
||||||
|
@ -607,41 +607,6 @@ EOD;
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @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
|
* @dataProvider answerProvider
|
||||||
*/
|
*/
|
||||||
|
@ -59,6 +59,18 @@ class ChoiceQuestionTest extends TestCase
|
|||||||
['First response', 'Second response'],
|
['First response', 'Second response'],
|
||||||
'When passed multiple answers on MultiSelect, the defaultValidator must return these answers as an array',
|
'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 @@ class ChoiceQuestionTest extends TestCase
|
|||||||
|
|
||||||
$this->assertSame(['First response ', ' Second response'], $question->getValidator()('First response , Second response'));
|
$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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user