From 34075741384fe02474f146475ca855cbd0d82d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sat, 7 Sep 2024 14:54:24 +0200 Subject: [PATCH] Improve PHP 8.4+ support by avoiding implicitly nullable types --- composer.json | 4 ++-- src/Factory.php | 8 ++++++-- tests/FunctionalTest.php | 12 +++++++++--- tests/TestCase.php | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 353c4f3..e5507e4 100644 --- a/composer.json +++ b/composer.json @@ -22,8 +22,8 @@ }, "require": { "php": ">=5.3", - "react/event-loop": "^1.2", - "react/datagram": "~1.0" + "react/datagram": "^1.10", + "react/event-loop": "^1.2" }, "require-dev": { "clue/hexdump": "0.2.*", diff --git a/src/Factory.php b/src/Factory.php index 8b3f634..e8e1028 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -15,7 +15,7 @@ class Factory /** * The `Factory` is responsible for creating your [`SocketInterface`](#socketinterface) instances. - * + * * This class takes an optional `LoopInterface|null $loop` parameter that can be used to * pass the event loop instance to use for this object. You can use a `null` value * here in order to use the [default loop](https://github.com/reactphp/event-loop#loop). @@ -29,8 +29,12 @@ class Factory * * @param LoopInterface $loop */ - public function __construct(LoopInterface $loop = null) + public function __construct($loop = null) { + if ($loop !== null && !$loop instanceof LoopInterface) { // manual type check to support legacy PHP < 7.1 + throw new \InvalidArgumentException('Argument #1 ($loop) expected null|React\EventLoop\LoopInterface'); + } + $this->loop = $loop ?: Loop::get(); } diff --git a/tests/FunctionalTest.php b/tests/FunctionalTest.php index e232c23..05ef5e6 100644 --- a/tests/FunctionalTest.php +++ b/tests/FunctionalTest.php @@ -57,15 +57,21 @@ public function testMultipleReceivers() $this->loop->run(); } - + public function testConstructWithoutLoopAssignsLoopAutomatically() { $factory = new Factory(); - + $ref = new \ReflectionProperty($factory, 'loop'); $ref->setAccessible(true); $loop = $ref->getValue($factory); - + $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop); } + + public function testCtorThrowsForInvalidLoop() + { + $this->setExpectedException('InvalidArgumentException', 'Argument #1 ($loop) expected null|React\EventLoop\LoopInterface'); + new Factory('loop'); + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 171dd2a..a4e5bed 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -41,4 +41,21 @@ protected function createCallableMock() { return $this->getMockBuilder('stdClass')->setMethods(array('__invoke'))->getMock(); } + + public function setExpectedException($exception, $exceptionMessage = '', $exceptionCode = null) + { + if (method_exists($this, 'expectException')) { + // PHPUnit 5.2+ + $this->expectException($exception); + if ($exceptionMessage !== '') { + $this->expectExceptionMessage($exceptionMessage); + } + if ($exceptionCode !== null) { + $this->expectExceptionCode($exceptionCode); + } + } else { + // legacy PHPUnit + parent::setExpectedException($exception, $exceptionMessage, $exceptionCode); + } + } }