feature #18710 [Console] Simplify simulation of user inputs in CommandTester (chalasr)

This PR was merged into the 3.2-dev branch.

Discussion
----------

[Console] Simplify simulation of user inputs in CommandTester

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | https://github.com/symfony/symfony-docs/pull/6623

After @javiereguiluz pointed it in #17470, I open this PR to simplify the simulation of user inputs for testing a Command.
It would be done by calling `CommandTester::setUserInputs()` with an array of inputs as argument, and so make the CommandTester creating an input stream from the inputs set by the developer, then call `QuestionHelper::setInputStream` and assign it to the helperSet of the command, sort as all is done automatically in one call.

Depends on #18999

Commits
-------

c7ba38a [Console] Set user inputs from CommandTester
This commit is contained in:
Fabien Potencier 2016-06-16 16:59:22 +02:00
commit 4742962c74
2 changed files with 109 additions and 0 deletions

View File

@ -21,12 +21,14 @@ use Symfony\Component\Console\Output\OutputInterface;
* Eases the testing of console commands.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Robin Chalas <robin.chalas@gmail.com>
*/
class CommandTester
{
private $command;
private $input;
private $output;
private $inputs = array();
private $statusCode;
/**
@ -65,6 +67,10 @@ class CommandTester
}
$this->input = new ArrayInput($input);
if ($this->inputs) {
$this->input->setStream(self::createStream($this->inputs));
}
if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']);
}
@ -129,4 +135,29 @@ class CommandTester
{
return $this->statusCode;
}
/**
* Sets the user inputs.
*
* @param array An array of strings representing each input
* passed to the command input stream.
*
* @return CommandTester
*/
public function setInputs(array $inputs)
{
$this->inputs = $inputs;
return $this;
}
private static function createStream(array $inputs)
{
$stream = fopen('php://memory', 'r+', false);
fputs($stream, implode(PHP_EOL, $inputs));
rewind($stream);
return $stream;
}
}

View File

@ -15,6 +15,10 @@ use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Output\Output;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Style\SymfonyStyle;
class CommandTesterTest extends \PHPUnit_Framework_TestCase
{
@ -81,4 +85,78 @@ class CommandTesterTest extends \PHPUnit_Framework_TestCase
// check that there is no need to pass the command name here
$this->assertEquals(0, $tester->execute(array()));
}
public function testCommandWithInputs()
{
$questions = array(
'What\'s your name?',
'How are you?',
'Where do you come from?',
);
$command = new Command('foo');
$command->setHelperSet(new HelperSet(array(new QuestionHelper())));
$command->setCode(function ($input, $output) use ($questions, $command) {
$helper = $command->getHelper('question');
$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(array('Bobby', 'Fine', 'France'));
$tester->execute(array());
$this->assertEquals(0, $tester->getStatusCode());
$this->assertEquals(implode('', $questions), $tester->getDisplay(true));
}
/**
* @expectedException \RuntimeException
* @expectedMessage Aborted
*/
public function testCommandWithWrongInputsNumber()
{
$questions = array(
'What\'s your name?',
'How are you?',
'Where do you come from?',
);
$command = new Command('foo');
$command->setHelperSet(new HelperSet(array(new QuestionHelper())));
$command->setCode(function ($input, $output) use ($questions, $command) {
$helper = $command->getHelper('question');
$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(array('Bobby', 'Fine'));
$tester->execute(array());
}
public function testSymfonyStyleCommandWithInputs()
{
$questions = array(
'What\'s your name?',
'How are you?',
'Where do you come from?',
);
$command = new Command('foo');
$command->setCode(function ($input, $output) use ($questions, $command) {
$io = new SymfonyStyle($input, $output);
$io->ask($questions[0]);
$io->ask($questions[1]);
$io->ask($questions[2]);
});
$tester = new CommandTester($command);
$tester->setInputs(array('Bobby', 'Fine', 'France'));
$tester->execute(array());
$this->assertEquals(0, $tester->getStatusCode());
}
}