[Console] allow answer to be trimmed by adding a flag
This commit is contained in:
parent
7207849037
commit
8f182d811e
@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
4.4.0
|
||||
-----
|
||||
|
||||
* added `Question::setTrimmable` default to true to allow the answer to be trimmed or not
|
||||
|
||||
4.3.0
|
||||
-----
|
||||
|
||||
|
@ -64,7 +64,7 @@ class QuestionHelper extends Helper
|
||||
|
||||
$default = explode(',', $default);
|
||||
foreach ($default as $k => $v) {
|
||||
$v = trim($v);
|
||||
$v = $question->isTrimmable() ? trim($v) : $v;
|
||||
$default[$k] = isset($choices[$v]) ? $choices[$v] : $v;
|
||||
}
|
||||
}
|
||||
@ -121,7 +121,8 @@ class QuestionHelper extends Helper
|
||||
$ret = false;
|
||||
if ($question->isHidden()) {
|
||||
try {
|
||||
$ret = trim($this->getHiddenResponse($output, $inputStream));
|
||||
$hiddenResponse = $this->getHiddenResponse($output, $inputStream, $question->isTrimmable());
|
||||
$ret = $question->isTrimmable() ? trim($hiddenResponse) : $hiddenResponse;
|
||||
} catch (RuntimeException $e) {
|
||||
if (!$question->isHiddenFallback()) {
|
||||
throw $e;
|
||||
@ -134,10 +135,13 @@ class QuestionHelper extends Helper
|
||||
if (false === $ret) {
|
||||
throw new RuntimeException('Aborted.');
|
||||
}
|
||||
$ret = trim($ret);
|
||||
if ($question->isTrimmable()) {
|
||||
$ret = trim($ret);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ret = trim($this->autocomplete($output, $question, $inputStream, $autocomplete));
|
||||
$autocomplete = $this->autocomplete($output, $question, $inputStream, $autocomplete);
|
||||
$ret = $question->isTrimmable() ? trim($autocomplete) : $autocomplete;
|
||||
}
|
||||
|
||||
if ($output instanceof ConsoleSectionOutput) {
|
||||
@ -351,10 +355,11 @@ class QuestionHelper extends Helper
|
||||
*
|
||||
* @param OutputInterface $output An Output instance
|
||||
* @param resource $inputStream The handler resource
|
||||
* @param bool $trimmable Is the answer trimmable
|
||||
*
|
||||
* @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
|
||||
*/
|
||||
private function getHiddenResponse(OutputInterface $output, $inputStream): string
|
||||
private function getHiddenResponse(OutputInterface $output, $inputStream, $trimmable = true): string
|
||||
{
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$exe = __DIR__.'/../Resources/bin/hiddeninput.exe';
|
||||
@ -366,7 +371,8 @@ class QuestionHelper extends Helper
|
||||
$exe = $tmpExe;
|
||||
}
|
||||
|
||||
$value = rtrim(shell_exec($exe));
|
||||
$sExec = shell_exec($exe);
|
||||
$value = $trimmable ? rtrim($sExec) : $sExec;
|
||||
$output->writeln('');
|
||||
|
||||
if (isset($tmpExe)) {
|
||||
@ -386,8 +392,9 @@ class QuestionHelper extends Helper
|
||||
if (false === $value) {
|
||||
throw new RuntimeException('Aborted.');
|
||||
}
|
||||
|
||||
$value = trim($value);
|
||||
if ($trimmable) {
|
||||
$value = trim($value);
|
||||
}
|
||||
$output->writeln('');
|
||||
|
||||
return $value;
|
||||
@ -396,7 +403,8 @@ class QuestionHelper extends Helper
|
||||
if (false !== $shell = $this->getShell()) {
|
||||
$readCmd = 'csh' === $shell ? 'set mypassword = $<' : 'read -r mypassword';
|
||||
$command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
|
||||
$value = rtrim(shell_exec($command));
|
||||
$sCommand = shell_exec($command);
|
||||
$value = $trimmable ? rtrim($sCommand) : $sCommand;
|
||||
$output->writeln('');
|
||||
|
||||
return $value;
|
||||
|
@ -29,6 +29,7 @@ class Question
|
||||
private $validator;
|
||||
private $default;
|
||||
private $normalizer;
|
||||
private $trimmable = true;
|
||||
|
||||
/**
|
||||
* @param string $question The question to ask to the user
|
||||
@ -274,4 +275,19 @@ class Question
|
||||
{
|
||||
return (bool) \count(array_filter(array_keys($array), 'is_string'));
|
||||
}
|
||||
|
||||
public function isTrimmable(): bool
|
||||
{
|
||||
return $this->trimmable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setTrimmable(bool $trimmable): self
|
||||
{
|
||||
$this->trimmable = $trimmable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -165,6 +165,20 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
|
||||
$this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
|
||||
}
|
||||
|
||||
public function testAskNonTrimmed()
|
||||
{
|
||||
$dialog = new QuestionHelper();
|
||||
|
||||
$inputStream = $this->getInputStream(' 8AM ');
|
||||
|
||||
$question = new Question('What time is it?', '2PM');
|
||||
$question->setTrimmable(false);
|
||||
$this->assertEquals(' 8AM ', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $output = $this->createOutputInterface(), $question));
|
||||
|
||||
rewind($output->getStream());
|
||||
$this->assertEquals('What time is it?', stream_get_contents($output->getStream()));
|
||||
}
|
||||
|
||||
public function testAskWithAutocomplete()
|
||||
{
|
||||
if (!$this->hasSttyAvailable()) {
|
||||
@ -198,6 +212,40 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
|
||||
$this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
}
|
||||
|
||||
public function testAskWithAutocompleteTrimmable()
|
||||
{
|
||||
if (!$this->hasSttyAvailable()) {
|
||||
$this->markTestSkipped('`stty` is required to test autocomplete functionality');
|
||||
}
|
||||
|
||||
// Acm<NEWLINE>
|
||||
// Ac<BACKSPACE><BACKSPACE>s<TAB>Test<NEWLINE>
|
||||
// <NEWLINE>
|
||||
// <UP ARROW><UP ARROW><NEWLINE>
|
||||
// <UP ARROW><UP ARROW><UP ARROW><UP ARROW><UP ARROW><TAB>Test<NEWLINE>
|
||||
// <DOWN ARROW><NEWLINE>
|
||||
// S<BACKSPACE><BACKSPACE><DOWN ARROW><DOWN ARROW><NEWLINE>
|
||||
// F00<BACKSPACE><BACKSPACE>oo<TAB><NEWLINE>
|
||||
$inputStream = $this->getInputStream("Acm\nAc\177\177s\tTest\n\n\033[A\033[A\n\033[A\033[A\033[A\033[A\033[A\tTest\n\033[B\nS\177\177\033[B\033[B\nF00\177\177oo\t\n");
|
||||
|
||||
$dialog = new QuestionHelper();
|
||||
$helperSet = new HelperSet([new FormatterHelper()]);
|
||||
$dialog->setHelperSet($helperSet);
|
||||
|
||||
$question = new Question('Please select a bundle', 'FrameworkBundle');
|
||||
$question->setAutocompleterValues(['AcmeDemoBundle ', 'AsseticBundle', ' SecurityBundle ', 'FooBundle']);
|
||||
$question->setTrimmable(false);
|
||||
|
||||
$this->assertEquals('AcmeDemoBundle ', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
$this->assertEquals('AsseticBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
$this->assertEquals('FrameworkBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
$this->assertEquals(' SecurityBundle ', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
$this->assertEquals('FooBundleTest', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
$this->assertEquals('AcmeDemoBundle ', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
$this->assertEquals('AsseticBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
$this->assertEquals('FooBundle', $dialog->ask($this->createStreamableInputInterfaceMock($inputStream), $this->createOutputInterface(), $question));
|
||||
}
|
||||
|
||||
public function testAskWithAutocompleteCallback()
|
||||
{
|
||||
if (!$this->hasSttyAvailable()) {
|
||||
@ -373,6 +421,21 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
|
||||
$this->assertEquals('8AM', $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream("8AM\n")), $this->createOutputInterface(), $question));
|
||||
}
|
||||
|
||||
public function testAskHiddenResponseTrimmed()
|
||||
{
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$this->markTestSkipped('This test is not supported on Windows');
|
||||
}
|
||||
|
||||
$dialog = new QuestionHelper();
|
||||
|
||||
$question = new Question('What time is it?');
|
||||
$question->setHidden(true);
|
||||
$question->setTrimmable(false);
|
||||
|
||||
$this->assertEquals(' 8AM', $dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream(' 8AM')), $this->createOutputInterface(), $question));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAskConfirmationData
|
||||
*/
|
||||
|
Reference in New Issue
Block a user