From 804d0ee6fb12460cb828ab51bffac66e72c4d9f3 Mon Sep 17 00:00:00 2001 From: Eduardo Dobay Date: Sat, 10 Oct 2020 12:44:35 -0300 Subject: [PATCH 1/3] Allow running under PHP 8 and PHPUnit 9.x - PHPUnit 9.3 is required to support PHP 8. PHPUnit 8.x will not be updated to support PHP 8 and will become unsupported in February 2021. - Methods that were removed from 9.x were migrated. - Prophecy will no longer be bundled with PHPUnit, but the replacement phpspec/prophecy-phpunit required PHP 7.3. To keep PHP 7.2 compatibility, weirdan/prophecy-shim is used as a "migration layer". Note: 2.0.1 was tagged incorrectly, hence it is avoided in the version constraint. - http-factory-tests upgraded to 0.7 (allows installing on PHP 8) - In PHP 8, fopen throws ValueError instead of triggering an error. In PHP 7, that exception does not exist and PHPStan fails. Hence the symfony/polyfill-php80 dependency was brought. - Some dependencies cannot be installed on PHP 8 yet (namely, fig/http-message-util and php-http/psr7-integration-tests). "--ignore-platform-reqs" was temporarily added to the CI build with PHP 'nightly'. --- composer.json | 10 ++++++---- src/Factory/StreamFactory.php | 11 ++++++++++- tests/Factory/UploadedFileFactoryTest.php | 3 +++ tests/StreamTest.php | 3 +++ tests/UploadedFileTest.php | 7 +++++-- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index b8b9c6c..50051ff 100644 --- a/composer.json +++ b/composer.json @@ -28,11 +28,12 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2 || ^8.0", "fig/http-message-util": "^1.1.4", "psr/http-factory": "^1.0", "psr/http-message": "^1.0", - "ralouphie/getallheaders": "^3" + "ralouphie/getallheaders": "^3", + "symfony/polyfill-php80": "^1.18" }, "require-dev": { "ext-json": "*", @@ -40,8 +41,9 @@ "http-interop/http-factory-tests": "^0.7.0", "php-http/psr7-integration-tests": "dev-master", "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^8.5", - "squizlabs/php_codesniffer": "^3.5" + "phpunit/phpunit": "^8.5 || ^9.3", + "squizlabs/php_codesniffer": "^3.5", + "weirdan/prophecy-shim": "^1.0 || ^2.0.2" }, "provide": { "psr/http-message-implementation": "1.0", diff --git a/src/Factory/StreamFactory.php b/src/Factory/StreamFactory.php index dd1d1b1..07b92b2 100644 --- a/src/Factory/StreamFactory.php +++ b/src/Factory/StreamFactory.php @@ -66,7 +66,16 @@ public function createStreamFromFile( )); }); - $resource = fopen($filename, $mode); + try { + $resource = fopen($filename, $mode); + } catch (\ValueError $exception) { + throw new RuntimeException(sprintf( + 'Unable to open %s using mode %s: %s', + $filename, + $mode, + $exception->getMessage() + )); + } restore_error_handler(); if ($exc) { diff --git a/tests/Factory/UploadedFileFactoryTest.php b/tests/Factory/UploadedFileFactoryTest.php index 9c14d18..1c23225 100644 --- a/tests/Factory/UploadedFileFactoryTest.php +++ b/tests/Factory/UploadedFileFactoryTest.php @@ -12,6 +12,7 @@ use Interop\Http\Factory\UploadedFileFactoryTestCase; use InvalidArgumentException; +use Prophecy\PhpUnit\ProphecyTrait; use Psr\Http\Message\StreamInterface; use Slim\Psr7\Factory\StreamFactory; use Slim\Psr7\Factory\UploadedFileFactory; @@ -24,6 +25,8 @@ class UploadedFileFactoryTest extends UploadedFileFactoryTestCase { + use ProphecyTrait; + /** * @return UploadedFileFactory */ diff --git a/tests/StreamTest.php b/tests/StreamTest.php index 1bcdaab..ad1e3ca 100644 --- a/tests/StreamTest.php +++ b/tests/StreamTest.php @@ -11,6 +11,7 @@ namespace Slim\Tests\Psr7; use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; use ReflectionException; use ReflectionMethod; use ReflectionProperty; @@ -24,6 +25,8 @@ class StreamTest extends TestCase { + use ProphecyTrait; + /** * @var resource pipe stream file handle */ diff --git a/tests/UploadedFileTest.php b/tests/UploadedFileTest.php index adeefaa..4a4ffaf 100644 --- a/tests/UploadedFileTest.php +++ b/tests/UploadedFileTest.php @@ -12,6 +12,7 @@ use InvalidArgumentException; use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; use Psr\Http\Message\StreamInterface; use Psr\Http\Message\UploadedFileInterface; use ReflectionProperty; @@ -42,6 +43,8 @@ class UploadedFileTest extends TestCase { + use ProphecyTrait; + private static $filename = './phpUxcOty'; private static $tmpFiles = ['./phpUxcOty']; @@ -245,7 +248,7 @@ public function testMoveTo(UploadedFile $uploadedFile) public function testMoveToRenameFailure() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessageRegExp('/^Error moving uploaded file .* to .*$/'); + $this->expectExceptionMessageMatches('/^Error moving uploaded file .* to .*$/'); $uploadedFile = $this->generateNewTmpFile(); @@ -280,7 +283,7 @@ public function testMoveToSapiNonUploadedFile(UploadedFile $uploadedFile) public function testMoveToSapiMoveUploadedFileFails(UploadedFile $uploadedFile) { $this->expectException(RuntimeException::class); - $this->expectExceptionMessageRegExp('~Error moving uploaded file.*~'); + $this->expectExceptionMessageMatches('~Error moving uploaded file.*~'); $GLOBALS['is_uploaded_file_return'] = true; From 4298b115c65c0d2de908cf67a9a82b732cb19e60 Mon Sep 17 00:00:00 2001 From: Eduardo Dobay Date: Sun, 1 Nov 2020 14:30:43 -0300 Subject: [PATCH 2/3] Add coverage ignore for code that only runs in PHP 8.0 --- src/Factory/StreamFactory.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Factory/StreamFactory.php b/src/Factory/StreamFactory.php index 07b92b2..df74cff 100644 --- a/src/Factory/StreamFactory.php +++ b/src/Factory/StreamFactory.php @@ -53,29 +53,35 @@ public function createStreamFromFile( string $mode = 'r', StreamInterface $cache = null ): StreamInterface { - // When fopen fails, PHP normally raises a warning. Add an error + // When fopen fails, PHP 7 normally raises a warning. Add an error // handler to check for errors and throw an exception instead. + // On PHP 8, exceptions are thrown. $exc = null; - set_error_handler(function (int $errno, string $errstr) use ($filename, $mode, &$exc) { + // Would not be initialized if fopen throws on PHP >= 8.0 + $resource = null; + + $errorHandler = function (string $errorMessage) use ($filename, $mode, &$exc) { $exc = new RuntimeException(sprintf( 'Unable to open %s using mode %s: %s', $filename, $mode, - $errstr + $errorMessage )); + }; + + set_error_handler(function (int $errno, string $errstr) use ($errorHandler) { + $errorHandler($errstr); }); try { $resource = fopen($filename, $mode); + // @codeCoverageIgnoreStart + // (Can only be executed in PHP >= 8.0) } catch (\ValueError $exception) { - throw new RuntimeException(sprintf( - 'Unable to open %s using mode %s: %s', - $filename, - $mode, - $exception->getMessage() - )); + $errorHandler($exception->getMessage()); } + // @codeCoverageIgnoreEnd restore_error_handler(); if ($exc) { From aaf88e872b1279c24a3490b37c98631de3632946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20B=C3=A9rub=C3=A9?= Date: Fri, 27 Nov 2020 21:07:26 -0700 Subject: [PATCH 3/3] add import --- src/Factory/StreamFactory.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Factory/StreamFactory.php b/src/Factory/StreamFactory.php index df74cff..caeab21 100644 --- a/src/Factory/StreamFactory.php +++ b/src/Factory/StreamFactory.php @@ -15,6 +15,7 @@ use Psr\Http\Message\StreamInterface; use RuntimeException; use Slim\Psr7\Stream; +use ValueError; use function fopen; use function fwrite; @@ -78,7 +79,7 @@ public function createStreamFromFile( $resource = fopen($filename, $mode); // @codeCoverageIgnoreStart // (Can only be executed in PHP >= 8.0) - } catch (\ValueError $exception) { + } catch (ValueError $exception) { $errorHandler($exception->getMessage()); } // @codeCoverageIgnoreEnd