[Console][SymfonyQuestionHelper] Handle multibytes question choices keys and custom prompt

Co-authored-by: Mikhail Fesenko <m.fesenko@corp.vk.com>
This commit is contained in:
fancyweb 2019-12-16 21:06:42 +01:00 committed by Thomas Calvet
parent a073606ea8
commit f175032ed8
3 changed files with 72 additions and 15 deletions

View File

@ -198,15 +198,9 @@ class QuestionHelper extends Helper
$message = $question->getQuestion(); $message = $question->getQuestion();
if ($question instanceof ChoiceQuestion) { if ($question instanceof ChoiceQuestion) {
$maxWidth = max(array_map([$this, 'strlen'], array_keys($question->getChoices()))); $output->writeln(array_merge([
$question->getQuestion(),
$messages = (array) $question->getQuestion(); ], $this->formatChoiceQuestionChoices($question, 'info')));
foreach ($question->getChoices() as $key => $value) {
$width = $maxWidth - $this->strlen($key);
$messages[] = ' [<info>'.$key.str_repeat(' ', $width).'</info>] '.$value;
}
$output->writeln($messages);
$message = $question->getPrompt(); $message = $question->getPrompt();
} }
@ -214,6 +208,26 @@ class QuestionHelper extends Helper
$output->write($message); $output->write($message);
} }
/**
* @param string $tag
*
* @return string[]
*/
protected function formatChoiceQuestionChoices(ChoiceQuestion $question, $tag)
{
$messages = [];
$maxWidth = max(array_map('self::strlen', array_keys($choices = $question->getChoices())));
foreach ($choices as $key => $value) {
$padding = str_repeat(' ', $maxWidth - self::strlen($key));
$messages[] = sprintf(" [<$tag>%s$padding</$tag>] %s", $key, $value);
}
return $messages;
}
/** /**
* Outputs an error message. * Outputs an error message.
*/ */

View File

@ -96,15 +96,15 @@ class SymfonyQuestionHelper extends QuestionHelper
$output->writeln($text); $output->writeln($text);
if ($question instanceof ChoiceQuestion) { $prompt = ' > ';
$width = max(array_map('strlen', array_keys($question->getChoices())));
foreach ($question->getChoices() as $key => $value) { if ($question instanceof ChoiceQuestion) {
$output->writeln(sprintf(" [<comment>%-${width}s</comment>] %s", $key, $value)); $output->writeln($this->formatChoiceQuestionChoices($question, 'comment'));
}
$prompt = $question->getPrompt();
} }
$output->write(' > '); $output->write($prompt);
} }
/** /**

View File

@ -130,6 +130,49 @@ class SymfonyQuestionHelperTest extends AbstractQuestionHelperTest
$dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream('')), $this->createOutputInterface(), new Question('What\'s your name?')); $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream('')), $this->createOutputInterface(), new Question('What\'s your name?'));
} }
public function testChoiceQuestionPadding()
{
$choiceQuestion = new ChoiceQuestion('qqq', [
'foo' => 'foo',
'żółw' => 'bar',
'łabądź' => 'baz',
]);
(new SymfonyQuestionHelper())->ask(
$this->createStreamableInputInterfaceMock($this->getInputStream("foo\n")),
$output = $this->createOutputInterface(),
$choiceQuestion
);
$this->assertOutputContains(<<<EOT
qqq:
[foo ] foo
[żółw ] bar
[łabądź] baz
>
EOT
, $output);
}
public function testChoiceQuestionCustomPrompt()
{
$choiceQuestion = new ChoiceQuestion('qqq', ['foo']);
$choiceQuestion->setPrompt(' >ccc> ');
(new SymfonyQuestionHelper())->ask(
$this->createStreamableInputInterfaceMock($this->getInputStream("foo\n")),
$output = $this->createOutputInterface(),
$choiceQuestion
);
$this->assertOutputContains(<<<EOT
qqq:
[0] foo
>ccc>
EOT
, $output);
}
protected function getInputStream($input) protected function getInputStream($input)
{ {
$stream = fopen('php://memory', 'r+', false); $stream = fopen('php://memory', 'r+', false);