diff --git a/examples/index.php b/examples/index.php index 5bf34f7..36c902e 100644 --- a/examples/index.php +++ b/examples/index.php @@ -21,8 +21,11 @@ return htmlspecialchars_decode(htmlspecialchars($str, ENT_SUBSTITUTE | ENT_DISALLOWED, 'utf-8')); }; + $name = $request->getAttribute('name'); + assert(is_string($name)); + return React\Http\Message\Response::plaintext( - "Hello " . $escape($request->getAttribute('name')) . "!\n" + "Hello " . $escape($name) . "!\n" ); }); @@ -63,6 +66,7 @@ ob_start(); var_dump($request); $info = ob_get_clean(); + assert(is_string($info)); if (PHP_SAPI !== 'cli' && (!function_exists('xdebug_is_enabled') || !xdebug_is_enabled())) { $info = htmlspecialchars($info, 0, 'utf-8'); @@ -201,9 +205,10 @@ }); $app->get('/location/{status:\d+}', function (Psr\Http\Message\ServerRequestInterface $request) { - $statusCode = (int) $request->getAttribute('status'); + $statusCode = $request->getAttribute('status'); + assert(is_string($statusCode) && is_numeric($statusCode)); - return new React\Http\Message\Response($statusCode, ['Location' => '/foobar']); + return new React\Http\Message\Response((int) $statusCode, ['Location' => '/foobar']); }); $app->run(); diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 428e5d0..6112643 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ parameters: - level: 5 + level: max paths: - examples/ @@ -14,4 +14,4 @@ parameters: - '/^Instantiated class Fiber not found\.$/' - '/^Call to method (start|isTerminated|getReturn)\(\) on an unknown class Fiber\.$/' # ignore incomplete type information for mocks in legacy PHPUnit 7.5 - - '/^Parameter #\d+ \$.+ of class .+ constructor expects .+, PHPUnit\\Framework\\MockObject\\MockObject given\.$/' + - '/^Parameter #\d+ .+ of .+ expects .+, PHPUnit\\Framework\\MockObject\\MockObject given\.$/' diff --git a/src/AccessLogHandler.php b/src/AccessLogHandler.php index 1d13321..a8d6e80 100644 --- a/src/AccessLogHandler.php +++ b/src/AccessLogHandler.php @@ -94,7 +94,7 @@ private function log(ServerRequestInterface $request, ResponseInterface $respons private function escape(string $s): string { - return preg_replace_callback('/[\x00-\x1F\x7F-\xFF"\\\\]+/', function (array $m) { + return (string) preg_replace_callback('/[\x00-\x1F\x7F-\xFF"\\\\]+/', function (array $m) { return str_replace('%', '\x', rawurlencode($m[0])); }, $s); } diff --git a/src/App.php b/src/App.php index 30d93ad..2799a62 100644 --- a/src/App.php +++ b/src/App.php @@ -220,7 +220,7 @@ public function redirect(string $route, string $target, int $code = Response::ST $this->any($route, new RedirectHandler($target, $code)); } - public function run() + public function run(): void { if (\PHP_SAPI === 'cli') { $this->runLoop(); @@ -229,7 +229,7 @@ public function run() } } - private function runLoop() + private function runLoop(): void { $http = new HttpServer(function (ServerRequestInterface $request) { return $this->handleRequest($request); @@ -240,7 +240,7 @@ private function runLoop() $socket = new SocketServer($listen); $http->listen($socket); - $this->sapi->log('Listening on ' . \str_replace('tcp:', 'http:', $socket->getAddress())); + $this->sapi->log('Listening on ' . \str_replace('tcp:', 'http:', (string) $socket->getAddress())); $http->on('error', function (\Exception $e) { $orig = $e; @@ -290,7 +290,7 @@ private function runLoop() Loop::removeSignal(\defined('SIGTERM') ? \SIGTERM : 15, $f2 ?? 'printf'); } - private function runOnce() + private function runOnce(): void { $request = $this->sapi->requestFromGlobals(); @@ -319,11 +319,14 @@ private function runOnce() private function handleRequest(ServerRequestInterface $request) { $response = ($this->handler)($request); + assert($response instanceof ResponseInterface || $response instanceof PromiseInterface || $response instanceof \Generator); + if ($response instanceof \Generator) { if ($response->valid()) { $response = $this->coroutine($response); } else { $response = $response->getReturn(); + assert($response instanceof ResponseInterface); } } @@ -341,6 +344,8 @@ private function coroutine(\Generator $generator): PromiseInterface } $promise = $generator->current(); + assert($promise instanceof PromiseInterface); + $promise->then(function ($value) use ($generator, $next) { $generator->send($value); $next(); diff --git a/src/Container.php b/src/Container.php index def505b..23175ba 100644 --- a/src/Container.php +++ b/src/Container.php @@ -34,6 +34,7 @@ public function __construct($loader = []) $this->container = $loader; } + /** @return mixed */ public function __invoke(ServerRequestInterface $request, callable $next = null) { if ($next === null) { @@ -117,6 +118,7 @@ public function getAccessLogHandler(): AccessLogHandler { if ($this->container instanceof ContainerInterface) { if ($this->container->has(AccessLogHandler::class)) { + // @phpstan-ignore-next-line method return type will ensure correct type or throw `TypeError` return $this->container->get(AccessLogHandler::class); } else { return new AccessLogHandler(); @@ -130,6 +132,7 @@ public function getErrorHandler(): ErrorHandler { if ($this->container instanceof ContainerInterface) { if ($this->container->has(ErrorHandler::class)) { + // @phpstan-ignore-next-line method return type will ensure correct type or throw `TypeError` return $this->container->get(ErrorHandler::class); } else { return new ErrorHandler(); @@ -139,22 +142,25 @@ public function getErrorHandler(): ErrorHandler } /** - * @template T + * @template T of object * @param class-string $name * @return T * @throws \BadMethodCallException if object of type $name can not be loaded */ private function loadObject(string $name, int $depth = 64) /*: object (PHP 7.2+) */ { + assert(\is_array($this->container)); + if (\array_key_exists($name, $this->container)) { if (\is_string($this->container[$name])) { if ($depth < 1) { throw new \BadMethodCallException('Factory for ' . $name . ' is recursive'); } + // @phpstan-ignore-next-line because type of container value is explicitly checked after getting here $value = $this->loadObject($this->container[$name], $depth - 1); if (!$value instanceof $name) { - throw new \BadMethodCallException('Factory for ' . $name . ' returned unexpected ' . (is_object($value) ? get_class($value) : gettype($value))); + throw new \BadMethodCallException('Factory for ' . $name . ' returned unexpected ' . \get_class($value)); } $this->container[$name] = $value; @@ -171,6 +177,7 @@ private function loadObject(string $name, int $depth = 64) /*: object (PHP 7.2+) throw new \BadMethodCallException('Factory for ' . $name . ' is recursive'); } + // @phpstan-ignore-next-line because type of container value is explicitly checked after getting here $value = $this->loadObject($value, $depth - 1); } if (!$value instanceof $name) { @@ -210,10 +217,14 @@ private function loadObject(string $name, int $depth = 64) /*: object (PHP 7.2+) $params = $ctor === null ? [] : $this->loadFunctionParams($ctor, $depth, false); // instantiate with list of parameters + // @phpstan-ignore-next-line because `$class->newInstance()` is known to return `T` return $this->container[$name] = $params === [] ? new $name() : $class->newInstance(...$params); } - /** @throws \BadMethodCallException if either parameter can not be loaded */ + /** + * @return list + * @throws \BadMethodCallException if either parameter can not be loaded + */ private function loadFunctionParams(\ReflectionFunctionAbstract $function, int $depth, bool $allowVariables): array { $params = []; @@ -230,6 +241,8 @@ private function loadFunctionParams(\ReflectionFunctionAbstract $function, int $ */ private function loadParameter(\ReflectionParameter $parameter, int $depth, bool $allowVariables) /*: mixed (PHP 8.0+) */ { + assert(\is_array($this->container)); + $type = $parameter->getType(); $hasDefault = $parameter->isDefaultValueAvailable() || ((!$type instanceof \ReflectionNamedType || $type->getName() !== 'mixed') && $parameter->allowsNull()); @@ -277,6 +290,7 @@ private function loadParameter(\ReflectionParameter $parameter, int $depth, bool throw new \BadMethodCallException(self::parameterError($parameter) . ' is recursive'); } + // @phpstan-ignore-next-line because `$type->getName()` is a `class-string` by definition return $this->loadObject($type->getName(), $depth - 1); } @@ -286,7 +300,7 @@ private function loadParameter(\ReflectionParameter $parameter, int $depth, bool */ private function loadVariable(string $name, string $type, bool $nullable, int $depth) /*: object|string|int|float|bool|null (PHP 8.0+) */ { - assert(\array_key_exists($name, $this->container) || isset($_SERVER[$name])); + assert(\is_array($this->container) && (\array_key_exists($name, $this->container) || isset($_SERVER[$name]))); if (($this->container[$name] ?? null) instanceof \Closure) { if ($depth < 1) { @@ -294,11 +308,13 @@ private function loadVariable(string $name, string $type, bool $nullable, int $d } // build list of factory parameters based on parameter types - $closure = new \ReflectionFunction($this->container[$name]); + $factory = $this->container[$name]; + assert($factory instanceof \Closure); + $closure = new \ReflectionFunction($factory); $params = $this->loadFunctionParams($closure, $depth - 1, true); // invoke factory with list of parameters - $value = $params === [] ? ($this->container[$name])() : ($this->container[$name])(...$params); + $value = $params === [] ? $factory() : $factory(...$params); if (!\is_object($value) && !\is_scalar($value) && $value !== null) { throw new \BadMethodCallException('Container variable $' . $name . ' expected type object|scalar|null from factory, but got ' . \gettype($value)); diff --git a/src/ErrorHandler.php b/src/ErrorHandler.php index e2feebe..1035d3f 100644 --- a/src/ErrorHandler.php +++ b/src/ErrorHandler.php @@ -120,7 +120,10 @@ public function requestNotFound(): ResponseInterface ); } - /** @internal */ + /** + * @internal + * @param list $allowedMethods + */ public function requestMethodNotAllowed(array $allowedMethods): ResponseInterface { $methods = \implode('/', \array_map(function (string $method) { return '' . $method . ''; }, $allowedMethods)); @@ -155,6 +158,7 @@ private function errorInvalidException(\Throwable $e): ResponseInterface ); } + /** @param mixed $value */ private function errorInvalidResponse($value): ResponseInterface { return $this->htmlResponse( @@ -165,6 +169,7 @@ private function errorInvalidResponse($value): ResponseInterface ); } + /** @param mixed $value */ private function errorInvalidCoroutine($value, string $file, int $line): ResponseInterface { $where = ' near or before '. $this->where($file, $line) . '.'; @@ -192,6 +197,7 @@ private function htmlResponse(int $statusCode, string $title, string ...$info): ); } + /** @param mixed $value */ private function describeType($value): string { if ($value === null) { diff --git a/src/FilesystemHandler.php b/src/FilesystemHandler.php index be46c76..b29ddb9 100644 --- a/src/FilesystemHandler.php +++ b/src/FilesystemHandler.php @@ -4,11 +4,13 @@ use FrameworkX\Io\HtmlHandler; use FrameworkX\Io\RedirectHandler; +use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use React\Http\Message\Response; class FilesystemHandler { + /** @var string */ private $root; /** @@ -59,9 +61,10 @@ public function __construct(string $root) $this->html = new HtmlHandler(); } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): ResponseInterface { $local = $request->getAttribute('path', ''); + assert(\is_string($local)); $path = \rtrim($this->root . '/' . $local, '/'); // local path should not contain "./", "../", "//" or null bytes or start with slash @@ -80,6 +83,7 @@ public function __invoke(ServerRequestInterface $request) } $files = \scandir($path); + // @phpstan-ignore-next-line TODO handle error if directory can not be accessed foreach ($files as $file) { if ($file === '.' || $file === '..') { continue; @@ -117,7 +121,7 @@ public function __invoke(ServerRequestInterface $request) return new Response( Response::STATUS_OK, $headers, - \file_get_contents($path) + \file_get_contents($path) // @phpstan-ignore-line TODO handle error if file can not be accessed ); } else { return $this->errorHandler->requestNotFound(); diff --git a/src/Io/FiberHandler.php b/src/Io/FiberHandler.php index e23107d..819360a 100644 --- a/src/Io/FiberHandler.php +++ b/src/Io/FiberHandler.php @@ -56,6 +56,7 @@ public function __invoke(ServerRequestInterface $request, callable $next): mixed $fiber->start(); if ($fiber->isTerminated()) { /** @throws void because fiber is known to have terminated successfully */ + /** @var ResponseInterface|PromiseInterface|\Generator */ return $fiber->getReturn(); } diff --git a/src/Io/HtmlHandler.php b/src/Io/HtmlHandler.php index 2eb0a94..0e87e65 100644 --- a/src/Io/HtmlHandler.php +++ b/src/Io/HtmlHandler.php @@ -50,12 +50,12 @@ public function statusResponse(int $statusCode, string $title, string $subtitle, public function escape(string $s): string { - return \preg_replace_callback( + return (string) \preg_replace_callback( '/[\x00-\x1F]+/', function (array $match): string { return '' . \addcslashes($match[0], "\x00..\xff") . ''; }, - \preg_replace( + (string) \preg_replace( '/(^| ) |(?: $)/', '$1 ', \htmlspecialchars($s, \ENT_NOQUOTES | \ENT_SUBSTITUTE | \ENT_DISALLOWED, 'utf-8') diff --git a/src/Io/MiddlewareHandler.php b/src/Io/MiddlewareHandler.php index 3feeea0..dd62f01 100644 --- a/src/Io/MiddlewareHandler.php +++ b/src/Io/MiddlewareHandler.php @@ -9,8 +9,10 @@ */ class MiddlewareHandler { + /** @var list $handlers */ private $handlers; + /** @param list $handlers */ public function __construct(array $handlers) { assert(count($handlers) >= 2); @@ -18,11 +20,13 @@ public function __construct(array $handlers) $this->handlers = $handlers; } + /** @return mixed */ public function __invoke(ServerRequestInterface $request) { return $this->call($request, 0); } + /** @return mixed */ private function call(ServerRequestInterface $request, int $position) { if (!isset($this->handlers[$position + 2])) { diff --git a/src/Io/RedirectHandler.php b/src/Io/RedirectHandler.php index 39ab3b9..3924ccb 100644 --- a/src/Io/RedirectHandler.php +++ b/src/Io/RedirectHandler.php @@ -10,8 +10,13 @@ */ class RedirectHandler { + /** @var string */ private $target; + + /** @var int */ private $code; + + /** @var string */ private $reason; /** @var HtmlHandler */ diff --git a/src/Io/RouteHandler.php b/src/Io/RouteHandler.php index 2d637e3..0402d6e 100644 --- a/src/Io/RouteHandler.php +++ b/src/Io/RouteHandler.php @@ -65,6 +65,7 @@ public function map(array $methods, string $route, $handler, ...$handlers): void } } + /** @var non-empty-array $handlers */ $handler = \count($handlers) > 1 ? new MiddlewareHandler(array_values($handlers)) : \reset($handlers); $this->routeDispatcher = null; $this->routeCollector->addRoute($methods, $route, $handler); diff --git a/src/Io/SapiHandler.php b/src/Io/SapiHandler.php index 37218dd..3f4f2c9 100644 --- a/src/Io/SapiHandler.php +++ b/src/Io/SapiHandler.php @@ -18,6 +18,7 @@ class SapiHandler public function __construct() { + // @phpstan-ignore-next-line because `fopen()` is known to always return a `resource` for built-in wrappers $this->logStream = PHP_SAPI === 'cli' ? \fopen('php://output', 'a') : (\defined('STDERR') ? \STDERR : \fopen('php://stderr', 'a')); } @@ -50,6 +51,7 @@ public function requestFromGlobals(): ServerRequestInterface } $body = file_get_contents('php://input'); + assert(\is_string($body)); $request = new ServerRequest( $_SERVER['REQUEST_METHOD'] ?? 'GET', @@ -102,6 +104,7 @@ public function sendResponse(ResponseInterface $response): void // send all headers without applying default "; charset=utf-8" set by PHP (default_charset) $old = ini_get('default_charset'); + assert(\is_string($old)); ini_set('default_charset', ''); foreach ($response->getHeaders() as $name => $values) { foreach ($values as $value) { diff --git a/tests/AccessLogHandlerTest.php b/tests/AccessLogHandlerTest.php index db38244..d6badfa 100644 --- a/tests/AccessLogHandlerTest.php +++ b/tests/AccessLogHandlerTest.php @@ -11,7 +11,7 @@ class AccessLogHandlerTest extends TestCase { - public function testInvokePrintsRequestLogWithCurrentDateAndTime() + public function testInvokePrintsRequestLogWithCurrentDateAndTime(): void { $handler = new AccessLogHandler(); @@ -23,7 +23,7 @@ public function testInvokePrintsRequestLogWithCurrentDateAndTime() $handler($request, function () use ($response) { return $response; }); } - public function testInvokePrintsRequestWithQueryParametersLogWithCurrentDateAndTime() + public function testInvokePrintsRequestWithQueryParametersLogWithCurrentDateAndTime(): void { $handler = new AccessLogHandler(); @@ -35,7 +35,7 @@ public function testInvokePrintsRequestWithQueryParametersLogWithCurrentDateAndT $handler($request, function () use ($response) { return $response; }); } - public function testInvokePrintsRequestWithEscapedSpecialCharactersInRequestMethodAndTargetWithCurrentDateAndTime() + public function testInvokePrintsRequestWithEscapedSpecialCharactersInRequestMethodAndTargetWithCurrentDateAndTime(): void { $handler = new AccessLogHandler(); @@ -48,7 +48,7 @@ public function testInvokePrintsRequestWithEscapedSpecialCharactersInRequestMeth $handler($request, function () use ($response) { return $response; }); } - public function testInvokePrintsRequestLogForHeadRequestWithResponseSizeAsZero() + public function testInvokePrintsRequestLogForHeadRequestWithResponseSizeAsZero(): void { $handler = new AccessLogHandler(); @@ -60,7 +60,7 @@ public function testInvokePrintsRequestLogForHeadRequestWithResponseSizeAsZero() $handler($request, function () use ($response) { return $response; }); } - public function testInvokePrintsRequestLogForNoContentResponseWithResponseSizeAsZero() + public function testInvokePrintsRequestLogForNoContentResponseWithResponseSizeAsZero(): void { $handler = new AccessLogHandler(); @@ -72,7 +72,7 @@ public function testInvokePrintsRequestLogForNoContentResponseWithResponseSizeAs $handler($request, function () use ($response) { return $response; }); } - public function testInvokePrintsRequestLogForNotModifiedResponseWithResponseSizeAsZero() + public function testInvokePrintsRequestLogForNotModifiedResponseWithResponseSizeAsZero(): void { $handler = new AccessLogHandler(); @@ -84,7 +84,7 @@ public function testInvokePrintsRequestLogForNotModifiedResponseWithResponseSize $handler($request, function () use ($response) { return $response; }); } - public function testInvokePrintsPlainProxyRequestLogWithCurrentDateAndTime() + public function testInvokePrintsPlainProxyRequestLogWithCurrentDateAndTime(): void { $handler = new AccessLogHandler(); @@ -97,7 +97,7 @@ public function testInvokePrintsPlainProxyRequestLogWithCurrentDateAndTime() $handler($request, function () use ($response) { return $response; }); } - public function testInvokePrintsConnectProxyRequestLogWithCurrentDateAndTime() + public function testInvokePrintsConnectProxyRequestLogWithCurrentDateAndTime(): void { $handler = new AccessLogHandler(); @@ -110,7 +110,7 @@ public function testInvokePrintsConnectProxyRequestLogWithCurrentDateAndTime() $handler($request, function () use ($response) { return $response; }); } - public function testInvokePrintsOptionsAsteriskLogWithCurrentDateAndTime() + public function testInvokePrintsOptionsAsteriskLogWithCurrentDateAndTime(): void { $handler = new AccessLogHandler(); @@ -123,7 +123,7 @@ public function testInvokePrintsOptionsAsteriskLogWithCurrentDateAndTime() $handler($request, function () use ($response) { return $response; }); } - public function testInvokeWithDeferredNextPrintsRequestLogWithCurrentDateAndTime() + public function testInvokeWithDeferredNextPrintsRequestLogWithCurrentDateAndTime(): void { $handler = new AccessLogHandler(); @@ -135,7 +135,7 @@ public function testInvokeWithDeferredNextPrintsRequestLogWithCurrentDateAndTime $handler($request, function () use ($response) { return resolve($response); }); } - public function testInvokeWithCoroutineNextPrintsRequestLogWithCurrentDateAndTime() + public function testInvokeWithCoroutineNextPrintsRequestLogWithCurrentDateAndTime(): void { $handler = new AccessLogHandler(); @@ -157,7 +157,7 @@ public function testInvokeWithCoroutineNextPrintsRequestLogWithCurrentDateAndTim $generator->next(); } - public function testInvokeWithStreamingResponsePrintsRequestLogWithCurrentDateAndTime() + public function testInvokeWithStreamingResponsePrintsRequestLogWithCurrentDateAndTime(): void { $handler = new AccessLogHandler(); @@ -172,7 +172,7 @@ public function testInvokeWithStreamingResponsePrintsRequestLogWithCurrentDateAn $stream->end('world'); } - public function testInvokeWithStreamingResponseThatClosesAfterSomeTimePrintsRequestLogWithCurrentDateAndTime() + public function testInvokeWithStreamingResponseThatClosesAfterSomeTimePrintsRequestLogWithCurrentDateAndTime(): void { $handler = new AccessLogHandler(); @@ -188,7 +188,7 @@ public function testInvokeWithStreamingResponseThatClosesAfterSomeTimePrintsRequ $stream->end(); } - public function testInvokeWithClosedStreamingResponsePrintsRequestLogWithCurrentDateAndTime() + public function testInvokeWithClosedStreamingResponsePrintsRequestLogWithCurrentDateAndTime(): void { $handler = new AccessLogHandler(); @@ -202,7 +202,7 @@ public function testInvokeWithClosedStreamingResponsePrintsRequestLogWithCurrent $handler($request, function () use ($response) { return $response; }); } - public function testInvokeWithStreamingResponsePrintsNothingIfStreamIsPending() + public function testInvokeWithStreamingResponsePrintsNothingIfStreamIsPending(): void { $handler = new AccessLogHandler(); @@ -215,7 +215,7 @@ public function testInvokeWithStreamingResponsePrintsNothingIfStreamIsPending() $stream->write('hello'); } - public function testInvokeWithRemoteAddrAttributePrintsRequestLogWithIpFromAttribute() + public function testInvokeWithRemoteAddrAttributePrintsRequestLogWithIpFromAttribute(): void { $handler = new AccessLogHandler(); @@ -228,7 +228,7 @@ public function testInvokeWithRemoteAddrAttributePrintsRequestLogWithIpFromAttri $handler($request, function () use ($response) { return $response; }); } - public function testInvokeWithoutRemoteAddressPrintsRequestLogWithDashAsPlaceholder() + public function testInvokeWithoutRemoteAddressPrintsRequestLogWithDashAsPlaceholder(): void { $handler = new AccessLogHandler(); diff --git a/tests/AppMiddlewareTest.php b/tests/AppMiddlewareTest.php index 340f4e5..d0ec78d 100644 --- a/tests/AppMiddlewareTest.php +++ b/tests/AppMiddlewareTest.php @@ -5,6 +5,7 @@ use FrameworkX\AccessLogHandler; use FrameworkX\App; use FrameworkX\Io\FiberHandler; +use FrameworkX\Io\MiddlewareHandler; use FrameworkX\Io\RouteHandler; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; @@ -16,7 +17,7 @@ class AppMiddlewareTest extends TestCase { - public function testGetMethodWithMiddlewareAddsGetRouteOnRouter() + public function testGetMethodWithMiddlewareAddsGetRouteOnRouter(): void { $app = $this->createAppWithoutLogger(); @@ -33,7 +34,7 @@ public function testGetMethodWithMiddlewareAddsGetRouteOnRouter() $app->get('/', $middleware, $controller); } - public function testHeadMethodWithMiddlewareAddsHeadRouteOnRouter() + public function testHeadMethodWithMiddlewareAddsHeadRouteOnRouter(): void { $app = $this->createAppWithoutLogger(); @@ -50,7 +51,7 @@ public function testHeadMethodWithMiddlewareAddsHeadRouteOnRouter() $app->head('/', $middleware, $controller); } - public function testPostMethodWithMiddlewareAddsPostRouteOnRouter() + public function testPostMethodWithMiddlewareAddsPostRouteOnRouter(): void { $app = $this->createAppWithoutLogger(); @@ -67,7 +68,7 @@ public function testPostMethodWithMiddlewareAddsPostRouteOnRouter() $app->post('/', $middleware, $controller); } - public function testPutMethodWithMiddlewareAddsPutRouteOnRouter() + public function testPutMethodWithMiddlewareAddsPutRouteOnRouter(): void { $app = $this->createAppWithoutLogger(); @@ -84,7 +85,7 @@ public function testPutMethodWithMiddlewareAddsPutRouteOnRouter() $app->put('/', $middleware, $controller); } - public function testPatchMethodWithMiddlewareAddsPatchRouteOnRouter() + public function testPatchMethodWithMiddlewareAddsPatchRouteOnRouter(): void { $app = $this->createAppWithoutLogger(); @@ -101,7 +102,7 @@ public function testPatchMethodWithMiddlewareAddsPatchRouteOnRouter() $app->patch('/', $middleware, $controller); } - public function testDeleteMethodWithMiddlewareAddsDeleteRouteOnRouter() + public function testDeleteMethodWithMiddlewareAddsDeleteRouteOnRouter(): void { $app = $this->createAppWithoutLogger(); @@ -118,7 +119,7 @@ public function testDeleteMethodWithMiddlewareAddsDeleteRouteOnRouter() $app->delete('/', $middleware, $controller); } - public function testOptionsMethodWithMiddlewareAddsOptionsRouteOnRouter() + public function testOptionsMethodWithMiddlewareAddsOptionsRouteOnRouter(): void { $app = $this->createAppWithoutLogger(); @@ -135,7 +136,7 @@ public function testOptionsMethodWithMiddlewareAddsOptionsRouteOnRouter() $app->options('/', $middleware, $controller); } - public function testAnyMethodWithMiddlewareAddsAllHttpMethodsOnRouter() + public function testAnyMethodWithMiddlewareAddsAllHttpMethodsOnRouter(): void { $app = $this->createAppWithoutLogger(); @@ -152,7 +153,7 @@ public function testAnyMethodWithMiddlewareAddsAllHttpMethodsOnRouter() $app->any('/', $middleware, $controller); } - public function testMapMethodWithMiddlewareAddsGivenMethodsOnRouter() + public function testMapMethodWithMiddlewareAddsGivenMethodsOnRouter(): void { $app = $this->createAppWithoutLogger(); @@ -169,7 +170,7 @@ public function testMapMethodWithMiddlewareAddsGivenMethodsOnRouter() $app->map(['GET', 'POST'], '/', $middleware, $controller); } - public function testMiddlewareCallsNextReturnsResponseFromRouter() + public function testMiddlewareCallsNextReturnsResponseFromRouter(): void { $app = $this->createAppWithoutLogger(); @@ -203,7 +204,7 @@ public function testMiddlewareCallsNextReturnsResponseFromRouter() $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testMiddlewareCallsNextWithModifiedRequestReturnsResponseFromRouter() + public function testMiddlewareCallsNextWithModifiedRequestReturnsResponseFromRouter(): void { $app = $this->createAppWithoutLogger(); @@ -217,7 +218,7 @@ public function testMiddlewareCallsNextWithModifiedRequestReturnsResponseFromRou [ 'Content-Type' => 'text/html' ], - $request->getAttribute('name') + $request->getAttribute('name') // @phpstan-ignore-line known to return string ); }; @@ -237,7 +238,7 @@ public function testMiddlewareCallsNextWithModifiedRequestReturnsResponseFromRou $this->assertEquals('Alice', (string) $response->getBody()); } - public function testMiddlewareCallsNextReturnsResponseModifiedInMiddlewareFromRouter() + public function testMiddlewareCallsNextReturnsResponseModifiedInMiddlewareFromRouter(): void { $app = $this->createAppWithoutLogger(); @@ -272,7 +273,7 @@ public function testMiddlewareCallsNextReturnsResponseModifiedInMiddlewareFromRo $this->assertEquals('Alice', (string) $response->getBody()); } - public function testMiddlewareCallsNextReturnsDeferredResponseModifiedInMiddlewareFromRouter() + public function testMiddlewareCallsNextReturnsDeferredResponseModifiedInMiddlewareFromRouter(): void { $app = $this->createAppWithoutLogger(); @@ -317,7 +318,7 @@ public function testMiddlewareCallsNextReturnsDeferredResponseModifiedInMiddlewa $this->assertEquals('Alice', (string) $response->getBody()); } - public function testMiddlewareCallsNextReturnsCoroutineResponseModifiedInMiddlewareFromRouter() + public function testMiddlewareCallsNextReturnsCoroutineResponseModifiedInMiddlewareFromRouter(): void { $app = $this->createAppWithoutLogger(); @@ -364,7 +365,7 @@ public function testMiddlewareCallsNextReturnsCoroutineResponseModifiedInMiddlew $this->assertEquals('Alice', (string) $response->getBody()); } - public function testMiddlewareCallsNextWhichThrowsExceptionReturnsInternalServerErrorResponse() + public function testMiddlewareCallsNextWhichThrowsExceptionReturnsInternalServerErrorResponse(): void { $app = $this->createAppWithoutLogger(); @@ -395,7 +396,7 @@ public function testMiddlewareCallsNextWhichThrowsExceptionReturnsInternalServer $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught RuntimeException with message Foo in AppMiddlewareTest.php:$line.

