queue = new MiddlewareQueue(); $this->ok = function ($request, $handler) { return $handler->handle($request->withAttribute('ok', true)); }; $this->pass = function ($request, $handler) { return $handler->handle($request->withAttribute('pass', true)); }; $this->fail = function ($request, $handler): void { throw new RuntimeException('A bad thing'); }; } /** * Test running a single middleware object. */ public function testRunSingle(): void { $this->queue->add($this->ok); $req = new ServerRequest(); $runner = new Runner(); $result = $runner->run($this->queue, $req); $this->assertInstanceof(ResponseInterface::class, $result); } /** * Test that middleware is run in sequence */ public function testRunSequencing(): void { $log = []; $one = function ($request, $handler) use (&$log) { $log[] = 'one'; return $handler->handle($request); }; $two = function ($request, $handler) use (&$log) { $log[] = 'two'; return $handler->handle($request); }; $three = function ($request, $handler) use (&$log) { $log[] = 'three'; return $handler->handle($request); }; $this->queue->add($one)->add($two)->add($three); $runner = new Runner(); $req = new ServerRequest(); $result = $runner->run($this->queue, $req); $this->assertInstanceof(Response::class, $result); $expected = ['one', 'two', 'three']; $this->assertEquals($expected, $log); } /** * Test that exceptions bubble up. */ public function testRunExceptionInMiddleware(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage('A bad thing'); $this->queue->add($this->ok)->add($this->fail); $req = new ServerRequest(); $runner = new Runner(); $runner->run($this->queue, $req); } public function testRunSetRouterContext(): void { $attributes = []; $this->queue ->add(function ($request, $handler) use (&$attributes) { try { return $handler->handle($request); } catch (Throwable) { $request = Router::getRequest(); $attributes['pass'] = $request->getAttribute('pass'); $attributes['ok'] = $request->getAttribute('ok'); } return new Response(); }) ->add($this->ok) ->add($this->pass) ->add($this->fail); $runner = new Runner(); $app = new Application(CONFIG); $runner->run($this->queue, new ServerRequest(), $app); $this->assertSame(['pass' => true, 'ok' => true], $attributes); } }