diff --git a/src/MiddlewarePipe.php b/src/MiddlewarePipe.php index 58ad2c2..2d9965b 100644 --- a/src/MiddlewarePipe.php +++ b/src/MiddlewarePipe.php @@ -10,6 +10,8 @@ use Psr\Http\Server\RequestHandlerInterface; use SplQueue; +use function iterator_to_array; + /** * Pipe middleware like unix pipes. * @@ -84,4 +86,12 @@ public function pipe(MiddlewareInterface $middleware): void { $this->pipeline->enqueue($middleware); } + + /** @return list */ + public function toArray(): array + { + $pipeline = clone $this->pipeline; + + return iterator_to_array($pipeline, false); + } } diff --git a/src/MiddlewarePipeInterface.php b/src/MiddlewarePipeInterface.php index d5fc58d..c46bd8c 100644 --- a/src/MiddlewarePipeInterface.php +++ b/src/MiddlewarePipeInterface.php @@ -10,4 +10,7 @@ interface MiddlewarePipeInterface extends MiddlewareInterface, RequestHandlerInterface { public function pipe(MiddlewareInterface $middleware): void; + + /** @return list */ + public function toArray(): array; } diff --git a/test/MiddlewarePipeTest.php b/test/MiddlewarePipeTest.php index dcf6351..9fba910 100644 --- a/test/MiddlewarePipeTest.php +++ b/test/MiddlewarePipeTest.php @@ -17,6 +17,7 @@ use ReflectionClass; use ReflectionMethod; use ReflectionObject; +use SplQueue; use function sort; use function spl_object_hash; @@ -64,15 +65,15 @@ public function testCanPipeInteropMiddleware(): void static function ($argument1): bool { self::assertInstanceOf(ServerRequestInterface::class, $argument1); return true; - } + }, ), self::callback( /** @psalm-suppress MissingClosureParamType */ static function ($argument2): bool { self::assertInstanceOf(RequestHandlerInterface::class, $argument2); return true; - } - ) + }, + ), ) ->willReturn($response); @@ -177,12 +178,12 @@ public function testHandleProcessesEnqueuedMiddleware(): void $middleware1 ->method('process') ->with( - $this->request + $this->request, ) ->willReturnCallback( static fn( ServerRequestInterface $request, - RequestHandlerInterface $handler): ResponseInterface => $handler->handle($request) + RequestHandlerInterface $handler): ResponseInterface => $handler->handle($request), ); $middleware2 = $this->createMock(MiddlewareInterface::class); $middleware2 @@ -223,4 +224,36 @@ public function testMiddlewarePipeOnlyImplementsMiddlewarePipeInterfaceApi(): vo self::assertEquals($expected, $actual); self::assertInstanceOf(MiddlewarePipeInterface::class, $pipeline); } + + public function testThatToArrayReturnsEnqueuedMiddlewareAsAListInQueueOrder(): void + { + $pipeline = new MiddlewarePipe(); + $a = $this->createMock(MiddlewareInterface::class); + $b = $this->createMock(MiddlewareInterface::class); + $c = $this->createMock(MiddlewareInterface::class); + + $pipeline->pipe($c); + $pipeline->pipe($a); + $pipeline->pipe($b); + + self::assertSame([$c, $a, $b], $pipeline->toArray()); + } + + public function testThatCloningThePipelineAlsoClonesTheInternalQueue(): void + { + $pipe = new MiddlewarePipe(); + $pipe->pipe($this->createMock(MiddlewareInterface::class)); + + $clone = clone $pipe; + + $reflectionClass = new ReflectionClass(MiddlewarePipe::class); + $property = $reflectionClass->getProperty('pipeline'); + + $queue1 = $property->getValue($pipe); + self::assertInstanceOf(SplQueue::class, $queue1); + $queue2 = $property->getValue($clone); + self::assertInstanceOf(SplQueue::class, $queue2); + + self::assertNotSame($queue1, $queue2); + } }