From 404b4f80d0a8d92b57bb0b6f3f53462a964b4c95 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 12 Jan 2025 05:01:56 +0100 Subject: [PATCH 1/3] Drop support for PHP < 7.1 [1] * Update Composer version requirements. * Remove PHP 7.0 specific Composer script. * Stop running tests/linting in CI against PHP 7.0. --- .github/workflows/lint.yml | 8 ++------ .github/workflows/test.yml | 12 ++++-------- .phpcs.xml.dist | 7 ------- README.md | 2 +- composer.json | 8 ++------ phpstan.neon.dist | 2 +- 6 files changed, 10 insertions(+), 29 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 517b7c0..cd0dfb7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: - php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', 'nightly'] + php: ['7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', 'nightly'] continue-on-error: ${{ matrix.php == 'nightly' }} @@ -62,12 +62,8 @@ jobs: # Bust the cache at least once a month - output format: YYYY-MM. custom-cache-suffix: $(date -u "+%Y-%m") - - name: "Lint PHP files against parse errors - PHP 7.0" - if: ${{ matrix.php == '7.0' }} - run: composer lint70 - - name: "Lint PHP files against parse errors - PHP 7.1 - 7.4" - if: ${{ startsWith( matrix.php, '7' ) && matrix.php != '7.0' }} + if: ${{ startsWith( matrix.php, '7' ) }} run: composer lint7 - name: "Lint PHP files against parse errors - PHP 8.0+" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3416381..cefa257 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: - php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + php: ['7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] phpunit: ['auto'] coverage: [true] experimental: [false] @@ -43,17 +43,13 @@ jobs: include: # Test against a version on the low-end of the PHPUnit versions supported for each PHP version. # Using the Composer `--prefer-lowest` option is, unfortunately, not viable, as - # it would result PHP 7.0 - 7.4 all using PHPUnit 6.4.4, which is not the intention. + # it would result PHP 7.1 - 7.4 all using PHPUnit 6.4.4, which is not the intention. # It also would run into trouble with PHP 8.5.12 being used on PHP 8.0+, while the # 8.5.12 release still contained a bug which makes it incompatible with PHP 8.1+, # even though it officially allows for it. # # Note: PHPUnit 10 is not supported for the PHPUnit Polyfills 3.x branch, so there are # no builds against PHPUnit 10! - - php: '7.0' - phpunit: '6.4.4' - coverage: true - experimental: false - php: '7.1' phpunit: '~6.4.4' coverage: true @@ -208,9 +204,9 @@ jobs: # This should be sufficient to record the coverage for the PHAR specific code. # PHPUnit 6 is only supported for PHPUnit 6.4.4-latest on the officially supported PHP versions. - - php: '7.0' + - php: '7.1' phpunit: '6.4' - - php: '7.0' + - php: '7.1' phpunit: '6' - php: '7.2' phpunit: '6.4' diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist index 73d7cbc..e306e90 100644 --- a/.phpcs.xml.dist +++ b/.phpcs.xml.dist @@ -125,13 +125,6 @@ /src/Helpers/ResourceHelper\.php$ - - - - /src/TestCases/TestCasePHPUnitGte8\.php$ - /src/TestListeners/TestListenerDefaultImplementationPHPUnitGte7\.php$ - - diff --git a/README.md b/README.md index 44018c9..496e9ef 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit Requirements ------------ -* PHP 7.0 or higher. +* PHP 7.1 or higher. * [PHPUnit] 6.4 - 9.x and 11.x (automatically required via Composer). [PHPUnit]: https://packagist.org/packages/phpunit/phpunit diff --git a/composer.json b/composer.json index c859926..bf0fc76 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "security": "https://github.com/Yoast/PHPUnit-Polyfills/security/policy" }, "require": { - "php": ">=7.0", + "php": ">=7.1", "phpunit/phpunit": "^6.4.4 || ^7.0 || ^8.0 || ^9.0 || ^11.0" }, "require-dev": { @@ -61,14 +61,11 @@ "lint7": [ "@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --show-deprecated --exclude vendor --exclude .git --exclude tests/Polyfills/Fixtures/ValueObjectUnion.php --exclude tests/Polyfills/Fixtures/ValueObjectUnionReturnType.php" ], - "lint70": [ - "@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --show-deprecated --exclude vendor --exclude .git --exclude src/Exceptions/Error.php --exclude src/Exceptions/TypeError.php --exclude tests/Polyfills/Fixtures/ValueObjectParamNotRequired.php --exclude tests/Polyfills/Fixtures/ValueObjectNullableReturnType.php --exclude tests/Polyfills/Fixtures/ValueObjectUnion.php --exclude tests/Polyfills/Fixtures/ValueObjectUnionReturnType.php" - ], "lint-gte80": [ "@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --show-deprecated --exclude vendor --exclude .git" ], "check-cs": [ - "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --runtime-set testVersion 7.0-" + "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --runtime-set testVersion 7.1-" ], "fix-cs": [ "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf" @@ -88,7 +85,6 @@ }, "scripts-descriptions": { "lint7": "Check the PHP files for parse errors. (PHP 7.1 - 7.4)", - "lint70": "Check the PHP files for parse errors. (PHP 7.0)", "lint-gte80": "Check the PHP files for parse errors. (PHP 8.0+)", "check-cs": "Check the PHP files for code style violations and best practices.", "fix-cs": "Auto-fix code style violations in the PHP files.", diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 20b9dea..5b0f878 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ parameters: - phpVersion: 70100 # Needs to be 70100 or higher... sigh... + phpVersion: 70100 level: 9 bootstrapFiles: - phpstan-bootstrap.php From 58f45ce759ea3c5f3991ef899359725e2c8bcd71 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 12 Jan 2025 05:05:21 +0100 Subject: [PATCH 2/3] Drop support for PHP < 7.1 [2] Remove various in-code work-arounds which were specifically to support PHP 7.0. --- src/Helpers/ComparatorValidator.php | 46 ++++------------------------ src/Helpers/ResourceHelper.php | 6 +--- src/Polyfills/AssertContainsOnly.php | 8 ++--- 3 files changed, 10 insertions(+), 50 deletions(-) diff --git a/src/Helpers/ComparatorValidator.php b/src/Helpers/ComparatorValidator.php index 0de5dd3..d5a0dab 100644 --- a/src/Helpers/ComparatorValidator.php +++ b/src/Helpers/ComparatorValidator.php @@ -4,7 +4,6 @@ use ReflectionNamedType; use ReflectionObject; -use ReflectionType; use Yoast\PHPUnitPolyfills\Exceptions\InvalidComparisonMethodException; /** @@ -82,18 +81,7 @@ public static function isValid( $expected, $actual, $method = 'equals' ) { $returnType = $reflMethod->getReturnType(); - if ( \class_exists( 'ReflectionNamedType' ) ) { - // PHP >= 7.1: guard against union/intersection return types. - if ( ( $returnType instanceof ReflectionNamedType ) === false ) { - throw new InvalidComparisonMethodException( $returnTypeError ); - } - } - elseif ( ( $returnType instanceof ReflectionType ) === false ) { - /* - * PHP 7.0. - * Checking for `ReflectionType` will not throw an error on union types, - * but then again union types are not supported on PHP 7.0. - */ + if ( ( $returnType instanceof ReflectionNamedType ) === false ) { throw new InvalidComparisonMethodException( $returnTypeError ); } @@ -101,14 +89,7 @@ public static function isValid( $expected, $actual, $method = 'equals' ) { throw new InvalidComparisonMethodException( $returnTypeError ); } - if ( \method_exists( $returnType, 'getName' ) ) { - // PHP >= 7.1. - if ( $returnType->getName() !== 'bool' ) { - throw new InvalidComparisonMethodException( $returnTypeError ); - } - } - elseif ( (string) $returnType !== 'bool' ) { - // PHP 7.0. + if ( $returnType->getName() !== 'bool' ) { throw new InvalidComparisonMethodException( $returnTypeError ); } @@ -148,27 +129,12 @@ public static function isValid( $expected, $actual, $method = 'equals' ) { } $type = $reflParameter->getType(); - if ( \class_exists( 'ReflectionNamedType' ) ) { - // PHP >= 7.1. - if ( ( $type instanceof ReflectionNamedType ) === false ) { - throw new InvalidComparisonMethodException( $noDeclaredTypeError ); - } - - $typeName = $type->getName(); - } - else { - /* - * PHP 7.0. - * Checking for `ReflectionType` will not throw an error on union types, - * but then again union types are not supported on PHP 7.0. - */ - if ( ( $type instanceof ReflectionType ) === false ) { - throw new InvalidComparisonMethodException( $noDeclaredTypeError ); - } - - $typeName = (string) $type; + if ( ( $type instanceof ReflectionNamedType ) === false ) { + throw new InvalidComparisonMethodException( $noDeclaredTypeError ); } + $typeName = $type->getName(); + /* * Validate that the $expected object complies with the declared parameter type. */ diff --git a/src/Helpers/ResourceHelper.php b/src/Helpers/ResourceHelper.php index 020fc51..d2a77e9 100644 --- a/src/Helpers/ResourceHelper.php +++ b/src/Helpers/ResourceHelper.php @@ -114,15 +114,11 @@ public static function isResourceStateReliable( $actual ) { * correctly. * * Version ranges based on {@link https://3v4l.org/tc4fE}. - * 7.0.8 - 7.0.33, 7.1.0 - 7.1.33, 7.2.0 - 7.2.34, 7.3.0 - 7.3.21, 7.4.0 - 7.4.9 + * 7.1.0 - 7.1.33, 7.2.0 - 7.2.34, 7.3.0 - 7.3.21, 7.4.0 - 7.4.9 * * @return bool */ public static function isIncompatiblePHPForLibXMLResources() { - if ( \PHP_VERSION_ID >= 70008 && \PHP_VERSION_ID < 70034 ) { - return true; - } - if ( \PHP_VERSION_ID >= 70100 && \PHP_VERSION_ID < 70134 ) { return true; } diff --git a/src/Polyfills/AssertContainsOnly.php b/src/Polyfills/AssertContainsOnly.php index 308dfe1..b8478ed 100644 --- a/src/Polyfills/AssertContainsOnly.php +++ b/src/Polyfills/AssertContainsOnly.php @@ -176,14 +176,12 @@ final public static function assertContainsNotOnlyInt( $haystack, string $messag * @return void */ final public static function assertContainsOnlyIterable( $haystack, string $message = '' ) { - if ( \function_exists( 'is_iterable' ) === true - && \version_compare( Autoload::getPHPUnitVersion(), '7.1.0', '>=' ) - ) { - // PHP >= 7.1 with PHPUnit >= 7.1.0. + if ( \version_compare( Autoload::getPHPUnitVersion(), '7.1.0', '>=' ) ) { + // PHPUnit >= 7.1.0. static::assertContainsOnly( 'iterable', $haystack, true, $message ); } else { - // PHP < 7.1 or PHPUnit 6.x/7.0.0. + // PHPUnit 6.x/7.0.0. $exporter = self::getPHPUnitExporterObjectForContainsOnly(); $msg = \sprintf( 'Failed asserting that %s contains only values of type "iterable".', $exporter->export( $haystack ) ); From f800be80964e21ed2af2aa63a76ef41f12118b8c Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 12 Jan 2025 06:59:06 +0100 Subject: [PATCH 3/3] Drop support for PHP < 7.1 [3] Remove the PHP 7.1+ specific test fixtures for the `AssertObjectEquals` and `AssertObjectNotEquals` tests. As support for PHP < 7.1 has been dropped, these fixture methods no longer need their own class and can be moved into the main test fixture. --- .phpcs.xml.dist | 8 +--- tests/Polyfills/AssertObjectEqualsTest.php | 20 +++------- tests/Polyfills/AssertObjectNotEqualsTest.php | 20 +++------- tests/Polyfills/Fixtures/ValueObject.php | 22 ++++++++++ .../ValueObjectNullableReturnType.php | 39 ------------------ .../Fixtures/ValueObjectParamNotRequired.php | 40 ------------------- 6 files changed, 35 insertions(+), 114 deletions(-) delete mode 100644 tests/Polyfills/Fixtures/ValueObjectNullableReturnType.php delete mode 100644 tests/Polyfills/Fixtures/ValueObjectParamNotRequired.php diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist index e306e90..cc8f2cb 100644 --- a/.phpcs.xml.dist +++ b/.phpcs.xml.dist @@ -153,13 +153,7 @@ /tests/Polyfills/Fixtures/*\.php$ - - - /tests/Polyfills/Fixtures/ValueObjectParamNotRequired\.php$ - - - /tests/Polyfills/Fixtures/ValueObjectNullableReturnType\.php$ - + /tests/Polyfills/Fixtures/ValueObjectUnion\.php$ diff --git a/tests/Polyfills/AssertObjectEqualsTest.php b/tests/Polyfills/AssertObjectEqualsTest.php index b115f9c..3dce8d5 100644 --- a/tests/Polyfills/AssertObjectEqualsTest.php +++ b/tests/Polyfills/AssertObjectEqualsTest.php @@ -20,8 +20,6 @@ use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ChildValueObject; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject; -use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectNullableReturnType; -use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectParamNotRequired; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectUnion; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectUnionReturnType; @@ -237,13 +235,10 @@ public function testAssertObjectEqualsFailsOnNonNamedTypeReturnType() { /** * Verify that the assertObjectEquals() method throws an error when the declared return type is nullable. * - * @requires PHP 7.1 - * * @return void */ - #[RequiresPhp( '7.1' )] public function testAssertObjectEqualsFailsOnNullableReturnType() { - $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectNullableReturnType::equalsNullableReturnType() does not declare bool return type.'; + $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equalsNullableReturnType() does not declare bool return type.'; $exception = self::COMPARATOR_EXCEPTION; if ( \class_exists( ComparisonMethodDoesNotDeclareBoolReturnTypeException::class ) ) { @@ -254,8 +249,8 @@ public function testAssertObjectEqualsFailsOnNullableReturnType() { $this->expectException( $exception ); $this->expectExceptionMessage( $msg ); - $expected = new ValueObjectNullableReturnType( 100 ); - $actual = new ValueObjectNullableReturnType( 100 ); + $expected = new ValueObject( 100 ); + $actual = new ValueObject( 100 ); $this->assertObjectEquals( $expected, $actual, 'equalsNullableReturnType' ); } @@ -306,13 +301,10 @@ public function testAssertObjectEqualsFailsOnMethodAllowsForMoreParams() { /** * Verify that the assertObjectEquals() method throws an error when the $method is not a required parameter. * - * @requires PHP 7.1 - * * @return void */ - #[RequiresPhp( '7.1' )] public function testAssertObjectEqualsFailsOnMethodParamNotRequired() { - $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectParamNotRequired::equalsParamNotRequired() does not declare exactly one parameter.'; + $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equalsParamNotRequired() does not declare exactly one parameter.'; $exception = self::COMPARATOR_EXCEPTION; if ( \class_exists( ComparisonMethodDoesNotDeclareExactlyOneParameterException::class ) ) { @@ -323,8 +315,8 @@ public function testAssertObjectEqualsFailsOnMethodParamNotRequired() { $this->expectException( $exception ); $this->expectExceptionMessage( $msg ); - $expected = new ValueObjectParamNotRequired( 'test' ); - $actual = new ValueObjectParamNotRequired( 'test' ); + $expected = new ValueObject( 'test' ); + $actual = new ValueObject( 'test' ); $this->assertObjectEquals( $expected, $actual, 'equalsParamNotRequired' ); } diff --git a/tests/Polyfills/AssertObjectNotEqualsTest.php b/tests/Polyfills/AssertObjectNotEqualsTest.php index ec32be5..e6e7510 100644 --- a/tests/Polyfills/AssertObjectNotEqualsTest.php +++ b/tests/Polyfills/AssertObjectNotEqualsTest.php @@ -20,8 +20,6 @@ use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ChildValueObject; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject; -use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectNullableReturnType; -use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectParamNotRequired; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectUnion; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectUnionReturnType; @@ -243,13 +241,10 @@ public function testAssertObjectNotEqualsFailsOnNonNamedTypeReturnType() { /** * Verify that the assertObjectNotEquals() method throws an error when the declared return type is nullable. * - * @requires PHP 7.1 - * * @return void */ - #[RequiresPhp( '7.1' )] public function testAssertObjectNotEqualsFailsOnNullableReturnType() { - $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectNullableReturnType::equalsNullableReturnType() does not declare bool return type.'; + $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equalsNullableReturnType() does not declare bool return type.'; $exception = self::COMPARATOR_EXCEPTION; if ( \class_exists( ComparisonMethodDoesNotDeclareBoolReturnTypeException::class ) @@ -262,8 +257,8 @@ public function testAssertObjectNotEqualsFailsOnNullableReturnType() { $this->expectException( $exception ); $this->expectExceptionMessage( $msg ); - $expected = new ValueObjectNullableReturnType( 100 ); - $actual = new ValueObjectNullableReturnType( 250 ); + $expected = new ValueObject( 100 ); + $actual = new ValueObject( 250 ); $this->assertObjectNotEquals( $expected, $actual, 'equalsNullableReturnType' ); } @@ -318,13 +313,10 @@ public function testAssertObjectNotEqualsFailsOnMethodAllowsForMoreParams() { /** * Verify that the assertObjectNotEquals() method throws an error when the $method is not a required parameter. * - * @requires PHP 7.1 - * * @return void */ - #[RequiresPhp( '7.1' )] public function testAssertObjectNotEqualsFailsOnMethodParamNotRequired() { - $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectParamNotRequired::equalsParamNotRequired() does not declare exactly one parameter.'; + $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equalsParamNotRequired() does not declare exactly one parameter.'; $exception = self::COMPARATOR_EXCEPTION; if ( \class_exists( ComparisonMethodDoesNotDeclareExactlyOneParameterException::class ) @@ -337,8 +329,8 @@ public function testAssertObjectNotEqualsFailsOnMethodParamNotRequired() { $this->expectException( $exception ); $this->expectExceptionMessage( $msg ); - $expected = new ValueObjectParamNotRequired( 'test' ); - $actual = new ValueObjectParamNotRequired( 'different' ); + $expected = new ValueObject( 'test' ); + $actual = new ValueObject( 'different' ); $this->assertObjectNotEquals( $expected, $actual, 'equalsParamNotRequired' ); } diff --git a/tests/Polyfills/Fixtures/ValueObject.php b/tests/Polyfills/Fixtures/ValueObject.php index 7d3a013..d767cc7 100644 --- a/tests/Polyfills/Fixtures/ValueObject.php +++ b/tests/Polyfills/Fixtures/ValueObject.php @@ -58,6 +58,17 @@ public function equalsMissingReturnType( self $other ) { return ( $this->value === $other->value ); } + /** + * Comparator method: incorrectly declared - return type is nullable. + * + * @param self $other Object to compare. + * + * @return bool + */ + public function equalsNullableReturnType( self $other ): ?bool { + return ( $this->value === $other->value ); + } + /** * Comparator method: incorrectly declared - non-boolean return type/value. * @@ -81,6 +92,17 @@ public function equalsTwoParams( $other, $param ): bool { return ( $param && $this->value === $other->value ); } + /** + * Comparator method: incorrectly declared - parameter is not required. + * + * @param self|null $other Object to compare. + * + * @return bool + */ + public function equalsParamNotRequired( ?self $other = null ): bool { + return ( $this->value === $other->value ); + } + /** * Comparator method: incorrectly declared - parameter is not typed. * diff --git a/tests/Polyfills/Fixtures/ValueObjectNullableReturnType.php b/tests/Polyfills/Fixtures/ValueObjectNullableReturnType.php deleted file mode 100644 index 45c98af..0000000 --- a/tests/Polyfills/Fixtures/ValueObjectNullableReturnType.php +++ /dev/null @@ -1,39 +0,0 @@ -value = $value; - } - - /** - * Comparator method: incorrectly declared - return type is nullable. - * - * @param self $other Object to compare. - * - * @return bool - */ - public function equalsNullableReturnType( self $other ): ?bool { - return ( $this->value === $other->value ); - } -} diff --git a/tests/Polyfills/Fixtures/ValueObjectParamNotRequired.php b/tests/Polyfills/Fixtures/ValueObjectParamNotRequired.php deleted file mode 100644 index 6579643..0000000 --- a/tests/Polyfills/Fixtures/ValueObjectParamNotRequired.php +++ /dev/null @@ -1,40 +0,0 @@ -value = $value; - } - - /** - * Comparator method: incorrectly declared - parameter is not required. - * - * @param self|null $other Object to compare. - * - * @return bool - */ - public function equalsParamNotRequired( ?self $other = null ): bool { - return ( $this->value === $other->value ); - } -}