Skip to content

Commit 1fc247d

Browse files
committed
Add PHPStan to test environment
1 parent 6a883a9 commit 1fc247d

File tree

10 files changed

+56
-6
lines changed

10 files changed

+56
-6
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/.github/workflows/ export-ignore
33
/.gitignore export-ignore
44
/examples/ export-ignore
5+
/phpstan.neon.dist export-ignore
56
/phpunit.xml.dist export-ignore
67
/phpunit.xml.legacy export-ignore
78
/tests/ export-ignore

.github/workflows/ci.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,25 @@ jobs:
3737
<?php
3838
$metrics = simplexml_load_file('clover.xml')->project->metrics;
3939
exit((int) $metrics['statements'] === (int) $metrics['coveredstatements'] ? 0 : 1);
40+
41+
PHPStan:
42+
name: PHPStan (PHP ${{ matrix.php }})
43+
runs-on: ubuntu-22.04
44+
strategy:
45+
matrix:
46+
php:
47+
- 8.2
48+
- 8.1
49+
- 8.0
50+
- 7.4
51+
- 7.3
52+
- 7.2
53+
- 7.1
54+
steps:
55+
- uses: actions/checkout@v3
56+
- uses: shivammathur/setup-php@v2
57+
with:
58+
php-version: ${{ matrix.php }}
59+
coverage: none
60+
- run: composer install
61+
- run: vendor/bin/phpstan

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
},
2222
"require-dev": {
2323
"clue/block-react": "^1.5",
24+
"phpstan/phpstan": "1.8.11 || 1.4.10",
2425
"phpunit/phpunit": "^9.5 || ^7.5"
2526
},
2627
"autoload": {

phpstan.neon.dist

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
parameters:
2+
level: 3
3+
4+
paths:
5+
- examples/
6+
- src/
7+
- tests/
8+
9+
reportUnmatchedIgnoredErrors: false
10+
ignoreErrors:
11+
# ignore generic usage like `PromiseInterface<T>` until fixed upstream
12+
- '/^PHPDoc tag @return contains generic type React\\Promise\\PromiseInterface<.+> but interface React\\Promise\\PromiseInterface is not generic\.$/'
13+
# ignore undefined methods due to magic `__call()` method
14+
- '/^Call to an undefined method Clue\\React\\Redis\\RedisClient::.+\(\)\.$/'
15+
- '/^Call to an undefined method Clue\\React\\Redis\\Io\\StreamingClient::.+\(\)\.$/'

src/Io/Factory.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public function createClient(string $uri): PromiseInterface
9191
$connecting->then(function (ConnectionInterface $connection) {
9292
$connection->close();
9393
});
94+
assert(\method_exists($connecting, 'cancel'));
9495
$connecting->cancel();
9596
});
9697

src/RedisClient.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class RedisClient extends EventEmitter
4646
/** @var float */
4747
private $idlePeriod = 0.001;
4848

49-
/** @var ?TimerInterface */
49+
/** @var ?\React\EventLoop\TimerInterface */
5050
private $idleTimer = null;
5151

5252
/** @var int */
@@ -221,6 +221,7 @@ public function close(): void
221221
$redis->close();
222222
});
223223
if ($this->promise !== null) {
224+
assert(\method_exists($this->promise, 'cancel'));
224225
$this->promise->cancel();
225226
$this->promise = null;
226227
}

tests/FunctionalTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public function testInvalidCommand()
106106
if (method_exists($this, 'expectException')) {
107107
$this->expectException('Exception');
108108
} else {
109+
assert(method_exists($this, 'setExpectedException'));
109110
$this->setExpectedException('Exception');
110111
}
111112
await($promise, $this->loop);

tests/Io/FactoryStreamingClientTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,8 @@ public function testCancelWillRejectPromise()
444444
$this->connector->expects($this->once())->method('connect')->with('127.0.0.1:2')->willReturn($promise);
445445

446446
$promise = $this->factory->createClient('redis://127.0.0.1:2');
447+
448+
assert(method_exists($promise, 'cancel'));
447449
$promise->cancel();
448450

449451
$promise->then(null, $this->expectCallableOnceWith($this->isInstanceOf(\RuntimeException::class)));
@@ -526,6 +528,8 @@ public function testCancelWillRejectWithUriInMessageAndCancelConnectorWhenConnec
526528
$this->connector->expects($this->once())->method('connect')->willReturn($deferred->promise());
527529

528530
$promise = $this->factory->createClient($uri);
531+
532+
assert(method_exists($promise, 'cancel'));
529533
$promise->cancel();
530534

531535
$promise->then(null, $this->expectCallableOnceWith(
@@ -550,6 +554,8 @@ public function testCancelWillCloseConnectionWhenConnectionWaitsForSelect()
550554
$this->connector->expects($this->once())->method('connect')->willReturn(resolve($stream));
551555

552556
$promise = $this->factory->createClient('redis://127.0.0.1:2/123');
557+
558+
assert(method_exists($promise, 'cancel'));
553559
$promise->cancel();
554560

555561
$promise->then(null, $this->expectCallableOnceWith(

tests/RedisClientTest.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ public function testCloseAfterPingRejectsWillEmitClose()
347347
$client = $this->createMock(StreamingClient::class);
348348
$client->expects($this->once())->method('__call')->willReturn($deferred->promise());
349349
$client->expects($this->once())->method('close')->willReturnCallback(function () use ($client) {
350+
assert($client instanceof StreamingClient);
350351
$client->emit('close');
351352
});
352353

@@ -356,11 +357,10 @@ public function testCloseAfterPingRejectsWillEmitClose()
356357
$this->loop->expects($this->once())->method('addTimer')->willReturn($timer);
357358
$this->loop->expects($this->once())->method('cancelTimer')->with($timer);
358359

359-
$ref = $this->redis;
360-
$ref->ping()->then(null, function () use ($ref, $client) {
361-
$ref->close();
360+
$this->redis->ping()->then(null, function () {
361+
$this->redis->close();
362362
});
363-
$ref->on('close', $this->expectCallableOnce());
363+
$this->redis->on('close', $this->expectCallableOnce());
364364
$deferred->reject(new \RuntimeException());
365365
}
366366

@@ -423,6 +423,7 @@ public function testEmitsNoErrorEventWhenUnderlyingClientEmitsError()
423423
$deferred->resolve($client);
424424

425425
$this->redis->on('error', $this->expectCallableNever());
426+
assert($client instanceof StreamingClient);
426427
$client->emit('error', [$error]);
427428
}
428429

@@ -438,6 +439,7 @@ public function testEmitsNoCloseEventWhenUnderlyingClientEmitsClose()
438439
$deferred->resolve($client);
439440

440441
$this->redis->on('close', $this->expectCallableNever());
442+
assert($client instanceof StreamingClient);
441443
$client->emit('close');
442444
}
443445

tests/TestCase.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ protected function expectCallableNever(): callable
3636
protected function createCallableMock(): MockObject
3737
{
3838
if (method_exists(MockBuilder::class, 'addMethods')) {
39-
// PHPUnit 9+
39+
// @phpstan-ignore-next-line requires PHPUnit 9+
4040
return $this->getMockBuilder(\stdClass::class)->addMethods(['__invoke'])->getMock();
4141
} else {
4242
// legacy PHPUnit < 9

0 commit comments

Comments
 (0)