tempDir = sys_get_temp_dir() . '/beacon_discovery_test_' . uniqid(); mkdir($this->tempDir); } protected function tearDown(): void { $this->removeDir($this->tempDir); } public function test_it_discovers_attributed_listeners(): void { $this->createTestClass('TestListener', <<<'PHP' namespace Phred\Discovery; use Phred\Beacon\AsEventListener; class TestListener { #[AsEventListener(event: 'stdClass', priority: 10)] public function onEvent($event): void { $event->called = true; } } PHP ); $provider = new ListenerProvider(); $discovery = new ListenerDiscovery([$this->tempDir]); $discovery->discover($provider); $dispatcher = new EventDispatcher($provider); $event = new \stdClass(); $event->called = false; $dispatcher->dispatch($event); $this->assertTrue($event->called); } public function test_it_discovers_subscribers(): void { $this->createTestClass('TestSubscriber', <<<'PHP' namespace Phred\Discovery; use Phred\Beacon\AsSubscriber; use Phred\BeaconContracts\SubscriberInterface; #[AsSubscriber] class TestSubscriber implements SubscriberInterface { public static function getSubscribedEvents(): array { return ['stdClass' => 'onEvent']; } public function onEvent($event): void { $event->sub_called = true; } } PHP ); $provider = new ListenerProvider(); $discovery = new ListenerDiscovery([$this->tempDir]); $discovery->discover($provider); $dispatcher = new EventDispatcher($provider); $event = new \stdClass(); $event->sub_called = false; $dispatcher->dispatch($event); $this->assertTrue($event->sub_called); } public function test_lazy_loading_via_container(): void { $this->createTestClass('LazyListener', <<<'PHP' namespace Phred\Discovery; use Phred\Beacon\AsEventListener; class LazyListener { #[AsEventListener(event: 'stdClass')] public function __invoke($event): void { $event->lazy_called = true; } } PHP ); $container = $this->createMock(ContainerInterface::class); $container->expects($this->once()) ->method('get') ->with('Phred\Discovery\LazyListener') ->willReturn(new class { public function __invoke($event) { $event->lazy_called = true; } }); $provider = new ListenerProvider($container); $discovery = new ListenerDiscovery([$this->tempDir]); $discovery->discover($provider); $dispatcher = new EventDispatcher($provider); $event = new \stdClass(); $event->lazy_called = false; $dispatcher->dispatch($event); $this->assertTrue($event->lazy_called); } private function createTestClass(string $name, string $content): void { file_put_contents($this->tempDir . '/' . $name . '.php', "tempDir . '/' . $name . '.php'; } private function removeDir(string $dir): void { $files = array_diff(scandir($dir), ['.', '..']); foreach ($files as $file) { $path = $dir . '/' . $file; is_dir($path) ? $this->removeDir($path) : unlink($path); } rmdir($dir); } }