\n", (string) $response->getBody()); } - public function testMiddlewareWhichThrowsExceptionReturnsInternalServerErrorResponse() + public function testMiddlewareWhichThrowsExceptionReturnsInternalServerErrorResponse(): void { $app = $this->createAppWithoutLogger(); @@ -424,7 +425,7 @@ public function testMiddlewareWhichThrowsExceptionReturnsInternalServerErrorResp $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught RuntimeException with message Foo in AppMiddlewareTest.php:$line.

\n", (string) $response->getBody()); } - public function testGlobalMiddlewareCallsNextReturnsResponseFromController() + public function testGlobalMiddlewareCallsNextReturnsResponseFromController(): void { $app = $this->createAppWithoutLogger(function (ServerRequestInterface $request, callable $next) { return $next($request); @@ -454,10 +455,10 @@ public function testGlobalMiddlewareCallsNextReturnsResponseFromController() $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testGlobalMiddlewareInstanceCallsNextReturnsResponseFromController() + public function testGlobalMiddlewareInstanceCallsNextReturnsResponseFromController(): void { $middleware = new class { - public function __invoke(ServerRequestInterface $request, callable $next) + public function __invoke(ServerRequestInterface $request, callable $next): Response { return $next($request); } @@ -489,10 +490,10 @@ public function __invoke(ServerRequestInterface $request, callable $next) $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testGlobalMiddlewareClassNameCallsNextReturnsResponseFromController() + public function testGlobalMiddlewareClassNameCallsNextReturnsResponseFromController(): void { $middleware = new class { - public function __invoke(ServerRequestInterface $request, callable $next) + public function __invoke(ServerRequestInterface $request, callable $next): Response { return $next($request); } @@ -524,11 +525,12 @@ public function __invoke(ServerRequestInterface $request, callable $next) $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testGlobalMiddlewareClassNameAndSameForRouterCallsSameMiddlewareInstanceTwiceAndNextReturnsResponseFromController() + public function testGlobalMiddlewareClassNameAndSameForRouterCallsSameMiddlewareInstanceTwiceAndNextReturnsResponseFromController(): void { $middleware = new class { + /** @var int */ private $called = 0; - public function __invoke(ServerRequestInterface $request, callable $next) + public function __invoke(ServerRequestInterface $request, callable $next): Response { return $next($request->withAttribute('called', ++$this->called)); } @@ -560,9 +562,9 @@ public function __invoke(ServerRequestInterface $request, callable $next) $this->assertEquals("2\n", (string) $response->getBody()); } - public function testGlobalMiddlewareCallsNextWithModifiedRequestWillBeUsedForRouting() + public function testGlobalMiddlewareCallsNextWithModifiedRequestWillBeUsedForRouting(): void { - $app = $this->createAppWithoutLogger(function (ServerRequestInterface $request, callable $next) { + $app = $this->createAppWithoutLogger(function (ServerRequestInterface $request, callable $next): Response { return $next($request->withUri($request->getUri()->withPath('/users'))); }); @@ -590,7 +592,7 @@ public function testGlobalMiddlewareCallsNextWithModifiedRequestWillBeUsedForRou $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testGlobalMiddlewareCallsNextReturnsModifiedResponseWhenModifyingResponseFromRouter() + public function testGlobalMiddlewareCallsNextReturnsModifiedResponseWhenModifyingResponseFromRouter(): void { $app = $this->createAppWithoutLogger(function (ServerRequestInterface $request, callable $next) { $response = $next($request); @@ -621,7 +623,7 @@ public function testGlobalMiddlewareCallsNextReturnsModifiedResponseWhenModifyin $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testGlobalMiddlewareReturnsResponseWithoutCallingNextReturnsResponseWithoutCallingRouter() + public function testGlobalMiddlewareReturnsResponseWithoutCallingNextReturnsResponseWithoutCallingRouter(): void { $app = $this->createAppWithoutLogger(function () { return new Response( @@ -654,7 +656,7 @@ public function testGlobalMiddlewareReturnsResponseWithoutCallingNextReturnsResp $this->assertFalse($called); } - public function testGlobalMiddlewareReturnsPromiseWhichResolvesWithResponseWithoutCallingNextDoesNotCallRouter() + public function testGlobalMiddlewareReturnsPromiseWhichResolvesWithResponseWithoutCallingNextDoesNotCallRouter(): void { $app = $this->createAppWithoutLogger(function () { return resolve(new Response( @@ -695,7 +697,7 @@ public function testGlobalMiddlewareReturnsPromiseWhichResolvesWithResponseWitho $this->assertFalse($called); } - public function testGlobalMiddlewareCallsNextReturnsPromiseWhichResolvesWithModifiedResponseWhenModifyingPromiseWhichResolvesToResponseFromRouter() + public function testGlobalMiddlewareCallsNextReturnsPromiseWhichResolvesWithModifiedResponseWhenModifyingPromiseWhichResolvesToResponseFromRouter(): void { $app = $this->createAppWithoutLogger(function (ServerRequestInterface $request, callable $next) { return $next($request)->then(function (ResponseInterface $response) { @@ -733,7 +735,7 @@ public function testGlobalMiddlewareCallsNextReturnsPromiseWhichResolvesWithModi $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testGlobalMiddlewareCallsNextReturnsPromiseWhichResolvesWithModifiedResponseWhenModifyingCoroutineWhichYieldsResponseFromRouter() + public function testGlobalMiddlewareCallsNextReturnsPromiseWhichResolvesWithModifiedResponseWhenModifyingCoroutineWhichYieldsResponseFromRouter(): void { $app = $this->createAppWithoutLogger(function (ServerRequestInterface $request, callable $next) { $generator = $next($request); @@ -785,10 +787,12 @@ private function createAppWithoutLogger(...$middleware): App $ref = new \ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $middleware = $ref->getValue($app); + assert($middleware instanceof MiddlewareHandler); $ref = new \ReflectionProperty($middleware, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($middleware); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); diff --git a/tests/AppTest.php b/tests/AppTest.php index 24c9947..9433d03 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -38,7 +38,7 @@ class AppTest extends TestCase { - public function testConstructWithMiddlewareAssignsGivenMiddleware() + public function testConstructWithMiddlewareAssignsGivenMiddleware(): void { $middleware = function () { }; $app = new App($middleware); @@ -46,11 +46,12 @@ public function testConstructWithMiddlewareAssignsGivenMiddleware() $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -64,7 +65,7 @@ public function testConstructWithMiddlewareAssignsGivenMiddleware() $this->assertInstanceOf(RouteHandler::class, $handlers[3]); } - public function testConstructWithContainerAssignsDefaultHandlersAndContainerForRouteHandlerOnly() + public function testConstructWithContainerAssignsDefaultHandlersAndContainerForRouteHandlerOnly(): void { $accessLogHandler = new AccessLogHandler(); $errorHandler = new ErrorHandler(); @@ -78,11 +79,12 @@ public function testConstructWithContainerAssignsDefaultHandlersAndContainerForR $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -100,7 +102,7 @@ public function testConstructWithContainerAssignsDefaultHandlersAndContainerForR $this->assertSame($container, $ref->getValue($routeHandler)); } - public function testConstructWithContainerAndMiddlewareClassNameAssignsCallableFromContainerAsMiddleware() + public function testConstructWithContainerAndMiddlewareClassNameAssignsCallableFromContainerAsMiddleware(): void { $middleware = function (ServerRequestInterface $request, callable $next) { }; @@ -112,11 +114,12 @@ public function testConstructWithContainerAndMiddlewareClassNameAssignsCallableF $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -135,7 +138,7 @@ public function testConstructWithContainerAndMiddlewareClassNameAssignsCallableF $this->assertSame($container, $ref->getValue($routeHandler)); } - public function testConstructWithErrorHandlerOnlyAssignsErrorHandlerAfterDefaultAccessLogHandler() + public function testConstructWithErrorHandlerOnlyAssignsErrorHandlerAfterDefaultAccessLogHandler(): void { $errorHandler = new ErrorHandler(); @@ -144,11 +147,12 @@ public function testConstructWithErrorHandlerOnlyAssignsErrorHandlerAfterDefault $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -161,18 +165,19 @@ public function testConstructWithErrorHandlerOnlyAssignsErrorHandlerAfterDefault $this->assertInstanceOf(RouteHandler::class, $handlers[2]); } - public function testConstructWithErrorHandlerClassOnlyAssignsErrorHandlerAfterDefaultAccessLogHandler() + public function testConstructWithErrorHandlerClassOnlyAssignsErrorHandlerAfterDefaultAccessLogHandler(): void { $app = new App(ErrorHandler::class); $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -185,7 +190,7 @@ public function testConstructWithErrorHandlerClassOnlyAssignsErrorHandlerAfterDe $this->assertInstanceOf(RouteHandler::class, $handlers[2]); } - public function testConstructWithContainerAndErrorHandlerAssignsErrorHandlerAfterDefaultAccessLogHandler() + public function testConstructWithContainerAndErrorHandlerAssignsErrorHandlerAfterDefaultAccessLogHandler(): void { $errorHandler = new ErrorHandler(); @@ -194,11 +199,12 @@ public function testConstructWithContainerAndErrorHandlerAssignsErrorHandlerAfte $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -211,7 +217,7 @@ public function testConstructWithContainerAndErrorHandlerAssignsErrorHandlerAfte $this->assertInstanceOf(RouteHandler::class, $handlers[2]); } - public function testConstructWithContainerAndErrorHandlerClassAssignsErrorHandlerFromContainerAfterDefaultAccessLogHandler() + public function testConstructWithContainerAndErrorHandlerClassAssignsErrorHandlerFromContainerAfterDefaultAccessLogHandler(): void { $errorHandler = new ErrorHandler(); @@ -223,11 +229,12 @@ public function testConstructWithContainerAndErrorHandlerClassAssignsErrorHandle $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -240,7 +247,7 @@ public function testConstructWithContainerAndErrorHandlerClassAssignsErrorHandle $this->assertInstanceOf(RouteHandler::class, $handlers[2]); } - public function testConstructWithMultipleContainersAndErrorHandlerClassAssignsErrorHandlerFromLastContainerBeforeErrorHandlerAfterDefaultAccessLogHandler() + public function testConstructWithMultipleContainersAndErrorHandlerClassAssignsErrorHandlerFromLastContainerBeforeErrorHandlerAfterDefaultAccessLogHandler(): void { $errorHandler = new ErrorHandler(); @@ -255,11 +262,12 @@ public function testConstructWithMultipleContainersAndErrorHandlerClassAssignsEr $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -272,7 +280,7 @@ public function testConstructWithMultipleContainersAndErrorHandlerClassAssignsEr $this->assertInstanceOf(RouteHandler::class, $handlers[2]); } - public function testConstructWithMultipleContainersAndMiddlewareAssignsErrorHandlerFromLastContainerBeforeMiddlewareAfterDefaultAccessLogHandler() + public function testConstructWithMultipleContainersAndMiddlewareAssignsErrorHandlerFromLastContainerBeforeMiddlewareAfterDefaultAccessLogHandler(): void { $middleware = function (ServerRequestInterface $request, callable $next) { }; $errorHandler = new ErrorHandler(); @@ -288,11 +296,12 @@ public function testConstructWithMultipleContainersAndMiddlewareAssignsErrorHand $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -306,7 +315,7 @@ public function testConstructWithMultipleContainersAndMiddlewareAssignsErrorHand $this->assertInstanceOf(RouteHandler::class, $handlers[3]); } - public function testConstructWithMiddlewareAndErrorHandlerAssignsGivenErrorHandlerAfterMiddlewareAndDefaultAccessLogHandlerAndErrorHandlerFirst() + public function testConstructWithMiddlewareAndErrorHandlerAssignsGivenErrorHandlerAfterMiddlewareAndDefaultAccessLogHandlerAndErrorHandlerFirst(): void { $middleware = function (ServerRequestInterface $request, callable $next) { }; $errorHandler = new ErrorHandler(); @@ -316,11 +325,12 @@ public function testConstructWithMiddlewareAndErrorHandlerAssignsGivenErrorHandl $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -336,7 +346,7 @@ public function testConstructWithMiddlewareAndErrorHandlerAssignsGivenErrorHandl $this->assertInstanceOf(RouteHandler::class, $handlers[4]); } - public function testConstructWithMultipleContainersAndMiddlewareAndErrorHandlerClassAssignsDefaultErrorHandlerFromLastContainerBeforeMiddlewareAndErrorHandlerFromLastContainerAfterDefaultAccessLogHandler() + public function testConstructWithMultipleContainersAndMiddlewareAndErrorHandlerClassAssignsDefaultErrorHandlerFromLastContainerBeforeMiddlewareAndErrorHandlerFromLastContainerAfterDefaultAccessLogHandler(): void { $middleware = function (ServerRequestInterface $request, callable $next) { }; @@ -356,11 +366,12 @@ public function testConstructWithMultipleContainersAndMiddlewareAndErrorHandlerC $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -375,7 +386,7 @@ public function testConstructWithMultipleContainersAndMiddlewareAndErrorHandlerC $this->assertInstanceOf(RouteHandler::class, $handlers[4]); } - public function testConstructWithAccessLogHandlerAndErrorHandlerAssignsHandlersAsGiven() + public function testConstructWithAccessLogHandlerAndErrorHandlerAssignsHandlersAsGiven(): void { $accessLogHandler = new AccessLogHandler(); $errorHandler = new ErrorHandler(); @@ -385,11 +396,12 @@ public function testConstructWithAccessLogHandlerAndErrorHandlerAssignsHandlersA $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -402,18 +414,19 @@ public function testConstructWithAccessLogHandlerAndErrorHandlerAssignsHandlersA $this->assertInstanceOf(RouteHandler::class, $handlers[2]); } - public function testConstructWithAccessLogHandlerClassAndErrorHandlerClassAssignsDefaultHandlers() + public function testConstructWithAccessLogHandlerClassAndErrorHandlerClassAssignsDefaultHandlers(): void { $app = new App(AccessLogHandler::class, ErrorHandler::class); $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -426,7 +439,7 @@ public function testConstructWithAccessLogHandlerClassAndErrorHandlerClassAssign $this->assertInstanceOf(RouteHandler::class, $handlers[2]); } - public function testConstructWithContainerAndAccessLogHandlerClassAndErrorHandlerClassAssignsHandlersFromContainer() + public function testConstructWithContainerAndAccessLogHandlerClassAndErrorHandlerClassAssignsHandlersFromContainer(): void { $accessLogHandler = new AccessLogHandler(); $errorHandler = new ErrorHandler(); @@ -440,11 +453,12 @@ public function testConstructWithContainerAndAccessLogHandlerClassAndErrorHandle $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -457,7 +471,7 @@ public function testConstructWithContainerAndAccessLogHandlerClassAndErrorHandle $this->assertInstanceOf(RouteHandler::class, $handlers[2]); } - public function testConstructWithMiddlewareBeforeAccessLogHandlerAndErrorHandlerAssignsDefaultErrorHandlerAsFirstHandlerFollowedByGivenHandlers() + public function testConstructWithMiddlewareBeforeAccessLogHandlerAndErrorHandlerAssignsDefaultErrorHandlerAsFirstHandlerFollowedByGivenHandlers(): void { $middleware = static function (ServerRequestInterface $request, callable $next) { }; $accessLog = new AccessLogHandler(); @@ -468,11 +482,12 @@ public function testConstructWithMiddlewareBeforeAccessLogHandlerAndErrorHandler $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -488,7 +503,7 @@ public function testConstructWithMiddlewareBeforeAccessLogHandlerAndErrorHandler $this->assertInstanceOf(RouteHandler::class, $handlers[4]); } - public function testConstructWithMultipleContainersAndAccessLogHandlerClassAndErrorHandlerClassAssignsHandlersFromLastContainer() + public function testConstructWithMultipleContainersAndAccessLogHandlerClassAndErrorHandlerClassAssignsHandlersFromLastContainer(): void { $accessLogHandler = new AccessLogHandler(); $errorHandler = new ErrorHandler(); @@ -505,11 +520,12 @@ public function testConstructWithMultipleContainersAndAccessLogHandlerClassAndEr $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -523,7 +539,7 @@ public function testConstructWithMultipleContainersAndAccessLogHandlerClassAndEr } - public function testConstructWithMultipleContainersAndMiddlewareAssignsDefaultHandlersFromLastContainerBeforeMiddleware() + public function testConstructWithMultipleContainersAndMiddlewareAssignsDefaultHandlersFromLastContainerBeforeMiddleware(): void { $middleware = function (ServerRequestInterface $request, callable $next) { }; @@ -543,11 +559,12 @@ public function testConstructWithMultipleContainersAndMiddlewareAssignsDefaultHa $ref = new ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $handler = $ref->getValue($app); + assert($handler instanceof MiddlewareHandler); - $this->assertInstanceOf(MiddlewareHandler::class, $handler); $ref = new ReflectionProperty($handler, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($handler); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); @@ -561,7 +578,7 @@ public function testConstructWithMultipleContainersAndMiddlewareAssignsDefaultHa $this->assertInstanceOf(RouteHandler::class, $handlers[3]); } - public function testConstructWithAccessLogHandlerOnlyThrows() + public function testConstructWithAccessLogHandlerOnlyThrows(): void { $accessLogHandler = new AccessLogHandler(); @@ -569,7 +586,7 @@ public function testConstructWithAccessLogHandlerOnlyThrows() new App($accessLogHandler); } - public function testConstructWithAccessLogHandlerFollowedByMiddlewareThrows() + public function testConstructWithAccessLogHandlerFollowedByMiddlewareThrows(): void { $accessLogHandler = new AccessLogHandler(); $middleware = function (ServerRequestInterface $request, callable $next) { }; @@ -578,12 +595,13 @@ public function testConstructWithAccessLogHandlerFollowedByMiddlewareThrows() new App($accessLogHandler, $middleware); } - public function testRunWillReportListeningAddressAndRunLoopWithSocketServer() + public function testRunWillReportListeningAddressAndRunLoopWithSocketServer(): void { $socket = @stream_socket_server('127.0.0.1:8080'); if ($socket === false) { $this->markTestSkipped('Listen address :8080 already in use'); } + assert(is_resource($socket)); fclose($socket); $app = new App(); @@ -592,6 +610,7 @@ public function testRunWillReportListeningAddressAndRunLoopWithSocketServer() Loop::futureTick(function () { $resources = get_resources(); $socket = end($resources); + assert(is_resource($socket)); Loop::removeReadStream($socket); fclose($socket); @@ -603,9 +622,10 @@ public function testRunWillReportListeningAddressAndRunLoopWithSocketServer() $app->run(); } - public function testRunWillReportListeningAddressFromContainerEnvironmentAndRunLoopWithSocketServer() + public function testRunWillReportListeningAddressFromContainerEnvironmentAndRunLoopWithSocketServer(): void { - $socket = @stream_socket_server('127.0.0.1:0'); + $socket = stream_socket_server('127.0.0.1:0'); + assert(is_resource($socket)); $addr = stream_socket_get_name($socket, false); fclose($socket); @@ -619,6 +639,7 @@ public function testRunWillReportListeningAddressFromContainerEnvironmentAndRunL Loop::futureTick(function () { $resources = get_resources(); $socket = end($resources); + assert(is_resource($socket)); Loop::removeReadStream($socket); fclose($socket); @@ -630,7 +651,7 @@ public function testRunWillReportListeningAddressFromContainerEnvironmentAndRunL $app->run(); } - public function testRunWillReportListeningAddressFromContainerEnvironmentWithRandomPortAndRunLoopWithSocketServer() + public function testRunWillReportListeningAddressFromContainerEnvironmentWithRandomPortAndRunLoopWithSocketServer(): void { $container = new Container([ 'X_LISTEN' => '127.0.0.1:0' @@ -642,6 +663,7 @@ public function testRunWillReportListeningAddressFromContainerEnvironmentWithRan Loop::futureTick(function () { $resources = get_resources(); $socket = end($resources); + assert(is_resource($socket)); Loop::removeReadStream($socket); fclose($socket); @@ -653,7 +675,7 @@ public function testRunWillReportListeningAddressFromContainerEnvironmentWithRan $app->run(); } - public function testRunWillRestartLoopUntilSocketIsClosed() + public function testRunWillRestartLoopUntilSocketIsClosed(): void { $container = new Container([ 'X_LISTEN' => '127.0.0.1:0' @@ -665,6 +687,7 @@ public function testRunWillRestartLoopUntilSocketIsClosed() Loop::futureTick(function () { $resources = get_resources(); $socket = end($resources); + assert(is_resource($socket)); Loop::futureTick(function () use ($socket) { Loop::removeReadStream($socket); @@ -684,7 +707,7 @@ public function testRunWillRestartLoopUntilSocketIsClosed() * @requires function pcntl_signal * @requires function posix_kill */ - public function testRunWillStopWhenReceivingSigint() + public function testRunWillStopWhenReceivingSigint(): void { $container = new Container([ 'X_LISTEN' => '127.0.0.1:0' @@ -693,7 +716,9 @@ public function testRunWillStopWhenReceivingSigint() $app = new App($container); Loop::futureTick(function () { - posix_kill(getmypid(), defined('SIGINT') ? SIGINT : 2); + $pid = getmypid(); + assert(is_int($pid)); + posix_kill($pid, defined('SIGINT') ? SIGINT : 2); }); $this->expectOutputRegex('/' . preg_quote('Received SIGINT, stopping loop' . PHP_EOL, '/') . '$/'); @@ -704,7 +729,7 @@ public function testRunWillStopWhenReceivingSigint() * @requires function pcntl_signal * @requires function posix_kill */ - public function testRunWillStopWhenReceivingSigterm() + public function testRunWillStopWhenReceivingSigterm(): void { $container = new Container([ 'X_LISTEN' => '127.0.0.1:0' @@ -713,14 +738,16 @@ public function testRunWillStopWhenReceivingSigterm() $app = new App($container); Loop::futureTick(function () { - posix_kill(getmypid(), defined('SIGTERM') ? SIGTERM : 15); + $pid = getmypid(); + assert(is_int($pid)); + posix_kill($pid, defined('SIGTERM') ? SIGTERM : 15); }); $this->expectOutputRegex('/' . preg_quote('Received SIGTERM, stopping loop' . PHP_EOL, '/') . '$/'); $app->run(); } - public function testRunAppWithEmptyAddressThrows() + public function testRunAppWithEmptyAddressThrows(): void { $container = new Container([ 'X_LISTEN' => '' @@ -733,10 +760,12 @@ public function testRunAppWithEmptyAddressThrows() $app->run(); } - public function testRunAppWithBusyPortThrows() + public function testRunAppWithBusyPortThrows(): void { - $socket = @stream_socket_server('127.0.0.1:0'); + $socket = stream_socket_server('127.0.0.1:0'); + assert(is_resource($socket)); $addr = stream_socket_get_name($socket, false); + assert(is_string($addr)); if (@stream_socket_server($addr) !== false) { $this->markTestSkipped('System does not prevent listening on same address twice'); @@ -753,7 +782,7 @@ public function testRunAppWithBusyPortThrows() $app->run(); } - public function testRunOnceWillCreateRequestFromSapiThenRouteRequestAndThenSendResponseFromHandler() + public function testRunOnceWillCreateRequestFromSapiThenRouteRequestAndThenSendResponseFromHandler(): void { $app = $this->createAppWithoutLogger(); @@ -779,7 +808,7 @@ public function testRunOnceWillCreateRequestFromSapiThenRouteRequestAndThenSendR $ref->invoke($app); } - public function testRunOnceWillCreateRequestFromSapiThenRouteRequestAndThenSendResponseFromDeferredHandler() + public function testRunOnceWillCreateRequestFromSapiThenRouteRequestAndThenSendResponseFromDeferredHandler(): void { $app = $this->createAppWithoutLogger(); @@ -805,7 +834,7 @@ public function testRunOnceWillCreateRequestFromSapiThenRouteRequestAndThenSendR $ref->invoke($app); } - public function testGetMethodAddsGetRouteOnRouter() + public function testGetMethodAddsGetRouteOnRouter(): void { $app = new App(); @@ -819,7 +848,7 @@ public function testGetMethodAddsGetRouteOnRouter() $app->get('/', function () { }); } - public function testHeadMethodAddsHeadRouteOnRouter() + public function testHeadMethodAddsHeadRouteOnRouter(): void { $app = new App(); @@ -833,7 +862,7 @@ public function testHeadMethodAddsHeadRouteOnRouter() $app->head('/', function () { }); } - public function testPostMethodAddsPostRouteOnRouter() + public function testPostMethodAddsPostRouteOnRouter(): void { $app = new App(); @@ -847,7 +876,7 @@ public function testPostMethodAddsPostRouteOnRouter() $app->post('/', function () { }); } - public function testPutMethodAddsPutRouteOnRouter() + public function testPutMethodAddsPutRouteOnRouter(): void { $app = new App(); @@ -861,7 +890,7 @@ public function testPutMethodAddsPutRouteOnRouter() $app->put('/', function () { }); } - public function testPatchMethodAddsPatchRouteOnRouter() + public function testPatchMethodAddsPatchRouteOnRouter(): void { $app = new App(); @@ -875,7 +904,7 @@ public function testPatchMethodAddsPatchRouteOnRouter() $app->patch('/', function () { }); } - public function testDeleteMethodAddsDeleteRouteOnRouter() + public function testDeleteMethodAddsDeleteRouteOnRouter(): void { $app = new App(); @@ -889,7 +918,7 @@ public function testDeleteMethodAddsDeleteRouteOnRouter() $app->delete('/', function () { }); } - public function testOptionsMethodAddsOptionsRouteOnRouter() + public function testOptionsMethodAddsOptionsRouteOnRouter(): void { $app = new App(); @@ -903,7 +932,7 @@ public function testOptionsMethodAddsOptionsRouteOnRouter() $app->options('/', function () { }); } - public function testAnyMethodAddsRouteOnRouter() + public function testAnyMethodAddsRouteOnRouter(): void { $app = new App(); @@ -917,7 +946,7 @@ public function testAnyMethodAddsRouteOnRouter() $app->any('/', function () { }); } - public function testMapMethodAddsRouteOnRouter() + public function testMapMethodAddsRouteOnRouter(): void { $app = new App(); @@ -931,7 +960,7 @@ public function testMapMethodAddsRouteOnRouter() $app->map(['GET', 'POST'], '/', function () { }); } - public function testGetWithAccessLogHandlerAsMiddlewareThrows() + public function testGetWithAccessLogHandlerAsMiddlewareThrows(): void { $app = new App(); @@ -939,7 +968,7 @@ public function testGetWithAccessLogHandlerAsMiddlewareThrows() $app->get('/', new AccessLogHandler(), function () { }); } - public function testGetWithAccessLogHandlerClassAsMiddlewareThrows() + public function testGetWithAccessLogHandlerClassAsMiddlewareThrows(): void { $app = new App(); @@ -947,7 +976,7 @@ public function testGetWithAccessLogHandlerClassAsMiddlewareThrows() $app->get('/', AccessLogHandler::class, function () { }); } - public function testRedirectMethodAddsAnyRouteOnRouterWhichWhenInvokedReturnsRedirectResponseWithTargetLocation() + public function testRedirectMethodAddsAnyRouteOnRouterWhichWhenInvokedReturnsRedirectResponseWithTargetLocation(): void { $app = new App(); @@ -979,7 +1008,7 @@ public function testRedirectMethodAddsAnyRouteOnRouterWhichWhenInvokedReturnsRed $this->assertStringContainsString("

