104 lines
3 KiB
PHP
104 lines
3 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace Phred\Beacon\Tests\Integration;
|
||
|
|
|
||
|
|
use PHPUnit\Framework\TestCase;
|
||
|
|
use Phred\Beacon\EventDispatcher;
|
||
|
|
use Phred\Beacon\ListenerProvider;
|
||
|
|
use Phred\Beacon\TelemetryMiddleware;
|
||
|
|
use Phred\BeaconContracts\DispatchMiddlewareInterface;
|
||
|
|
|
||
|
|
class MiddlewarePipelineTest extends TestCase
|
||
|
|
{
|
||
|
|
public function test_it_executes_middleware_in_order(): void
|
||
|
|
{
|
||
|
|
$provider = new ListenerProvider();
|
||
|
|
$dispatcher = new EventDispatcher($provider);
|
||
|
|
$order = [];
|
||
|
|
|
||
|
|
$middleware1 = new class($order) implements DispatchMiddlewareInterface {
|
||
|
|
public function __construct(private array &$order) {}
|
||
|
|
public function handle(object $event, callable $next): object {
|
||
|
|
$this->order[] = 'm1_before';
|
||
|
|
$result = $next($event);
|
||
|
|
$this->order[] = 'm1_after';
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
$middleware2 = new class($order) implements DispatchMiddlewareInterface {
|
||
|
|
public function __construct(private array &$order) {}
|
||
|
|
public function handle(object $event, callable $next): object {
|
||
|
|
$this->order[] = 'm2_before';
|
||
|
|
$result = $next($event);
|
||
|
|
$this->order[] = 'm2_after';
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
$dispatcher->addMiddleware($middleware1);
|
||
|
|
$dispatcher->addMiddleware($middleware2);
|
||
|
|
|
||
|
|
$provider->addListener('stdClass', function() use (&$order) {
|
||
|
|
$order[] = 'listener';
|
||
|
|
});
|
||
|
|
|
||
|
|
$dispatcher->dispatch(new \stdClass());
|
||
|
|
|
||
|
|
$expected = [
|
||
|
|
'm1_before',
|
||
|
|
'm2_before',
|
||
|
|
'listener',
|
||
|
|
'm2_after',
|
||
|
|
'm1_after'
|
||
|
|
];
|
||
|
|
|
||
|
|
$this->assertEquals($expected, $order);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_middleware_can_modify_event(): void
|
||
|
|
{
|
||
|
|
$provider = new ListenerProvider();
|
||
|
|
$dispatcher = new EventDispatcher($provider);
|
||
|
|
|
||
|
|
$middleware = new class implements DispatchMiddlewareInterface {
|
||
|
|
public function handle(object $event, callable $next): object {
|
||
|
|
$event->modified = true;
|
||
|
|
return $next($event);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
$dispatcher->addMiddleware($middleware);
|
||
|
|
|
||
|
|
$event = new \stdClass();
|
||
|
|
$event->modified = false;
|
||
|
|
|
||
|
|
$dispatcher->dispatch($event);
|
||
|
|
|
||
|
|
$this->assertTrue($event->modified);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_telemetry_middleware_records_data(): void
|
||
|
|
{
|
||
|
|
$provider = new ListenerProvider();
|
||
|
|
$dispatcher = new EventDispatcher($provider);
|
||
|
|
$telemetry = new TelemetryMiddleware();
|
||
|
|
|
||
|
|
$dispatcher->addMiddleware($telemetry);
|
||
|
|
|
||
|
|
$provider->addListener('stdClass', function() {
|
||
|
|
usleep(1000); // 1ms
|
||
|
|
});
|
||
|
|
|
||
|
|
$event = new \stdClass();
|
||
|
|
$dispatcher->dispatch($event);
|
||
|
|
|
||
|
|
$data = $telemetry->getData();
|
||
|
|
|
||
|
|
$this->assertArrayHasKey('stdClass', $data);
|
||
|
|
$this->assertGreaterThan(0, $data['stdClass']['time']);
|
||
|
|
}
|
||
|
|
}
|