Beacon/tests/Integration/MiddlewarePipelineTest.php

104 lines
3 KiB
PHP
Raw Normal View History

<?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']);
}
}