Beacon/tests/Unit/AdvancedResolutionTest.php

101 lines
3.6 KiB
PHP

<?php
declare(strict_types=1);
namespace Phred\Beacon\Tests\Unit;
use PHPUnit\Framework\TestCase;
use Phred\Beacon\ListenerProvider;
interface TestInterface {}
class ParentEvent {}
class ChildEvent extends ParentEvent implements TestInterface {}
class AdvancedResolutionTest extends TestCase
{
public function test_it_sorts_listeners_by_priority(): void
{
$provider = new ListenerProvider();
$order = [];
$provider->addListener('stdClass', function() use (&$order) { $order[] = 'low'; }, 0);
$provider->addListener('stdClass', function() use (&$order) { $order[] = 'high'; }, 100);
$provider->addListener('stdClass', function() use (&$order) { $order[] = 'medium'; }, 50);
$listeners = $provider->getListenersForEvent(new \stdClass());
foreach ($listeners as $listener) {
$listener();
}
$this->assertEquals(['high', 'medium', 'low'], $order);
}
public function test_it_resolves_inheritance(): void
{
$provider = new ListenerProvider();
$called = [];
$provider->addListener(ParentEvent::class, function() use (&$called) { $called[] = 'parent'; });
$provider->addListener(TestInterface::class, function() use (&$called) { $called[] = 'interface'; });
$provider->addListener(ChildEvent::class, function() use (&$called) { $called[] = 'child'; });
$listeners = $provider->getListenersForEvent(new ChildEvent());
foreach ($listeners as $listener) {
$listener();
}
$this->assertContains('parent', $called);
$this->assertContains('interface', $called);
$this->assertContains('child', $called);
}
public function test_it_respects_interface_resolution_toggle(): void
{
$provider = new ListenerProvider();
$provider->setResolveInterfaces(false);
$called = [];
$provider->addListener(TestInterface::class, function() use (&$called) { $called[] = 'interface'; });
$provider->addListener(ChildEvent::class, function() use (&$called) { $called[] = 'child'; });
$listeners = $provider->getListenersForEvent(new ChildEvent());
foreach ($listeners as $listener) { $listener(); }
$this->assertNotContains('interface', $called);
$this->assertContains('child', $called);
}
public function test_it_resolves_wildcards(): void
{
$provider = new ListenerProvider();
$called = [];
$provider->addListener('Phred\Beacon\Tests\Unit\*', function() use (&$called) { $called[] = 'wildcard'; });
$listeners = $provider->getListenersForEvent(new ChildEvent());
foreach ($listeners as $listener) { $listener(); }
$this->assertContains('wildcard', $called);
}
public function test_complex_priority_with_inheritance_and_wildcards(): void
{
$provider = new ListenerProvider();
$order = [];
// Exact match (low priority)
$provider->addListener(ChildEvent::class, function() use (&$order) { $order[] = 'exact'; }, 0);
// Wildcard match (high priority)
$provider->addListener('Phred\*', function() use (&$order) { $order[] = 'wildcard'; }, 100);
// Interface match (medium priority)
$provider->addListener(TestInterface::class, function() use (&$order) { $order[] = 'interface'; }, 50);
$listeners = $provider->getListenersForEvent(new ChildEvent());
foreach ($listeners as $listener) { $listener(); }
$this->assertEquals(['wildcard', 'interface', 'exact'], $order);
}
}