Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\Console\Tester; Chris@0: Chris@0: use Symfony\Component\Console\Command\Command; Chris@0: use Symfony\Component\Console\Input\ArrayInput; Chris@0: use Symfony\Component\Console\Input\InputInterface; Chris@0: use Symfony\Component\Console\Output\OutputInterface; Chris@17: use Symfony\Component\Console\Output\StreamOutput; Chris@0: Chris@0: /** Chris@0: * Eases the testing of console commands. Chris@0: * Chris@0: * @author Fabien Potencier Chris@0: * @author Robin Chalas Chris@0: */ Chris@0: class CommandTester Chris@0: { Chris@0: private $command; Chris@0: private $input; Chris@0: private $output; Chris@17: private $inputs = []; Chris@0: private $statusCode; Chris@0: Chris@0: public function __construct(Command $command) Chris@0: { Chris@0: $this->command = $command; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Executes the command. Chris@0: * Chris@0: * Available execution options: Chris@0: * Chris@0: * * interactive: Sets the input interactive flag Chris@0: * * decorated: Sets the output decorated flag Chris@0: * * verbosity: Sets the output verbosity flag Chris@0: * Chris@0: * @param array $input An array of command arguments and options Chris@0: * @param array $options An array of execution options Chris@0: * Chris@0: * @return int The command exit code Chris@0: */ Chris@17: public function execute(array $input, array $options = []) Chris@0: { Chris@0: // set the command name automatically if the application requires Chris@0: // this argument and no command name was passed Chris@0: if (!isset($input['command']) Chris@0: && (null !== $application = $this->command->getApplication()) Chris@0: && $application->getDefinition()->hasArgument('command') Chris@0: ) { Chris@17: $input = array_merge(['command' => $this->command->getName()], $input); Chris@0: } Chris@0: Chris@0: $this->input = new ArrayInput($input); Chris@18: // Use an in-memory input stream even if no inputs are set so that QuestionHelper::ask() does not rely on the blocking STDIN. Chris@18: $this->input->setStream(self::createStream($this->inputs)); Chris@0: Chris@0: if (isset($options['interactive'])) { Chris@0: $this->input->setInteractive($options['interactive']); Chris@0: } Chris@0: Chris@0: $this->output = new StreamOutput(fopen('php://memory', 'w', false)); Chris@0: $this->output->setDecorated(isset($options['decorated']) ? $options['decorated'] : false); Chris@0: if (isset($options['verbosity'])) { Chris@0: $this->output->setVerbosity($options['verbosity']); Chris@0: } Chris@0: Chris@0: return $this->statusCode = $this->command->run($this->input, $this->output); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the display returned by the last execution of the command. Chris@0: * Chris@0: * @param bool $normalize Whether to normalize end of lines to \n or not Chris@0: * Chris@0: * @return string The display Chris@0: */ Chris@0: public function getDisplay($normalize = false) Chris@0: { Chris@18: if (null === $this->output) { Chris@18: throw new \RuntimeException('Output not initialized, did you execute the command before requesting the display?'); Chris@18: } Chris@18: Chris@0: rewind($this->output->getStream()); Chris@0: Chris@0: $display = stream_get_contents($this->output->getStream()); Chris@0: Chris@0: if ($normalize) { Chris@0: $display = str_replace(PHP_EOL, "\n", $display); Chris@0: } Chris@0: Chris@0: return $display; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the input instance used by the last execution of the command. Chris@0: * Chris@0: * @return InputInterface The current input instance Chris@0: */ Chris@0: public function getInput() Chris@0: { Chris@0: return $this->input; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the output instance used by the last execution of the command. Chris@0: * Chris@0: * @return OutputInterface The current output instance Chris@0: */ Chris@0: public function getOutput() Chris@0: { Chris@0: return $this->output; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the status code returned by the last execution of the application. Chris@0: * Chris@0: * @return int The status code Chris@0: */ Chris@0: public function getStatusCode() Chris@0: { Chris@0: return $this->statusCode; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the user inputs. Chris@0: * Chris@14: * @param array $inputs An array of strings representing each input Chris@14: * passed to the command input stream Chris@0: * Chris@0: * @return CommandTester Chris@0: */ Chris@0: public function setInputs(array $inputs) Chris@0: { Chris@0: $this->inputs = $inputs; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: private static function createStream(array $inputs) Chris@0: { Chris@0: $stream = fopen('php://memory', 'r+', false); Chris@0: Chris@17: foreach ($inputs as $input) { Chris@17: fwrite($stream, $input.PHP_EOL); Chris@17: } Chris@17: Chris@0: rewind($stream); Chris@0: Chris@0: return $stream; Chris@0: } Chris@0: }