Skip to content

Commit 7bfa495

Browse files
committed
Add PHPStan to test environment
1 parent cf107f5 commit 7bfa495

13 files changed

+60
-16
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/.github/ 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: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,26 @@ jobs:
4747
- run: composer install
4848
- run: vendor/bin/phpunit --coverage-text
4949
- run: time php examples/91-benchmark-throughput.php
50+
51+
PHPStan:
52+
name: PHPStan (PHP ${{ matrix.php }})
53+
runs-on: ubuntu-22.04
54+
strategy:
55+
matrix:
56+
php:
57+
- 8.3
58+
- 8.2
59+
- 8.1
60+
- 8.0
61+
- 7.4
62+
- 7.3
63+
- 7.2
64+
- 7.1
65+
steps:
66+
- uses: actions/checkout@v4
67+
- uses: shivammathur/setup-php@v2
68+
with:
69+
php-version: ${{ matrix.php }}
70+
coverage: none
71+
- run: composer install
72+
- run: vendor/bin/phpstan

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,12 @@ If you do not want to run these, they can simply be skipped like this:
12431243
vendor/bin/phpunit --exclude-group internet
12441244
```
12451245

1246+
On top of this, we use PHPStan on level 5 to ensure type safety across the project:
1247+
1248+
```bash
1249+
vendor/bin/phpstan
1250+
```
1251+
12461252
## License
12471253

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

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@
3131
"evenement/evenement": "^3.0 || ^2.0 || ^1.0"
3232
},
3333
"require-dev": {
34-
"phpunit/phpunit": "^9.6 || ^7.5",
35-
"clue/stream-filter": "~1.2"
34+
"clue/stream-filter": "^1.2",
35+
"phpstan/phpstan": "1.11.1 || 1.4.10",
36+
"phpunit/phpunit": "^9.6 || ^7.5"
3637
},
3738
"autoload": {
3839
"psr-4": {

phpstan.neon.dist

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
parameters:
2+
level: 5
3+
4+
paths:
5+
- examples/
6+
- src/
7+
- tests/

src/DuplexResourceStream.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,15 @@ public function pipe(WritableStreamInterface $dest, array $options = []): Writab
171171
public function handleData($stream)
172172
{
173173
$error = null;
174-
\set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) {
174+
\set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error): bool {
175175
$error = new \ErrorException(
176176
$errstr,
177177
0,
178178
$errno,
179179
$errfile,
180180
$errline
181181
);
182+
return true;
182183
});
183184

184185
$data = \stream_get_contents($stream, $this->bufferSize);

src/ReadableResourceStream.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,15 @@ public function close(): void
124124
public function handleData()
125125
{
126126
$error = null;
127-
\set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) {
127+
\set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error): bool {
128128
$error = new \ErrorException(
129129
$errstr,
130130
0,
131131
$errno,
132132
$errfile,
133133
$errline
134134
);
135+
return true;
135136
});
136137

137138
$data = \stream_get_contents($this->stream, $this->bufferSize);

src/ThroughStream.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ public function write($data): bool
144144
}
145145

146146
// continue writing if still writable and not paused (throttled), false otherwise
147+
// @phpstan-ignore-next-line (may be false when write() causes stream to close)
147148
return $this->writable && !$this->paused;
148149
}
149150

@@ -157,6 +158,7 @@ public function end($data = null): void
157158
$this->write($data);
158159

159160
// return if write() already caused the stream to close
161+
// @phpstan-ignore-next-line (may be false when write() causes stream to close)
160162
if (!$this->writable) {
161163
return;
162164
}

src/WritableResourceStream.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ public function close(): void
122122
public function handleWrite()
123123
{
124124
$error = null;
125-
\set_error_handler(function ($_, $errstr) use (&$error) {
125+
\set_error_handler(function ($_, $errstr) use (&$error): bool {
126126
$error = $errstr;
127+
return true;
127128
});
128129

129130
if ($this->writeChunkSize === -1) {

tests/DuplexResourceStreamTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function testConstructorThrowsExceptionOnInvalidStream()
5959
$loop = $this->createLoopMock();
6060

6161
$this->expectException(\InvalidArgumentException::class);
62-
new DuplexResourceStream('breakme', $loop);
62+
new DuplexResourceStream('breakme', $loop); // @phpstan-ignore-line
6363
}
6464

6565
/**

tests/ReadableResourceStreamTest.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public function testConstructorThrowsExceptionOnInvalidStream()
5858
$loop = $this->createLoopMock();
5959

6060
$this->expectException(\InvalidArgumentException::class);
61-
new ReadableResourceStream(false, $loop);
61+
new ReadableResourceStream(false, $loop); // @phpstan-ignore-line
6262
}
6363

6464
/**
@@ -148,7 +148,7 @@ public function testDataEvent()
148148
fwrite($stream, "foobar\n");
149149
rewind($stream);
150150

151-
$conn->handleData($stream);
151+
$conn->handleData();
152152
$this->assertSame("foobar\n", $capturedData);
153153
}
154154

@@ -171,7 +171,7 @@ public function testDataEventDoesEmitOneChunkMatchingBufferSize()
171171
fwrite($stream, str_repeat("a", 100000));
172172
rewind($stream);
173173

174-
$conn->handleData($stream);
174+
$conn->handleData();
175175

176176
$this->assertTrue($conn->isReadable());
177177
$this->assertEquals(4321, strlen($capturedData));
@@ -197,7 +197,7 @@ public function testDataEventDoesEmitOneChunkUntilStreamEndsWhenBufferSizeIsInfi
197197
fwrite($stream, str_repeat("a", 100000));
198198
rewind($stream);
199199

200-
$conn->handleData($stream);
200+
$conn->handleData();
201201

202202
$this->assertTrue($conn->isReadable());
203203
$this->assertEquals(100000, strlen($capturedData));
@@ -214,7 +214,7 @@ public function testEmptyStreamShouldNotEmitData()
214214
$conn = new ReadableResourceStream($stream, $loop);
215215
$conn->on('data', $this->expectCallableNever());
216216

217-
$conn->handleData($stream);
217+
$conn->handleData();
218218
}
219219

220220
public function testPipeShouldReturnDestination()
@@ -245,7 +245,7 @@ public function testClosingStreamInDataEventShouldNotTriggerError()
245245
fwrite($stream, "foobar\n");
246246
rewind($stream);
247247

248-
$conn->handleData($stream);
248+
$conn->handleData();
249249
}
250250

251251
/**
@@ -344,7 +344,7 @@ public function testDataFiltered()
344344
fwrite($stream, "foobar\n");
345345
rewind($stream);
346346

347-
$conn->handleData($stream);
347+
$conn->handleData();
348348
$this->assertSame("foobr\n", $capturedData);
349349
}
350350

@@ -373,7 +373,7 @@ public function testDataErrorShouldEmitErrorAndClose()
373373
fwrite($stream, "foobar\n");
374374
rewind($stream);
375375

376-
$conn->handleData($stream);
376+
$conn->handleData();
377377
}
378378

379379
/**

tests/ThroughStreamTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public function endShouldWriteDataBeforeClosing()
216216
public function endTwiceShouldOnlyEmitOnce()
217217
{
218218
$through = new ThroughStream();
219-
$through->on('data', $this->expectCallableOnce('first'));
219+
$through->on('data', $this->expectCallableOnceWith('first'));
220220
$through->end('first');
221221
$through->end('ignored');
222222
}

tests/WritableResourceStreamTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public function testConstructorThrowsIfNotAValidStreamResource()
5858
$loop = $this->createLoopMock();
5959

6060
$this->expectException(\InvalidArgumentException::class);
61-
new WritableResourceStream($stream, $loop);
61+
new WritableResourceStream($stream, $loop); // @phpstan-ignore-line
6262
}
6363

6464
/**
@@ -165,6 +165,7 @@ public function testWriteReturnsFalseWhenWritableResourceStreamIsFull()
165165
->expects($this->any())
166166
->method('addWriteStream')
167167
->will($this->returnCallback(function ($stream, $listener) use (&$preventWrites) {
168+
/** @var bool $preventWrites */
168169
if (!$preventWrites) {
169170
call_user_func($listener, $stream);
170171
}

0 commit comments

Comments
 (0)