diff --git a/composer.json b/composer.json index 0bedc59..43275fe 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "phpstan/phpstan": "1.10.16 || 1.4.10", "phpunit/phpunit": "^9.6 || ^7.5", "psr/container": "^2 || ^1", - "react/promise-timer": "^1.9" + "react/promise-timer": "^1.10" }, "autoload": { "psr-4": { diff --git a/src/AccessLogHandler.php b/src/AccessLogHandler.php index 74052c0..d62016f 100644 --- a/src/AccessLogHandler.php +++ b/src/AccessLogHandler.php @@ -37,6 +37,7 @@ public function __invoke(ServerRequestInterface $request, callable $next) $response = $next($request); if ($response instanceof PromiseInterface) { + /** @var PromiseInterface $response */ return $response->then(function (ResponseInterface $response) use ($request, $now) { $this->logWhenClosed($request, $response, $now); return $response; diff --git a/src/App.php b/src/App.php index 9fb72c7..c49aa80 100644 --- a/src/App.php +++ b/src/App.php @@ -271,6 +271,9 @@ private function handleRequest(ServerRequestInterface $request) return $response; } + /** + * @return PromiseInterface + */ private function coroutine(\Generator $generator): PromiseInterface { $next = null; diff --git a/src/ErrorHandler.php b/src/ErrorHandler.php index 1035d3f..e26d184 100644 --- a/src/ErrorHandler.php +++ b/src/ErrorHandler.php @@ -49,11 +49,12 @@ public function __invoke(ServerRequestInterface $request, callable $next) } }, function ($e) { // Promise rejected, always a `\Throwable` as of Promise v3 - assert($e instanceof \Throwable || !\method_exists(PromiseInterface::class, 'catch')); + assert($e instanceof \Throwable || !\method_exists(PromiseInterface::class, 'catch')); // @phpstan-ignore-line if ($e instanceof \Throwable) { return $this->errorInvalidException($e); - } else { + } else { // @phpstan-ignore-line + // @phpstan-ignore-next-line return $this->errorInvalidResponse(\React\Promise\reject($e)); // @codeCoverageIgnore } }); diff --git a/src/Io/FiberHandler.php b/src/Io/FiberHandler.php index 1a36740..07dc713 100644 --- a/src/Io/FiberHandler.php +++ b/src/Io/FiberHandler.php @@ -44,8 +44,9 @@ public function __invoke(ServerRequestInterface $request, callable $next) // if the next request handler returns immediately, the fiber can terminate immediately without using a Deferred // if the next request handler suspends the fiber, we only reach this point after resuming the fiber, so the code below will have assigned a Deferred - /** @var ?Deferred $deferred */ + /** @var ?Deferred $deferred */ if ($deferred !== null) { + assert($response instanceof ResponseInterface); $deferred->resolve($response); } @@ -56,7 +57,7 @@ public function __invoke(ServerRequestInterface $request, callable $next) $fiber->start(); if ($fiber->isTerminated()) { /** @throws void because fiber is known to have terminated successfully */ - /** @var ResponseInterface|PromiseInterface|\Generator */ + /** @var ResponseInterface|PromiseInterface|\Generator */ return $fiber->getReturn(); } diff --git a/src/Io/SapiHandler.php b/src/Io/SapiHandler.php index 918a62f..d3faf27 100644 --- a/src/Io/SapiHandler.php +++ b/src/Io/SapiHandler.php @@ -34,6 +34,7 @@ public function run(callable $handler): void if ($response instanceof ResponseInterface) { $this->sendResponse($response); } elseif ($response instanceof PromiseInterface) { + /** @var PromiseInterface $response */ $response->then(function (ResponseInterface $response): void { $this->sendResponse($response); }); diff --git a/tests/AppMiddlewareTest.php b/tests/AppMiddlewareTest.php index d0ec78d..5fcc067 100644 --- a/tests/AppMiddlewareTest.php +++ b/tests/AppMiddlewareTest.php @@ -280,6 +280,7 @@ public function testMiddlewareCallsNextReturnsDeferredResponseModifiedInMiddlewa $middleware = function (ServerRequestInterface $request, callable $next) { $promise = $next($request); assert($promise instanceof PromiseInterface); + /** @var PromiseInterface $promise */ return $promise->then(function (ResponseInterface $response) { return $response->withHeader('Content-Type', 'text/html'); @@ -303,7 +304,7 @@ public function testMiddlewareCallsNextReturnsDeferredResponseModifiedInMiddlewa $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -350,7 +351,7 @@ public function testMiddlewareCallsNextReturnsCoroutineResponseModifiedInMiddlew $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -680,7 +681,7 @@ public function testGlobalMiddlewareReturnsPromiseWhichResolvesWithResponseWitho $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -720,7 +721,7 @@ public function testGlobalMiddlewareCallsNextReturnsPromiseWhichResolvesWithModi $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -764,7 +765,7 @@ public function testGlobalMiddlewareCallsNextReturnsPromiseWhichResolvesWithModi $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; diff --git a/tests/AppTest.php b/tests/AppTest.php index b5e1411..43679f5 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -1052,7 +1052,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -1082,7 +1082,7 @@ public function testHandleRequestWithMatchingRouteReturnsPendingPromiseWhenHandl $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $resolved = false; @@ -1150,7 +1150,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -1193,7 +1193,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -1223,7 +1223,7 @@ public function testHandleRequestWithMatchingRouteReturnsPendingPromiseWhenHandl $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $resolved = false; @@ -1285,7 +1285,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseResolvingWithRes $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -1384,7 +1384,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -1412,7 +1412,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $app = $this->createAppWithoutLogger(); $app->get('/users', function () { - return reject(null); + return reject(null); // @phpstan-ignore-line }); $request = new ServerRequest('GET', 'http://localhost/users'); @@ -1422,7 +1422,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -1457,7 +1457,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -1523,7 +1523,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -1593,7 +1593,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -1632,7 +1632,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -1889,7 +1889,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -1924,7 +1924,7 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp $ref->setAccessible(true); $promise = $ref->invoke($app, $request); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; diff --git a/tests/ErrorHandlerTest.php b/tests/ErrorHandlerTest.php index 905c1e8..96fb02a 100644 --- a/tests/ErrorHandlerTest.php +++ b/tests/ErrorHandlerTest.php @@ -34,7 +34,7 @@ public function testInvokeWithHandlerReturningPromiseResolvingWithResponseReturn $promise = $handler($request, function () use ($response) { return resolve($response); }); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $ret = null; @@ -106,7 +106,7 @@ public function testInvokeWithHandlerReturningGeneratorYieldingRejectedPromiseIn $this->assertInstanceOf(\Generator::class, $generator); $promise = $generator->current(); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $e = null; $promise->then(null, function ($reason) use (&$e) { @@ -146,7 +146,7 @@ public function testInvokeWithHandlerReturningPromiseRejectingWithExceptionRetur return reject(new \RuntimeException()); }); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -216,7 +216,7 @@ public function testInvokeWithHandlerReturningGeneratorYieldingPromiseRejectingW $this->assertInstanceOf(\Generator::class, $generator); $promise = $generator->current(); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $e = null; $promise->then(null, function ($reason) use (&$e) { @@ -258,7 +258,7 @@ public function testInvokeWithHandlerReturningPromiseResolvingWithNullReturnsPro return resolve(null); }); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; @@ -282,10 +282,10 @@ public function testInvokeWithHandlerReturningPromiseRejectingWithNullReturnsPro $request = new ServerRequest('GET', 'http://example.com/'); $promise = $handler($request, function () { - return reject(null); + return reject(null); // @phpstan-ignore-line }); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $response = null; diff --git a/tests/Io/FiberHandlerTest.php b/tests/Io/FiberHandlerTest.php index a552a09..cb354f7 100644 --- a/tests/Io/FiberHandlerTest.php +++ b/tests/Io/FiberHandlerTest.php @@ -35,7 +35,7 @@ public function testInvokeWithHandlerReturningPromiseResolvingWithResponseReturn $promise = $handler($request, function () use ($response) { return resolve($response); }); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $ret = null; @@ -157,7 +157,7 @@ public function testInvokeWithHandlerReturningResponseAfterAwaitingPendingPromis return await($deferred->promise()); }); - /** @var PromiseInterface $promise */ + /** @var PromiseInterface $promise */ $this->assertInstanceOf(PromiseInterface::class, $promise); $ret = null; diff --git a/tests/Io/ReactiveHandlerTest.php b/tests/Io/ReactiveHandlerTest.php index d9b43fb..70e63a5 100644 --- a/tests/Io/ReactiveHandlerTest.php +++ b/tests/Io/ReactiveHandlerTest.php @@ -156,7 +156,10 @@ public function testRunWillListenForHttpRequestAndSendBackHttpResponseOverSocket Loop::futureTick(function () use ($addr): void { $connector = new Connector(); - $connector->connect($addr)->then(function (ConnectionInterface $connection): void { + $promise = $connector->connect($addr); + + /** @var \React\Promise\PromiseInterface $promise */ + $promise->then(function (ConnectionInterface $connection): void { $connection->on('data', function (string $data): void { $this->assertEquals("HTTP/1.0 200 OK\r\nContent-Length: 3\r\n\r\nOK\n", $data); }); @@ -203,7 +206,10 @@ public function testRunWillReportHttpErrorForInvalidClientRequest(): void Loop::futureTick(function () use ($addr, $logger): void { $connector = new Connector(); - $connector->connect($addr)->then(function (ConnectionInterface $connection) use ($logger): void { + $promise = $connector->connect($addr); + + /** @var \React\Promise\PromiseInterface $promise */ + $promise->then(function (ConnectionInterface $connection) use ($logger): void { $logger->expects($this->once())->method('log')->with($this->matchesRegularExpression('/^HTTP error: .*$/')); $connection->write("not a valid HTTP request\r\n\r\n"); diff --git a/tests/install-as-dep/composer.json b/tests/install-as-dep/composer.json index d003086..45c2243 100644 --- a/tests/install-as-dep/composer.json +++ b/tests/install-as-dep/composer.json @@ -1,7 +1,7 @@ { "require": { "clue/framework-x": "*@dev", - "react/promise-timer": "^1.9" + "react/promise-timer": "^1.10" }, "repositories": [ {