Skip to content

Commit

Permalink
Add PHPStan to test environment
Browse files Browse the repository at this point in the history
  • Loading branch information
clue committed May 22, 2024
1 parent cf107f5 commit 7bfa495
Show file tree
Hide file tree
Showing 13 changed files with 60 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/.github/ export-ignore
/.gitignore export-ignore
/examples/ export-ignore
/phpstan.neon.dist export-ignore
/phpunit.xml.dist export-ignore
/phpunit.xml.legacy export-ignore
/tests/ export-ignore
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,26 @@ jobs:
- run: composer install
- run: vendor/bin/phpunit --coverage-text
- run: time php examples/91-benchmark-throughput.php

PHPStan:
name: PHPStan (PHP ${{ matrix.php }})
runs-on: ubuntu-22.04
strategy:
matrix:
php:
- 8.3
- 8.2
- 8.1
- 8.0
- 7.4
- 7.3
- 7.2
- 7.1
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
- run: composer install
- run: vendor/bin/phpstan
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,12 @@ If you do not want to run these, they can simply be skipped like this:
vendor/bin/phpunit --exclude-group internet
```

On top of this, we use PHPStan on level 5 to ensure type safety across the project:

```bash
vendor/bin/phpstan
```

## License

MIT, see [LICENSE file](LICENSE).
Expand Down
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
"evenement/evenement": "^3.0 || ^2.0 || ^1.0"
},
"require-dev": {
"phpunit/phpunit": "^9.6 || ^7.5",
"clue/stream-filter": "~1.2"
"clue/stream-filter": "^1.2",
"phpstan/phpstan": "1.11.1 || 1.4.10",
"phpunit/phpunit": "^9.6 || ^7.5"
},
"autoload": {
"psr-4": {
Expand Down
7 changes: 7 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
parameters:
level: 5

paths:
- examples/
- src/
- tests/
3 changes: 2 additions & 1 deletion src/DuplexResourceStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,15 @@ public function pipe(WritableStreamInterface $dest, array $options = []): Writab
public function handleData($stream)
{
$error = null;
\set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) {
\set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error): bool {
$error = new \ErrorException(
$errstr,
0,
$errno,
$errfile,
$errline
);
return true;
});

$data = \stream_get_contents($stream, $this->bufferSize);
Expand Down
3 changes: 2 additions & 1 deletion src/ReadableResourceStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,15 @@ public function close(): void
public function handleData()
{
$error = null;
\set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error) {
\set_error_handler(function ($errno, $errstr, $errfile, $errline) use (&$error): bool {
$error = new \ErrorException(
$errstr,
0,
$errno,
$errfile,
$errline
);
return true;
});

$data = \stream_get_contents($this->stream, $this->bufferSize);
Expand Down
2 changes: 2 additions & 0 deletions src/ThroughStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ public function write($data): bool
}

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

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

// return if write() already caused the stream to close
// @phpstan-ignore-next-line (may be false when write() causes stream to close)
if (!$this->writable) {
return;
}
Expand Down
3 changes: 2 additions & 1 deletion src/WritableResourceStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ public function close(): void
public function handleWrite()
{
$error = null;
\set_error_handler(function ($_, $errstr) use (&$error) {
\set_error_handler(function ($_, $errstr) use (&$error): bool {
$error = $errstr;
return true;
});

if ($this->writeChunkSize === -1) {
Expand Down
2 changes: 1 addition & 1 deletion tests/DuplexResourceStreamTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function testConstructorThrowsExceptionOnInvalidStream()
$loop = $this->createLoopMock();

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

/**
Expand Down
16 changes: 8 additions & 8 deletions tests/ReadableResourceStreamTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function testConstructorThrowsExceptionOnInvalidStream()
$loop = $this->createLoopMock();

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

/**
Expand Down Expand Up @@ -148,7 +148,7 @@ public function testDataEvent()
fwrite($stream, "foobar\n");
rewind($stream);

$conn->handleData($stream);
$conn->handleData();
$this->assertSame("foobar\n", $capturedData);
}

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

$conn->handleData($stream);
$conn->handleData();

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

$conn->handleData($stream);
$conn->handleData();

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

$conn->handleData($stream);
$conn->handleData();
}

public function testPipeShouldReturnDestination()
Expand Down Expand Up @@ -245,7 +245,7 @@ public function testClosingStreamInDataEventShouldNotTriggerError()
fwrite($stream, "foobar\n");
rewind($stream);

$conn->handleData($stream);
$conn->handleData();
}

/**
Expand Down Expand Up @@ -344,7 +344,7 @@ public function testDataFiltered()
fwrite($stream, "foobar\n");
rewind($stream);

$conn->handleData($stream);
$conn->handleData();
$this->assertSame("foobr\n", $capturedData);
}

Expand Down Expand Up @@ -373,7 +373,7 @@ public function testDataErrorShouldEmitErrorAndClose()
fwrite($stream, "foobar\n");
rewind($stream);

$conn->handleData($stream);
$conn->handleData();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/ThroughStreamTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ public function endShouldWriteDataBeforeClosing()
public function endTwiceShouldOnlyEmitOnce()
{
$through = new ThroughStream();
$through->on('data', $this->expectCallableOnce('first'));
$through->on('data', $this->expectCallableOnceWith('first'));
$through->end('first');
$through->end('ignored');
}
Expand Down
3 changes: 2 additions & 1 deletion tests/WritableResourceStreamTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function testConstructorThrowsIfNotAValidStreamResource()
$loop = $this->createLoopMock();

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

/**
Expand Down Expand Up @@ -165,6 +165,7 @@ public function testWriteReturnsFalseWhenWritableResourceStreamIsFull()
->expects($this->any())
->method('addWriteStream')
->will($this->returnCallback(function ($stream, $listener) use (&$preventWrites) {
/** @var bool $preventWrites */
if (!$preventWrites) {
call_user_func($listener, $stream);
}
Expand Down

0 comments on commit 7bfa495

Please sign in to comment.