From 62988eee310e1c3c5412d3edb98766b1d2be36a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ha=C5=82as?= Date: Wed, 15 Apr 2026 07:31:35 +0200 Subject: [PATCH 1/2] fix: replace anonymous class CompilerPass with proper class Extract anonymous class from config/compilerpass.php to src/DependencyInjection/WorkermanCompilerPass.php Closes #37 --- .../WorkermanCompilerPass.php} | 7 ++++--- src/WorkermanBundle.php | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) rename src/{config/compilerpass.php => DependencyInjection/WorkermanCompilerPass.php} (96%) diff --git a/src/config/compilerpass.php b/src/DependencyInjection/WorkermanCompilerPass.php similarity index 96% rename from src/config/compilerpass.php rename to src/DependencyInjection/WorkermanCompilerPass.php index 1e910c7..e9aeb60 100644 --- a/src/config/compilerpass.php +++ b/src/DependencyInjection/WorkermanCompilerPass.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace CrazyGoat\WorkermanBundle\config; +namespace CrazyGoat\WorkermanBundle\DependencyInjection; use CrazyGoat\WorkermanBundle\Http\HttpRequestHandler; use CrazyGoat\WorkermanBundle\Http\Response\ResponseConverter; @@ -16,7 +16,8 @@ use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; -return new class implements CompilerPassInterface { +final class WorkermanCompilerPass implements CompilerPassInterface +{ public function process(ContainerBuilder $container): void { $tasks = array_map(fn(array $a) => $a[0], $container->findTaggedServiceIds('workerman.task')); @@ -89,4 +90,4 @@ private function referenceMap(array $taggedServices): array } return $result; } -}; +} diff --git a/src/WorkermanBundle.php b/src/WorkermanBundle.php index 03f9dbe..b70a2e8 100644 --- a/src/WorkermanBundle.php +++ b/src/WorkermanBundle.php @@ -4,6 +4,7 @@ namespace CrazyGoat\WorkermanBundle; +use CrazyGoat\WorkermanBundle\DependencyInjection\WorkermanCompilerPass; use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; @@ -19,7 +20,7 @@ public function configure(DefinitionConfigurator $definition): void public function build(ContainerBuilder $container): void { - $container->addCompilerPass(require __DIR__ . '/config/compilerpass.php'); + $container->addCompilerPass(new WorkermanCompilerPass()); } /** From 20c42b054a5bfdbaa8a3009b54c1e9c676fcb25b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ha=C5=82as?= Date: Wed, 15 Apr 2026 07:43:00 +0200 Subject: [PATCH 2/2] test: add unit tests for WorkermanCompilerPass Cover: - Service locator registration - Priority-based sorting of response converter strategies - Public visibility of handlers - Reference map structure --- .../WorkermanCompilerPassTest.php | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 tests/DependencyInjection/WorkermanCompilerPassTest.php diff --git a/tests/DependencyInjection/WorkermanCompilerPassTest.php b/tests/DependencyInjection/WorkermanCompilerPassTest.php new file mode 100644 index 0000000..6518505 --- /dev/null +++ b/tests/DependencyInjection/WorkermanCompilerPassTest.php @@ -0,0 +1,157 @@ +container = new ContainerBuilder(); + $this->compilerPass = new WorkermanCompilerPass(); + } + + public function testImplementsCompilerPassInterface(): void + { + $this->assertInstanceOf(\Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface::class, $this->compilerPass); + } + + public function testRegistersServiceLocatorsWhenTaggedServicesExist(): void + { + $this->container->register('workerman.config_loader', \stdClass::class); + + $this->container->register('test.task', \stdClass::class) + ->addTag('workerman.task'); + $this->container->register('test.process', \stdClass::class) + ->addTag('workerman.process'); + + $this->compilerPass->process($this->container); + + $this->assertTrue($this->container->has('workerman.task_locator')); + $this->assertTrue($this->container->has('workerman.process_locator')); + $this->assertTrue($this->container->has('workerman.reboot_strategy')); + $this->assertTrue($this->container->has('workerman.response_converter')); + $this->assertTrue($this->container->has('workerman.http_request_handler')); + $this->assertTrue($this->container->has('workerman.task_handler')); + $this->assertTrue($this->container->has('workerman.process_handler')); + } + + public function testServiceLocatorsContainCorrectReferences(): void + { + $this->container->register('workerman.config_loader', \stdClass::class); + + $this->container->register('task.service', \stdClass::class) + ->addTag('workerman.task'); + $this->container->register('process.service', \stdClass::class) + ->addTag('workerman.process'); + + $this->compilerPass->process($this->container); + + $taskLocator = $this->container->getDefinition('workerman.task_locator'); + $taskLocatorArgs = $taskLocator->getArguments(); + $this->assertArrayHasKey('task.service', $taskLocatorArgs[0]); + + $processLocator = $this->container->getDefinition('workerman.process_locator'); + $processLocatorArgs = $processLocator->getArguments(); + $this->assertArrayHasKey('process.service', $processLocatorArgs[0]); + } + + public function testHandlesNoTaggedServices(): void + { + $this->container->register('workerman.config_loader', \stdClass::class); + + $this->compilerPass->process($this->container); + + $this->assertTrue($this->container->has('workerman.task_locator')); + $this->assertTrue($this->container->has('workerman.process_locator')); + $this->assertTrue($this->container->has('workerman.reboot_strategy')); + $this->assertTrue($this->container->has('workerman.response_converter')); + } + + public function testResponseConverterStrategiesAreSortedByPriority(): void + { + $this->container->register('workerman.config_loader', \stdClass::class); + + $this->container->register('strategy.low', \stdClass::class) + ->addTag('workerman.response_converter.strategy', ['priority' => 0]); + $this->container->register('strategy.high', \stdClass::class) + ->addTag('workerman.response_converter.strategy', ['priority' => 100]); + $this->container->register('strategy.medium', \stdClass::class) + ->addTag('workerman.response_converter.strategy', ['priority' => 50]); + + $this->compilerPass->process($this->container); + + $responseConverter = $this->container->getDefinition('workerman.response_converter'); + $args = $responseConverter->getArguments(); + $references = $args[0]; + + $this->assertCount(3, $references); + $this->assertArrayHasKey('strategy.high', $references); + $this->assertArrayHasKey('strategy.medium', $references); + $this->assertArrayHasKey('strategy.low', $references); + $this->assertInstanceOf(Reference::class, $references['strategy.high']); + $this->assertInstanceOf(Reference::class, $references['strategy.medium']); + $this->assertInstanceOf(Reference::class, $references['strategy.low']); + $this->assertSame('strategy.high', (string) $references['strategy.high']); + $this->assertSame('strategy.medium', (string) $references['strategy.medium']); + $this->assertSame('strategy.low', (string) $references['strategy.low']); + } + + public function testHttpRequestHandlerIsPublic(): void + { + $this->container->register('workerman.config_loader', \stdClass::class); + + $this->compilerPass->process($this->container); + + $httpRequestHandler = $this->container->getDefinition('workerman.http_request_handler'); + $this->assertTrue($httpRequestHandler->isPublic()); + } + + public function testTaskAndProcessHandlersArePublic(): void + { + $this->container->register('workerman.config_loader', \stdClass::class); + + $this->container->register('task.service', \stdClass::class) + ->addTag('workerman.task'); + $this->container->register('process.service', \stdClass::class) + ->addTag('workerman.process'); + + $this->compilerPass->process($this->container); + + $taskHandler = $this->container->getDefinition('workerman.task_handler'); + $processHandler = $this->container->getDefinition('workerman.process_handler'); + + $this->assertTrue($taskHandler->isPublic()); + $this->assertTrue($processHandler->isPublic()); + } + + public function testReferenceMapReturnsCorrectStructure(): void + { + $this->container->register('workerman.config_loader', \stdClass::class); + + $this->container->register('service.a', \stdClass::class) + ->addTag('workerman.task'); + $this->container->register('service.b', \stdClass::class) + ->addTag('workerman.task'); + + $this->compilerPass->process($this->container); + + $taskLocator = $this->container->getDefinition('workerman.task_locator'); + $args = $taskLocator->getArguments(); + $references = $args[0]; + + $this->assertInstanceOf(Reference::class, $references['service.a']); + $this->assertInstanceOf(Reference::class, $references['service.b']); + $this->assertSame('service.a', (string) $references['service.a']); + $this->assertSame('service.b', (string) $references['service.b']); + } +}