Skip to content

Commit 2b3fef6

Browse files
committed
Improve PHP 8.4+ support by avoiding implicitly nullable types
1 parent 2283690 commit 2b3fef6

File tree

6 files changed

+63
-8
lines changed

6 files changed

+63
-8
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ on:
77
jobs:
88
PHPUnit:
99
name: PHPUnit (PHP ${{ matrix.php }})
10-
runs-on: ubuntu-22.04
10+
runs-on: ubuntu-24.04
1111
strategy:
1212
matrix:
1313
php:
14+
- 8.4
1415
- 8.3
1516
- 8.2
1617
- 8.1
@@ -39,7 +40,7 @@ jobs:
3940

4041
PHPUnit-hhvm:
4142
name: PHPUnit (HHVM)
42-
runs-on: ubuntu-22.04
43+
runs-on: ubuntu-24.04
4344
continue-on-error: true
4445
services:
4546
redis:

composer.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
],
1313
"require": {
1414
"php": ">=5.3",
15-
"clue/redis-protocol": "0.3.*",
15+
"clue/redis-protocol": "^0.3.2",
1616
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
1717
"react/event-loop": "^1.2",
18-
"react/promise": "^3 || ^2.0 || ^1.1",
19-
"react/promise-timer": "^1.9",
20-
"react/socket": "^1.12"
18+
"react/promise": "^3.2 || ^2.0 || ^1.1",
19+
"react/promise-timer": "^1.11",
20+
"react/socket": "^1.16"
2121
},
2222
"require-dev": {
2323
"clue/block-react": "^1.5",

src/Factory.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,18 @@ class Factory
2727
* @param ?ConnectorInterface $connector
2828
* @param ?ProtocolFactory $protocol
2929
*/
30-
public function __construct(LoopInterface $loop = null, ConnectorInterface $connector = null, ProtocolFactory $protocol = null)
30+
public function __construct($loop = null, $connector = null, $protocol = null)
3131
{
32+
if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
33+
throw new \InvalidArgumentException('Argument #1 ($loop) expected null|React\EventLoop\LoopInterface');
34+
}
35+
if ($connector !== null && !$connector instanceof ConnectorInterface) { // manual type check to support legacy PHP < 7.1
36+
throw new \InvalidArgumentException('Argument #2 ($connector) expected null|React\Socket\ConnectorInterface');
37+
}
38+
if ($protocol !== null && !$protocol instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1
39+
throw new \InvalidArgumentException('Argument #3 ($protocol) expected null|Clue\Redis\Protocol\Factory');
40+
}
41+
3242
$this->loop = $loop ?: Loop::get();
3343
$this->connector = $connector ?: new Connector(array(), $this->loop);
3444
$this->protocol = $protocol ?: new ProtocolFactory();

src/StreamingClient.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,17 @@ class StreamingClient extends EventEmitter implements Client
2828
private $subscribed = 0;
2929
private $psubscribed = 0;
3030

31-
public function __construct(DuplexStreamInterface $stream, ParserInterface $parser = null, SerializerInterface $serializer = null)
31+
/**
32+
* @param DuplexStreamInterface $stream
33+
* @param ?ParserInterface $parser
34+
* @param ?SerializerInterface $serializer
35+
*/
36+
public function __construct(DuplexStreamInterface $stream, $parser = null, $serializer = null)
3237
{
38+
// manual type checks to support legacy PHP < 7.1
39+
assert($parser === null || $parser instanceof ParserInterface);
40+
assert($serializer === null || $serializer instanceof SerializerInterface);
41+
3342
if ($parser === null || $serializer === null) {
3443
$factory = new ProtocolFactory();
3544
if ($parser === null) {

tests/FactoryLazyClientTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,24 @@ public function testConstructWithoutLoopAssignsLoopAutomatically()
3232
$this->assertInstanceOf('React\EventLoop\LoopInterface', $loop);
3333
}
3434

35+
public function testContructorThrowsExceptionForInvalidLoop()
36+
{
37+
$this->setExpectedException('InvalidArgumentException', 'Argument #1 ($loop) expected null|React\EventLoop\LoopInterface');
38+
new Factory('loop');
39+
}
40+
41+
public function testContructorThrowsExceptionForInvalidConnector()
42+
{
43+
$this->setExpectedException('InvalidArgumentException', 'Argument #2 ($connector) expected null|React\Socket\ConnectorInterface');
44+
new Factory(null, 'connector');
45+
}
46+
47+
public function testContructorThrowsExceptionForInvalidProtocolFactory()
48+
{
49+
$this->setExpectedException('InvalidArgumentException', 'Argument #3 ($protocol) expected null|Clue\Redis\Protocol\Factory');
50+
new Factory(null, null, 'protocol');
51+
}
52+
3553
public function testWillConnectWithDefaultPort()
3654
{
3755
$this->connector->expects($this->never())->method('connect');

tests/TestCase.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,21 @@ protected function expectPromiseReject($promise)
6969

7070
return $promise;
7171
}
72+
73+
public function setExpectedException($exception, $exceptionMessage = '', $exceptionCode = null)
74+
{
75+
if (method_exists($this, 'expectException')) {
76+
// PHPUnit 5.2+
77+
$this->expectException($exception);
78+
if ($exceptionMessage !== '') {
79+
$this->expectExceptionMessage($exceptionMessage);
80+
}
81+
if ($exceptionCode !== null) {
82+
$this->expectExceptionCode($exceptionCode);
83+
}
84+
} else {
85+
// legacy PHPUnit
86+
parent::setExpectedException($exception, $exceptionMessage, $exceptionCode);
87+
}
88+
}
7289
}

0 commit comments

Comments
 (0)