Skip to content

Commit

Permalink
Autoconfigure EventDispatcher
Browse files Browse the repository at this point in the history
  • Loading branch information
mabar committed Jun 7, 2019
1 parent 892c180 commit b69b543
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 1 deletion.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"phpstan/phpstan-deprecation-rules": "^0.11.2",
"phpstan/phpstan-nette": "^0.11.1",
"phpstan/phpstan-shim": "^0.11.8",
"phpstan/phpstan-strict-rules": "^0.11.1"
"phpstan/phpstan-strict-rules": "^0.11.1",
"symfony/event-dispatcher": "^4.0.0"
},
"suggest": {
"nette/di": "to use ConsoleExtension[CompilerExtension]"
Expand Down
10 changes: 10 additions & 0 deletions src/DI/ConsoleExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Nette\DI\CompilerExtension;
use Nette\DI\Definitions\ServiceDefinition;
use Nette\DI\Definitions\Statement;
use Nette\DI\MissingServiceException;
use Nette\DI\ServiceCreationException;
use Nette\Http\Request;
use Nette\Http\UrlScript;
Expand All @@ -18,6 +19,7 @@
use stdClass;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
* @property-read stdClass $config
Expand Down Expand Up @@ -195,6 +197,14 @@ public function beforeCompile(): void
$commandLoaderDef = $builder->getDefinition($this->prefix('commandLoader'));
$commandLoaderDef->getFactory()->arguments = ['@container', $commandMap];
}

// Register event dispatcher, if available
try {
$dispatcherDef = $builder->getDefinitionByType(EventDispatcherInterface::class);
$applicationDef->addSetup('setDispatcher', [$dispatcherDef]);
} catch (MissingServiceException $e) {
// Event dispatcher is not installed, ignore
}
}

}
51 changes: 51 additions & 0 deletions tests/cases/Unit/DI/ConsoleExtension.EventDispatcher.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php declare(strict_types = 1);

use Contributte\Console\Application;
use Contributte\Console\DI\ConsoleExtension;
use Nette\DI\Compiler;
use Nette\DI\Container;
use Nette\DI\ContainerLoader;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleErrorEvent;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Tester\Assert;
use Tester\FileMock;
use Tests\Fixtures\ThrowingCommand;

require_once __DIR__ . '/../../../bootstrap.php';

test(function (): void {
$loader = new ContainerLoader(TEMP_DIR, true);
$class = $loader->load(function (Compiler $compiler): void {
$compiler->addExtension('console', new ConsoleExtension(true));
$compiler->loadConfig(FileMock::create('
services:
- Tests\Fixtures\ThrowingCommand
- Symfony\Component\EventDispatcher\EventDispatcher
', 'neon'));
}, [getmypid(), 1]);

/** @var Container $container */
$container = new $class();

/** @var Application $application */
$application = $container->getByType(Application::class);
Assert::type(Application::class, $container->getByType(Application::class));

/** @var EventDispatcherInterface $dispatcher */
$dispatcher = $container->getByType(EventDispatcherInterface::class);
$dispatcher->addListener(ConsoleEvents::ERROR, function (ConsoleErrorEvent $event): void {
Assert::same(ThrowingCommand::ERROR_MESSAGE, $event->getError()->getMessage());
});

Assert::exception(function () use ($application): void {
$application->doRun(
new ArrayInput([
'command' => 'throwing',
]),
new NullOutput()
);
}, Throwable::class, ThrowingCommand::ERROR_MESSAGE);
});
31 changes: 31 additions & 0 deletions tests/fixtures/ThrowingCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php declare(strict_types = 1);

namespace Tests\Fixtures;

use Exception;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

final class ThrowingCommand extends Command
{

/** @var string */
protected static $defaultName = 'throwing';

public const ERROR_MESSAGE = 'I am internally broken.';

/**
* Configure command
*/
protected function configure(): void
{
$this->setName(self::$defaultName);
}

protected function execute(InputInterface $input, OutputInterface $output): void
{
throw new Exception(self::ERROR_MESSAGE);
}

}

0 comments on commit b69b543

Please sign in to comment.