[Console] Send the right exit code to console.terminate listeners

This commit is contained in:
Matthias Pigulla 2018-09-21 19:07:33 +02:00 committed by Robin Chalas
parent d5a366faa1
commit b90a3f12a1
2 changed files with 75 additions and 10 deletions

View File

@ -129,15 +129,7 @@ class Application
$this->renderException($e, $output);
}
$exitCode = $e->getCode();
if (is_numeric($exitCode)) {
$exitCode = (int) $exitCode;
if (0 === $exitCode) {
$exitCode = 1;
}
} else {
$exitCode = 1;
}
$exitCode = $this->getExitCodeForThrowable($e);
}
if ($this->autoExit) {
@ -873,7 +865,8 @@ class Application
if ($x !== $event->getException()) {
$e = $event->getException();
}
$exitCode = $e->getCode();
$exitCode = $this->getExitCodeForThrowable($e);
}
$event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
@ -1148,4 +1141,26 @@ class Application
$this->add($command);
}
}
/**
* Type hint omitted to be PHP5 compatible.
*
* @param \Exception|\Throwable $throwable
*
* @return int
*/
private function getExitCodeForThrowable($throwable)
{
$exitCode = $throwable->getCode();
if (is_numeric($exitCode)) {
$exitCode = (int) $exitCode;
if (0 === $exitCode) {
$exitCode = 1;
}
} else {
$exitCode = 1;
}
return $exitCode;
}
}

View File

@ -774,6 +774,31 @@ class ApplicationTest extends TestCase
$this->assertSame(4, $exitCode, '->run() returns integer exit code extracted from raised exception');
}
public function testRunDispatchesIntegerExitCode()
{
$passedRightValue = false;
// We can assume here that some other test asserts that the event is dispatched at all
$dispatcher = new EventDispatcher();
$self = $this;
$dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($self, &$passedRightValue) {
$passedRightValue = (4 === $event->getExitCode());
});
$application = new Application();
$application->setDispatcher($dispatcher);
$application->setAutoExit(false);
$application->register('test')->setCode(function (InputInterface $input, OutputInterface $output) {
throw new \Exception('', 4);
});
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'test'));
$this->assertTrue($passedRightValue, '-> exit code 4 was passed in the console.terminate event');
}
public function testRunReturnsExitCodeOneForExceptionCodeZero()
{
$exception = new \Exception('', 0);
@ -789,6 +814,31 @@ class ApplicationTest extends TestCase
$this->assertSame(1, $exitCode, '->run() returns exit code 1 when exception code is 0');
}
public function testRunDispatchesExitCodeOneForExceptionCodeZero()
{
$passedRightValue = false;
// We can assume here that some other test asserts that the event is dispatched at all
$dispatcher = new EventDispatcher();
$self = $this;
$dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($self, &$passedRightValue) {
$passedRightValue = (1 === $event->getExitCode());
});
$application = new Application();
$application->setDispatcher($dispatcher);
$application->setAutoExit(false);
$application->register('test')->setCode(function (InputInterface $input, OutputInterface $output) {
throw new \Exception();
});
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'test'));
$this->assertTrue($passedRightValue, '-> exit code 1 was passed in the console.terminate event');
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage An option with shortcut "e" already exists.