From b190ddae27d1fe95bf4be39ba6fdc2935ec9b8a9 Mon Sep 17 00:00:00 2001 From: Valentin CLARAS Date: Wed, 1 Sep 2021 12:12:52 +0200 Subject: [PATCH] feat: update phpstan and fix reported errors --- composer.json | 2 +- examples/tests/ExamplesTest.php | 2 +- phpstan.neon | 24 +++++++++++++++++ src/Adapter/Amp/Internal/PromiseWrapper.php | 4 +-- src/Adapter/Guzzle/HttpClient.php | 4 ++- .../ReactPhp/Internal/PromiseWrapper.php | 4 +-- src/Adapter/Symfony/HttpClient.php | 2 +- .../Tornado/Internal/PendingPromise.php | 10 ++++--- .../Tornado/Internal/StreamEventLoop.php | 9 +++++++ src/Adapter/Tornado/Internal/Task.php | 2 ++ src/Adapter/Tornado/SynchronousEventLoop.php | 5 ++-- src/Deferred.php | 1 + src/EventLoop.php | 1 + tests/Adapter/Amp/EventLoopTest.php | 6 ++--- tests/Adapter/Guzzle/HttpClientTest.php | 4 +-- .../Tornado/SynchronousEventLoopTest.php | 14 +++++----- tests/EventLoopTest.php | 20 +++++++------- tests/EventLoopTest/AsyncTest.php | 26 ++++++++++--------- tests/EventLoopTest/PromiseAllTest.php | 12 +++++---- tests/EventLoopTest/PromiseForeachTest.php | 20 ++++++++------ tests/EventLoopTest/PromiseRaceTest.php | 10 ++++--- tests/EventLoopTest/StreamsTest.php | 8 +++--- tests/HttpClientTest.php | 19 ++++++++------ 23 files changed, 134 insertions(+), 75 deletions(-) create mode 100644 phpstan.neon diff --git a/composer.json b/composer.json index df0dc6a..b99aac2 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "ext-curl": "^7.1", "react/event-loop": "^1.0", "react/promise": "^2.7", - "phpstan/phpstan": "^0.10.5", + "phpstan/phpstan": "^0.12", "symfony/http-client": "^4.3", "psr/http-factory": "^1.0", "http-interop/http-factory-guzzle": "^1.0" diff --git a/examples/tests/ExamplesTest.php b/examples/tests/ExamplesTest.php index 41bede9..9a1ce7a 100644 --- a/examples/tests/ExamplesTest.php +++ b/examples/tests/ExamplesTest.php @@ -29,7 +29,7 @@ public function examplesProvider() /** * @dataProvider examplesProvider */ - public function testExampleShouldRun(string $exampleFile, string $eventloopName, string $exampleCode) + public function testExampleShouldRun(string $exampleFile, string $eventloopName, string $exampleCode): void { // Sanitize loop name to create a relevant temporary filename $eventLoopFileId = preg_replace('/[^a-z0-9]+/', '', strtolower($eventloopName)); diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..b643c07 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,24 @@ +parameters: + checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false + ignoreErrors: + - + message: '#Negated boolean expression is always true\.#' + path: src/Adapter/Amp/Internal/PromiseWrapper.php + count: 1 + - + message: '#Negated boolean expression is always true\.#' + path: src/Adapter/ReactPhp/Internal/PromiseWrapper.php + count: 1 + - + message: '#Anonymous function should return Generator but empty return statement found.#' + path: src/Adapter/Tornado/EventLoop.php + count: 1 + - + message: '#Unreachable statement - code above always terminates\.#' + path: src/Adapter/Tornado/EventLoop.php + count: 1 + - + message: '#Unreachable statement - code above always terminates\.#' + path: tests/EventLoopTest.php + count: 3 diff --git a/src/Adapter/Amp/Internal/PromiseWrapper.php b/src/Adapter/Amp/Internal/PromiseWrapper.php index 788c709..b5ab182 100644 --- a/src/Adapter/Amp/Internal/PromiseWrapper.php +++ b/src/Adapter/Amp/Internal/PromiseWrapper.php @@ -24,7 +24,7 @@ private function __construct() { } - public static function createUnhandled(\Amp\Promise $ampPromise, FailingPromiseCollection $failingPromiseCollection) + public static function createUnhandled(\Amp\Promise $ampPromise, FailingPromiseCollection $failingPromiseCollection): self { $promiseWrapper = new self(); $promiseWrapper->isHandled = false; @@ -40,7 +40,7 @@ function (?\Throwable $reason, $value) use ($promiseWrapper, $failingPromiseColl return $promiseWrapper; } - public static function createHandled(\Amp\Promise $ampPromise) + public static function createHandled(\Amp\Promise $ampPromise): self { $promiseWrapper = new self(); $promiseWrapper->isHandled = true; diff --git a/src/Adapter/Guzzle/HttpClient.php b/src/Adapter/Guzzle/HttpClient.php index da38f83..f9d469c 100644 --- a/src/Adapter/Guzzle/HttpClient.php +++ b/src/Adapter/Guzzle/HttpClient.php @@ -16,6 +16,7 @@ class HttpClient implements \M6Web\Tornado\HttpClient /** @var GuzzleClientWrapper */ private $clientWrapper; + /** @var int */ private $nbConcurrentRequests = 0; public function __construct(EventLoop $eventLoop, GuzzleClientWrapper $clientWrapper) @@ -67,7 +68,8 @@ private function http2fallback(RequestInterface $request): RequestInterface if ( 'https' !== $request->getUri()->getScheme() || !\defined('CURL_VERSION_HTTP2') - || !(CURL_VERSION_HTTP2 & curl_version()['features']) + || (($curlVersion = curl_version()) === false) + || !(CURL_VERSION_HTTP2 & $curlVersion['features']) ) { return $request->withProtocolVersion('1.1'); } diff --git a/src/Adapter/ReactPhp/Internal/PromiseWrapper.php b/src/Adapter/ReactPhp/Internal/PromiseWrapper.php index 170819a..0e2f9d9 100644 --- a/src/Adapter/ReactPhp/Internal/PromiseWrapper.php +++ b/src/Adapter/ReactPhp/Internal/PromiseWrapper.php @@ -24,7 +24,7 @@ private function __construct() { } - public static function createUnhandled(\React\Promise\PromiseInterface $reactPromise, FailingPromiseCollection $failingPromiseCollection) + public static function createUnhandled(\React\Promise\PromiseInterface $reactPromise, FailingPromiseCollection $failingPromiseCollection): self { $promiseWrapper = new self(); $promiseWrapper->isHandled = false; @@ -41,7 +41,7 @@ function (?\Throwable $reason) use ($promiseWrapper, $failingPromiseCollection) return $promiseWrapper; } - public static function createHandled(\React\Promise\PromiseInterface $reactPromise) + public static function createHandled(\React\Promise\PromiseInterface $reactPromise): self { $promiseWrapper = new self(); $promiseWrapper->isHandled = true; diff --git a/src/Adapter/Symfony/HttpClient.php b/src/Adapter/Symfony/HttpClient.php index 127a665..8ca44e7 100644 --- a/src/Adapter/Symfony/HttpClient.php +++ b/src/Adapter/Symfony/HttpClient.php @@ -79,7 +79,7 @@ private function symfonyEventLoop(): \Generator $currentJobs = $this->jobs; $this->jobs = []; /** - * @var SfResponseInterface + * @var SfResponseInterface $response * @var ChunkInterface $chunk */ foreach ($this->symfonyClient->stream($currentJobs, 0) as $response => $chunk) { diff --git a/src/Adapter/Tornado/Internal/PendingPromise.php b/src/Adapter/Tornado/Internal/PendingPromise.php index 7354332..914b10e 100644 --- a/src/Adapter/Tornado/Internal/PendingPromise.php +++ b/src/Adapter/Tornado/Internal/PendingPromise.php @@ -12,9 +12,13 @@ */ class PendingPromise implements Promise, Deferred { + /** @var mixed */ private $value; + /** @var \Throwable */ private $throwable; + /** @var callable[][] */ private $callbacks = []; + /** @var bool */ private $isSettled = false; /** @var ?FailingPromiseCollection */ private $failingPromiseCollection; @@ -26,7 +30,7 @@ private function __construct() { } - public static function createUnhandled(FailingPromiseCollection $failingPromiseCollection) + public static function createUnhandled(FailingPromiseCollection $failingPromiseCollection): self { $promiseWrapper = new self(); $promiseWrapper->failingPromiseCollection = $failingPromiseCollection; @@ -34,7 +38,7 @@ public static function createUnhandled(FailingPromiseCollection $failingPromiseC return $promiseWrapper; } - public static function createHandled() + public static function createHandled(): self { $promiseWrapper = new self(); $promiseWrapper->failingPromiseCollection = null; @@ -103,7 +107,7 @@ private function triggerCallbacks(): self return $this; } - private function settle() + private function settle(): void { if ($this->isSettled) { throw new \LogicException('Cannot resolve/reject a promise already settled.'); diff --git a/src/Adapter/Tornado/Internal/StreamEventLoop.php b/src/Adapter/Tornado/Internal/StreamEventLoop.php index edf848b..6b87409 100644 --- a/src/Adapter/Tornado/Internal/StreamEventLoop.php +++ b/src/Adapter/Tornado/Internal/StreamEventLoop.php @@ -16,11 +16,17 @@ class StreamEventLoop /** @var PendingPromise[] */ private $pendingPromises = []; + /** + * @param resource $stream + */ public function readable(EventLoop $eventLoop, $stream): PendingPromise { return $this->recordStream($eventLoop, $stream, $this->readStreams); } + /** + * @param resource $stream + */ public function writable(EventLoop $eventLoop, $stream): PendingPromise { return $this->recordStream($eventLoop, $stream, $this->writeStreams); @@ -58,6 +64,9 @@ private function internalLoop(EventLoop $eventLoop): \Generator } } + /** + * @param resource $stream + */ private function recordStream(EventLoop $eventLoop, $stream, array &$streamsList): PendingPromise { $streamId = (int) $stream; diff --git a/src/Adapter/Tornado/Internal/Task.php b/src/Adapter/Tornado/Internal/Task.php index 6656ffd..5753687 100644 --- a/src/Adapter/Tornado/Internal/Task.php +++ b/src/Adapter/Tornado/Internal/Task.php @@ -8,7 +8,9 @@ */ class Task { + /** @var \Generator */ private $generator; + /** @var PendingPromise */ private $promise; public function __construct(\Generator $generator, PendingPromise $pendingPromise) diff --git a/src/Adapter/Tornado/SynchronousEventLoop.php b/src/Adapter/Tornado/SynchronousEventLoop.php index 21cd4f8..307e79f 100644 --- a/src/Adapter/Tornado/SynchronousEventLoop.php +++ b/src/Adapter/Tornado/SynchronousEventLoop.php @@ -156,11 +156,12 @@ public function deferred(): Deferred $deferred = new class() implements Deferred { /** @var SynchronousEventLoop */ public $eventLoop; - private $promise; + /** @var ?Promise */ + private $promise = null; public function getPromise(): Promise { - if (!$this->promise) { + if ($this->promise === null) { throw new \Error('Synchronous Deferred must be resolved/rejected before to retrieve its promise.'); } diff --git a/src/Deferred.php b/src/Deferred.php index b29ca9d..95a2398 100644 --- a/src/Deferred.php +++ b/src/Deferred.php @@ -14,6 +14,7 @@ public function getPromise(): Promise; /** * Resolves associated promise. + * @param mixed $value */ public function resolve($value): void; diff --git a/src/EventLoop.php b/src/EventLoop.php index d93d742..15fee71 100644 --- a/src/EventLoop.php +++ b/src/EventLoop.php @@ -40,6 +40,7 @@ public function promiseRace(Promise ...$promises): Promise; /** * Creates a promise already resolved with $value. + * @param mixed $value */ public function promiseFulfilled($value): Promise; diff --git a/tests/Adapter/Amp/EventLoopTest.php b/tests/Adapter/Amp/EventLoopTest.php index cbce018..9e29bc5 100644 --- a/tests/Adapter/Amp/EventLoopTest.php +++ b/tests/Adapter/Amp/EventLoopTest.php @@ -12,13 +12,13 @@ protected function createEventLoop(): EventLoop return new Amp\EventLoop(); } - public function testStreamShouldReadFromWritable($expectedSequence = '') + public function testStreamShouldReadFromWritable(string $expectedSequence = ''): void { // Because Amp resolve promises in a slightly different order. parent::testStreamShouldReadFromWritable('W0R0W12345R12R34W6R56R'); } - public function testStreamShouldNotBeWritableIfClosed() + public function testStreamShouldNotBeWritableIfClosed(): void { assert_options(ASSERT_EXCEPTION, 1); $this->expectException(\Throwable::class); @@ -26,7 +26,7 @@ public function testStreamShouldNotBeWritableIfClosed() parent::testStreamShouldNotBeWritableIfClosed(); } - public function testStreamShouldNotBeReadableIfClosed() + public function testStreamShouldNotBeReadableIfClosed(): void { assert_options(ASSERT_EXCEPTION, 1); $this->expectException(\Throwable::class); diff --git a/tests/Adapter/Guzzle/HttpClientTest.php b/tests/Adapter/Guzzle/HttpClientTest.php index 4bec8a4..1ac4831 100644 --- a/tests/Adapter/Guzzle/HttpClientTest.php +++ b/tests/Adapter/Guzzle/HttpClientTest.php @@ -20,7 +20,7 @@ protected function createHttpClient(EventLoop $eventLoop, array $responsesOrExce /** * @dataProvider eventLoopProvider */ - public function testWrapperIsTicked(EventLoop $eventLoop) + public function testWrapperIsTicked(EventLoop $eventLoop): void { $httpClient = new \M6Web\Tornado\Adapter\Guzzle\HttpClient( $eventLoop, @@ -35,7 +35,7 @@ public function testWrapperIsTicked(EventLoop $eventLoop) /** * @dataProvider eventLoopProvider */ - public function testRequestExceptionsAreSuccessful(EventLoop $eventLoop) + public function testRequestExceptionsAreSuccessful(EventLoop $eventLoop): void { $request = new Request('GET', 'http://www.example.com'); $expectedResponse = new Response(500, [], 'An error occurred'); diff --git a/tests/Adapter/Tornado/SynchronousEventLoopTest.php b/tests/Adapter/Tornado/SynchronousEventLoopTest.php index c7b05b4..ea3fd3d 100644 --- a/tests/Adapter/Tornado/SynchronousEventLoopTest.php +++ b/tests/Adapter/Tornado/SynchronousEventLoopTest.php @@ -12,31 +12,31 @@ protected function createEventLoop(): EventLoop return new Tornado\SynchronousEventLoop(); } - public function testIdle($expectedSequence = '') + public function testIdle(string $expectedSequence = ''): void { //By definition, this is not an asynchronous EventLoop parent::testIdle('AAABBC'); } - public function testPromiseRaceShouldResolvePromisesArray(int $expectedValue = 2) + public function testPromiseRaceShouldResolvePromisesArray(int $expectedValue = 2): void { // In the synchronous case, there is no race, first promise always win parent::testPromiseRaceShouldResolvePromisesArray(1); } - public function testPromiseRaceShouldRejectIfFirstSettledPromiseRejects(int $expectedValue = 2) + public function testPromiseRaceShouldRejectIfFirstSettledPromiseRejects(int $expectedValue = 2): void { // In the synchronous case, there is no race, first promise always win parent::testPromiseRaceShouldRejectIfFirstSettledPromiseRejects(1); } - public function testStreamShouldReadFromWritable($expectedSequence = '') + public function testStreamShouldReadFromWritable(string $expectedSequence = ''): void { // Never wait… parent::testStreamShouldReadFromWritable('W0W12345W6R01R23R45R6R'); } - public function testDelay() + public function testDelay(): void { $expectedDelay = 42; /*ms*/ $eventLoop = $this->createEventLoop(); @@ -54,14 +54,14 @@ public function testDelay() $this->assertLessThanOrEqual($expectedDelay + 10, $duration); } - public function testWaitFunctionShouldReturnAsSoonAsPromiseIsResolved() + public function testWaitFunctionShouldReturnAsSoonAsPromiseIsResolved(): void { // By definition, synchronous event loop can only wait a promise if already resolved. // So this use case is not relevant for this particular implementation. $this->assertTrue(true); } - public function testWaitFunctionShouldThrowIfPromiseCannotBeResolved() + public function testWaitFunctionShouldThrowIfPromiseCannotBeResolved(): void { $eventLoop = $this->createEventLoop(); $deferred = $eventLoop->deferred(); diff --git a/tests/EventLoopTest.php b/tests/EventLoopTest.php index b352878..3313121 100644 --- a/tests/EventLoopTest.php +++ b/tests/EventLoopTest.php @@ -17,7 +17,7 @@ abstract class EventLoopTest extends TestCase abstract protected function createEventLoop(): EventLoop; - public function testFulfilledPromise() + public function testFulfilledPromise(): void { $expectedValue = 1664; @@ -30,7 +30,7 @@ public function testFulfilledPromise() ); } - public function testRejectedPromise() + public function testRejectedPromise(): void { $expectedException = new class() extends \Exception { }; @@ -42,7 +42,7 @@ public function testRejectedPromise() $eventLoop->wait($promise); } - public function testIdle($expectedSequence = 'ABCABA') + public function testIdle(string $expectedSequence = 'ABCABA'): void { $eventLoop = $this->createEventLoop(); $outputBuffer = ''; @@ -63,7 +63,7 @@ public function testIdle($expectedSequence = 'ABCABA') $this->assertSame($expectedSequence, $outputBuffer); } - public function testDelay() + public function testDelay(): void { $expectedDelay = 42; /*ms*/ $eventLoop = $this->createEventLoop(); @@ -80,7 +80,7 @@ public function testDelay() $this->assertLessThanOrEqual($expectedDelay + 10, $duration); } - public function testDeferredResolved() + public function testDeferredResolved(): void { $expectedValue = 'Caramba!'; $eventLoop = $this->createEventLoop(); @@ -108,7 +108,7 @@ public function testDeferredResolved() ); } - public function testDeferredRejected() + public function testDeferredRejected(): void { $expectedException = new class() extends \Exception { }; @@ -133,7 +133,7 @@ public function testDeferredRejected() $eventLoop->wait($promise); } - public function testWaitFunctionShouldReturnAsSoonAsPromiseIsResolved() + public function testWaitFunctionShouldReturnAsSoonAsPromiseIsResolved(): void { $eventLoop = $this->createEventLoop(); $count = 0; @@ -150,7 +150,7 @@ public function testWaitFunctionShouldReturnAsSoonAsPromiseIsResolved() $this->assertLessThanOrEqual(2, $count); } - public function testWaitFunctionShouldThrowIfPromiseCannotBeResolved() + public function testWaitFunctionShouldThrowIfPromiseCannotBeResolved(): void { $eventLoop = $this->createEventLoop(); $deferred = $eventLoop->deferred(); @@ -160,7 +160,7 @@ public function testWaitFunctionShouldThrowIfPromiseCannotBeResolved() $eventLoop->wait($deferred->getPromise()); } - public function testExceptionBeforeYieldAreCatchable() + public function testExceptionBeforeYieldAreCatchable(): void { $eventLoop = $this->createEventLoop(); @@ -172,6 +172,8 @@ public function testExceptionBeforeYieldAreCatchable() $createGenerator = function () use ($failingPromise): \Generator { try { yield $failingPromise; + + return 'not catched :('; } catch (\Exception $e) { return 'catched!'; } diff --git a/tests/EventLoopTest/AsyncTest.php b/tests/EventLoopTest/AsyncTest.php index e0798a1..9a29f7b 100644 --- a/tests/EventLoopTest/AsyncTest.php +++ b/tests/EventLoopTest/AsyncTest.php @@ -9,7 +9,7 @@ trait AsyncTest { abstract protected function createEventLoop(): EventLoop; - public function testDummyGenerator() + public function testDummyGenerator(): void { $expectedValue = 42; $generator = (function ($value): \Generator { @@ -26,7 +26,7 @@ public function testDummyGenerator() ); } - public function testDummyGeneratorThrowing() + public function testDummyGeneratorThrowing(): void { $expectedException = new class() extends \Exception { }; @@ -42,7 +42,7 @@ public function testDummyGeneratorThrowing() $eventLoop->wait($promise); } - public function testYieldingInvalidValueMayThrowAnError() + public function testYieldingInvalidValueMayThrowAnError(): void { $createGenerator = function (): \Generator { yield 'Something that is not a promise.'; @@ -56,7 +56,7 @@ public function testYieldingInvalidValueMayThrowAnError() $eventLoop->wait($promise); } - public function testYieldingGenerator() + public function testYieldingGenerator(): void { $createGenerator = function (EventLoop $eventLoop, $a, $b, $c): \Generator { $result = ''; @@ -73,11 +73,13 @@ public function testYieldingGenerator() $this->assertSame('ABC', $eventLoop->wait($promise)); } - public function testYieldingGeneratorWithRejectedPromise() + public function testYieldingGeneratorWithRejectedPromise(): void { $createGenerator = function (EventLoop $eventLoop, \Exception $exception): \Generator { try { yield $eventLoop->promiseRejected($exception); + + return 'not catched :('; } catch (\Throwable $exception) { return $exception; } @@ -94,7 +96,7 @@ public function testYieldingGeneratorWithRejectedPromise() ); } - public function testSubGenerators() + public function testSubGenerators(): void { $eventLoop = $this->createEventLoop(); $createGenerator = function (Promise ...$promises): \Generator { @@ -120,7 +122,7 @@ public function testSubGenerators() $this->assertSame([1, [2, 3], 4], $eventLoop->wait($promise)); } - public function testSubGeneratorThrowing() + public function testSubGeneratorThrowing(): void { $eventLoop = $this->createEventLoop(); $throwingGenerator = function (\Throwable $throwable) use ($eventLoop): \Generator { @@ -148,7 +150,7 @@ public function testSubGeneratorThrowing() $this->assertSame('Error Message', $eventLoop->wait($promise)); } - public function testYieldingForTheSameFulfilledPromise() + public function testYieldingForTheSameFulfilledPromise(): void { $eventLoop = $this->createEventLoop(); $commonPromise = $eventLoop->idle(); @@ -170,7 +172,7 @@ public function testYieldingForTheSameFulfilledPromise() ); } - public function testYieldingForTheSameRejectedPromise() + public function testYieldingForTheSameRejectedPromise(): void { $expectedMessage = 'Common Exception'; $eventLoop = $this->createEventLoop(); @@ -197,7 +199,7 @@ public function testYieldingForTheSameRejectedPromise() ); } - public function testEventLoopFirstTick() + public function testEventLoopFirstTick(): void { $eventLoop = $this->createEventLoop(); @@ -212,7 +214,7 @@ public function testEventLoopFirstTick() $this->assertSame(1, $count); } - public function testEventLoopShouldThrowInCaseOfUncaughtExceptionInBackgroundGenerator() + public function testEventLoopShouldThrowInCaseOfUncaughtExceptionInBackgroundGenerator(): void { $eventLoop = $this->createEventLoop(); @@ -236,7 +238,7 @@ public function testEventLoopShouldThrowInCaseOfUncaughtExceptionInBackgroundGen gc_collect_cycles(); } - public function testEventLoopShouldNotThrowInCaseOfExplicitlyRejectedPromise() + public function testEventLoopShouldNotThrowInCaseOfExplicitlyRejectedPromise(): void { $eventLoop = $this->createEventLoop(); diff --git a/tests/EventLoopTest/PromiseAllTest.php b/tests/EventLoopTest/PromiseAllTest.php index 38a9c52..3c0db4c 100644 --- a/tests/EventLoopTest/PromiseAllTest.php +++ b/tests/EventLoopTest/PromiseAllTest.php @@ -8,7 +8,7 @@ trait PromiseAllTest { abstract protected function createEventLoop(): EventLoop; - public function testPromiseAllShouldResolvePromisesArray() + public function testPromiseAllShouldResolvePromisesArray(): void { $expectedValues = [1, 'ok', new \stdClass(), ['array']]; @@ -22,7 +22,7 @@ public function testPromiseAllShouldResolvePromisesArray() ); } - public function testPromiseAllShouldRejectIfAnyInputPromiseRejects() + public function testPromiseAllShouldRejectIfAnyInputPromiseRejects(): void { $expectedException = new class() extends \Exception { }; @@ -39,7 +39,7 @@ public function testPromiseAllShouldRejectIfAnyInputPromiseRejects() $eventLoop->wait($promise); } - public function testPromiseAllShouldResolveEmptyInput() + public function testPromiseAllShouldResolveEmptyInput(): void { $eventLoop = $this->createEventLoop(); $promise = $eventLoop->promiseAll(); @@ -50,7 +50,7 @@ public function testPromiseAllShouldResolveEmptyInput() ); } - public function testPromiseAllShouldPreserveTheOrderOfArrayWhenResolvingAsyncPromises() + public function testPromiseAllShouldPreserveTheOrderOfArrayWhenResolvingAsyncPromises(): void { $eventLoop = $this->createEventLoop(); @@ -75,7 +75,7 @@ public function testPromiseAllShouldPreserveTheOrderOfArrayWhenResolvingAsyncPro ); } - public function testPromiseAllCatchableException() + public function testPromiseAllCatchableException(): void { $eventLoop = $this->createEventLoop(); @@ -87,6 +87,8 @@ public function testPromiseAllCatchableException() $createGenerator = function () use ($eventLoop, $throwingGenerator): \Generator { try { yield $eventLoop->promiseAll($eventLoop->async($throwingGenerator)); + + return 'not catched :('; } catch (\Exception $e) { return 'catched!'; } diff --git a/tests/EventLoopTest/PromiseForeachTest.php b/tests/EventLoopTest/PromiseForeachTest.php index 8f916be..5d46b46 100644 --- a/tests/EventLoopTest/PromiseForeachTest.php +++ b/tests/EventLoopTest/PromiseForeachTest.php @@ -10,8 +10,10 @@ abstract protected function createEventLoop(): EventLoop; /** * Helper function to test that promiseForeach works for array AND iterator inputs. + * @param mixed[] $input + * @param mixed[] $expected */ - private function assertSameForeach(EventLoop $eventLoop, array $input, callable $callback, array $expected) + private function assertSameForeach(EventLoop $eventLoop, array $input, callable $callback, array $expected): void { $this->assertSame( $expected, @@ -24,7 +26,7 @@ private function assertSameForeach(EventLoop $eventLoop, array $input, callable ); } - public function testPromiseForeachAcceptsEmptyTraversable() + public function testPromiseForeachAcceptsEmptyTraversable(): void { $eventLoop = $this->createEventLoop(); $callback = function () { @@ -34,7 +36,7 @@ public function testPromiseForeachAcceptsEmptyTraversable() $this->assertSameForeach($eventLoop, [], $callback, []); } - public function testPromiseForeachShouldThrowIfCallbackDoesNotReturnGenerator() + public function testPromiseForeachShouldThrowIfCallbackDoesNotReturnGenerator(): void { $eventLoop = $this->createEventLoop(); $callback = function () { @@ -47,7 +49,7 @@ public function testPromiseForeachShouldThrowIfCallbackDoesNotReturnGenerator() ); } - public function testPromiseForeachWithCallbackUsingValueOnly() + public function testPromiseForeachWithCallbackUsingValueOnly(): void { $eventLoop = $this->createEventLoop(); $callback = function ($value) use ($eventLoop) { @@ -60,7 +62,7 @@ public function testPromiseForeachWithCallbackUsingValueOnly() $this->assertSameForeach($eventLoop, $input, $callback, $input); } - public function testPromiseForeachWithCallbackUsingValueAndKey() + public function testPromiseForeachWithCallbackUsingValueAndKey(): void { $eventLoop = $this->createEventLoop(); $callback = function ($value, $key) use ($eventLoop) { @@ -75,7 +77,7 @@ public function testPromiseForeachWithCallbackUsingValueAndKey() )); } - public function testPromiseForeachPropagateThrownExceptions() + public function testPromiseForeachPropagateThrownExceptions(): void { $eventLoop = $this->createEventLoop(); $exception = new \LogicException(); @@ -90,15 +92,17 @@ public function testPromiseForeachPropagateThrownExceptions() ); } - public function testPromiseForeachCatchableException() + public function testPromiseForeachCatchableException(): void { $eventLoop = $this->createEventLoop(); $createGenerator = function () use ($eventLoop): \Generator { try { - yield $eventLoop->promiseForeach([1], function ($value) use ($eventLoop) { + yield $eventLoop->promiseForeach([1], function ($value) use ($eventLoop): \Generator { yield $eventLoop->idle(); throw new \Exception('This is a failure'); }); + + return 'Not catched :('; } catch (\Exception $e) { return 'catched'; } diff --git a/tests/EventLoopTest/PromiseRaceTest.php b/tests/EventLoopTest/PromiseRaceTest.php index 643cfec..be4bcea 100644 --- a/tests/EventLoopTest/PromiseRaceTest.php +++ b/tests/EventLoopTest/PromiseRaceTest.php @@ -8,7 +8,7 @@ trait PromiseRaceTest { abstract protected function createEventLoop(): EventLoop; - public function testPromiseRaceShouldResolveEmptyInput() + public function testPromiseRaceShouldResolveEmptyInput(): void { $eventLoop = $this->createEventLoop(); @@ -20,7 +20,7 @@ public function testPromiseRaceShouldResolveEmptyInput() ); } - public function testPromiseRaceShouldResolvePromisesArray(int $expectedValue = 2) + public function testPromiseRaceShouldResolvePromisesArray(int $expectedValue = 2): void { $eventLoop = $this->createEventLoop(); $d1 = $eventLoop->deferred(); @@ -54,7 +54,7 @@ public function testPromiseRaceShouldResolvePromisesArray(int $expectedValue = 2 ); } - public function testPromiseRaceShouldRejectIfFirstSettledPromiseRejects(int $expectedValue = 2) + public function testPromiseRaceShouldRejectIfFirstSettledPromiseRejects(int $expectedValue = 2): void { $eventLoop = $this->createEventLoop(); $d1 = $eventLoop->deferred(); @@ -86,7 +86,7 @@ public function testPromiseRaceShouldRejectIfFirstSettledPromiseRejects(int $exp $eventLoop->wait($promise); } - public function testPromiseRaceCatchableException() + public function testPromiseRaceCatchableException(): void { $eventLoop = $this->createEventLoop(); @@ -101,6 +101,8 @@ public function testPromiseRaceCatchableException() $eventLoop->async($throwingGenerator), $eventLoop->delay(1000) ); + + return 'Not catched :('; } catch (\Exception $e) { return 'catched!'; } diff --git a/tests/EventLoopTest/StreamsTest.php b/tests/EventLoopTest/StreamsTest.php index b7711a9..5c0e1ab 100644 --- a/tests/EventLoopTest/StreamsTest.php +++ b/tests/EventLoopTest/StreamsTest.php @@ -31,7 +31,7 @@ private function createStreamPair() return $sockets; } - public function testStreamShouldReadFromWritable($expectedSequence = 'W0R0W12345R12W6R34R56R') + public function testStreamShouldReadFromWritable(string $expectedSequence = 'W0R0W12345R12W6R34R56R'): void { $tokens = ['0', '12345', '6']; [$streamIn, $streamOut] = $this->createStreamPair(); @@ -70,7 +70,7 @@ public function testStreamShouldReadFromWritable($expectedSequence = 'W0R0W12345 $this->assertSame($expectedSequence, $eventLoop->wait($readPromise)); } - public function testStreamShouldBeWritableIfOpened() + public function testStreamShouldBeWritableIfOpened(): void { $eventLoop = $this->createEventLoop(); [$streamIn, $streamOut] = $this->createStreamPair(); @@ -81,7 +81,7 @@ public function testStreamShouldBeWritableIfOpened() $this->assertSame($streamIn, $stream); } - public function testStreamShouldNotBeWritableIfClosed() + public function testStreamShouldNotBeWritableIfClosed(): void { $eventLoop = $this->createEventLoop(); [$streamIn, $streamOut] = $this->createStreamPair(); @@ -106,7 +106,7 @@ public function testStreamShouldNotBeWritableIfClosed() $this->assertSame('Aborted', $result); } - public function testStreamShouldNotBeReadableIfClosed() + public function testStreamShouldNotBeReadableIfClosed(): void { $eventLoop = $this->createEventLoop(); [$streamIn, $streamOut] = $this->createStreamPair(); diff --git a/tests/HttpClientTest.php b/tests/HttpClientTest.php index 226dff0..e3d89f6 100644 --- a/tests/HttpClientTest.php +++ b/tests/HttpClientTest.php @@ -11,11 +11,14 @@ abstract class HttpClientTest extends TestCase { /** - * @param array $responsesOrExceptions Psr7\Response to return, or \Exception to throw + * @param Response[]|\Exception[] $responsesOrExceptions Psr7\Response to return, or \Exception to throw */ abstract protected function createHttpClient(EventLoop $eventLoop, array $responsesOrExceptions): HttpClient; - public function eventLoopProvider() + /** + * @return \Generator + */ + public function eventLoopProvider(): \Generator { yield 'Tornado (synchronous)' => [new \M6Web\Tornado\Adapter\Tornado\SynchronousEventLoop()]; yield 'Tornado' => [new \M6Web\Tornado\Adapter\Tornado\EventLoop()]; @@ -26,7 +29,7 @@ public function eventLoopProvider() /** * @dataProvider eventLoopProvider */ - public function testGetValidUrl(EventLoop $eventLoop) + public function testGetValidUrl(EventLoop $eventLoop): void { $httpClient = $this->createHttpClient( $eventLoop, @@ -43,7 +46,7 @@ public function testGetValidUrl(EventLoop $eventLoop) /** * @dataProvider eventLoopProvider */ - public function testGetNotFoundUrl(EventLoop $eventLoop) + public function testGetNotFoundUrl(EventLoop $eventLoop): void { $httpClient = $this->createHttpClient( $eventLoop, @@ -60,7 +63,7 @@ public function testGetNotFoundUrl(EventLoop $eventLoop) /** * @dataProvider eventLoopProvider */ - public function testGetServerErrorUrl(EventLoop $eventLoop) + public function testGetServerErrorUrl(EventLoop $eventLoop): void { $httpClient = $this->createHttpClient( $eventLoop, @@ -78,7 +81,7 @@ public function testGetServerErrorUrl(EventLoop $eventLoop) /** * @dataProvider eventLoopProvider */ - public function testInvalidUrl(EventLoop $eventLoop) + public function testInvalidUrl(EventLoop $eventLoop): void { $httpClient = $this->createHttpClient( $eventLoop, @@ -95,7 +98,7 @@ public function testInvalidUrl(EventLoop $eventLoop) /** * @dataProvider eventLoopProvider */ - public function testSynchronousRequests(EventLoop $eventLoop) + public function testSynchronousRequests(EventLoop $eventLoop): void { $httpClient = $this->createHttpClient( $eventLoop, @@ -119,7 +122,7 @@ public function testSynchronousRequests(EventLoop $eventLoop) /** * @dataProvider eventLoopProvider */ - public function testAsynchronousRequests(EventLoop $eventLoop) + public function testAsynchronousRequests(EventLoop $eventLoop): void { $httpClient = $this->createHttpClient( $eventLoop,