Skip to content

Commit

Permalink
feature #18710 [Console] Simplify simulation of user inputs in Comman…
Browse files Browse the repository at this point in the history
…dTester (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        | symfony/symfony-docs#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
  • Loading branch information
fabpot committed Jun 16, 2016
2 parents dbee092 + c7ba38a commit 4742962
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/Symfony/Component/Console/Tester/CommandTester.php
Expand Up @@ -21,12 +21,14 @@
* 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;

/**
Expand Down Expand Up @@ -65,6 +67,10 @@ public function execute(array $input, array $options = array())
}

$this->input = new ArrayInput($input);
if ($this->inputs) {
$this->input->setStream(self::createStream($this->inputs));
}

if (isset($options['interactive'])) {
$this->input->setInteractive($options['interactive']);
}
Expand Down Expand Up @@ -129,4 +135,29 @@ public function getStatusCode()
{
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;
}
}
78 changes: 78 additions & 0 deletions src/Symfony/Component/Console/Tests/Tester/CommandTesterTest.php
Expand Up @@ -15,6 +15,10 @@
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
{
Expand Down Expand Up @@ -81,4 +85,78 @@ public function testCommandFromApplication()
// 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());
}
}

0 comments on commit 4742962

Please sign in to comment.