diff --git a/README.md b/README.md index d73a031..0f99e88 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ $app->emit($app->handle((new ServerRequestFactory())->createFromGlobals())); * [CallbackMiddleware][70] * [ExceptionMiddleware][71] * [LazyMiddleware][72] - * [MiddlewareDispatcher][73] + * [PipeMiddleware][73] * [RouteMatcherMiddleware][74] * [SlimCallbackMiddleware][75] * [SlimLazyMiddleware][76] @@ -156,6 +156,7 @@ $app->emit($app->handle((new ServerRequestFactory())->createFromGlobals())); ## Migration + * [5.x to 6.x][214] * [4.x to 5.x][213] * [3.x to 4.x][212] * [2.x to 3.x][211] @@ -205,7 +206,7 @@ $app->emit($app->handle((new ServerRequestFactory())->createFromGlobals())); [70]: doc/Middleware/CallbackMiddleware.md [71]: doc/Middleware/ExceptionMiddleware.md [72]: doc/Middleware/LazyMiddleware.md -[73]: doc/Middleware/MiddlewareDispatcher.md +[73]: doc/Middleware/PipeMiddleware.md [74]: doc/Middleware/RouteMatcherMiddleware.md [75]: doc/Middleware/SlimCallbackMiddleware.md [76]: doc/Middleware/SlimLazyMiddleware.md @@ -233,5 +234,6 @@ $app->emit($app->handle((new ServerRequestFactory())->createFromGlobals())); [211]: doc/Migration/2.x-3.x.md [212]: doc/Migration/3.x-4.x.md [213]: doc/Migration/4.x-5.x.md +[214]: doc/Migration/5.x-6.x.md [219]: doc/Migration/Slim-Chubbyphp.md diff --git a/composer.json b/composer.json index d22d0cb..3faa687 100644 --- a/composer.json +++ b/composer.json @@ -63,7 +63,7 @@ }, "extra": { "branch-alias": { - "dev-master": "5.2-dev" + "dev-master": "6.0-dev" } }, "scripts": { diff --git a/doc/Middleware/MiddlewareDispatcher.md b/doc/Middleware/PipeMiddleware.md similarity index 80% rename from doc/Middleware/MiddlewareDispatcher.md rename to doc/Middleware/PipeMiddleware.md index a59512f..adcf2d1 100644 --- a/doc/Middleware/MiddlewareDispatcher.md +++ b/doc/Middleware/PipeMiddleware.md @@ -1,4 +1,4 @@ -# MiddlewareDispatcher +# PipeMiddleware ## Methods @@ -7,7 +7,7 @@ ```php dispatch([$middleware1, $middleware2], $handler, $request); +$response = $pipeMiddleware->dispatch($request, $handler); ``` diff --git a/doc/Migration/5.x-6.x.md b/doc/Migration/5.x-6.x.md new file mode 100644 index 0000000..5f0eeda --- /dev/null +++ b/doc/Migration/5.x-6.x.md @@ -0,0 +1,18 @@ +# 5.x to 6.x + +`Chubbyphp\Framework\Middleware\MiddlewareDispatcher` gets dropped and replaced by `Chubbyphp\Framework\Middleware\PipeMiddleware`. +`Chubbyphp\Framework\Middleware\MiddlewareDispatcher` as an implements of `Chubbyphp\Framework\Middleware\MiddlewareDispatcherInterface` which is gone as well. + +This makes the framework as bit less flexible for special use cases, but easier in use for the majority. + +Resulting changes: +- `Chubbyphp\Framework\Handler\RouteRequestHandler::__construct` does not take a `Chubbyphp\Framework\Middleware\MiddlewareDispatcherInterface` as argument anymore. +- `Chubbyphp\Framework\Application::__construct` does not take a `Chubbyphp\Framework\Middleware\MiddlewareDispatcherInterface` and `Chubbyphp\Framework\Handler\RouteRequestHandler` as argument anymore. + +**If you need a custom `Chubbyphp\Framework\Middleware\PipeMiddleware` for your use case:** + +I suggest you: +- Create an own `Chubbyphp\Framework\Application` and `Chubbyphp\Framework\Handler\RouteRequestHandler` onces you read the code you'll see it's little to replace and to maintain yourself. +- Create an issue convincing me to find a better solution with you in collaboration + +`Chubbyphp\Framework\Collection` gets dropped, cause i do not believe the additional runtime security for typing arrays was worth the performance hit. Use phpstan or something compatible to prevent mistakes in usage. diff --git a/doc/RequestHandler/RouteRequestHandler.md b/doc/RequestHandler/RouteRequestHandler.md index d1b45d0..d54c70c 100644 --- a/doc/RequestHandler/RouteRequestHandler.md +++ b/doc/RequestHandler/RouteRequestHandler.md @@ -7,7 +7,6 @@ ```php handle($request); +$response = $handler->handle($request); ``` diff --git a/phpstan.neon b/phpstan.neon index b68e5b4..f51e71c 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,2 @@ parameters: - ignoreErrors: - - - message: '/Instanceof between Chubbyphp\\Framework\\Router\\RouteInterface and Chubbyphp\\Framework\\Router\\RouteInterface will always evaluate to true./' - path: %currentWorkingDirectory%/src/Router/RoutesByName.php + ignoreErrors: [] diff --git a/src/Application.php b/src/Application.php index dde6b2a..5a39c28 100644 --- a/src/Application.php +++ b/src/Application.php @@ -6,8 +6,7 @@ use Chubbyphp\Framework\Emitter\Emitter; use Chubbyphp\Framework\Emitter\EmitterInterface; -use Chubbyphp\Framework\Middleware\MiddlewareDispatcher; -use Chubbyphp\Framework\Middleware\MiddlewareDispatcherInterface; +use Chubbyphp\Framework\Middleware\PipeMiddleware; use Chubbyphp\Framework\RequestHandler\RouteRequestHandler; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -16,14 +15,9 @@ final class Application implements RequestHandlerInterface { - /** - * @var array - */ - private array $middlewares; - - private MiddlewareDispatcherInterface $middlewareDispatcher; + private PipeMiddleware $pipeMiddleware; - private RequestHandlerInterface $requestHandler; + private RequestHandlerInterface $routeRequestHandler; private EmitterInterface $emitter; @@ -32,13 +26,10 @@ final class Application implements RequestHandlerInterface */ public function __construct( array $middlewares, - ?MiddlewareDispatcherInterface $middlewareDispatcher = null, - ?RequestHandlerInterface $requestHandler = null, ?EmitterInterface $emitter = null ) { - $this->middlewares = (new Collection($middlewares, [MiddlewareInterface::class]))->toArray(); - $this->middlewareDispatcher = $middlewareDispatcher ?? new MiddlewareDispatcher(); - $this->requestHandler = $requestHandler ?? new RouteRequestHandler($this->middlewareDispatcher); + $this->pipeMiddleware = new PipeMiddleware($middlewares); + $this->routeRequestHandler = new RouteRequestHandler(); $this->emitter = $emitter ?? new Emitter(); } @@ -49,11 +40,7 @@ public function __invoke(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface { - return $this->middlewareDispatcher->dispatch( - $this->middlewares, - $this->requestHandler, - $request - ); + return $this->pipeMiddleware->process($request, $this->routeRequestHandler); } public function emit(ResponseInterface $response): void diff --git a/src/Collection.php b/src/Collection.php deleted file mode 100644 index 76a8274..0000000 --- a/src/Collection.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ - private array $items = []; - - /** - * @param array $items - * @param array $types - */ - public function __construct(array $items, array $types) - { - foreach ($items as $i => $item) { - foreach ($types as $type) { - if ($item instanceof $type) { - $this->items[$i] = $item; - - continue 2; - } - } - - throw new \TypeError( - \sprintf( - '%s::__construct() expects parameter 1 at index %s to be %s, %s given', - self::class, - $i, - implode('|', $types), - $item::class - ) - ); - } - } - - /** - * @return array - */ - public function toArray(): array - { - return $this->items; - } -} diff --git a/src/Middleware/MiddlewareDispatcher.php b/src/Middleware/MiddlewareDispatcher.php deleted file mode 100644 index 4965709..0000000 --- a/src/Middleware/MiddlewareDispatcher.php +++ /dev/null @@ -1,28 +0,0 @@ - $middlewares - */ - public function dispatch( - array $middlewares, - RequestHandlerInterface $handler, - ServerRequestInterface $request - ): ResponseInterface { - return array_reduce( - array_reverse($middlewares), - static fn ($handler, $middleware) => new MiddlewareRequestHandler($middleware, $handler), - $handler - )->handle($request); - } -} diff --git a/src/Middleware/MiddlewareDispatcherInterface.php b/src/Middleware/MiddlewareDispatcherInterface.php deleted file mode 100644 index be5d9bd..0000000 --- a/src/Middleware/MiddlewareDispatcherInterface.php +++ /dev/null @@ -1,22 +0,0 @@ - $middlewares - */ - public function dispatch( - array $middlewares, - RequestHandlerInterface $handler, - ServerRequestInterface $request - ): ResponseInterface; -} diff --git a/src/Middleware/PipeMiddleware.php b/src/Middleware/PipeMiddleware.php new file mode 100644 index 0000000..c839a41 --- /dev/null +++ b/src/Middleware/PipeMiddleware.php @@ -0,0 +1,36 @@ + + */ + private array $middlewares; + + /** + * @param array $middlewares + */ + public function __construct(array $middlewares) + { + $this->middlewares = array_reverse($middlewares); + } + + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + $reducedHandler = $handler; + foreach ($this->middlewares as $middleware) { + $reducedHandler = new MiddlewareRequestHandler($middleware, $reducedHandler); + } + + return $reducedHandler->handle($request); + } +} diff --git a/src/RequestHandler/RouteRequestHandler.php b/src/RequestHandler/RouteRequestHandler.php index 7eb0464..c8d008c 100644 --- a/src/RequestHandler/RouteRequestHandler.php +++ b/src/RequestHandler/RouteRequestHandler.php @@ -4,7 +4,7 @@ namespace Chubbyphp\Framework\RequestHandler; -use Chubbyphp\Framework\Middleware\MiddlewareDispatcherInterface; +use Chubbyphp\Framework\Middleware\PipeMiddleware; use Chubbyphp\Framework\Router\Exceptions\MissingRouteAttributeOnRequestException; use Chubbyphp\Framework\Router\RouteInterface; use Psr\Http\Message\ResponseInterface; @@ -13,8 +13,6 @@ final class RouteRequestHandler implements RequestHandlerInterface { - public function __construct(private MiddlewareDispatcherInterface $middlewareDispatcher) {} - public function handle(ServerRequestInterface $request): ResponseInterface { $route = $request->getAttribute('route'); @@ -23,10 +21,6 @@ public function handle(ServerRequestInterface $request): ResponseInterface throw MissingRouteAttributeOnRequestException::create($route); } - return $this->middlewareDispatcher->dispatch( - $route->getMiddlewares(), - $route->getRequestHandler(), - $request - ); + return (new PipeMiddleware($route->getMiddlewares()))->process($request, $route->getRequestHandler()); } } diff --git a/src/Router/Group.php b/src/Router/Group.php index 84ff25e..d61b716 100644 --- a/src/Router/Group.php +++ b/src/Router/Group.php @@ -4,7 +4,6 @@ namespace Chubbyphp\Framework\Router; -use Chubbyphp\Framework\Collection; use Psr\Http\Server\MiddlewareInterface; final class Group implements GroupInterface @@ -30,8 +29,8 @@ private function __construct( array $middlewares = [], private array $pathOptions = [] ) { - $this->children = (new Collection($children, [GroupInterface::class, RouteInterface::class]))->toArray(); - $this->middlewares = (new Collection($middlewares, [MiddlewareInterface::class]))->toArray(); + $this->children = $children; + $this->middlewares = $middlewares; } /** diff --git a/src/Router/Route.php b/src/Router/Route.php index 7e9e046..f12efa8 100644 --- a/src/Router/Route.php +++ b/src/Router/Route.php @@ -4,7 +4,6 @@ namespace Chubbyphp\Framework\Router; -use Chubbyphp\Framework\Collection; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; @@ -32,7 +31,7 @@ private function __construct( array $middlewares = [], private array $pathOptions = [] ) { - $this->middlewares = (new Collection($middlewares, [MiddlewareInterface::class]))->toArray(); + $this->middlewares = $middlewares; } /** diff --git a/src/Router/RoutesByName.php b/src/Router/RoutesByName.php index aaede6c..065fb1b 100644 --- a/src/Router/RoutesByName.php +++ b/src/Router/RoutesByName.php @@ -17,17 +17,6 @@ final class RoutesByName implements RoutesByNameInterface public function __construct(array $routes) { foreach ($routes as $i => $route) { - if (!$route instanceof RouteInterface) { - throw new \TypeError( - \sprintf( - '%s::__construct() expects parameter 1 at index %s to be %s, %s given', - self::class, - $i, - RouteInterface::class, - $route::class - ) - ); - } $this->routes[$route->getName()] = $route; } } diff --git a/tests/Integration/MiddlewareDispatcherTest.php b/tests/Integration/MiddlewareDispatcherTest.php deleted file mode 100644 index 94c05a1..0000000 --- a/tests/Integration/MiddlewareDispatcherTest.php +++ /dev/null @@ -1,157 +0,0 @@ -dispatch( - [ - new CallbackMiddleware( - static fn (ServerRequestInterface $request, RequestHandlerInterface $handler) => $handler->handle($request->withHeader('req1', 'value1')) - ), - new CallbackMiddleware( - static fn (ServerRequestInterface $request, RequestHandlerInterface $handler) => $handler->handle($request->withHeader('req2', 'value2')) - ), - new CallbackMiddleware( - static fn (ServerRequestInterface $request, RequestHandlerInterface $handler) => $handler->handle($request->withHeader('req3', 'value3')) - ), - new CallbackMiddleware( - static fn (ServerRequestInterface $request, RequestHandlerInterface $handler) => $handler->handle($request->withAttribute('req', 'value')) - ), - ], - new CallbackRequestHandler( - static function (ServerRequestInterface $request) use ($responseFactory) { - self::assertSame([ - 'req1' => ['value1'], - 'req2' => ['value2'], - 'req3' => ['value3'], - ], $request->getHeaders()); - - return $responseFactory->createResponse(); - } - ), - $serverRequestFactory->createServerRequest('GET', '/hello/test') - ); - } - - public function testSlim(): void - { - $responseFactory = new SlimResponseFactory(); - $serverRequestFactory = new SunriseServerRequestFactory(); - - $middlewareDispatcher = new MiddlewareDispatcher(); - $middlewareDispatcher->dispatch( - [ - new SlimCallbackMiddleware( - static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withHeader('req1', 'value1'), $res->withHeader('res1', 'value1')), - $responseFactory - ), - new SlimCallbackMiddleware( - static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withHeader('req2', 'value2'), $res->withHeader('res2', 'value2')), - $responseFactory - ), - new SlimCallbackMiddleware( - static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withHeader('req3', 'value3'), $res->withHeader('res3', 'value3')), - $responseFactory - ), - new SlimCallbackMiddleware( - static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withAttribute('req', 'value'), $res), - $responseFactory - ), - ], - new SlimCallbackRequestHandler( - static function (ServerRequestInterface $req, ResponseInterface $res, array $args) { - self::assertSame([ - 'req1' => ['value1'], - 'req2' => ['value2'], - 'req3' => ['value3'], - ], $req->getHeaders()); - - self::assertSame([ - 'res1' => ['value1'], - 'res2' => ['value2'], - 'res3' => ['value3'], - ], $res->getHeaders()); - - self::assertSame(['response', 'req'], array_keys($args)); - self::assertSame('value', $args['req']); - - return $res; - }, - $responseFactory - ), - $serverRequestFactory->createServerRequest('GET', '/hello/test') - ); - } - - public function testCallbackSlimMixed(): void - { - $responseFactory = new SlimResponseFactory(); - $serverRequestFactory = new SunriseServerRequestFactory(); - - $middlewareDispatcher = new MiddlewareDispatcher(); - $middlewareDispatcher->dispatch( - [ - new CallbackMiddleware( - static fn (ServerRequestInterface $request, RequestHandlerInterface $handler) => $handler->handle($request->withHeader('req1', 'value1')) - ), - new SlimCallbackMiddleware( - static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withHeader('req2', 'value2'), $res->withHeader('res2', 'value2')), - $responseFactory - ), - new CallbackMiddleware( - static fn (ServerRequestInterface $request, RequestHandlerInterface $handler) => $handler->handle($request->withHeader('req3', 'value3')) - ), - new SlimCallbackMiddleware( - static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withAttribute('req', 'value'), $res), - $responseFactory - ), - ], - new SlimCallbackRequestHandler( - static function (ServerRequestInterface $req, ResponseInterface $res, array $args) { - self::assertSame([ - 'req1' => ['value1'], - 'req2' => ['value2'], - 'req3' => ['value3'], - ], $req->getHeaders()); - - self::assertSame([ - 'res2' => ['value2'], - ], $res->getHeaders()); - - self::assertSame(['response', 'req'], array_keys($args)); - self::assertSame('value', $args['req']); - - return $res; - }, - $responseFactory - ), - $serverRequestFactory->createServerRequest('GET', '/hello/test') - ); - } -} diff --git a/tests/Integration/PipeMiddlewareTest.php b/tests/Integration/PipeMiddlewareTest.php new file mode 100644 index 0000000..c3a8f4f --- /dev/null +++ b/tests/Integration/PipeMiddlewareTest.php @@ -0,0 +1,154 @@ + $handler->handle($request->withHeader('req1', 'value1')) + ), + new CallbackMiddleware( + static fn (ServerRequestInterface $request, RequestHandlerInterface $handler) => $handler->handle($request->withHeader('req2', 'value2')) + ), + new CallbackMiddleware( + static fn (ServerRequestInterface $request, RequestHandlerInterface $handler) => $handler->handle($request->withHeader('req3', 'value3')) + ), + new CallbackMiddleware( + static fn (ServerRequestInterface $request, RequestHandlerInterface $handler) => $handler->handle($request->withAttribute('req', 'value')) + ), + ]); + $pipeMiddleware->process( + $serverRequestFactory->createServerRequest('GET', '/hello/test'), + new CallbackRequestHandler( + static function (ServerRequestInterface $request) use ($responseFactory) { + self::assertSame([ + 'req1' => ['value1'], + 'req2' => ['value2'], + 'req3' => ['value3'], + ], $request->getHeaders()); + + return $responseFactory->createResponse(); + } + ), + ); + } + + public function testSlim(): void + { + $responseFactory = new SlimResponseFactory(); + $serverRequestFactory = new SunriseServerRequestFactory(); + + $pipeMiddleware = new PipeMiddleware([ + new SlimCallbackMiddleware( + static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withHeader('req1', 'value1'), $res->withHeader('res1', 'value1')), + $responseFactory + ), + new SlimCallbackMiddleware( + static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withHeader('req2', 'value2'), $res->withHeader('res2', 'value2')), + $responseFactory + ), + new SlimCallbackMiddleware( + static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withHeader('req3', 'value3'), $res->withHeader('res3', 'value3')), + $responseFactory + ), + new SlimCallbackMiddleware( + static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withAttribute('req', 'value'), $res), + $responseFactory + ), + ]); + $pipeMiddleware->process( + $serverRequestFactory->createServerRequest('GET', '/hello/test'), + new SlimCallbackRequestHandler( + static function (ServerRequestInterface $req, ResponseInterface $res, array $args) { + self::assertSame([ + 'req1' => ['value1'], + 'req2' => ['value2'], + 'req3' => ['value3'], + ], $req->getHeaders()); + + self::assertSame([ + 'res1' => ['value1'], + 'res2' => ['value2'], + 'res3' => ['value3'], + ], $res->getHeaders()); + + self::assertSame(['response', 'req'], array_keys($args)); + self::assertSame('value', $args['req']); + + return $res; + }, + $responseFactory + ), + ); + } + + public function testCallbackSlimMixed(): void + { + $responseFactory = new SlimResponseFactory(); + $serverRequestFactory = new SunriseServerRequestFactory(); + + $pipeMiddleware = new PipeMiddleware([ + new CallbackMiddleware( + static fn (ServerRequestInterface $request, RequestHandlerInterface $handler) => $handler->handle($request->withHeader('req1', 'value1')) + ), + new SlimCallbackMiddleware( + static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withHeader('req2', 'value2'), $res->withHeader('res2', 'value2')), + $responseFactory + ), + new CallbackMiddleware( + static fn (ServerRequestInterface $request, RequestHandlerInterface $handler) => $handler->handle($request->withHeader('req3', 'value3')) + ), + new SlimCallbackMiddleware( + static fn (ServerRequestInterface $req, ResponseInterface $res, callable $next) => $next($req->withAttribute('req', 'value'), $res), + $responseFactory + ), + ]); + $pipeMiddleware->process( + $serverRequestFactory->createServerRequest('GET', '/hello/test'), + new SlimCallbackRequestHandler( + static function (ServerRequestInterface $req, ResponseInterface $res, array $args) { + self::assertSame([ + 'req1' => ['value1'], + 'req2' => ['value2'], + 'req3' => ['value3'], + ], $req->getHeaders()); + + self::assertSame([ + 'res2' => ['value2'], + ], $res->getHeaders()); + + self::assertSame(['response', 'req'], array_keys($args)); + self::assertSame('value', $args['req']); + + return $res; + }, + $responseFactory + ), + ); + } +} diff --git a/tests/Unit/ApplicationTest.php b/tests/Unit/ApplicationTest.php index 1db0b27..7dc09e2 100644 --- a/tests/Unit/ApplicationTest.php +++ b/tests/Unit/ApplicationTest.php @@ -6,7 +6,6 @@ use Chubbyphp\Framework\Application; use Chubbyphp\Framework\Emitter\EmitterInterface; -use Chubbyphp\Framework\Middleware\MiddlewareDispatcherInterface; use Chubbyphp\Framework\Router\RouteInterface; use Chubbyphp\Mock\MockMethod\WithCallback; use Chubbyphp\Mock\MockMethod\WithReturn; @@ -30,14 +29,29 @@ public function testInvoke(): void { $builder = new MockObjectBuilder(); - /** @var MiddlewareInterface $routeIndependentMiddleware */ - $routeIndependentMiddleware = $builder->create(MiddlewareInterface::class, []); + /** @var MockObject|ResponseInterface $response */ + $response = $builder->create(ResponseInterface::class, []); /** @var MiddlewareInterface $middleware */ - $middleware = $builder->create(MiddlewareInterface::class, []); + $middleware = $builder->create(MiddlewareInterface::class, [ + new WithCallback( + 'process', + static fn ( + ServerRequestInterface $request, + RequestHandlerInterface $requestHandler + ) => $requestHandler->handle($request) + ), + ]); /** @var MockObject|RequestHandlerInterface $handler */ - $handler = $builder->create(RequestHandlerInterface::class, []); + $handler = $builder->create(RequestHandlerInterface::class, [ + new WithCallback( + 'handle', + static fn ( + ServerRequestInterface $request, + ) => $response, + ), + ]); /** @var MockObject|RouteInterface $route */ $route = $builder->create(RouteInterface::class, [ @@ -50,25 +64,20 @@ public function testInvoke(): void new WithReturn('getAttribute', ['route', null], $route), ]); - /** @var MockObject|ResponseInterface $response */ - $response = $builder->create(ResponseInterface::class, []); - - /** @var MiddlewareDispatcherInterface $middlewareDispatcher */ - $middlewareDispatcher = $builder->create(MiddlewareDispatcherInterface::class, [ + /** @var MiddlewareInterface $routeIndependentMiddleware */ + $routeIndependentMiddleware = $builder->create(MiddlewareInterface::class, [ new WithCallback( - 'dispatch', - static function (array $middlewares, RequestHandlerInterface $requestHandler, ServerRequestInterface $req) use ($routeIndependentMiddleware): ResponseInterface { - TestCase::assertSame([$routeIndependentMiddleware], $middlewares); - - return $requestHandler->handle($req); - } + 'process', + static fn ( + ServerRequestInterface $request, + RequestHandlerInterface $requestHandler + ) => $requestHandler->handle($request) ), - new WithReturn('dispatch', [[$middleware], $handler, $request], $response), ]); $application = new Application([ $routeIndependentMiddleware, - ], $middlewareDispatcher); + ]); self::assertSame($response, $application($request)); } @@ -77,35 +86,55 @@ public function testHandle(): void { $builder = new MockObjectBuilder(); - /** @var MiddlewareInterface $routeIndependentMiddleware */ - $routeIndependentMiddleware = $builder->create(MiddlewareInterface::class, []); - - /** @var MockObject|ServerRequestInterface $request */ - $request = $builder->create(ServerRequestInterface::class, []); - /** @var MockObject|ResponseInterface $response */ $response = $builder->create(ResponseInterface::class, []); - /** @var MiddlewareDispatcherInterface $middlewareDispatcher */ - $middlewareDispatcher = $builder->create(MiddlewareDispatcherInterface::class, [ + /** @var MiddlewareInterface $middleware */ + $middleware = $builder->create(MiddlewareInterface::class, [ new WithCallback( - 'dispatch', - static function (array $middlewares, RequestHandlerInterface $requestHandler, ServerRequestInterface $req) use ($routeIndependentMiddleware): ResponseInterface { - TestCase::assertSame([$routeIndependentMiddleware], $middlewares); + 'process', + static fn ( + ServerRequestInterface $request, + RequestHandlerInterface $requestHandler + ) => $requestHandler->handle($request) + ), + ]); - return $requestHandler->handle($req); - } + /** @var MockObject|RequestHandlerInterface $handler */ + $handler = $builder->create(RequestHandlerInterface::class, [ + new WithCallback( + 'handle', + static fn ( + ServerRequestInterface $request, + ) => $response, ), ]); - /** @var MockObject|RequestHandlerInterface $requestHandler */ - $requestHandler = $builder->create(RequestHandlerInterface::class, [ - new WithReturn('handle', [$request], $response), + /** @var MockObject|RouteInterface $route */ + $route = $builder->create(RouteInterface::class, [ + new WithReturn('getMiddlewares', [], [$middleware]), + new WithReturn('getRequestHandler', [], $handler), + ]); + + /** @var MockObject|ServerRequestInterface $request */ + $request = $builder->create(ServerRequestInterface::class, [ + new WithReturn('getAttribute', ['route', null], $route), + ]); + + /** @var MiddlewareInterface $routeIndependentMiddleware */ + $routeIndependentMiddleware = $builder->create(MiddlewareInterface::class, [ + new WithCallback( + 'process', + static fn ( + ServerRequestInterface $request, + RequestHandlerInterface $requestHandler + ) => $requestHandler->handle($request) + ), ]); $application = new Application([ $routeIndependentMiddleware, - ], $middlewareDispatcher, $requestHandler); + ]); self::assertSame($response, $application->handle($request)); } @@ -123,7 +152,7 @@ public function testEmit(): void new WithReturn('emit', [$response], null), ]); - $application = new Application([], null, null, $emitter); + $application = new Application([], $emitter); $application->emit($response); } } diff --git a/tests/Unit/CollectionTest.php b/tests/Unit/CollectionTest.php deleted file mode 100644 index d5c6380..0000000 --- a/tests/Unit/CollectionTest.php +++ /dev/null @@ -1,65 +0,0 @@ -toArray()); - } - - public function testValidWithOneType(): void - { - $items = [new \stdClass()]; - - self::assertSame($items, (new Collection($items, [\stdClass::class]))->toArray()); - } - - public function testInValidWithOneType(): void - { - $this->expectException(\TypeError::class); - $this->expectExceptionMessage( - 'Chubbyphp\Framework\Collection::__construct() expects parameter 1 at index 1 to be' - .' stdClass, DateTimeImmutable given' - ); - - new Collection([new \stdClass(), new \DateTimeImmutable()], [\stdClass::class]); - } - - public function testValidWithMultipleTypes(): void - { - $items = [new \stdClass(), new \DateTimeImmutable(), new \Exception()]; - - self::assertSame( - $items, - (new Collection($items, [\stdClass::class, \DateTimeImmutable::class, \Exception::class]))->toArray() - ); - } - - public function testInValidWithMultipleTypes(): void - { - $this->expectException(\TypeError::class); - $this->expectExceptionMessage( - 'Chubbyphp\Framework\Collection::__construct() expects parameter 1 at index 1 to be' - .' stdClass|DateTimeImmutable|Exception, Error given' - ); - - new Collection( - [new \stdClass(), new \Error(), new \DateTimeImmutable()], - [\stdClass::class, \DateTimeImmutable::class, \Exception::class] - ); - } -} diff --git a/tests/Unit/Middleware/MiddlewareDispatcherTest.php b/tests/Unit/Middleware/PipeMiddlewareTest.php similarity index 85% rename from tests/Unit/Middleware/MiddlewareDispatcherTest.php rename to tests/Unit/Middleware/PipeMiddlewareTest.php index 2dda21b..b758aa3 100644 --- a/tests/Unit/Middleware/MiddlewareDispatcherTest.php +++ b/tests/Unit/Middleware/PipeMiddlewareTest.php @@ -4,7 +4,7 @@ namespace Chubbyphp\Tests\Framework\Unit\Middleware; -use Chubbyphp\Framework\Middleware\MiddlewareDispatcher; +use Chubbyphp\Framework\Middleware\PipeMiddleware; use Chubbyphp\Mock\MockMethod\WithCallback; use Chubbyphp\Mock\MockMethod\WithReturn; use Chubbyphp\Mock\MockMethod\WithReturnSelf; @@ -16,11 +16,11 @@ use Psr\Http\Server\RequestHandlerInterface; /** - * @covers \Chubbyphp\Framework\Middleware\MiddlewareDispatcher + * @covers \Chubbyphp\Framework\Middleware\PipeMiddleware * * @internal */ -final class MiddlewareDispatcherTest extends TestCase +final class PipeMiddlewareTest extends TestCase { public function testWithoutMiddlewares(): void { @@ -37,9 +37,9 @@ public function testWithoutMiddlewares(): void new WithReturn('handle', [$request], $response), ]); - $middlewareDispatcher = new MiddlewareDispatcher(); + $pipeMiddleware = new PipeMiddleware([]); - self::assertSame($response, $middlewareDispatcher->dispatch([], $handler, $request)); + self::assertSame($response, $pipeMiddleware->process($request, $handler)); } public function testWithMiddlewares(): void @@ -90,11 +90,11 @@ static function ( ), ]); - $middlewareDispatcher = new MiddlewareDispatcher(); + $pipeMiddleware = new PipeMiddleware([$middleware1, $middleware2]); self::assertSame( $response, - $middlewareDispatcher->dispatch([$middleware1, $middleware2], $handler, $request) + $pipeMiddleware->process($request, $handler) ); } } diff --git a/tests/Unit/RequestHandler/RouteRequestHandlerTest.php b/tests/Unit/RequestHandler/RouteRequestHandlerTest.php index 0647b71..c6d78d5 100644 --- a/tests/Unit/RequestHandler/RouteRequestHandlerTest.php +++ b/tests/Unit/RequestHandler/RouteRequestHandlerTest.php @@ -4,10 +4,10 @@ namespace Chubbyphp\Tests\Framework\Unit\RequestHandler; -use Chubbyphp\Framework\Middleware\MiddlewareDispatcherInterface; use Chubbyphp\Framework\RequestHandler\RouteRequestHandler; use Chubbyphp\Framework\Router\Exceptions\MissingRouteAttributeOnRequestException; use Chubbyphp\Framework\Router\RouteInterface; +use Chubbyphp\Mock\MockMethod\WithCallback; use Chubbyphp\Mock\MockMethod\WithReturn; use Chubbyphp\Mock\MockObjectBuilder; use PHPUnit\Framework\TestCase; @@ -41,10 +41,7 @@ public function testHandleWithoutRoute(): void /** @var ResponseInterface $response */ $response = $builder->create(ResponseInterface::class, []); - /** @var MiddlewareDispatcherInterface $middlewareDispatcher */ - $middlewareDispatcher = $builder->create(MiddlewareDispatcherInterface::class, []); - - $requestHandler = new RouteRequestHandler($middlewareDispatcher); + $requestHandler = new RouteRequestHandler(); self::assertSame($response, $requestHandler->handle($request)); } @@ -53,11 +50,29 @@ public function testHandleWithRoute(): void { $builder = new MockObjectBuilder(); + /** @var ResponseInterface $response */ + $response = $builder->create(ResponseInterface::class, []); + /** @var MiddlewareInterface $middleware */ - $middleware = $builder->create(MiddlewareInterface::class, []); + $middleware = $builder->create(MiddlewareInterface::class, [ + new WithCallback( + 'process', + static fn ( + ServerRequestInterface $request, + RequestHandlerInterface $requestHandler + ) => $requestHandler->handle($request) + ), + ]); /** @var RequestHandlerInterface $innerRequestHandler */ - $innerRequestHandler = $builder->create(RequestHandlerInterface::class, []); + $innerRequestHandler = $builder->create(RequestHandlerInterface::class, [ + new WithCallback( + 'handle', + static fn ( + ServerRequestInterface $request, + ) => $response, + ), + ]); /** @var RouteInterface $route */ $route = $builder->create(RouteInterface::class, [ @@ -70,15 +85,7 @@ public function testHandleWithRoute(): void new WithReturn('getAttribute', ['route', null], $route), ]); - /** @var ResponseInterface $response */ - $response = $builder->create(ResponseInterface::class, []); - - /** @var MiddlewareDispatcherInterface $middlewareDispatcher */ - $middlewareDispatcher = $builder->create(MiddlewareDispatcherInterface::class, [ - new WithReturn('dispatch', [[$middleware], $innerRequestHandler, $request], $response), - ]); - - $requestHandler = new RouteRequestHandler($middlewareDispatcher); + $requestHandler = new RouteRequestHandler(); self::assertSame($response, $requestHandler->handle($request)); } diff --git a/tests/Unit/Router/GroupTest.php b/tests/Unit/Router/GroupTest.php index 382efab..c95bd98 100644 --- a/tests/Unit/Router/GroupTest.php +++ b/tests/Unit/Router/GroupTest.php @@ -27,17 +27,6 @@ public function testMinimal(): void self::assertSame([], $group->getRoutes()); } - public function testWithInvalidChildren(): void - { - $this->expectException(\TypeError::class); - $this->expectExceptionMessage( - 'Chubbyphp\Framework\Collection::__construct() expects parameter 1 at index 0 to be ' - .'Chubbyphp\Framework\Router\GroupInterface|Chubbyphp\Framework\Router\RouteInterface, stdClass given' - ); - - Group::create('', [new \stdClass()]); - } - public function testMaximal(): void { $builder = new MockObjectBuilder(); diff --git a/tests/Unit/Router/RoutesByNameTest.php b/tests/Unit/Router/RoutesByNameTest.php index 6a52339..e64f52e 100644 --- a/tests/Unit/Router/RoutesByNameTest.php +++ b/tests/Unit/Router/RoutesByNameTest.php @@ -17,19 +17,6 @@ */ final class RoutesByNameTest extends TestCase { - public function testWithWrongType(): void - { - $this->expectException(\TypeError::class); - $this->expectExceptionMessage( - 'Chubbyphp\Framework\Router\RoutesByName::__construct() expects parameter 1' - .' at index 0 to be Chubbyphp\Framework\Router\RouteInterface, stdClass given' - ); - - $route = new \stdClass(); - - new RoutesByName([$route]); - } - public function testGetRoutes(): void { $builder = new MockObjectBuilder();