Redirecting to /users...

\n", (string) $response->getBody()); } - public function testRedirectMethodWithCustomRedirectCodeAddsAnyRouteOnRouterWhichWhenInvokedReturnsRedirectResponseWithCustomRedirectCode() + public function testRedirectMethodWithCustomRedirectCodeAddsAnyRouteOnRouterWhichWhenInvokedReturnsRedirectResponseWithCustomRedirectCode(): void { $app = new App(); @@ -1011,7 +1040,7 @@ public function testRedirectMethodWithCustomRedirectCodeAddsAnyRouteOnRouterWhic $this->assertStringContainsString("

Redirecting to /users...

\n", (string) $response->getBody()); } - public function testHandleRequestWithProxyRequestReturnsResponseWithMessageThatProxyRequestsAreNotAllowed() + public function testHandleRequestWithProxyRequestReturnsResponseWithMessageThatProxyRequestsAreNotAllowed(): void { $app = $this->createAppWithoutLogger(); @@ -1033,7 +1062,7 @@ public function testHandleRequestWithProxyRequestReturnsResponseWithMessageThatP $this->assertStringContainsString("

Please check your settings and retry.

\n", (string) $response->getBody()); } - public function testHandleRequestWithUnknownRouteReturnsResponseWithFileNotFoundMessage() + public function testHandleRequestWithUnknownRouteReturnsResponseWithFileNotFoundMessage(): void { $app = $this->createAppWithoutLogger(); @@ -1054,7 +1083,7 @@ public function testHandleRequestWithUnknownRouteReturnsResponseWithFileNotFound $this->assertStringContainsString("

