Last active
January 4, 2018 09:22
-
-
Save peterjmit/1653643cb7b48782e64a to your computer and use it in GitHub Desktop.
Console events are not dispatched in Symfony when using the CommandTester class shown in http://symfony.com/doc/current/components/console/introduction.html#testing-commands. This class fixes that
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Symfony\Bundle\FrameworkBundle\Console\Application; | |
use Symfony\Component\Console\Command\Command; | |
use Symfony\Component\Console\ConsoleEvents; | |
use Symfony\Component\Console\Event\ConsoleCommandEvent; | |
use Symfony\Component\Console\Event\ConsoleExceptionEvent; | |
use Symfony\Component\Console\Event\ConsoleTerminateEvent; | |
use Symfony\Component\Console\Input\ArrayInput; | |
use Symfony\Component\Console\Input\InputInterface; | |
use Symfony\Component\Console\Output\OutputInterface; | |
use Symfony\Component\Console\Output\StreamOutput; | |
use Symfony\Component\Console\Tester\CommandTester; | |
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |
class EventDispatchingCommandTester | |
{ | |
private $command; | |
private $input; | |
private $output; | |
private $statusCode; | |
private $dispatcher; | |
/** | |
* Constructor. | |
* | |
* @param Command $command A Command instance to test. | |
*/ | |
public function __construct(Command $command, EventDispatcherInterface $dispatcher) | |
{ | |
$this->command = $command; | |
$this->dispatcher = $dispatcher; | |
} | |
/** | |
* Same behaviour as the CommandTester::execute method, with the addition of | |
* the event dispatching mechanism that happens in a "production" code command | |
* | |
* @see Symfony\Component\Console\Tester\CommandTester::execute | |
* @see Symfony\Component\Console\Application::doRunCommand | |
*/ | |
public function execute(array $input, array $options = array()) | |
{ | |
$this->createIO($input, $options); | |
$event = new ConsoleCommandEvent($this->command, $this->input, $this->output); | |
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event); | |
if ($event->commandShouldRun()) { | |
try { | |
$exitCode = $this->command->run($this->input, $this->output); | |
} catch (\Exception $e) { | |
$event = new ConsoleTerminateEvent($this->command, $this->input, $this->output, $e->getCode()); | |
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event); | |
$event = new ConsoleExceptionEvent($this->command, $this->input, $this->output, $e, $event->getExitCode()); | |
$this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event); | |
throw $event->getException(); | |
} | |
} else { | |
$exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED; | |
} | |
$event = new ConsoleTerminateEvent($this->command, $this->input, $this->output, $exitCode); | |
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event); | |
return $this->statusCode = $event->getExitCode(); | |
} | |
/** | |
* Gets the display returned by the last execution of the command. | |
* | |
* @param bool $normalize Whether to normalize end of lines to \n or not | |
* | |
* @return string The display | |
*/ | |
public function getDisplay($normalize = false) | |
{ | |
rewind($this->output->getStream()); | |
$display = stream_get_contents($this->output->getStream()); | |
if ($normalize) { | |
$display = str_replace(PHP_EOL, "\n", $display); | |
} | |
return $display; | |
} | |
/** | |
* Gets the input instance used by the last execution of the command. | |
* | |
* @return InputInterface The current input instance | |
*/ | |
public function getInput() | |
{ | |
return $this->input; | |
} | |
/** | |
* Gets the output instance used by the last execution of the command. | |
* | |
* @return OutputInterface The current output instance | |
*/ | |
public function getOutput() | |
{ | |
return $this->output; | |
} | |
/** | |
* Gets the status code returned by the last execution of the application. | |
* | |
* @return int The status code | |
*/ | |
public function getStatusCode() | |
{ | |
return $this->statusCode; | |
} | |
private function createIO(array $input, array $options = array()) | |
{ | |
// set the command name automatically if the application requires | |
// this argument and no command name was passed | |
if (!isset($input['command']) | |
&& (null !== $application = $this->command->getApplication()) | |
&& $application->getDefinition()->hasArgument('command') | |
) { | |
$input['command'] = $this->command->getName(); | |
} | |
$this->input = new ArrayInput($input); | |
if (isset($options['interactive'])) { | |
$this->input->setInteractive($options['interactive']); | |
} | |
$this->output = new StreamOutput(fopen('php://memory', 'w', false)); | |
if (isset($options['decorated'])) { | |
$this->output->setDecorated($options['decorated']); | |
} | |
if (isset($options['verbosity'])) { | |
$this->output->setVerbosity($options['verbosity']); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment