Skip to content

Commit 0fdd6a4

Browse files
committed
Add PHPStan to test environment
1 parent 7012b4c commit 0fdd6a4

12 files changed

+51
-4
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/.gitattributes export-ignore
22
/.github/ export-ignore
33
/.gitignore export-ignore
4+
/phpstan.neon.dist export-ignore
45
/phpunit.xml.dist export-ignore
56
/tests/ export-ignore

.github/workflows/ci.yml

+17
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,20 @@ jobs:
2222
ini-file: development
2323
- run: composer install
2424
- run: vendor/bin/phpunit --coverage-text
25+
26+
PHPStan:
27+
name: PHPStan (PHP ${{ matrix.php }})
28+
runs-on: ubuntu-22.04
29+
strategy:
30+
matrix:
31+
php:
32+
- 8.2
33+
- 8.1
34+
steps:
35+
- uses: actions/checkout@v3
36+
- uses: shivammathur/setup-php@v2
37+
with:
38+
php-version: ${{ matrix.php }}
39+
coverage: none
40+
- run: composer install
41+
- run: vendor/bin/phpstan

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,12 @@ To run the test suite, go to the project root and run:
659659
vendor/bin/phpunit
660660
```
661661

662+
On top of this, we use PHPStan on level 3 to ensure type safety across the project:
663+
664+
```bash
665+
vendor/bin/phpstan
666+
```
667+
662668
## License
663669

664670
MIT, see [LICENSE file](LICENSE).

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"react/promise": "^3.0 || ^2.8 || ^1.2.1"
3232
},
3333
"require-dev": {
34+
"phpstan/phpstan": "1.10.18",
3435
"phpunit/phpunit": "^9.5"
3536
},
3637
"autoload": {

phpstan.neon.dist

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
parameters:
2+
level: 3
3+
4+
paths:
5+
- src/
6+
- tests/
7+
8+
reportUnmatchedIgnoredErrors: false
9+
ignoreErrors:
10+
# ignore generic usage like `PromiseInterface<T>` until fixed upstream
11+
- '/^PHPDoc .* contains generic type React\\Promise\\PromiseInterface<.+> but interface React\\Promise\\PromiseInterface is not generic\.$/'

src/functions.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@
177177
* ```
178178
*
179179
* @param callable(mixed ...$args):mixed $function
180-
* @return callable(): PromiseInterface<mixed>
180+
* @return callable(mixed ...$args): PromiseInterface<mixed>
181181
* @since 4.0.0
182182
* @see coroutine()
183183
*/
@@ -587,7 +587,7 @@ function delay(float $seconds): void
587587
* });
588588
* ```
589589
*
590-
* @param callable(...$args):\Generator<mixed,PromiseInterface,mixed,mixed> $function
590+
* @param callable(mixed ...$args):\Generator<mixed,PromiseInterface,mixed,mixed> $function
591591
* @param mixed ...$args Optional list of additional arguments that will be passed to the given `$function` as is
592592
* @return PromiseInterface<mixed>
593593
* @since 3.0.0
@@ -730,9 +730,9 @@ function series(iterable $tasks): PromiseInterface
730730
assert($tasks instanceof \Iterator);
731731
}
732732

733-
/** @var callable():void $next */
734733
$taskCallback = function ($result) use (&$results, &$next) {
735734
$results[] = $result;
735+
assert($next instanceof \Closure);
736736
$next();
737737
};
738738

tests/AsyncTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ public function testCancelAsyncWillReturnRejectedPromiseWhenCancellingPendingPro
194194
}));
195195
})();
196196

197+
assert(method_exists($promise, 'cancel'));
197198
$promise->cancel();
198199

199200
$promise->then(null, $this->expectCallableOnceWith(new \RuntimeException('Operation cancelled')));
@@ -211,6 +212,7 @@ public function testCancelAsyncWillReturnFulfilledPromiseWhenCancellingPendingPr
211212
}
212213
})();
213214

215+
assert(method_exists($promise, 'cancel'));
214216
$promise->cancel();
215217

216218
$promise->then($this->expectCallableOnceWith(42));
@@ -230,6 +232,7 @@ public function testCancelAsycWillReturnPendigPromiseWhenCancellingFirstPromiseR
230232
}
231233
})();
232234

235+
assert(method_exists($promise, 'cancel'));
233236
$promise->cancel();
234237

235238
$promise->then($this->expectCallableNever(), $this->expectCallableNever());
@@ -259,6 +262,7 @@ public function testCancelAsyncWillCancelNestedAwait()
259262
return time();
260263
})();
261264

265+
assert(method_exists($promise, 'cancel'));
262266
$promise->cancel();
263267
await($promise);
264268
}

tests/AwaitTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ public function testNestedAwaits(callable $await)
361361
$resolve($await(new Promise(function ($resolve) use ($await) {
362362
$resolve($await(new Promise(function ($resolve) use ($await) {
363363
$resolve($await(new Promise(function ($resolve) use ($await) {
364-
$resolve($await(new Promise(function ($resolve) use ($await) {
364+
$resolve($await(new Promise(function ($resolve) {
365365
Loop::addTimer(0.01, function () use ($resolve) {
366366
$resolve(true);
367367
});

tests/CoroutineTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ public function testCancelCoroutineWillReturnRejectedPromiseWhenCancellingPendin
114114
});
115115
});
116116

117+
assert(method_exists($promise, 'cancel'));
117118
$promise->cancel();
118119

119120
$promise->then(null, $this->expectCallableOnceWith(new \RuntimeException('Operation cancelled')));
@@ -131,6 +132,7 @@ public function testCancelCoroutineWillReturnFulfilledPromiseWhenCancellingPendi
131132
}
132133
});
133134

135+
assert(method_exists($promise, 'cancel'));
134136
$promise->cancel();
135137

136138
$promise->then($this->expectCallableOnceWith(42));
@@ -150,6 +152,7 @@ public function testCancelCoroutineWillReturnPendigPromiseWhenCancellingFirstPro
150152
}
151153
});
152154

155+
assert(method_exists($promise, 'cancel'));
153156
$promise->cancel();
154157

155158
$promise->then($this->expectCallableNever(), $this->expectCallableNever());
@@ -209,6 +212,7 @@ public function testCoroutineShouldNotCreateAnyGarbageReferencesForPromiseReject
209212
});
210213
});
211214

215+
assert(method_exists($promise, 'cancel'));
212216
$promise->cancel();
213217
unset($promise);
214218

tests/ParallelTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ function () use (&$cancelled) {
193193
);
194194

195195
$promise = React\Async\parallel($tasks);
196+
assert(method_exists($promise, 'cancel'));
196197
$promise->cancel();
197198

198199
$this->assertSame(2, $cancelled);

tests/SeriesTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ function () use (&$cancelled) {
185185
);
186186

187187
$promise = React\Async\series($tasks);
188+
assert(method_exists($promise, 'cancel'));
188189
$promise->cancel();
189190

190191
$this->assertSame(1, $cancelled);

tests/WaterfallTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ function () use (&$cancelled) {
199199
);
200200

201201
$promise = React\Async\waterfall($tasks);
202+
assert(method_exists($promise, 'cancel'));
202203
$promise->cancel();
203204

204205
$this->assertSame(1, $cancelled);

0 commit comments

Comments
 (0)