Please check the URL in the address bar and try again.

\n", (string) $response->getBody()); } - public function testHandleRequestWithInvalidRequestMethodReturnsResponseWithSingleMethodNotAllowedMessage() + public function testHandleRequestWithInvalidRequestMethodReturnsResponseWithSingleMethodNotAllowedMessage(): void { $app = $this->createAppWithoutLogger(); @@ -1078,7 +1107,7 @@ public function testHandleRequestWithInvalidRequestMethodReturnsResponseWithSing $this->assertStringContainsString("

Please check the URL in the address bar and try again with GET request.

\n", (string) $response->getBody()); } - public function testHandleRequestWithInvalidRequestMethodReturnsResponseWithMultipleMethodNotAllowedMessage() + public function testHandleRequestWithInvalidRequestMethodReturnsResponseWithMultipleMethodNotAllowedMessage(): void { $app = $this->createAppWithoutLogger(); @@ -1104,7 +1133,7 @@ public function testHandleRequestWithInvalidRequestMethodReturnsResponseWithMult $this->assertStringContainsString("

Please check the URL in the address bar and try again with GET/HEAD/POST request.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsResponseFromMatchingRouteHandler() + public function testHandleRequestWithMatchingRouteReturnsResponseFromMatchingRouteHandler(): void { $app = $this->createAppWithoutLogger(); @@ -1132,7 +1161,7 @@ public function testHandleRequestWithMatchingRouteReturnsResponseFromMatchingRou $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testHandleRequestWithOptionsAsteriskRequestReturnsResponseFromMatchingEmptyRouteHandler() + public function testHandleRequestWithOptionsAsteriskRequestReturnsResponseFromMatchingEmptyRouteHandler(): void { $app = $this->createAppWithoutLogger(); @@ -1161,7 +1190,7 @@ public function testHandleRequestWithOptionsAsteriskRequestReturnsResponseFromMa $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithResponseWhenHandlerReturnsPromiseWhichFulfillsWithResponse() + public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithResponseWhenHandlerReturnsPromiseWhichFulfillsWithResponse(): void { $app = $this->createAppWithoutLogger(); @@ -1197,7 +1226,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPendingPromiseWhenHandlerReturnsPendingPromise() + public function testHandleRequestWithMatchingRouteReturnsPendingPromiseWhenHandlerReturnsPendingPromise(): void { $app = $this->createAppWithoutLogger(); @@ -1225,7 +1254,7 @@ public function testHandleRequestWithMatchingRouteReturnsPendingPromiseWhenHandl $this->assertFalse($resolved); } - public function testHandleRequestWithMatchingRouteReturnsResponseWhenHandlerReturnsCoroutineWhichReturnsResponseWithoutYielding() + public function testHandleRequestWithMatchingRouteReturnsResponseWhenHandlerReturnsCoroutineWhichReturnsResponseWithoutYielding(): void { $app = $this->createAppWithoutLogger(); @@ -1257,7 +1286,7 @@ public function testHandleRequestWithMatchingRouteReturnsResponseWhenHandlerRetu $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithResponseWhenHandlerReturnsCoroutineWhichReturnsResponseAfterYieldingResolvedPromise() + public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithResponseWhenHandlerReturnsCoroutineWhichReturnsResponseAfterYieldingResolvedPromise(): void { $app = $this->createAppWithoutLogger(); @@ -1295,7 +1324,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithResponseWhenHandlerReturnsCoroutineWhichReturnsResponseAfterCatchingExceptionFromYieldingRejectedPromise() + public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithResponseWhenHandlerReturnsCoroutineWhichReturnsResponseAfterCatchingExceptionFromYieldingRejectedPromise(): void { $app = $this->createAppWithoutLogger(); @@ -1338,7 +1367,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPendingPromiseWhenHandlerReturnsCoroutineThatYieldsPendingPromise() + public function testHandleRequestWithMatchingRouteReturnsPendingPromiseWhenHandlerReturnsCoroutineThatYieldsPendingPromise(): void { $app = $this->createAppWithoutLogger(); @@ -1366,7 +1395,7 @@ public function testHandleRequestWithMatchingRouteReturnsPendingPromiseWhenHandl $this->assertFalse($resolved); } - public function testHandleRequestWithMatchingRouteReturnsResponseWhenHandlerReturnsResponseAfterAwaitingPromiseResolvingWithResponse() + public function testHandleRequestWithMatchingRouteReturnsResponseWhenHandlerReturnsResponseAfterAwaitingPromiseResolvingWithResponse(): void { $app = $this->createAppWithoutLogger(); @@ -1394,7 +1423,7 @@ public function testHandleRequestWithMatchingRouteReturnsResponseWhenHandlerRetu $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPromiseResolvingWithResponseWhenHandlerReturnsResponseAfterAwaitingPromiseResolvingWithResponse() + public function testHandleRequestWithMatchingRouteReturnsPromiseResolvingWithResponseWhenHandlerReturnsResponseAfterAwaitingPromiseResolvingWithResponse(): void { if (PHP_VERSION_ID < 80100 || !function_exists('React\Async\async')) { $this->markTestSkipped('Requires PHP 8.1+ with react/async 4+'); @@ -1440,12 +1469,13 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseResolvingWithRes $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteAndRouteVariablesReturnsResponseFromHandlerWithRouteVariablesAssignedAsRequestAttributes() + public function testHandleRequestWithMatchingRouteAndRouteVariablesReturnsResponseFromHandlerWithRouteVariablesAssignedAsRequestAttributes(): void { $app = $this->createAppWithoutLogger(); $app->get('/users/{name}', function (ServerRequestInterface $request) { $name = $request->getAttribute('name'); + assert(is_string($name)); return new Response( 200, @@ -1470,7 +1500,7 @@ public function testHandleRequestWithMatchingRouteAndRouteVariablesReturnsRespon $this->assertEquals("Hello alice\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerThrowsException() + public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerThrowsException(): void { $app = $this->createAppWithoutLogger(); @@ -1497,7 +1527,7 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught RuntimeException with message Foo in AppTest.php:$line.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsPromiseWhichRejectsWithException() + public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsPromiseWhichRejectsWithException(): void { $app = $this->createAppWithoutLogger(); @@ -1532,7 +1562,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught RuntimeException with message Foo in AppTest.php:$line.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsPromiseWhichRejectsWithNull() + public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsPromiseWhichRejectsWithNull(): void { if (method_exists(PromiseInterface::class, 'catch')) { $this->markTestSkipped('Only supported for legacy Promise v2, Promise v3 always rejects with Throwable'); @@ -1570,7 +1600,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got React\Promise\RejectedPromise.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsCoroutineWhichYieldsRejectedPromise() + public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsCoroutineWhichYieldsRejectedPromise(): void { $app = $this->createAppWithoutLogger(); @@ -1605,7 +1635,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught RuntimeException with message Foo in AppTest.php:$line.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerReturnsCoroutineWhichThrowsExceptionWithoutYielding() + public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerReturnsCoroutineWhichThrowsExceptionWithoutYielding(): void { $app = $this->createAppWithoutLogger(); @@ -1635,7 +1665,7 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught RuntimeException with message Foo in AppTest.php:$line.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsCoroutineWhichThrowsExceptionAfterYielding() + public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsCoroutineWhichThrowsExceptionAfterYielding(): void { $app = $this->createAppWithoutLogger(); @@ -1671,7 +1701,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught RuntimeException with message Foo in AppTest.php:$line.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerThrowsAfterAwaitingPromiseRejectingWithException() + public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerThrowsAfterAwaitingPromiseRejectingWithException(): void { $app = $this->createAppWithoutLogger(); @@ -1698,7 +1728,7 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught RuntimeException with message Foo in AppTest.php:$line.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerThrowsAfterAwaitingPromiseRejectingWithException() + public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerThrowsAfterAwaitingPromiseRejectingWithException(): void { if (PHP_VERSION_ID < 80100 || !function_exists('React\Async\async')) { $this->markTestSkipped('Requires PHP 8.1+ with react/async 4+'); @@ -1745,7 +1775,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught RuntimeException with message Foo in AppTest.php:$line.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsCoroutineWhichReturnsNull() + public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsCoroutineWhichReturnsNull(): void { $app = $this->createAppWithoutLogger(); @@ -1780,7 +1810,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got null.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerReturnsCoroutineWhichYieldsNullImmediately() + public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerReturnsCoroutineWhichYieldsNullImmediately(): void { $app = $this->createAppWithoutLogger(); @@ -1807,7 +1837,7 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp $this->assertStringContainsString("

Expected request handler to yield React\Promise\PromiseInterface but got null near or before AppTest.php:$line.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerReturnsWrongValue() + public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerReturnsWrongValue(): void { $app = $this->createAppWithoutLogger(); @@ -1833,7 +1863,7 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got null.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerClassDoesNotExist() + public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerClassDoesNotExist(): void { $app = $this->createAppWithoutLogger(); @@ -1857,7 +1887,7 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp $this->assertStringMatchesFormat("%a

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught BadMethodCallException with message Request handler class UnknownClass not found in Container.php:%d.

\n%a", (string) $response->getBody()); } - public function provideInvalidClasses() + public function provideInvalidClasses(): \Generator { yield [ InvalidConstructorPrivate::class, @@ -1924,7 +1954,7 @@ public function provideInvalidClasses() * @param class-string $class * @param string $error */ - public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerClassIsInvalid(string $class, string $error) + public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerClassIsInvalid(string $class, string $error): void { $app = $this->createAppWithoutLogger(); @@ -1948,13 +1978,13 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp $this->assertStringMatchesFormat("%a

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught BadMethodCallException with message Request handler class " . $class . " failed to load: $error in Container.php:%d.

\n%a", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerClassRequiresUnexpectedCallableParameter() + public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerClassRequiresUnexpectedCallableParameter(): void { $app = $this->createAppWithoutLogger(); $line = __LINE__ + 2; $controller = new class { - public function __invoke(int $value) { } + public function __invoke(int $value): void { } }; $app->get('/users', get_class($controller)); @@ -1977,7 +2007,7 @@ public function __invoke(int $value) { } $this->assertStringMatchesFormat("%a

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught TypeError with message %s in AppTest.php:$line.

\n%a", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerClassHasNoInvokeMethod() + public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerClassHasNoInvokeMethod(): void { $app = $this->createAppWithoutLogger(); @@ -2003,7 +2033,7 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp $this->assertStringMatchesFormat("%a

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught BadMethodCallException with message Request handler class %s has no public __invoke() method in Container.php:%d.

\n%a", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsPromiseWhichFulfillsWithWrongValue() + public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWithInternalServerErrorResponseWhenHandlerReturnsPromiseWhichFulfillsWithWrongValue(): void { $app = $this->createAppWithoutLogger(); @@ -2037,7 +2067,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got null.

\n", (string) $response->getBody()); } - public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerReturnsWrongValueAfterYielding() + public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResponseWhenHandlerReturnsWrongValueAfterYielding(): void { $app = $this->createAppWithoutLogger(); @@ -2079,10 +2109,12 @@ private function createAppWithoutLogger(): App $ref = new \ReflectionProperty($app, 'handler'); $ref->setAccessible(true); $middleware = $ref->getValue($app); + assert($middleware instanceof MiddlewareHandler); $ref = new \ReflectionProperty($middleware, 'handlers'); $ref->setAccessible(true); $handlers = $ref->getValue($middleware); + assert(is_array($handlers)); if (PHP_VERSION_ID >= 80100) { $first = array_shift($handlers); diff --git a/tests/ContainerTest.php b/tests/ContainerTest.php index 0c09c6d..d33d722 100644 --- a/tests/ContainerTest.php +++ b/tests/ContainerTest.php @@ -15,12 +15,12 @@ class ContainerTest extends TestCase { - public function testCallableReturnsCallableForClassNameViaAutowiring() + public function testCallableReturnsCallableForClassNameViaAutowiring(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class { - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { return new Response(200); } @@ -36,11 +36,12 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals(200, $response->getStatusCode()); } - public function testCallableReturnsCallableForClassNameViaAutowiringWithConfigurationForDependency() + public function testCallableReturnsCallableForClassNameViaAutowiringWithConfigurationForDependency(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -48,9 +49,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -67,11 +68,12 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('{"name":"Alice"}', (string) $response->getBody()); } - public function testCallableReturnsCallableForNullableClassViaAutowiringWillDefaultToNullValue() + public function testCallableReturnsCallableForNullableClassViaAutowiringWillDefaultToNullValue(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var ?\stdClass */ private $data; public function __construct(?\stdClass $data) @@ -79,9 +81,9 @@ public function __construct(?\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -96,11 +98,12 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('null', (string) $response->getBody()); } - public function testCallableReturnsCallableForNullableClassViaContainerConfiguration() + public function testCallableReturnsCallableForNullableClassViaContainerConfiguration(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var ?\stdClass */ private $data; public function __construct(?\stdClass $data) @@ -108,9 +111,9 @@ public function __construct(?\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -130,19 +133,20 @@ public function __invoke(ServerRequestInterface $request) /** * @requires PHP 8 */ - public function testCallableReturnsCallableForUnionWithNullViaAutowiringWillDefaultToNullValue() + public function testCallableReturnsCallableForUnionWithNullViaAutowiringWillDefaultToNullValue(): void { $request = new ServerRequest('GET', 'http://example.com/'); // @phpstan-ignore-next-line for PHP < 8 $controller = new class(null) { + /** @var mixed */ private $data = false; #[PHP8] public function __construct(string|int|null $data) { $this->data = $data; } // @phpstan-ignore-line - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -157,11 +161,12 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('null', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassWithNullDefaultViaAutowiringWillDefaultToNullValue() + public function testCallableReturnsCallableForClassWithNullDefaultViaAutowiringWillDefaultToNullValue(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(null) { + /** @var \stdClass|null|false */ private $data = false; public function __construct(\stdClass $data = null) @@ -169,9 +174,9 @@ public function __construct(\stdClass $data = null) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -186,11 +191,12 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('null', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassWithNullDefaultViaContainerConfiguration() + public function testCallableReturnsCallableForClassWithNullDefaultViaContainerConfiguration(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(null) { + /** @var \stdClass|null|false */ private $data = false; public function __construct(\stdClass $data = null) @@ -198,9 +204,9 @@ public function __construct(\stdClass $data = null) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -220,19 +226,20 @@ public function __invoke(ServerRequestInterface $request) /** * @requires PHP 8 */ - public function testCallableReturnsCallableForUnionWithIntDefaultValueViaAutowiringWillDefaultToIntValue() + public function testCallableReturnsCallableForUnionWithIntDefaultValueViaAutowiringWillDefaultToIntValue(): void { $request = new ServerRequest('GET', 'http://example.com/'); // @phpstan-ignore-next-line for PHP < 8 $controller = new class(null) { + /** @var string|int|null|false */ private $data = false; #[PHP8] public function __construct(string|int|null $data = 42) { $this->data = $data; } // @phpstan-ignore-line - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -247,21 +254,23 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('42', (string) $response->getBody()); } - public function testCallableReturnsCallableForUntypedWithStringDefaultViaAutowiringWillDefaultToStringValue() + public function testCallableReturnsCallableForUntypedWithStringDefaultViaAutowiringWillDefaultToStringValue(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(null) { + /** @var mixed */ private $data = false; + /** @param mixed $data */ public function __construct($data = 'empty') { $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -279,19 +288,20 @@ public function __invoke(ServerRequestInterface $request) /** * @requires PHP 8 */ - public function testCallableReturnsCallableForMixedWithStringDefaultViaAutowiringWillDefaultToStringValue() + public function testCallableReturnsCallableForMixedWithStringDefaultViaAutowiringWillDefaultToStringValue(): void { $request = new ServerRequest('GET', 'http://example.com/'); // @phpstan-ignore-next-line for PHP < 8 $controller = new class(null) { + /** @var mixed */ private $data = false; #[PHP8] public function __construct(mixed $data = 'empty') { $this->data = $data; } // @phpstan-ignore-line - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -306,11 +316,12 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('"empty"', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameViaAutowiringWithFactoryFunctionForDependency() + public function testCallableReturnsCallableForClassNameViaAutowiringWithFactoryFunctionForDependency(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -318,9 +329,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -339,11 +350,12 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('{"name":"Alice"}', (string) $response->getBody()); } - public function testCallableTwiceReturnsCallableForClassNameViaAutowiringWithFactoryFunctionForDependencyWillCallFactoryOnlyOnce() + public function testCallableTwiceReturnsCallableForClassNameViaAutowiringWithFactoryFunctionForDependencyWillCallFactoryOnlyOnce(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -351,9 +363,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -375,7 +387,7 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('{"num":1}', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedToSubclassExplicitly() + public function testCallableReturnsCallableForClassNameWithDependencyMappedToSubclassExplicitly(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -383,6 +395,7 @@ public function testCallableReturnsCallableForClassNameWithDependencyMappedToSub $dto->name = 'Alice'; $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -390,9 +403,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -410,7 +423,7 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('{"name":"Alice"}', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedToSubclassFromFactory() + public function testCallableReturnsCallableForClassNameWithDependencyMappedToSubclassFromFactory(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -418,6 +431,7 @@ public function testCallableReturnsCallableForClassNameWithDependencyMappedToSub $dto->name = 'Alice'; $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -425,9 +439,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -445,11 +459,12 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('{"name":"Alice"}', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresOtherClassWithFactory() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresOtherClassWithFactory(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -457,7 +472,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -465,7 +480,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (\stdClass $dto) { - return new Response(200, [], json_encode($dto)); + return new Response(200, [], (string) json_encode($dto)); }, \stdClass::class => function () { return (object)['name' => 'Alice']; } ]); @@ -479,11 +494,12 @@ public function __invoke() $this->assertEquals('{"name":"Alice"}', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresContainerVariable() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresContainerVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -491,7 +507,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -499,7 +515,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (\stdClass $data) { - return new Response(200, [], json_encode($data)); + return new Response(200, [], (string) json_encode($data)); }, 'data' => (object) ['name' => 'Alice'] ]); @@ -513,11 +529,12 @@ public function __invoke() $this->assertEquals('{"name":"Alice"}', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresContainerVariableWithFactory() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresContainerVariableWithFactory(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -525,7 +542,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -533,7 +550,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (\stdClass $data) { - return new Response(200, [], json_encode($data)); + return new Response(200, [], (string) json_encode($data)); }, 'data' => function () { return (object) ['name' => 'Alice']; @@ -549,7 +566,8 @@ public function __invoke() $this->assertEquals('{"name":"Alice"}', (string) $response->getBody()); } - public function provideMixedValue() + /** @return list> */ + public function provideMixedValue(): array { return [ [ @@ -569,12 +587,14 @@ public function provideMixedValue() /** * @dataProvider provideMixedValue + * @param \stdClass|string|null $value */ - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresUntypedContainerVariable($value, string $json) + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresUntypedContainerVariable($value, string $json): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -582,7 +602,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -590,7 +610,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function ($data) { - return new Response(200, [], json_encode($data)); + return new Response(200, [], (string) json_encode($data)); }, 'data' => $value ]); @@ -606,12 +626,14 @@ public function __invoke() /** * @dataProvider provideMixedValue + * @param \stdClass|string|null $value */ - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresUntypedContainerVariableWithFactory($value, string $json) + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresUntypedContainerVariableWithFactory($value, string $json): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -619,7 +641,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -627,7 +649,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function ($data) { - return new Response(200, [], json_encode($data)); + return new Response(200, [], (string) json_encode($data)); }, 'data' => function () use ($value) { return $value; @@ -646,12 +668,14 @@ public function __invoke() /** * @requires PHP 8 * @dataProvider provideMixedValue + * @param \stdClass|string|null $value */ - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresMixedContainerVariable($value, string $json) + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresMixedContainerVariable($value, string $json): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -659,7 +683,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -667,7 +691,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (mixed $data) { - return new Response(200, [], json_encode($data)); + return new Response(200, [], (string) json_encode($data)); }, 'data' => $value ]); @@ -684,12 +708,14 @@ public function __invoke() /** * @requires PHP 8 * @dataProvider provideMixedValue + * @param mixed $value */ - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresMixedContainerVariableWithFactory($value, string $json) + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresMixedContainerVariableWithFactory($value, string $json): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -697,7 +723,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -705,7 +731,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (mixed $data) { - return new Response(200, [], json_encode($data)); + return new Response(200, [], (string) json_encode($data)); }, 'data' => function () use ($value) { return $value; @@ -721,11 +747,12 @@ public function __invoke() $this->assertEquals($json, (string) $response->getBody()); } - public function testCallableReturnsCallableForClassWithDependencyMappedWithFactoryThatRequiresUntypedContainerVariableWithIntDefaultAssignExplicitNullValue() + public function testCallableReturnsCallableForClassWithDependencyMappedWithFactoryThatRequiresUntypedContainerVariableWithIntDefaultAssignExplicitNullValue(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -733,7 +760,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -741,7 +768,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function ($data = 42) { - return new Response(200, [], json_encode($data)); + return new Response(200, [], (string) json_encode($data)); }, 'data' => null ]); @@ -758,11 +785,12 @@ public function __invoke() /** * @requires PHP 8 */ - public function testCallableReturnsCallableForClassWithDependencyMappedWithFactoryThatRequiresMixedContainerVariableWithIntDefaultAssignExplicitNullValue() + public function testCallableReturnsCallableForClassWithDependencyMappedWithFactoryThatRequiresMixedContainerVariableWithIntDefaultAssignExplicitNullValue(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -770,14 +798,14 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } }; $fn = null; - $fn = #[PHP8] fn(mixed $data = 42) => new Response(200, [], json_encode($data)); // @phpstan-ignore-line + $fn = #[PHP8] fn(mixed $data = 42) => new Response(200, [], (string) json_encode($data)); // @phpstan-ignore-line $container = new Container([ ResponseInterface::class => $fn, 'data' => null @@ -792,11 +820,12 @@ public function __invoke() $this->assertEquals('null', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresNullableContainerVariables() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresNullableContainerVariables(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -804,7 +833,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -812,7 +841,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (?\stdClass $user, ?\stdClass $data) { - return new Response(200, [], json_encode(['user' => $user, 'data' => $data])); + return new Response(200, [], (string) json_encode(['user' => $user, 'data' => $data])); }, 'user' => (object) [] ]); @@ -826,11 +855,12 @@ public function __invoke() $this->assertEquals('{"user":{},"data":null}', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresNullableContainerVariablesWithFactory() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresNullableContainerVariablesWithFactory(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -838,7 +868,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -846,7 +876,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (?\stdClass $user, ?\stdClass $data) { - return new Response(200, [], json_encode(['user' => $user, 'data' => $data])); + return new Response(200, [], (string) json_encode(['user' => $user, 'data' => $data])); }, 'user' => function (): ?\stdClass { // @phpstan-ignore-line return (object) []; @@ -862,11 +892,12 @@ public function __invoke() $this->assertEquals('{"user":{},"data":null}', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresContainerVariablesWithDefaultValues() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresContainerVariablesWithDefaultValues(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -874,7 +905,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -882,7 +913,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (string $name = 'Alice', int $age = 0) { - return new Response(200, [], json_encode(['name' => $name, 'age' => $age])); + return new Response(200, [], (string) json_encode(['name' => $name, 'age' => $age])); }, 'age' => 42 ]); @@ -896,11 +927,12 @@ public function __invoke() $this->assertEquals('{"name":"Alice","age":42}', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresScalarVariables() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresScalarVariables(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -908,9 +940,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -933,11 +965,12 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('{"name":"Alice","age":42,"admin":true,"percent":0.5}', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameMappedFromFactoryWithScalarVariablesMappedFromFactory() + public function testCallableReturnsCallableForClassNameMappedFromFactoryWithScalarVariablesMappedFromFactory(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -945,9 +978,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -969,11 +1002,12 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('{"name":"Alice","age":42,"admin":true,"percent":0.5}', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameReferencingVariableMappedFromFactoryReferencingVariable() + public function testCallableReturnsCallableForClassNameReferencingVariableMappedFromFactoryReferencingVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -981,9 +1015,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1005,11 +1039,12 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals('{"name":"ADMIN"}', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresStringEnvironmentVariable() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresStringEnvironmentVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -1017,7 +1052,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -1025,7 +1060,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (string $FOO) { - return new Response(200, [], json_encode($FOO)); + return new Response(200, [], (string) json_encode($FOO)); } ]); @@ -1041,11 +1076,12 @@ public function __invoke() $this->assertEquals('"bar"', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresStringMappedFromFactoryThatRequiresStringEnvironmentVariable() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresStringMappedFromFactoryThatRequiresStringEnvironmentVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -1053,7 +1089,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -1061,7 +1097,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (string $address) { - return new Response(200, [], json_encode($address)); + return new Response(200, [], (string) json_encode($address)); }, 'address' => function (string $FOO) { return 'http://' . $FOO; @@ -1080,11 +1116,12 @@ public function __invoke() $this->assertEquals('"http:\/\/bar"', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresNullableStringEnvironmentVariable() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresNullableStringEnvironmentVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -1092,7 +1129,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -1100,7 +1137,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (?string $FOO) { - return new Response(200, [], json_encode($FOO)); + return new Response(200, [], (string) json_encode($FOO)); } ]); @@ -1116,11 +1153,12 @@ public function __invoke() $this->assertEquals('"bar"', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresNullableStringEnvironmentVariableAssignsNull() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresNullableStringEnvironmentVariableAssignsNull(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -1128,7 +1166,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -1136,7 +1174,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (?string $FOO) { - return new Response(200, [], json_encode($FOO)); + return new Response(200, [], (string) json_encode($FOO)); } ]); @@ -1149,11 +1187,12 @@ public function __invoke() $this->assertEquals('null', (string) $response->getBody()); } - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresUntypedEnvironmentVariable() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresUntypedEnvironmentVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -1161,7 +1200,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -1169,7 +1208,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function ($FOO) { - return new Response(200, [], json_encode($FOO)); + return new Response(200, [], (string) json_encode($FOO)); } ]); @@ -1188,11 +1227,12 @@ public function __invoke() /** * @requires PHP 8 */ - public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresMixedEnvironmentVariable() + public function testCallableReturnsCallableForClassNameWithDependencyMappedWithFactoryThatRequiresMixedEnvironmentVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response()) { + /** @var ResponseInterface */ private $response; public function __construct(ResponseInterface $response) @@ -1200,7 +1240,7 @@ public function __construct(ResponseInterface $response) $this->response = $response; } - public function __invoke() + public function __invoke(): ResponseInterface { return $this->response; } @@ -1208,7 +1248,7 @@ public function __invoke() $container = new Container([ ResponseInterface::class => function (mixed $FOO) { - return new Response(200, [], json_encode($FOO)); + return new Response(200, [], (string) json_encode($FOO)); } ]); @@ -1224,11 +1264,12 @@ public function __invoke() $this->assertEquals('"bar"', (string) $response->getBody()); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesUnknownVariable() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesUnknownVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1236,9 +1277,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1255,11 +1296,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesRecursiveVariable() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesRecursiveVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1267,9 +1309,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1286,11 +1328,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesStringVariableMappedWithUnexpectedObjectType() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesStringVariableMappedWithUnexpectedObjectType(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class('') { + /** @var string */ private $data; public function __construct(string $stdClass) @@ -1298,9 +1341,9 @@ public function __construct(string $stdClass) $this->data = $stdClass; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1319,11 +1362,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesVariableMappedFromFactoryWithUnexpectedReturnType() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesVariableMappedFromFactoryWithUnexpectedReturnType(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1331,9 +1375,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1353,11 +1397,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesObjectVariableMappedFromFactoryWithReturnsUnexpectedInteger() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesObjectVariableMappedFromFactoryWithReturnsUnexpectedInteger(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1365,9 +1410,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1385,11 +1430,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesStringVariableMappedFromFactoryWithReturnsUnexpectedInteger() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesStringVariableMappedFromFactoryWithReturnsUnexpectedInteger(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1397,9 +1443,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1417,11 +1463,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesIntVariableMappedFromFactoryWithReturnsUnexpectedString() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesIntVariableMappedFromFactoryWithReturnsUnexpectedString(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1429,9 +1476,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1449,11 +1496,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesFloatVariableMappedFromFactoryWithReturnsUnexpectedString() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesFloatVariableMappedFromFactoryWithReturnsUnexpectedString(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1461,9 +1509,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1481,11 +1529,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesBoolVariableMappedFromFactoryWithReturnsUnexpectedString() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesBoolVariableMappedFromFactoryWithReturnsUnexpectedString(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1493,9 +1542,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1513,11 +1562,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesClassNameButGetsStringVariable() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesClassNameButGetsStringVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1525,9 +1575,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1542,11 +1592,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesNullableClassButGetsStringVariable() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesNullableClassButGetsStringVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var ?\stdClass */ private $data; public function __construct(?\stdClass $data) @@ -1554,9 +1605,9 @@ public function __construct(?\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1571,11 +1622,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesClassNameButGetsIntVariable() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesClassNameButGetsIntVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1583,9 +1635,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1600,11 +1652,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesClassNameButGetsNullVariable() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesClassNameButGetsNullVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1612,9 +1665,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1629,11 +1682,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesNullableClassNameButGetsNullVariable() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesNullableClassNameButGetsNullVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var ?\stdClass */ private $data; public function __construct(?\stdClass $data) @@ -1641,9 +1695,9 @@ public function __construct(?\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1658,11 +1712,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesClassMappedToUnexpectedObject() + public function testCallableReturnsCallableThatThrowsWhenFactoryReferencesClassMappedToUnexpectedObject(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new \stdClass()) { + /** @var \stdClass */ private $data; public function __construct(\stdClass $data) @@ -1670,9 +1725,9 @@ public function __construct(\stdClass $data) $this->data = $data; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1687,11 +1742,12 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenConstructorWithoutFactoryFunctionReferencesStringVariable() + public function testCallableReturnsCallableThatThrowsWhenConstructorWithoutFactoryFunctionReferencesStringVariable(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class('Alice') { + /** @var string */ private $data; public function __construct(string $name) @@ -1699,9 +1755,9 @@ public function __construct(string $name) $this->data = $name; } - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { - return new Response(200, [], json_encode($this->data)); + return new Response(200, [], (string) json_encode($this->data)); } }; @@ -1716,7 +1772,7 @@ public function __invoke(ServerRequestInterface $request) $callable($request); } - public function testCtorThrowsWhenMapContainsInvalidArray() + public function testCtorThrowsWhenMapContainsInvalidArray(): void { $this->expectException(\BadMethodCallException::class); $this->expectExceptionMessage('Map for all contains unexpected array'); @@ -1726,17 +1782,17 @@ public function testCtorThrowsWhenMapContainsInvalidArray() ]); } - public function testCtorThrowsWhenMapContainsInvalidResource() + public function testCtorThrowsWhenMapContainsInvalidResource(): void { $this->expectException(\BadMethodCallException::class); $this->expectExceptionMessage('Map for file contains unexpected resource'); - new Container([ + new Container([ // @phpstan-ignore-line 'file' => tmpfile() ]); } - public function testCtorThrowsWhenMapForClassContainsInvalidObject() + public function testCtorThrowsWhenMapForClassContainsInvalidObject(): void { $this->expectException(\BadMethodCallException::class); $this->expectExceptionMessage('Map for Psr\Http\Message\ResponseInterface contains unexpected stdClass'); @@ -1746,7 +1802,7 @@ public function testCtorThrowsWhenMapForClassContainsInvalidObject() ]); } - public function testCtorThrowsWhenMapForClassContainsInvalidNull() + public function testCtorThrowsWhenMapForClassContainsInvalidNull(): void { $this->expectException(\BadMethodCallException::class); $this->expectExceptionMessage('Map for Psr\Http\Message\ResponseInterface contains unexpected NULL'); @@ -1756,7 +1812,7 @@ public function testCtorThrowsWhenMapForClassContainsInvalidNull() ]); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsInvalidClassName() + public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsInvalidClassName(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -1771,7 +1827,7 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsInvalidCl $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsInvalidInteger() + public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsInvalidInteger(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -1786,7 +1842,7 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsInvalidIn $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenMapReferencesClassNameThatDoesNotMatchType() + public function testCallableReturnsCallableThatThrowsWhenMapReferencesClassNameThatDoesNotMatchType(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -1801,7 +1857,7 @@ public function testCallableReturnsCallableThatThrowsWhenMapReferencesClassNameT $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsClassNameThatDoesNotMatchType() + public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsClassNameThatDoesNotMatchType(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -1816,7 +1872,7 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsClassName $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresInvalidClassName() + public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresInvalidClassName(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -1831,7 +1887,7 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresInvalidC $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresUntypedArgument() + public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresUntypedArgument(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -1849,7 +1905,7 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresUntypedA /** * @requires PHP 8 */ - public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresUndefinedMixedArgument() + public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresUndefinedMixedArgument(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -1864,7 +1920,7 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresUndefine $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresRecursiveClass() + public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresRecursiveClass(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -1879,7 +1935,7 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresRecursiv $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryIsRecursive() + public function testCallableReturnsCallableThatThrowsWhenFactoryIsRecursive(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -1894,7 +1950,7 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryIsRecursive() $callable($request); } - public function testCallableReturnsCallableThatThrowsWhenFactoryIsRecursiveClassName() + public function testCallableReturnsCallableThatThrowsWhenFactoryIsRecursiveClassName(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -1911,12 +1967,12 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryIsRecursiveClass $callable($request); } - public function testCallableReturnsCallableForClassNameViaPsrContainer() + public function testCallableReturnsCallableForClassNameViaPsrContainer(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class { - public function __invoke(ServerRequestInterface $request) + public function __invoke(ServerRequestInterface $request): Response { return new Response(200); } @@ -1936,7 +1992,7 @@ public function __invoke(ServerRequestInterface $request) $this->assertEquals(200, $response->getStatusCode()); } - public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsInvalidClassNameViaPsrContainer() + public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsInvalidClassNameViaPsrContainer(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -1955,14 +2011,14 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsInvalidCl $callable($request); } - public function testGetEnvReturnsNullWhenEnvironmentDoesNotExist() + public function testGetEnvReturnsNullWhenEnvironmentDoesNotExist(): void { $container = new Container([]); $this->assertNull($container->getEnv('X_FOO')); } - public function testGetEnvReturnsStringFromMap() + public function testGetEnvReturnsStringFromMap(): void { $container = new Container([ 'X_FOO' => 'bar' @@ -1971,7 +2027,7 @@ public function testGetEnvReturnsStringFromMap() $this->assertEquals('bar', $container->getEnv('X_FOO')); } - public function testGetEnvReturnsStringFromMapFactory() + public function testGetEnvReturnsStringFromMapFactory(): void { $container = new Container([ 'X_FOO' => function (string $bar) { return $bar; }, @@ -1981,7 +2037,7 @@ public function testGetEnvReturnsStringFromMapFactory() $this->assertEquals('bar', $container->getEnv('X_FOO')); } - public function testGetEnvReturnsStringFromGlobalServerIfNotSetInMap() + public function testGetEnvReturnsStringFromGlobalServerIfNotSetInMap(): void { $container = new Container([]); @@ -1992,7 +2048,7 @@ public function testGetEnvReturnsStringFromGlobalServerIfNotSetInMap() $this->assertEquals('bar', $ret); } - public function testGetEnvReturnsStringFromPsrContainer() + public function testGetEnvReturnsStringFromPsrContainer(): void { $psr = $this->createMock(ContainerInterface::class); $psr->expects($this->once())->method('has')->with('X_FOO')->willReturn(true); @@ -2003,7 +2059,7 @@ public function testGetEnvReturnsStringFromPsrContainer() $this->assertEquals('bar', $container->getEnv('X_FOO')); } - public function testGetEnvReturnsNullIfPsrContainerHasNoEntry() + public function testGetEnvReturnsNullIfPsrContainerHasNoEntry(): void { $psr = $this->createMock(ContainerInterface::class); $psr->expects($this->once())->method('has')->with('X_FOO')->willReturn(false); @@ -2014,7 +2070,7 @@ public function testGetEnvReturnsNullIfPsrContainerHasNoEntry() $this->assertNull($container->getEnv('X_FOO')); } - public function testGetEnvReturnsStringFromGlobalServerIfPsrContainerHasNoEntry() + public function testGetEnvReturnsStringFromGlobalServerIfPsrContainerHasNoEntry(): void { $psr = $this->createMock(ContainerInterface::class); $psr->expects($this->once())->method('has')->with('X_FOO')->willReturn(false); @@ -2029,7 +2085,7 @@ public function testGetEnvReturnsStringFromGlobalServerIfPsrContainerHasNoEntry( $this->assertEquals('bar', $ret); } - public function testGetEnvThrowsIfMapContainsInvalidType() + public function testGetEnvThrowsIfMapContainsInvalidType(): void { $container = new Container([ 'X_FOO' => false @@ -2040,7 +2096,7 @@ public function testGetEnvThrowsIfMapContainsInvalidType() $container->getEnv('X_FOO'); } - public function testGetEnvThrowsIfMapPsrContainerReturnsInvalidType() + public function testGetEnvThrowsIfMapPsrContainerReturnsInvalidType(): void { $psr = $this->createMock(ContainerInterface::class); $psr->expects($this->once())->method('has')->with('X_FOO')->willReturn(true); @@ -2053,7 +2109,7 @@ public function testGetEnvThrowsIfMapPsrContainerReturnsInvalidType() $container->getEnv('X_FOO'); } - public function testGetAccessLogHandlerReturnsDefaultAccessLogHandlerInstance() + public function testGetAccessLogHandlerReturnsDefaultAccessLogHandlerInstance(): void { $container = new Container([]); @@ -2062,7 +2118,7 @@ public function testGetAccessLogHandlerReturnsDefaultAccessLogHandlerInstance() $this->assertInstanceOf(AccessLogHandler::class, $accessLogHandler); } - public function testGetAccessLogHandlerReturnsAccessLogHandlerInstanceFromMap() + public function testGetAccessLogHandlerReturnsAccessLogHandlerInstanceFromMap(): void { $accessLogHandler = new AccessLogHandler(); @@ -2075,7 +2131,7 @@ public function testGetAccessLogHandlerReturnsAccessLogHandlerInstanceFromMap() $this->assertSame($accessLogHandler, $ret); } - public function testGetAccessLogHandlerReturnsAccessLogHandlerInstanceFromPsrContainer() + public function testGetAccessLogHandlerReturnsAccessLogHandlerInstanceFromPsrContainer(): void { $accessLogHandler = new AccessLogHandler(); @@ -2090,7 +2146,7 @@ public function testGetAccessLogHandlerReturnsAccessLogHandlerInstanceFromPsrCon $this->assertSame($accessLogHandler, $ret); } - public function testGetAccessLogHandlerReturnsDefaultAccessLogHandlerInstanceIfPsrContainerHasNoEntry() + public function testGetAccessLogHandlerReturnsDefaultAccessLogHandlerInstanceIfPsrContainerHasNoEntry(): void { $psr = $this->createMock(ContainerInterface::class); $psr->expects($this->once())->method('has')->with(AccessLogHandler::class)->willReturn(false); @@ -2103,7 +2159,7 @@ public function testGetAccessLogHandlerReturnsDefaultAccessLogHandlerInstanceIfP $this->assertInstanceOf(AccessLogHandler::class, $accessLogHandler); } - public function testGetErrorHandlerReturnsDefaultErrorHandlerInstance() + public function testGetErrorHandlerReturnsDefaultErrorHandlerInstance(): void { $container = new Container([]); @@ -2112,7 +2168,7 @@ public function testGetErrorHandlerReturnsDefaultErrorHandlerInstance() $this->assertInstanceOf(ErrorHandler::class, $errorHandler); } - public function testGetErrorHandlerReturnsErrorHandlerInstanceFromMap() + public function testGetErrorHandlerReturnsErrorHandlerInstanceFromMap(): void { $errorHandler = new ErrorHandler(); @@ -2125,7 +2181,7 @@ public function testGetErrorHandlerReturnsErrorHandlerInstanceFromMap() $this->assertSame($errorHandler, $ret); } - public function testGetErrorHandlerReturnsErrorHandlerInstanceFromPsrContainer() + public function testGetErrorHandlerReturnsErrorHandlerInstanceFromPsrContainer(): void { $errorHandler = new ErrorHandler(); @@ -2140,7 +2196,7 @@ public function testGetErrorHandlerReturnsErrorHandlerInstanceFromPsrContainer() $this->assertSame($errorHandler, $ret); } - public function testGetErrorHandlerReturnsDefaultErrorHandlerInstanceIfPsrContainerHasNoEntry() + public function testGetErrorHandlerReturnsDefaultErrorHandlerInstanceIfPsrContainerHasNoEntry(): void { $psr = $this->createMock(ContainerInterface::class); $psr->expects($this->once())->method('has')->with(ErrorHandler::class)->willReturn(false); @@ -2153,7 +2209,7 @@ public function testGetErrorHandlerReturnsDefaultErrorHandlerInstanceIfPsrContai $this->assertInstanceOf(ErrorHandler::class, $errorHandler); } - public function testInvokeContainerAsMiddlewareReturnsFromNextRequestHandler() + public function testInvokeContainerAsMiddlewareReturnsFromNextRequestHandler(): void { $request = new ServerRequest('GET', 'http://example.com/'); $response = new Response(200, [], ''); @@ -2164,7 +2220,7 @@ public function testInvokeContainerAsMiddlewareReturnsFromNextRequestHandler() $this->assertSame($response, $ret); } - public function testInvokeContainerAsFinalRequestHandlerThrows() + public function testInvokeContainerAsFinalRequestHandlerThrows(): void { $request = new ServerRequest('GET', 'http://example.com/'); @@ -2175,7 +2231,7 @@ public function testInvokeContainerAsFinalRequestHandlerThrows() $container($request); } - public function testCtorWithInvalidValueThrows() + public function testCtorWithInvalidValueThrows(): void { $this->expectException(\TypeError::class); $this->expectExceptionMessage('Argument #1 ($loader) must be of type array|Psr\Container\ContainerInterface, stdClass given'); diff --git a/tests/ErrorHandlerTest.php b/tests/ErrorHandlerTest.php index d565a52..905c1e8 100644 --- a/tests/ErrorHandlerTest.php +++ b/tests/ErrorHandlerTest.php @@ -13,7 +13,7 @@ class ErrorHandlerTest extends TestCase { - public function testInvokeWithHandlerReturningResponseReturnsSameResponse() + public function testInvokeWithHandlerReturningResponseReturnsSameResponse(): void { $handler = new ErrorHandler(); @@ -25,7 +25,7 @@ public function testInvokeWithHandlerReturningResponseReturnsSameResponse() $this->assertSame($response, $ret); } - public function testInvokeWithHandlerReturningPromiseResolvingWithResponseReturnsPromiseResolvingWithSameResponse() + public function testInvokeWithHandlerReturningPromiseResolvingWithResponseReturnsPromiseResolvingWithSameResponse(): void { $handler = new ErrorHandler(); @@ -45,7 +45,7 @@ public function testInvokeWithHandlerReturningPromiseResolvingWithResponseReturn $this->assertSame($response, $ret); } - public function testInvokeWithHandlerReturningGeneratorReturningResponseReturnsGeneratorYieldingSameResponse() + public function testInvokeWithHandlerReturningGeneratorReturningResponseReturnsGeneratorYieldingSameResponse(): void { $handler = new ErrorHandler(); @@ -66,7 +66,7 @@ public function testInvokeWithHandlerReturningGeneratorReturningResponseReturnsG $this->assertSame($response, $ret); } - public function testInvokeWithHandlerReturningGeneratorYieldingResolvedPromiseThenReturningResponseReturnsGeneratorYieldingSameResponse() + public function testInvokeWithHandlerReturningGeneratorYieldingResolvedPromiseThenReturningResponseReturnsGeneratorYieldingSameResponse(): void { $handler = new ErrorHandler(); @@ -87,7 +87,7 @@ public function testInvokeWithHandlerReturningGeneratorYieldingResolvedPromiseTh $this->assertSame($response, $ret); } - public function testInvokeWithHandlerReturningGeneratorYieldingRejectedPromiseInTryCatchThenReturningResponseReturnsGeneratorYieldingSameResponse() + public function testInvokeWithHandlerReturningGeneratorYieldingRejectedPromiseInTryCatchThenReturningResponseReturnsGeneratorYieldingSameResponse(): void { $handler = new ErrorHandler(); @@ -121,7 +121,7 @@ public function testInvokeWithHandlerReturningGeneratorYieldingRejectedPromiseIn $this->assertSame($response, $ret); } - public function testInvokeWithHandlerThrowingExceptionReturnsError500Response() + public function testInvokeWithHandlerThrowingExceptionReturnsError500Response(): void { $handler = new ErrorHandler(); @@ -136,7 +136,7 @@ public function testInvokeWithHandlerThrowingExceptionReturnsError500Response() $this->assertEquals(500, $response->getStatusCode()); } - public function testInvokeWithHandlerReturningPromiseRejectingWithExceptionReturnsPromiseResolvingWithError500Response() + public function testInvokeWithHandlerReturningPromiseRejectingWithExceptionReturnsPromiseResolvingWithError500Response(): void { $handler = new ErrorHandler(); @@ -159,7 +159,7 @@ public function testInvokeWithHandlerReturningPromiseRejectingWithExceptionRetur $this->assertEquals(500, $response->getStatusCode()); } - public function testInvokeWithHandlerReturningGeneratorThrowingExceptionReturnsGeneratorYieldingError500Response() + public function testInvokeWithHandlerReturningGeneratorThrowingExceptionReturnsGeneratorYieldingError500Response(): void { $handler = new ErrorHandler(); @@ -181,7 +181,7 @@ public function testInvokeWithHandlerReturningGeneratorThrowingExceptionReturnsG $this->assertEquals(500, $response->getStatusCode()); } - public function testInvokeWithHandlerReturningGeneratorYieldingPromiseThenThrowingExceptionReturnsGeneratorYieldingError500Response() + public function testInvokeWithHandlerReturningGeneratorYieldingPromiseThenThrowingExceptionReturnsGeneratorYieldingError500Response(): void { $handler = new ErrorHandler(); @@ -202,7 +202,7 @@ public function testInvokeWithHandlerReturningGeneratorYieldingPromiseThenThrowi $this->assertEquals(500, $response->getStatusCode()); } - public function testInvokeWithHandlerReturningGeneratorYieldingPromiseRejectingWithExceptionReturnsGeneratorYieldingError500Response() + public function testInvokeWithHandlerReturningGeneratorYieldingPromiseRejectingWithExceptionReturnsGeneratorYieldingError500Response(): void { $handler = new ErrorHandler(); @@ -233,7 +233,7 @@ public function testInvokeWithHandlerReturningGeneratorYieldingPromiseRejectingW $this->assertEquals(500, $response->getStatusCode()); } - public function testInvokeWithHandlerReturningNullReturnsError500Response() + public function testInvokeWithHandlerReturningNullReturnsError500Response(): void { $handler = new ErrorHandler(); @@ -248,7 +248,7 @@ public function testInvokeWithHandlerReturningNullReturnsError500Response() $this->assertEquals(500, $response->getStatusCode()); } - public function testInvokeWithHandlerReturningPromiseResolvingWithNullReturnsPromiseResolvingWithError500Response() + public function testInvokeWithHandlerReturningPromiseResolvingWithNullReturnsPromiseResolvingWithError500Response(): void { $handler = new ErrorHandler(); @@ -271,7 +271,7 @@ public function testInvokeWithHandlerReturningPromiseResolvingWithNullReturnsPro $this->assertEquals(500, $response->getStatusCode()); } - public function testInvokeWithHandlerReturningPromiseRejectingWithNullReturnsPromiseResolvingWithError500Response() + public function testInvokeWithHandlerReturningPromiseRejectingWithNullReturnsPromiseResolvingWithError500Response(): void { if (method_exists(PromiseInterface::class, 'catch')) { $this->markTestSkipped('Only supported for legacy Promise v2, Promise v3 always rejects with Throwable'); @@ -298,7 +298,7 @@ public function testInvokeWithHandlerReturningPromiseRejectingWithNullReturnsPro $this->assertEquals(500, $response->getStatusCode()); } - public function testInvokeWithHandlerReturningGeneratorYieldingNullReturnsGeneratorYieldingError500Response() + public function testInvokeWithHandlerReturningGeneratorYieldingNullReturnsGeneratorYieldingError500Response(): void { $handler = new ErrorHandler(); @@ -317,7 +317,7 @@ public function testInvokeWithHandlerReturningGeneratorYieldingNullReturnsGenera $this->assertEquals(500, $response->getStatusCode()); } - public function testInvokeWithHandlerReturningGeneratorReturningNullReturnsGeneratorYieldingError500Response() + public function testInvokeWithHandlerReturningGeneratorReturningNullReturnsGeneratorYieldingError500Response(): void { $handler = new ErrorHandler(); @@ -339,7 +339,7 @@ public function testInvokeWithHandlerReturningGeneratorReturningNullReturnsGener $this->assertEquals(500, $response->getStatusCode()); } - public function testRequestNotFoundReturnsError404() + public function testRequestNotFoundReturnsError404(): void { $handler = new ErrorHandler(); $response = $handler->requestNotFound(); @@ -354,7 +354,7 @@ public function testRequestNotFoundReturnsError404() $this->assertStringContainsString("

Please check the URL in the address bar and try again.

\n", (string) $response->getBody()); } - public function testRequestMethodNotAllowedReturnsError405WithSingleAllowedMethod() + public function testRequestMethodNotAllowedReturnsError405WithSingleAllowedMethod(): void { $handler = new ErrorHandler(); $response = $handler->requestMethodNotAllowed(['GET']); @@ -365,7 +365,7 @@ public function testRequestMethodNotAllowedReturnsError405WithSingleAllowedMetho $this->assertStringContainsString("

Please check the URL in the address bar and try again with GET request.

\n", (string) $response->getBody()); } - public function testRequestMethodNotAllowedReturnsError405WithMultipleAllowedMethods() + public function testRequestMethodNotAllowedReturnsError405WithMultipleAllowedMethods(): void { $handler = new ErrorHandler(); $response = $handler->requestMethodNotAllowed(['GET', 'HEAD', 'POST']); @@ -376,7 +376,7 @@ public function testRequestMethodNotAllowedReturnsError405WithMultipleAllowedMet $this->assertStringContainsString("

Please check the URL in the address bar and try again with GET/HEAD/POST request.

\n", (string) $response->getBody()); } - public function testRequestProxyUnsupportedReturnsError400() + public function testRequestProxyUnsupportedReturnsError400(): void { $handler = new ErrorHandler(); $response = $handler->requestProxyUnsupported(); @@ -386,7 +386,8 @@ public function testRequestProxyUnsupportedReturnsError400() $this->assertStringContainsString("

Please check your settings and retry.

\n", (string) $response->getBody()); } - public function provideExceptionMessage() + /** @return list> */ + public function provideExceptionMessage(): array { return [ [ @@ -439,7 +440,7 @@ public function provideExceptionMessage() /** * @dataProvider provideExceptionMessage */ - public function testErrorInvalidExceptionReturnsError500(string $in, string $expected) + public function testErrorInvalidExceptionReturnsError500(string $in, string $expected): void { $handler = new ErrorHandler(); @@ -450,13 +451,15 @@ public function testErrorInvalidExceptionReturnsError500(string $in, string $exp $ref = new \ReflectionMethod($handler, 'errorInvalidException'); $ref->setAccessible(true); $response = $ref->invoke($handler, $e); + assert($response instanceof ResponseInterface); $this->assertStringContainsString("Error 500: Internal Server Error\n", (string) $response->getBody()); $this->assertStringContainsString("

The requested page failed to load, please try again later.

\n", (string) $response->getBody()); $this->assertStringContainsString("

Expected request handler to return Psr\Http\Message\ResponseInterface but got uncaught RuntimeException with message $expected in ErrorHandlerTest.php:$line.

\n", (string) $response->getBody()); } - public function provideInvalidReturnValue() + /** @return list> */ + public function provideInvalidReturnValue(): array { return [ [ @@ -498,7 +501,7 @@ public function provideInvalidReturnValue() * @dataProvider provideInvalidReturnValue * @param mixed $value */ - public function testErrorInvalidResponseReturnsError500($value, string $name) + public function testErrorInvalidResponseReturnsError500($value, string $name): void { $handler = new ErrorHandler(); @@ -506,6 +509,7 @@ public function testErrorInvalidResponseReturnsError500($value, string $name) $ref = new \ReflectionMethod($handler, 'errorInvalidResponse'); $ref->setAccessible(true); $response = $ref->invoke($handler, $value); + assert($response instanceof ResponseInterface); $this->assertStringContainsString("Error 500: Internal Server Error\n", (string) $response->getBody()); $this->assertStringContainsString("

The requested page failed to load, please try again later.

\n", (string) $response->getBody()); @@ -516,7 +520,7 @@ public function testErrorInvalidResponseReturnsError500($value, string $name) * @dataProvider provideInvalidReturnValue * @param mixed $value */ - public function testErrorInvalidCoroutineReturnsError500($value, string $name) + public function testErrorInvalidCoroutineReturnsError500($value, string $name): void { $handler = new ErrorHandler(); @@ -527,6 +531,7 @@ public function testErrorInvalidCoroutineReturnsError500($value, string $name) $ref = new \ReflectionMethod($handler, 'errorInvalidCoroutine'); $ref->setAccessible(true); $response = $ref->invoke($handler, $value, $file, $line); + assert($response instanceof ResponseInterface); $this->assertStringContainsString("Error 500: Internal Server Error\n", (string) $response->getBody()); $this->assertStringContainsString("

The requested page failed to load, please try again later.

\n", (string) $response->getBody()); diff --git a/tests/FilesystemHandlerTest.php b/tests/FilesystemHandlerTest.php index 5c95158..e9838e7 100644 --- a/tests/FilesystemHandlerTest.php +++ b/tests/FilesystemHandlerTest.php @@ -9,7 +9,7 @@ class FilesystemHandlerTest extends TestCase { - public function testInvokeWithValidPathToComposerJsonWillReturnResponseWithFileContentsAndContentType() + public function testInvokeWithValidPathToComposerJsonWillReturnResponseWithFileContentsAndContentType(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -25,7 +25,7 @@ public function testInvokeWithValidPathToComposerJsonWillReturnResponseWithFileC $this->assertEquals(file_get_contents(__DIR__ . '/../composer.json'), (string) $response->getBody()); } - public function testInvokeWithValidPathToLicenseWillReturnResponseWithFileContentsAndDefaultContentType() + public function testInvokeWithValidPathToLicenseWillReturnResponseWithFileContentsAndDefaultContentType(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -41,7 +41,7 @@ public function testInvokeWithValidPathToLicenseWillReturnResponseWithFileConten $this->assertEquals(file_get_contents(__DIR__ . '/../LICENSE'), (string) $response->getBody()); } - public function testInvokeWithValidPathToOneCharacterFilenameWillReturnResponseWithFileContentsAndDefaultContentType() + public function testInvokeWithValidPathToOneCharacterFilenameWillReturnResponseWithFileContentsAndDefaultContentType(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -57,7 +57,7 @@ public function testInvokeWithValidPathToOneCharacterFilenameWillReturnResponseW $this->assertEquals(file_get_contents(__DIR__ . '/data/a'), (string) $response->getBody()); } - public function testInvokeWithValidPathToTwoCharacterFilenameWillReturnResponseWithFileContentsAndDefaultContentType() + public function testInvokeWithValidPathToTwoCharacterFilenameWillReturnResponseWithFileContentsAndDefaultContentType(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -73,7 +73,7 @@ public function testInvokeWithValidPathToTwoCharacterFilenameWillReturnResponseW $this->assertEquals(file_get_contents(__DIR__ . '/data/bb'), (string) $response->getBody()); } - public function testInvokeWithValidPathToComposerJsonAndCachingHeaderWillReturnResponseNotModifiedWithoutContents() + public function testInvokeWithValidPathToComposerJsonAndCachingHeaderWillReturnResponseNotModifiedWithoutContents(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -93,7 +93,7 @@ public function testInvokeWithValidPathToComposerJsonAndCachingHeaderWillReturnR $this->assertEquals('', (string) $response->getBody()); } - public function testInvokeWithInvalidPathWillReturnNotFoundResponse() + public function testInvokeWithInvalidPathWillReturnNotFoundResponse(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -109,7 +109,7 @@ public function testInvokeWithInvalidPathWillReturnNotFoundResponse() $this->assertStringContainsString("Error 404: Page Not Found\n", (string) $response->getBody()); } - public function testInvokeWithDoubleSlashWillReturnNotFoundResponse() + public function testInvokeWithDoubleSlashWillReturnNotFoundResponse(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -125,7 +125,7 @@ public function testInvokeWithDoubleSlashWillReturnNotFoundResponse() $this->assertStringContainsString("Error 404: Page Not Found\n", (string) $response->getBody()); } - public function testInvokeWithPathWithLeadingSlashWillReturnNotFoundResponse() + public function testInvokeWithPathWithLeadingSlashWillReturnNotFoundResponse(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -141,7 +141,7 @@ public function testInvokeWithPathWithLeadingSlashWillReturnNotFoundResponse() $this->assertStringContainsString("Error 404: Page Not Found\n", (string) $response->getBody()); } - public function testInvokeWithPathWithDotSegmentWillReturnNotFoundResponse() + public function testInvokeWithPathWithDotSegmentWillReturnNotFoundResponse(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -157,7 +157,7 @@ public function testInvokeWithPathWithDotSegmentWillReturnNotFoundResponse() $this->assertStringContainsString("Error 404: Page Not Found\n", (string) $response->getBody()); } - public function testInvokeWithPathBelowRootWillReturnNotFoundResponse() + public function testInvokeWithPathBelowRootWillReturnNotFoundResponse(): void { $handler = new FilesystemHandler(__DIR__); @@ -173,7 +173,7 @@ public function testInvokeWithPathBelowRootWillReturnNotFoundResponse() $this->assertStringContainsString("Error 404: Page Not Found\n", (string) $response->getBody()); } - public function testInvokeWithBinaryPathWillReturnNotFoundResponse() + public function testInvokeWithBinaryPathWillReturnNotFoundResponse(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -189,7 +189,7 @@ public function testInvokeWithBinaryPathWillReturnNotFoundResponse() $this->assertStringContainsString("Error 404: Page Not Found\n", (string) $response->getBody()); } - public function testInvokeWithoutPathWillReturnResponseWithDirectoryListing() + public function testInvokeWithoutPathWillReturnResponseWithDirectoryListing(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -206,7 +206,7 @@ public function testInvokeWithoutPathWillReturnResponseWithDirectoryListing() $this->assertStringNotContainsString('../', (string) $response->getBody()); } - public function testInvokeWithEmptyPathWillReturnResponseWithDirectoryListing() + public function testInvokeWithEmptyPathWillReturnResponseWithDirectoryListing(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -224,7 +224,7 @@ public function testInvokeWithEmptyPathWillReturnResponseWithDirectoryListing() $this->assertStringNotContainsString('../', (string) $response->getBody()); } - public function testInvokeWithoutPathAndRootIsFileWillReturnResponseWithFileContents() + public function testInvokeWithoutPathAndRootIsFileWillReturnResponseWithFileContents(): void { $handler = new FilesystemHandler(dirname(__DIR__) . '/LICENSE'); @@ -239,7 +239,7 @@ public function testInvokeWithoutPathAndRootIsFileWillReturnResponseWithFileCont $this->assertEquals(file_get_contents(__DIR__ . '/../LICENSE'), (string) $response->getBody()); } - public function testInvokeWithValidPathToDirectoryWillReturnResponseWithDirectoryListing() + public function testInvokeWithValidPathToDirectoryWillReturnResponseWithDirectoryListing(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -255,7 +255,7 @@ public function testInvokeWithValidPathToDirectoryWillReturnResponseWithDirector $this->assertEquals(".github/\n\n", (string) $response->getBody()); } - public function testInvokeWithValidPathToDirectoryButWithoutTrailingSlashWillReturnRedirectToPathWithSlash() + public function testInvokeWithValidPathToDirectoryButWithoutTrailingSlashWillReturnRedirectToPathWithSlash(): void { $handler = new FilesystemHandler(dirname(__DIR__)); @@ -275,7 +275,7 @@ public function testInvokeWithValidPathToDirectoryButWithoutTrailingSlashWillRet $this->assertStringContainsString("

Redirecting to .github/...

\n", (string) $response->getBody()); } - public function testInvokeWithValidPathToFileButWithTrailingSlashWillReturnRedirectToPathWithoutSlash() + public function testInvokeWithValidPathToFileButWithTrailingSlashWillReturnRedirectToPathWithoutSlash(): void { $handler = new FilesystemHandler(dirname(__DIR__)); diff --git a/tests/Io/FiberHandlerTest.php b/tests/Io/FiberHandlerTest.php index ac1e781..15c2dd1 100644 --- a/tests/Io/FiberHandlerTest.php +++ b/tests/Io/FiberHandlerTest.php @@ -21,7 +21,7 @@ public function setUp(): void } } - public function testInvokeWithHandlerReturningResponseReturnsSameResponse() + public function testInvokeWithHandlerReturningResponseReturnsSameResponse(): void { $handler = new FiberHandler(); @@ -33,7 +33,7 @@ public function testInvokeWithHandlerReturningResponseReturnsSameResponse() $this->assertSame($response, $ret); } - public function testInvokeWithHandlerReturningPromiseResolvingWithResponseReturnsPromiseResolvingWithSameResponse() + public function testInvokeWithHandlerReturningPromiseResolvingWithResponseReturnsPromiseResolvingWithSameResponse(): void { $handler = new FiberHandler(); @@ -53,7 +53,7 @@ public function testInvokeWithHandlerReturningPromiseResolvingWithResponseReturn $this->assertSame($response, $ret); } - public function testInvokeWithHandlerReturningGeneratorReturningResponseReturnsGeneratorReturningSameResponse() + public function testInvokeWithHandlerReturningGeneratorReturningResponseReturnsGeneratorReturningSameResponse(): void { $handler = new FiberHandler(); @@ -74,7 +74,7 @@ public function testInvokeWithHandlerReturningGeneratorReturningResponseReturnsG $this->assertSame($response, $ret); } - public function testInvokeWithHandlerReturningGeneratorReturningResponseAfterYieldingResolvedPromiseReturnsGeneratorReturningSameResponse() + public function testInvokeWithHandlerReturningGeneratorReturningResponseAfterYieldingResolvedPromiseReturnsGeneratorReturningSameResponse(): void { $handler = new FiberHandler(); @@ -93,7 +93,7 @@ public function testInvokeWithHandlerReturningGeneratorReturningResponseAfterYie $this->assertSame($response, $ret); } - public function testInvokeWithHandlerReturningGeneratorReturningResponseAfterYieldingRejectedPromiseReturnsGeneratorReturningSameResponse() + public function testInvokeWithHandlerReturningGeneratorReturningResponseAfterYieldingRejectedPromiseReturnsGeneratorReturningSameResponse(): void { $handler = new FiberHandler(); @@ -116,7 +116,7 @@ public function testInvokeWithHandlerReturningGeneratorReturningResponseAfterYie $this->assertSame($response, $ret); } - public function testInvokeWithHandlerReturningResponseAfterAwaitingResolvedPromiseReturnsSameResponse() + public function testInvokeWithHandlerReturningResponseAfterAwaitingResolvedPromiseReturnsSameResponse(): void { $handler = new FiberHandler(); @@ -130,7 +130,7 @@ public function testInvokeWithHandlerReturningResponseAfterAwaitingResolvedPromi $this->assertSame($response, $ret); } - public function testInvokeWithHandlerReturningResponseAfterAwaitingPendingPromiseReturnsPromiseResolvingWithSameResponse() + public function testInvokeWithHandlerReturningResponseAfterAwaitingPendingPromiseReturnsPromiseResolvingWithSameResponse(): void { $handler = new FiberHandler(); diff --git a/tests/Io/HtmlHandlerTest.php b/tests/Io/HtmlHandlerTest.php index 55204c7..1a106d9 100644 --- a/tests/Io/HtmlHandlerTest.php +++ b/tests/Io/HtmlHandlerTest.php @@ -12,14 +12,15 @@ class HtmlHandlerTest extends TestCase * @param string $in * @param string $expected */ - public function testEscapeHtml(string $in, string $expected) + public function testEscapeHtml(string $in, string $expected): void { $html = new HtmlHandler(); $this->assertEquals($expected, $html->escape($in)); } - public function provideNames() + /** @return list> */ + public function provideNames(): array { return [ [ diff --git a/tests/Io/MiddlewareHandlerTest.php b/tests/Io/MiddlewareHandlerTest.php index 7fa75f3..7606d52 100644 --- a/tests/Io/MiddlewareHandlerTest.php +++ b/tests/Io/MiddlewareHandlerTest.php @@ -11,7 +11,7 @@ class MiddlewareHandlerTest extends TestCase { - public function testOneMiddleware() + public function testOneMiddleware(): void { $handler = new MiddlewareHandler([ function (ServerRequestInterface $request, callable $next) { @@ -39,10 +39,11 @@ function (ServerRequestInterface $request) { $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testOneMiddlewareClass() + public function testOneMiddlewareClass(): void { $middleware = new class{ - public function __invoke(ServerRequestInterface $request, callable $next) { + public function __invoke(ServerRequestInterface $request, callable $next): Response + { return $next($request); } }; @@ -71,7 +72,7 @@ function (ServerRequestInterface $request) { $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testTwoMiddleware() + public function testTwoMiddleware(): void { $handler = new MiddlewareHandler([ function (ServerRequestInterface $request, callable $next) { @@ -102,7 +103,7 @@ function (ServerRequestInterface $request) { $this->assertEquals("OK\n", (string) $response->getBody()); } - public function testThreeMiddleware() + public function testThreeMiddleware(): void { $handler = new MiddlewareHandler([ function (ServerRequestInterface $request, callable $next) { diff --git a/tests/Io/RedirectHandlerTest.php b/tests/Io/RedirectHandlerTest.php index 1f49146..13752fd 100644 --- a/tests/Io/RedirectHandlerTest.php +++ b/tests/Io/RedirectHandlerTest.php @@ -8,7 +8,7 @@ class RedirectHandlerTest extends TestCase { - public function testInvokeReturnsResponseWithRedirectToGivenLocation() + public function testInvokeReturnsResponseWithRedirectToGivenLocation(): void { $handler = new RedirectHandler('http://example.com/'); @@ -29,7 +29,7 @@ public function testInvokeReturnsResponseWithRedirectToGivenLocation() $this->assertStringContainsString("

Redirecting to http://example.com/...

\n", (string) $response->getBody()); } - public function testInvokeReturnsResponseWithPermanentRedirectToGivenLocationAndCode() + public function testInvokeReturnsResponseWithPermanentRedirectToGivenLocationAndCode(): void { $handler = new RedirectHandler('/', 301); @@ -46,7 +46,7 @@ public function testInvokeReturnsResponseWithPermanentRedirectToGivenLocationAnd $this->assertStringContainsString("

Redirecting to /...

\n", (string) $response->getBody()); } - public function testInvokeReturnsResponseWithCustomRedirectStatusCodeAndGivenLocation() + public function testInvokeReturnsResponseWithCustomRedirectStatusCodeAndGivenLocation(): void { $handler = new RedirectHandler('/', 399); @@ -63,7 +63,7 @@ public function testInvokeReturnsResponseWithCustomRedirectStatusCodeAndGivenLoc $this->assertStringContainsString("

Redirecting to /...

\n", (string) $response->getBody()); } - public function testInvokeReturnsResponseWithRedirectToGivenLocationWithSpecialCharsEncoded() + public function testInvokeReturnsResponseWithRedirectToGivenLocationWithSpecialCharsEncoded(): void { $handler = new RedirectHandler('/hello%20w%7Frld?a=1&b=2'); @@ -80,19 +80,19 @@ public function testInvokeReturnsResponseWithRedirectToGivenLocationWithSpecialC $this->assertStringContainsString("

Redirecting to /hello%20w%7Frld?a=1&b=2...

\n", (string) $response->getBody()); } - public function testConstructWithSuccessCodeThrows() + public function testConstructWithSuccessCodeThrows(): void { $this->expectException(\InvalidArgumentException::class); new RedirectHandler('/', 200); } - public function testConstructWithNotModifiedCodeThrows() + public function testConstructWithNotModifiedCodeThrows(): void { $this->expectException(\InvalidArgumentException::class); new RedirectHandler('/', 304); } - public function testConstructWithBadRequestCodeThrows() + public function testConstructWithBadRequestCodeThrows(): void { $this->expectException(\InvalidArgumentException::class); new RedirectHandler('/', 400); diff --git a/tests/Io/RouteHandlerTest.php b/tests/Io/RouteHandlerTest.php index b38a81b..c12e195 100644 --- a/tests/Io/RouteHandlerTest.php +++ b/tests/Io/RouteHandlerTest.php @@ -14,7 +14,7 @@ class RouteHandlerTest extends TestCase { - public function testMapRouteWithControllerAddsRouteOnRouter() + public function testMapRouteWithControllerAddsRouteOnRouter(): void { $controller = function () { }; @@ -30,7 +30,7 @@ public function testMapRouteWithControllerAddsRouteOnRouter() $handler->map(['GET'], '/', $controller); } - public function testMapRouteWithMiddlewareAndControllerAddsRouteWithMiddlewareHandlerOnRouter() + public function testMapRouteWithMiddlewareAndControllerAddsRouteWithMiddlewareHandlerOnRouter(): void { $middleware = function () { }; $controller = function () { }; @@ -47,7 +47,7 @@ public function testMapRouteWithMiddlewareAndControllerAddsRouteWithMiddlewareHa $handler->map(['GET'], '/', $middleware, $controller); } - public function testMapRouteWithClassNameAddsRouteOnRouterWithControllerCallableFromContainer() + public function testMapRouteWithClassNameAddsRouteOnRouterWithControllerCallableFromContainer(): void { $controller = function () { }; @@ -66,7 +66,7 @@ public function testMapRouteWithClassNameAddsRouteOnRouterWithControllerCallable $handler->map(['GET'], '/', \stdClass::class); } - public function testMapRouteWithContainerAndControllerAddsRouteOnRouterWithControllerOnly() + public function testMapRouteWithContainerAndControllerAddsRouteOnRouterWithControllerOnly(): void { $controller = function () { }; @@ -82,7 +82,7 @@ public function testMapRouteWithContainerAndControllerAddsRouteOnRouterWithContr $handler->map(['GET'], '/', new Container(), $controller); } - public function testMapRouteWithContainerAndControllerClassNameAddsRouteOnRouterWithControllerCallableFromContainer() + public function testMapRouteWithContainerAndControllerClassNameAddsRouteOnRouterWithControllerCallableFromContainer(): void { $controller = function () { }; @@ -101,7 +101,7 @@ public function testMapRouteWithContainerAndControllerClassNameAddsRouteOnRouter $handler->map(['GET'], '/', $container, \stdClass::class); } - public function testHandleRequestWithProxyRequestReturnsResponseWithMessageThatProxyRequestsAreNotAllowed() + public function testHandleRequestWithProxyRequestReturnsResponseWithMessageThatProxyRequestsAreNotAllowed(): void { $request = new ServerRequest('GET', 'http://example.com/'); $request = $request->withRequestTarget('http://example.com/'); @@ -119,7 +119,7 @@ public function testHandleRequestWithProxyRequestReturnsResponseWithMessageThatP $this->assertStringContainsString("

Please check your settings and retry.

\n", (string) $response->getBody()); } - public function testHandleRequestWithConnectProxyRequestReturnsResponseWithMessageThatProxyRequestsAreNotAllowed() + public function testHandleRequestWithConnectProxyRequestReturnsResponseWithMessageThatProxyRequestsAreNotAllowed(): void { $request = new ServerRequest('CONNECT', 'example.com:80'); $request = $request->withRequestTarget('example.com:80'); @@ -137,7 +137,7 @@ public function testHandleRequestWithConnectProxyRequestReturnsResponseWithMessa $this->assertStringContainsString("

Please check your settings and retry.

\n", (string) $response->getBody()); } - public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandler() + public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandler(): void { $request = new ServerRequest('GET', 'http://example.com/'); $response = new Response(200, [], ''); @@ -150,14 +150,15 @@ public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandle $this->assertSame($response, $ret); } - public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerClass() + public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerClass(): void { $request = new ServerRequest('GET', 'http://example.com/'); $response = new Response(200, [], ''); $controller = new class { + /** @var ?Response */ public static $response; - public function __invoke() { + public function __invoke(): ?Response { return self::$response; } }; @@ -171,14 +172,16 @@ public function __invoke() { $this->assertSame($response, $ret); } - public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerClassName() + public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerClassName(): void { $request = new ServerRequest('GET', 'http://example.com/'); $response = new Response(200, [], ''); $controller = new class { + /** @var ?Response */ public static $response; - public function __invoke() { + public function __invoke(): ?Response + { return self::$response; } }; @@ -192,17 +195,20 @@ public function __invoke() { $this->assertSame($response, $ret); } - public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerClassNameWithOptionalConstructor() + public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerClassNameWithOptionalConstructor(): void { $request = new ServerRequest('GET', 'http://example.com/'); $response = new Response(200, [], ''); $controller = new class { + /** @var ?Response */ public static $response; - public function __construct(int $value = null) { + public function __construct(int $value = null) + { assert($value === null); } - public function __invoke() { + public function __invoke(): ?Response + { return self::$response; } }; @@ -216,17 +222,20 @@ public function __invoke() { $this->assertSame($response, $ret); } - public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerClassNameWithNullableConstructor() + public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerClassNameWithNullableConstructor(): void { $request = new ServerRequest('GET', 'http://example.com/'); $response = new Response(200, [], ''); $controller = new class(null) { + /** @var ?Response */ public static $response; - public function __construct(?int $value) { + public function __construct(?int $value) + { assert($value === null); } - public function __invoke() { + public function __invoke(): ?Response + { return self::$response; } }; @@ -240,16 +249,19 @@ public function __invoke() { $this->assertSame($response, $ret); } - public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerClassNameWithRequiredResponseInConstructor() + public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerClassNameWithRequiredResponseInConstructor(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class(new Response(500)) { + /** @var ?Response */ public static $response; - public function __construct(Response $response) { + public function __construct(Response $response) + { self::$response = $response; } - public function __invoke() { + public function __invoke(): ?Response + { return self::$response; } }; @@ -262,13 +274,14 @@ public function __invoke() { $this->assertSame($controller::$response, $ret); } - public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerWithClassNameMiddleware() + public function testHandleRequestWithGetRequestReturnsResponseFromMatchingHandlerWithClassNameMiddleware(): void { $request = new ServerRequest('GET', 'http://example.com/'); $response = new Response(200, [], ''); $middleware = new class { - public function __invoke(ServerRequestInterface $request, callable $next) { + public function __invoke(ServerRequestInterface $request, callable $next): Response + { return $next($request); } }; @@ -281,13 +294,15 @@ public function __invoke(ServerRequestInterface $request, callable $next) { $this->assertSame($response, $ret); } - public function testHandleRequestTwiceWithGetRequestCallsSameHandlerInstanceFromMatchingHandlerClassName() + public function testHandleRequestTwiceWithGetRequestCallsSameHandlerInstanceFromMatchingHandlerClassName(): void { $request = new ServerRequest('GET', 'http://example.com/'); $controller = new class { + /** @var int */ private $called = 0; - public function __invoke() { + public function __invoke(): int + { return ++$this->called; } }; @@ -302,7 +317,7 @@ public function __invoke() { $this->assertEquals(2, $ret); } - public function testHandleRequestWithGetRequestWithHttpUrlInPathReturnsResponseFromMatchingHandler() + public function testHandleRequestWithGetRequestWithHttpUrlInPathReturnsResponseFromMatchingHandler(): void { $request = new ServerRequest('GET', 'http://example.com/http://localhost/'); $response = new Response(200, [], ''); @@ -315,7 +330,7 @@ public function testHandleRequestWithGetRequestWithHttpUrlInPathReturnsResponseF $this->assertSame($response, $ret); } - public function testHandleRequestWithOptionsAsteriskRequestReturnsResponseFromMatchingEmptyHandler() + public function testHandleRequestWithOptionsAsteriskRequestReturnsResponseFromMatchingEmptyHandler(): void { $request = new ServerRequest('OPTIONS', 'http://example.com'); $request = $request->withRequestTarget('*'); @@ -329,7 +344,7 @@ public function testHandleRequestWithOptionsAsteriskRequestReturnsResponseFromMa $this->assertSame($response, $ret); } - public function testHandleRequestWithContainerOnlyThrows() + public function testHandleRequestWithContainerOnlyThrows(): void { $request = new ServerRequest('GET', 'http://example.com/'); diff --git a/tests/Io/SapiHandlerTest.php b/tests/Io/SapiHandlerTest.php index 17758a9..ef9a6e4 100644 --- a/tests/Io/SapiHandlerTest.php +++ b/tests/Io/SapiHandlerTest.php @@ -9,7 +9,7 @@ class SapiHandlerTest extends TestCase { - public function testRequestFromGlobalsWithNoServerVariablesDefaultsToGetRequestToLocalhost() + public function testRequestFromGlobalsWithNoServerVariablesDefaultsToGetRequestToLocalhost(): void { $sapi = new SapiHandler(); $request = $sapi->requestFromGlobals(); @@ -23,7 +23,7 @@ public function testRequestFromGlobalsWithNoServerVariablesDefaultsToGetRequestT /** * @backupGlobals enabled */ - public function testRequestFromGlobalsWithHeadRequest() + public function testRequestFromGlobalsWithHeadRequest(): void { $_SERVER['REQUEST_METHOD'] = 'HEAD'; $_SERVER['REQUEST_URI'] = '//'; @@ -42,7 +42,7 @@ public function testRequestFromGlobalsWithHeadRequest() /** * @backupGlobals enabled */ - public function testRequestFromGlobalsWithGetRequestOverCustomPort() + public function testRequestFromGlobalsWithGetRequestOverCustomPort(): void { $_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['REQUEST_URI'] = '/path'; @@ -61,7 +61,7 @@ public function testRequestFromGlobalsWithGetRequestOverCustomPort() /** * @backupGlobals enabled */ - public function testRequestFromGlobalsWithGetRequestOverHttps() + public function testRequestFromGlobalsWithGetRequestOverHttps(): void { $_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['REQUEST_URI'] = '/'; @@ -81,7 +81,7 @@ public function testRequestFromGlobalsWithGetRequestOverHttps() /** * @backupGlobals enabled */ - public function testRequestFromGlobalsWithOptionsAsterisk() + public function testRequestFromGlobalsWithOptionsAsterisk(): void { $_SERVER['REQUEST_METHOD'] = 'OPTIONS'; $_SERVER['REQUEST_URI'] = '*'; @@ -101,7 +101,7 @@ public function testRequestFromGlobalsWithOptionsAsterisk() /** * @backupGlobals enabled */ - public function testRequestFromGlobalsWithGetProxy() + public function testRequestFromGlobalsWithGetProxy(): void { $_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['REQUEST_URI'] = 'http://example.com/'; @@ -121,7 +121,7 @@ public function testRequestFromGlobalsWithGetProxy() /** * @backupGlobals enabled */ - public function testRequestFromGlobalsWithConnectProxy() + public function testRequestFromGlobalsWithConnectProxy(): void { $_SERVER['REQUEST_METHOD'] = 'CONNECT'; $_SERVER['REQUEST_URI'] = 'example.com:443'; @@ -138,7 +138,7 @@ public function testRequestFromGlobalsWithConnectProxy() $this->assertEquals('example.com:443', $request->getHeaderLine('Host')); } - public function testSendResponseSendsEmptyResponseWithNoHeadersAndEmptyBodyAndAssignsNoContentTypeAndEmptyContentLength() + public function testSendResponseSendsEmptyResponseWithNoHeadersAndEmptyBodyAndAssignsNoContentTypeAndEmptyContentLength(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -153,7 +153,7 @@ public function testSendResponseSendsEmptyResponseWithNoHeadersAndEmptyBodyAndAs $this->assertEquals(['Content-Type:', 'Content-Length: 0'], xdebug_get_headers()); } - public function testSendResponseSendsJsonResponseWithGivenHeadersAndBodyAndAssignsMatchingContentLength() + public function testSendResponseSendsJsonResponseWithGivenHeadersAndBodyAndAssignsMatchingContentLength(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -173,7 +173,7 @@ public function testSendResponseSendsJsonResponseWithGivenHeadersAndBodyAndAssig /** * @backupGlobals enabled */ - public function testSendResponseSendsJsonResponseWithGivenHeadersAndMatchingContentLengthButEmptyBodyForHeadRequest() + public function testSendResponseSendsJsonResponseWithGivenHeadersAndMatchingContentLengthButEmptyBodyForHeadRequest(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -191,7 +191,7 @@ public function testSendResponseSendsJsonResponseWithGivenHeadersAndMatchingCont $this->assertEquals(array_merge($previous, ['Content-Type: application/json', 'Content-Length: 2']), xdebug_get_headers()); } - public function testSendResponseSendsEmptyBodyWithGivenHeadersAndAssignsNoContentLengthForNoContentResponse() + public function testSendResponseSendsEmptyBodyWithGivenHeadersAndAssignsNoContentLengthForNoContentResponse(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -208,7 +208,7 @@ public function testSendResponseSendsEmptyBodyWithGivenHeadersAndAssignsNoConten $this->assertEquals(array_merge($previous, ['Content-Type: application/json']), xdebug_get_headers()); } - public function testSendResponseSendsEmptyBodyWithGivenHeadersButWithoutExplicitContentLengthForNoContentResponse() + public function testSendResponseSendsEmptyBodyWithGivenHeadersButWithoutExplicitContentLengthForNoContentResponse(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -225,7 +225,7 @@ public function testSendResponseSendsEmptyBodyWithGivenHeadersButWithoutExplicit $this->assertEquals(array_merge($previous, ['Content-Type: application/json']), xdebug_get_headers()); } - public function testSendResponseSendsEmptyBodyWithGivenHeadersAndAssignsContentLengthForNotModifiedResponse() + public function testSendResponseSendsEmptyBodyWithGivenHeadersAndAssignsContentLengthForNotModifiedResponse(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -242,7 +242,7 @@ public function testSendResponseSendsEmptyBodyWithGivenHeadersAndAssignsContentL $this->assertEquals(array_merge($previous, ['Content-Type: application/json', 'Content-Length: 4']), xdebug_get_headers()); } - public function testSendResponseSendsEmptyBodyWithGivenHeadersAndExplicitContentLengthForNotModifiedResponse() + public function testSendResponseSendsEmptyBodyWithGivenHeadersAndExplicitContentLengthForNotModifiedResponse(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -259,7 +259,7 @@ public function testSendResponseSendsEmptyBodyWithGivenHeadersAndExplicitContent $this->assertEquals(array_merge($previous, ['Content-Type: application/json', 'Content-Length: 2']), xdebug_get_headers()); } - public function testSendResponseSendsStreamingResponseWithNoHeadersAndBodyFromStreamData() + public function testSendResponseSendsStreamingResponseWithNoHeadersAndBodyFromStreamData(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -282,7 +282,7 @@ public function testSendResponseSendsStreamingResponseWithNoHeadersAndBodyFromSt /** * @backupGlobals enabled */ - public function testSendResponseClosesStreamingResponseAndSendsResponseWithNoHeadersAndBodyForHeadRequest() + public function testSendResponseClosesStreamingResponseAndSendsResponseWithNoHeadersAndBodyForHeadRequest(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -302,7 +302,7 @@ public function testSendResponseClosesStreamingResponseAndSendsResponseWithNoHea $this->assertFalse($body->isReadable()); } - public function testSendResponseClosesStreamingResponseAndSendsResponseWithNoHeadersAndBodyForNotModifiedResponse() + public function testSendResponseClosesStreamingResponseAndSendsResponseWithNoHeadersAndBodyForNotModifiedResponse(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -321,7 +321,7 @@ public function testSendResponseClosesStreamingResponseAndSendsResponseWithNoHea $this->assertFalse($body->isReadable()); } - public function testSendResponseClosesStreamingResponseAndSendsResponseWithNoHeadersAndBodyForNoContentResponse() + public function testSendResponseClosesStreamingResponseAndSendsResponseWithNoHeadersAndBodyForNoContentResponse(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -340,7 +340,7 @@ public function testSendResponseClosesStreamingResponseAndSendsResponseWithNoHea $this->assertFalse($body->isReadable()); } - public function testSendResponseSendsStreamingResponseWithNoHeadersAndBodyFromStreamDataAndNoBufferHeaderForNginxServer() + public function testSendResponseSendsStreamingResponseWithNoHeadersAndBodyFromStreamDataAndNoBufferHeaderForNginxServer(): void { if (headers_sent() || !function_exists('xdebug_get_headers')) { $this->markTestSkipped('Test requires running phpunit with --stderr and Xdebug enabled'); @@ -361,7 +361,7 @@ public function testSendResponseSendsStreamingResponseWithNoHeadersAndBodyFromSt $body->end('test'); } - public function testLogPrintsMessageWithCurrentDateAndTime() + public function testLogPrintsMessageWithCurrentDateAndTime(): void { // 2021-01-29 12:22:01.717 Hello\n $this->expectOutputRegex("/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} Hello" . PHP_EOL . "$/");