[Console] Fix command testing with missing inputs

This commit is contained in:
Robin Chalas 2019-02-16 17:06:31 +01:00
parent 491204400b
commit ac4e9b0b26
5 changed files with 51 additions and 12 deletions

View File

@ -166,7 +166,7 @@ class QuestionHelper extends Helper
if (false === $ret) { if (false === $ret) {
$ret = fgets($inputStream, 4096); $ret = fgets($inputStream, 4096);
if (false === $ret) { if (false === $ret) {
throw new RuntimeException('Aborted'); throw new RuntimeException('Aborted.');
} }
$ret = trim($ret); $ret = trim($ret);
} }
@ -252,8 +252,10 @@ class QuestionHelper extends Helper
while (!feof($inputStream)) { while (!feof($inputStream)) {
$c = fread($inputStream, 1); $c = fread($inputStream, 1);
// Backspace Character // as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false.
if ("\177" === $c) { if (false === $c || ('' === $ret && '' === $c && null === $question->getDefault())) {
throw new RuntimeException('Aborted.');
} elseif ("\177" === $c) { // Backspace Character
if (0 === $numMatches && 0 !== $i) { if (0 === $numMatches && 0 !== $i) {
--$i; --$i;
// Move cursor backwards // Move cursor backwards
@ -380,7 +382,7 @@ class QuestionHelper extends Helper
shell_exec(sprintf('stty %s', $sttyMode)); shell_exec(sprintf('stty %s', $sttyMode));
if (false === $value) { if (false === $value) {
throw new RuntimeException('Aborted'); throw new RuntimeException('Aborted.');
} }
$value = trim($value); $value = trim($value);

View File

@ -62,9 +62,8 @@ class CommandTester
} }
$this->input = new ArrayInput($input); $this->input = new ArrayInput($input);
if ($this->inputs) { // Use an in-memory input stream even if no inputs are set so that QuestionHelper::ask() does not rely on the blocking STDIN.
$this->input->setStream(self::createStream($this->inputs)); $this->input->setStream(self::createStream($this->inputs));
}
if (isset($options['interactive'])) { if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']); $this->input->setInteractive($options['interactive']);

View File

@ -900,7 +900,7 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
/** /**
* @expectedException \Symfony\Component\Console\Exception\RuntimeException * @expectedException \Symfony\Component\Console\Exception\RuntimeException
* @expectedExceptionMessage Aborted * @expectedExceptionMessage Aborted.
*/ */
public function testAskThrowsExceptionOnMissingInput() public function testAskThrowsExceptionOnMissingInput()
{ {
@ -910,7 +910,17 @@ class QuestionHelperTest extends AbstractQuestionHelperTest
/** /**
* @expectedException \Symfony\Component\Console\Exception\RuntimeException * @expectedException \Symfony\Component\Console\Exception\RuntimeException
* @expectedExceptionMessage Aborted * @expectedExceptionMessage Aborted.
*/
public function testAskThrowsExceptionOnMissingInputForChoiceQuestion()
{
$dialog = new QuestionHelper();
$dialog->ask($this->createStreamableInputInterfaceMock($this->getInputStream('')), $this->createOutputInterface(), new ChoiceQuestion('Choice', ['a', 'b']));
}
/**
* @expectedException \Symfony\Component\Console\Exception\RuntimeException
* @expectedExceptionMessage Aborted.
*/ */
public function testAskThrowsExceptionOnMissingInputWithValidator() public function testAskThrowsExceptionOnMissingInputWithValidator()
{ {

View File

@ -124,7 +124,7 @@ class SymfonyQuestionHelperTest extends AbstractQuestionHelperTest
/** /**
* @expectedException \Symfony\Component\Console\Exception\RuntimeException * @expectedException \Symfony\Component\Console\Exception\RuntimeException
* @expectedExceptionMessage Aborted * @expectedExceptionMessage Aborted.
*/ */
public function testAskThrowsExceptionOnMissingInput() public function testAskThrowsExceptionOnMissingInput()
{ {

View File

@ -17,6 +17,7 @@ use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\HelperSet; use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Output\Output; use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;
@ -139,7 +140,7 @@ class CommandTesterTest extends TestCase
/** /**
* @expectedException \RuntimeException * @expectedException \RuntimeException
* @expectedMessage Aborted * @expectedExceptionMessage Aborted.
*/ */
public function testCommandWithWrongInputsNumber() public function testCommandWithWrongInputsNumber()
{ {
@ -153,13 +154,40 @@ class CommandTesterTest extends TestCase
$command->setHelperSet(new HelperSet([new QuestionHelper()])); $command->setHelperSet(new HelperSet([new QuestionHelper()]));
$command->setCode(function ($input, $output) use ($questions, $command) { $command->setCode(function ($input, $output) use ($questions, $command) {
$helper = $command->getHelper('question'); $helper = $command->getHelper('question');
$helper->ask($input, $output, new ChoiceQuestion('choice', ['a', 'b']));
$helper->ask($input, $output, new Question($questions[0]));
$helper->ask($input, $output, new Question($questions[1]));
$helper->ask($input, $output, new Question($questions[2]));
});
$tester = new CommandTester($command);
$tester->setInputs(['a', 'Bobby', 'Fine']);
$tester->execute([]);
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Aborted.
*/
public function testCommandWithQuestionsButNoInputs()
{
$questions = [
'What\'s your name?',
'How are you?',
'Where do you come from?',
];
$command = new Command('foo');
$command->setHelperSet(new HelperSet([new QuestionHelper()]));
$command->setCode(function ($input, $output) use ($questions, $command) {
$helper = $command->getHelper('question');
$helper->ask($input, $output, new ChoiceQuestion('choice', ['a', 'b']));
$helper->ask($input, $output, new Question($questions[0])); $helper->ask($input, $output, new Question($questions[0]));
$helper->ask($input, $output, new Question($questions[1])); $helper->ask($input, $output, new Question($questions[1]));
$helper->ask($input, $output, new Question($questions[2])); $helper->ask($input, $output, new Question($questions[2]));
}); });
$tester = new CommandTester($command); $tester = new CommandTester($command);
$tester->setInputs(['Bobby', 'Fine']);
$tester->execute([]); $tester->execute([]);
} }