Skip to content

Commit

Permalink
Merge pull request #235 from clue-labs/template-types
Browse files Browse the repository at this point in the history
Use Promise v3 template types
  • Loading branch information
SimonFrings committed Jul 31, 2023
2 parents 3b10f71 + 0057af2 commit 277e9a5
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 37 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
1 change: 1 addition & 0 deletions src/AccessLogHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public function __invoke(ServerRequestInterface $request, callable $next)
$response = $next($request);

if ($response instanceof PromiseInterface) {
/** @var PromiseInterface<ResponseInterface> $response */
return $response->then(function (ResponseInterface $response) use ($request, $now) {
$this->logWhenClosed($request, $response, $now);
return $response;
Expand Down
3 changes: 3 additions & 0 deletions src/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ private function handleRequest(ServerRequestInterface $request)
return $response;
}

/**
* @return PromiseInterface<ResponseInterface>
*/
private function coroutine(\Generator $generator): PromiseInterface
{
$next = null;
Expand Down
5 changes: 3 additions & 2 deletions src/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
});
Expand Down
5 changes: 3 additions & 2 deletions src/Io/FiberHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<ResponseInterface> $deferred */
if ($deferred !== null) {
assert($response instanceof ResponseInterface);
$deferred->resolve($response);
}

Expand All @@ -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<ResponseInterface>|\Generator */
return $fiber->getReturn();
}

Expand Down
1 change: 1 addition & 0 deletions src/Io/SapiHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public function run(callable $handler): void
if ($response instanceof ResponseInterface) {
$this->sendResponse($response);
} elseif ($response instanceof PromiseInterface) {
/** @var PromiseInterface<ResponseInterface> $response */
$response->then(function (ResponseInterface $response): void {
$this->sendResponse($response);
});
Expand Down
11 changes: 6 additions & 5 deletions tests/AppMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ public function testMiddlewareCallsNextReturnsDeferredResponseModifiedInMiddlewa
$middleware = function (ServerRequestInterface $request, callable $next) {
$promise = $next($request);
assert($promise instanceof PromiseInterface);
/** @var PromiseInterface<ResponseInterface> $promise */

return $promise->then(function (ResponseInterface $response) {
return $response->withHeader('Content-Type', 'text/html');
Expand All @@ -303,7 +304,7 @@ public function testMiddlewareCallsNextReturnsDeferredResponseModifiedInMiddlewa
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -350,7 +351,7 @@ public function testMiddlewareCallsNextReturnsCoroutineResponseModifiedInMiddlew
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -680,7 +681,7 @@ public function testGlobalMiddlewareReturnsPromiseWhichResolvesWithResponseWitho
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -720,7 +721,7 @@ public function testGlobalMiddlewareCallsNextReturnsPromiseWhichResolvesWithModi
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -764,7 +765,7 @@ public function testGlobalMiddlewareCallsNextReturnsPromiseWhichResolvesWithModi
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down
30 changes: 15 additions & 15 deletions tests/AppTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -1082,7 +1082,7 @@ public function testHandleRequestWithMatchingRouteReturnsPendingPromiseWhenHandl
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$resolved = false;
Expand Down Expand Up @@ -1150,7 +1150,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -1193,7 +1193,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -1223,7 +1223,7 @@ public function testHandleRequestWithMatchingRouteReturnsPendingPromiseWhenHandl
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<never> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$resolved = false;
Expand Down Expand Up @@ -1285,7 +1285,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseResolvingWithRes
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -1384,7 +1384,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -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');
Expand All @@ -1422,7 +1422,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -1457,7 +1457,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -1523,7 +1523,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -1593,7 +1593,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -1632,7 +1632,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -1889,7 +1889,7 @@ public function testHandleRequestWithMatchingRouteReturnsPromiseWhichFulfillsWit
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -1924,7 +1924,7 @@ public function testHandleRequestWithMatchingRouteReturnsInternalServerErrorResp
$ref->setAccessible(true);
$promise = $ref->invoke($app, $request);

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down
14 changes: 7 additions & 7 deletions tests/ErrorHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function testInvokeWithHandlerReturningPromiseResolvingWithResponseReturn

$promise = $handler($request, function () use ($response) { return resolve($response); });

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$ret = null;
Expand Down Expand Up @@ -106,7 +106,7 @@ public function testInvokeWithHandlerReturningGeneratorYieldingRejectedPromiseIn
$this->assertInstanceOf(\Generator::class, $generator);
$promise = $generator->current();

/** @var PromiseInterface $promise */
/** @var PromiseInterface<never> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);
$e = null;
$promise->then(null, function ($reason) use (&$e) {
Expand Down Expand Up @@ -146,7 +146,7 @@ public function testInvokeWithHandlerReturningPromiseRejectingWithExceptionRetur
return reject(new \RuntimeException());
});

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down Expand Up @@ -216,7 +216,7 @@ public function testInvokeWithHandlerReturningGeneratorYieldingPromiseRejectingW
$this->assertInstanceOf(\Generator::class, $generator);
$promise = $generator->current();

/** @var PromiseInterface $promise */
/** @var PromiseInterface<never> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);
$e = null;
$promise->then(null, function ($reason) use (&$e) {
Expand Down Expand Up @@ -258,7 +258,7 @@ public function testInvokeWithHandlerReturningPromiseResolvingWithNullReturnsPro
return resolve(null);
});

/** @var PromiseInterface $promise */
/** @var PromiseInterface<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand All @@ -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<ResponseInterface> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$response = null;
Expand Down
4 changes: 2 additions & 2 deletions tests/Io/FiberHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function testInvokeWithHandlerReturningPromiseResolvingWithResponseReturn

$promise = $handler($request, function () use ($response) { return resolve($response); });

/** @var PromiseInterface $promise */
/** @var PromiseInterface<Response> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$ret = null;
Expand Down Expand Up @@ -157,7 +157,7 @@ public function testInvokeWithHandlerReturningResponseAfterAwaitingPendingPromis
return await($deferred->promise());
});

/** @var PromiseInterface $promise */
/** @var PromiseInterface<Response> $promise */
$this->assertInstanceOf(PromiseInterface::class, $promise);

$ret = null;
Expand Down
10 changes: 8 additions & 2 deletions tests/Io/ReactiveHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<ConnectionInterface> $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);
});
Expand Down Expand Up @@ -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<ConnectionInterface> $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");

Expand Down
2 changes: 1 addition & 1 deletion tests/install-as-dep/composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"require": {
"clue/framework-x": "*@dev",
"react/promise-timer": "^1.9"
"react/promise-timer": "^1.10"
},
"repositories": [
{
Expand Down

0 comments on commit 277e9a5

Please sign in to comment.