From 43bda04dedada2ad346c480d67f997ccdbec4eb6 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 5 Jun 2021 20:26:10 +0200 Subject: [PATCH 1/4] Composer: require-dev the PHPUnit Polyfills While generally speaking, the `require-dev` for PHPUnit should now be removed, I'm leaving it in place due to the PHPUnit >= 9.3.0 issue with PHP-Parser backfilling tokens. If/when that issue is resolved in the future, the direct requirement for PHPUnit can be removed. --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9d647b94..9412605b 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,8 @@ "require-dev" : { "php-parallel-lint/php-parallel-lint": "^1.3.0", "php-parallel-lint/php-console-highlighter": "^0.5", - "phpunit/phpunit": "^4.8 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || >=9.0 <9.3.0" + "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || >=9.0 <9.3.0", + "yoast/phpunit-polyfills": "^1.0.0" }, "conflict": { "squizlabs/php_codesniffer": "3.5.3" From a80afa9b7d52b855cae2c50b5fc5ae594f337a4d Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 5 Jun 2021 20:58:13 +0200 Subject: [PATCH 2/4] Tests: update the bootstrap file ... to always check that a `composer install` has been run and to load the PHPUnit Polyfill autoloader directly when running PHPUnit via a Phar file as the Polyfill library needs to be installed and its autoload file loaded for the tests to work correctly. --- Tests/bootstrap.php | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index 6660d5d1..21d5439a 100644 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -43,13 +43,21 @@ } } +if (\is_dir(\dirname(__DIR__) . '/vendor') && \file_exists(\dirname(__DIR__) . '/vendor/autoload.php')) { + $vendorDir = \dirname(__DIR__) . '/vendor'; +} else { + echo 'Please run `composer install` before attempting to run the unit tests. +You can still run the tests using a PHPUnit phar file, but some test dependencies need to be available. +'; + die(1); +} + // Get the PHPCS dir from an environment variable. $phpcsDir = \getenv('PHPCS_DIR'); // This may be a Composer install. -if ($phpcsDir === false && \is_dir(\dirname(__DIR__) . '/vendor/squizlabs/php_codesniffer')) { - $vendorDir = \dirname(__DIR__) . '/vendor'; - $phpcsDir = $vendorDir . '/squizlabs/php_codesniffer'; +if ($phpcsDir === false && \is_dir($vendorDir . '/squizlabs/php_codesniffer')) { + $phpcsDir = $vendorDir . '/squizlabs/php_codesniffer'; } elseif ($phpcsDir !== false) { $phpcsDir = \realpath($phpcsDir); } @@ -68,7 +76,6 @@ // Pre-load the token back-fills to prevent undefined constant notices. require_once $phpcsDir . '/CodeSniffer/Tokens.php'; } else { -// @todo: change URL!!!! echo 'Uh oh... can\'t find PHPCS. If you use Composer, please run `composer install`. @@ -78,10 +85,12 @@ die(1); } -// Load the composer autoload if available. -if (isset($vendorDir) && \file_exists($vendorDir . '/autoload.php')) { - require_once $vendorDir . '/autoload.php'; -} else { +if (\defined('__PHPUNIT_PHAR__')) { + // Testing via a PHPUnit phar. + + // Load the PHPUnit Polyfills autoloader. + require_once $vendorDir . '/yoast/phpunit-polyfills/phpunitpolyfills-autoload.php'; + /* * Autoloader specifically for the test files. * Fixes issues with PHPUnit not being able to find test classes being extended when running @@ -102,6 +111,9 @@ include_once $file; } }); +} else { + // Testing via a Composer setup. + require_once $vendorDir . '/autoload.php'; } /* From dc1b61ab6e81a02e066aa527acbab143dbc61864 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sat, 5 Jun 2021 20:42:15 +0200 Subject: [PATCH 3/4] Tests: add abstract `PolyfilledTestCase` This test case extends the `UtilityMethodTestCase` from which most test classes extend and makes both the PHPCSUtils native `AssertAttributeSame` polyfill, as well as all polyfills from the PHPUnit Polyfill library available. For test classes which don't need the set up and tear down methods contained in the `UtilityMethodTestCase` and would therefore normally extend the PHPUnit native `TestCase`, the PHPUnit Polyfill `Yoast\PHPUnitPolyfills\TestCases\XTestCase` can be extended instead. Alternatively, such a test class can just `use` any of the polyfill traits from the PHPUnit Polyfill library directly. Test classes which don't need the polyfilled assertion/expectation methods, can - and should - still just extend the PHPUnit native `TestCase` or the PHPCSUtils `UtilityMethodTestCase` directly. Note: The list of included polyfill traits should be reviewed after each new (major/minor) release of the PHPUnit Polyfill library. --- Tests/PolyfilledTestCase.php | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Tests/PolyfilledTestCase.php diff --git a/Tests/PolyfilledTestCase.php b/Tests/PolyfilledTestCase.php new file mode 100644 index 00000000..58af5e3d --- /dev/null +++ b/Tests/PolyfilledTestCase.php @@ -0,0 +1,65 @@ + Date: Sat, 5 Jun 2021 21:28:35 +0200 Subject: [PATCH 4/4] Tests: remove PHPUnit cross-version work-arounds ... in favour of using the PHPUnit Polyfills. --- .../AbstractArrayDeclarationSniffTest.php | 7 +--- Tests/BackCompat/Helper/ConfigDataTest.php | 15 ++----- .../FailedToTokenizeTest.php | 14 ++----- .../MissingCaseFileTest.php | 14 ++----- .../UtilityMethodTestCase/SkipCSJSTest.php | 14 ++----- .../UtilityMethodTestCaseTest.php | 42 ++++--------------- .../MessageHelper/HasNewLineSupportTest.php | 13 ++---- .../GetParametersSkipShortArrayCheckTest.php | 20 ++------- 8 files changed, 34 insertions(+), 105 deletions(-) diff --git a/Tests/AbstractSniffs/AbstractArrayDeclaration/AbstractArrayDeclarationSniffTest.php b/Tests/AbstractSniffs/AbstractArrayDeclaration/AbstractArrayDeclarationSniffTest.php index 1ea377ca..576e17ec 100644 --- a/Tests/AbstractSniffs/AbstractArrayDeclaration/AbstractArrayDeclarationSniffTest.php +++ b/Tests/AbstractSniffs/AbstractArrayDeclaration/AbstractArrayDeclarationSniffTest.php @@ -10,8 +10,7 @@ namespace PHPCSUtils\Tests\AbstractSniffs\AbstractArrayDeclaration; -use PHPCSUtils\Tests\AssertAttributeSame; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; /** * Tests for the \PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff class. @@ -22,10 +21,8 @@ * * @since 1.0.0 */ -class AbstractArrayDeclarationSniffTest extends UtilityMethodTestCase +class AbstractArrayDeclarationSniffTest extends PolyfilledTestCase { - // Backfill for the assertAttributeSame() method on PHPUnit 9.x. - use AssertAttributeSame; /** * List of methods in the abstract which should be mocked. diff --git a/Tests/BackCompat/Helper/ConfigDataTest.php b/Tests/BackCompat/Helper/ConfigDataTest.php index 5677d454..50b4f6d9 100644 --- a/Tests/BackCompat/Helper/ConfigDataTest.php +++ b/Tests/BackCompat/Helper/ConfigDataTest.php @@ -13,6 +13,7 @@ use PHP_CodeSniffer\Config; use PHPCSUtils\BackCompat\Helper; use PHPUnit\Framework\TestCase; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; /** * Test class. @@ -26,6 +27,7 @@ */ class ConfigDataTest extends TestCase { + use ExpectException; /** * Test the getConfigData() and setConfigData() method when used in a cross-version compatible manner. @@ -87,17 +89,8 @@ public function testConfigDataPHPCS4Exception() $this->markTestSkipped('Test only applicable to PHPCS 4.x'); } - $msg = 'Passing the $config parameter is required in PHPCS 4.x'; - $exception = 'PHP_CodeSniffer\Exceptions\RuntimeException'; - - if (\method_exists($this, 'expectException')) { - // PHPUnit 5+. - $this->expectException($exception); - $this->expectExceptionMessage($msg); - } else { - // PHPUnit 4. - $this->setExpectedException($exception, $msg); - } + $this->expectException('PHP_CodeSniffer\Exceptions\RuntimeException'); + $this->expectExceptionMessage('Passing the $config parameter is required in PHPCS 4.x'); Helper::setConfigData('arbitrary_name', 'test', true); } diff --git a/Tests/TestUtils/UtilityMethodTestCase/FailedToTokenizeTest.php b/Tests/TestUtils/UtilityMethodTestCase/FailedToTokenizeTest.php index 39a2af03..b08f7df4 100644 --- a/Tests/TestUtils/UtilityMethodTestCase/FailedToTokenizeTest.php +++ b/Tests/TestUtils/UtilityMethodTestCase/FailedToTokenizeTest.php @@ -10,7 +10,7 @@ namespace PHPCSUtils\Tests\TestUtils\UtilityMethodTestCase; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; /** * Tests for the \PHPCSUtils\TestUtils\UtilityMethodTestCase class. @@ -21,7 +21,7 @@ * * @since 1.0.0 */ -class FailedToTokenizeTest extends UtilityMethodTestCase +class FailedToTokenizeTest extends PolyfilledTestCase { /** @@ -50,14 +50,8 @@ public function testMissingCaseFile() $exception = 'PHPUnit_Framework_AssertionFailedError'; } - if (\method_exists($this, 'expectException')) { - // PHPUnit 5+. - $this->expectException($exception); - $this->expectExceptionMessage($msg); - } else { - // PHPUnit 4. - $this->setExpectedException($exception, $msg); - } + $this->expectException($exception); + $this->expectExceptionMessage($msg); parent::setUpTestFile(); } diff --git a/Tests/TestUtils/UtilityMethodTestCase/MissingCaseFileTest.php b/Tests/TestUtils/UtilityMethodTestCase/MissingCaseFileTest.php index f53d4c87..82befee7 100644 --- a/Tests/TestUtils/UtilityMethodTestCase/MissingCaseFileTest.php +++ b/Tests/TestUtils/UtilityMethodTestCase/MissingCaseFileTest.php @@ -10,7 +10,7 @@ namespace PHPCSUtils\Tests\TestUtils\UtilityMethodTestCase; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; /** * Tests for the \PHPCSUtils\TestUtils\UtilityMethodTestCase class. @@ -21,7 +21,7 @@ * * @since 1.0.0 */ -class MissingCaseFileTest extends UtilityMethodTestCase +class MissingCaseFileTest extends PolyfilledTestCase { /** @@ -50,14 +50,8 @@ public function testMissingCaseFile() $exception = 'PHPUnit_Framework_AssertionFailedError'; } - if (\method_exists($this, 'expectException')) { - // PHPUnit 5+. - $this->expectException($exception); - $this->expectExceptionMessage($msg); - } else { - // PHPUnit 4. - $this->setExpectedException($exception, $msg); - } + $this->expectException($exception); + $this->expectExceptionMessage($msg); parent::setUpTestFile(); } diff --git a/Tests/TestUtils/UtilityMethodTestCase/SkipCSJSTest.php b/Tests/TestUtils/UtilityMethodTestCase/SkipCSJSTest.php index fe19e2b6..362bb062 100644 --- a/Tests/TestUtils/UtilityMethodTestCase/SkipCSJSTest.php +++ b/Tests/TestUtils/UtilityMethodTestCase/SkipCSJSTest.php @@ -10,7 +10,7 @@ namespace PHPCSUtils\Tests\TestUtils\UtilityMethodTestCase; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; /** * Tests for the \PHPCSUtils\TestUtils\UtilityMethodTestCase class. @@ -21,7 +21,7 @@ * * @since 1.0.0 */ -class SkipJSCSSTest extends UtilityMethodTestCase +class SkipJSCSSTest extends PolyfilledTestCase { /** @@ -58,14 +58,8 @@ public function testSkipJsCss() $exception = 'PHPUnit_Framework_SkippedTestError'; } - if (\method_exists($this, 'expectException')) { - // PHPUnit 5+. - $this->expectException($exception); - $this->expectExceptionMessage($msg); - } else { - // PHPUnit 4. - $this->setExpectedException($exception, $msg); - } + $this->expectException($exception); + $this->expectExceptionMessage($msg); } else { // Get rid of the "does not perform assertions" warning when run with PHPCS 3.x. $this->assertTrue(true); diff --git a/Tests/TestUtils/UtilityMethodTestCase/UtilityMethodTestCaseTest.php b/Tests/TestUtils/UtilityMethodTestCase/UtilityMethodTestCaseTest.php index d6e2381e..6ad12b84 100644 --- a/Tests/TestUtils/UtilityMethodTestCase/UtilityMethodTestCaseTest.php +++ b/Tests/TestUtils/UtilityMethodTestCase/UtilityMethodTestCaseTest.php @@ -12,7 +12,7 @@ use PHP_CodeSniffer\Exceptions\RuntimeException; use PHP_CodeSniffer\Exceptions\TokenizerException; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; /** * Tests for the \PHPCSUtils\TestUtils\UtilityMethodTestCase class. @@ -23,7 +23,7 @@ * * @since 1.0.0 */ -class UtilityMethodTestCaseTest extends UtilityMethodTestCase +class UtilityMethodTestCaseTest extends PolyfilledTestCase { /** @@ -51,13 +51,7 @@ public function testSetUp() $this->assertSame(57, self::$phpcsFile->numTokens); $tokens = self::$phpcsFile->getTokens(); - if (\method_exists($this, 'assertIsArray')) { - // PHPUnit 7+. - $this->assertIsArray($tokens); - } else { - // PHPUnit 4/5/6. - $this->assertInternalType('array', $tokens); - } + $this->assertIsArray($tokens); } /** @@ -161,14 +155,8 @@ public function testGetTargetTokenCommentNotFound() $exception = 'PHPUnit_Framework_AssertionFailedError'; } - if (\method_exists($this, 'expectException')) { - // PHPUnit 5+. - $this->expectException($exception); - $this->expectExceptionMessage($msg); - } else { - // PHPUnit 4. - $this->setExpectedException($exception, $msg); - } + $this->expectException($exception); + $this->expectExceptionMessage($msg); $this->getTargetToken('/* testCommentDoesNotExist */', [\T_VARIABLE], '$a'); } @@ -187,14 +175,8 @@ public function testGetTargetTokenNotFound() $exception = 'PHPUnit_Framework_AssertionFailedError'; } - if (\method_exists($this, 'expectException')) { - // PHPUnit 5+. - $this->expectException($exception); - $this->expectExceptionMessage($msg); - } else { - // PHPUnit 4. - $this->setExpectedException($exception, $msg); - } + $this->expectException($exception); + $this->expectExceptionMessage($msg); $this->getTargetToken('/* testNotFindingTarget */', [\T_VARIABLE], '$a'); } @@ -209,14 +191,8 @@ public function testGetTargetTokenNotFoundException() $msg = 'Failed to find test target token for comment string: '; $exception = '\RuntimeException'; - if (\method_exists($this, 'expectException')) { - // PHPUnit 5+. - $this->expectException($exception); - $this->expectExceptionMessage($msg); - } else { - // PHPUnit 4. - $this->setExpectedException($exception, $msg); - } + $this->expectException($exception); + $this->expectExceptionMessage($msg); $this->getTargetToken('/* testNotFindingTarget */', [\T_VARIABLE], '$a', false); } diff --git a/Tests/Utils/MessageHelper/HasNewLineSupportTest.php b/Tests/Utils/MessageHelper/HasNewLineSupportTest.php index dcd7d957..24482dda 100644 --- a/Tests/Utils/MessageHelper/HasNewLineSupportTest.php +++ b/Tests/Utils/MessageHelper/HasNewLineSupportTest.php @@ -12,7 +12,7 @@ use PHP_CodeSniffer\Reporter; use PHP_CodeSniffer\Reports\Full; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; use PHPCSUtils\Utils\MessageHelper; /** @@ -27,7 +27,7 @@ * * @since 1.0.0 */ -class HasNewLineSupportTest extends UtilityMethodTestCase +class HasNewLineSupportTest extends PolyfilledTestCase { /** @@ -54,14 +54,7 @@ class HasNewLineSupportTest extends UtilityMethodTestCase public function testHasNewLineSupport() { $result = MessageHelper::hasNewLineSupport(); - - if (\method_exists($this, 'assertIsBool') === true) { - // PHPUnit >= 7.5. - $this->assertIsBool($result); - } else { - // PHPUnit < 7.5. - $this->assertInternalType('bool', $result); - } + $this->assertIsBool($result); if ($result === false) { return; diff --git a/Tests/Utils/PassedParameters/GetParametersSkipShortArrayCheckTest.php b/Tests/Utils/PassedParameters/GetParametersSkipShortArrayCheckTest.php index 8b2eae5b..464b1ec7 100644 --- a/Tests/Utils/PassedParameters/GetParametersSkipShortArrayCheckTest.php +++ b/Tests/Utils/PassedParameters/GetParametersSkipShortArrayCheckTest.php @@ -10,7 +10,7 @@ namespace PHPCSUtils\Tests\Utils\PassedParameters; -use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use PHPCSUtils\Tests\PolyfilledTestCase; use PHPCSUtils\Utils\PassedParameters; /** @@ -25,7 +25,7 @@ * * @since 1.0.0 */ -class GetParametersSkipShortArrayCheckTest extends UtilityMethodTestCase +class GetParametersSkipShortArrayCheckTest extends PolyfilledTestCase { /** @@ -54,13 +54,7 @@ public function testHasParametersDontSkipShortArrayCheck($testMarker, $targetTyp $hasParams = PassedParameters::hasParameters(self::$phpcsFile, $target); if ($expectException === false) { - if (\method_exists($this, 'assertIsBool') === true) { - // PHPUnit 7.5+. - $this->assertIsBool($hasParams); - } else { - // PHPUnit < 7.5. - $this->assertInternalType('bool', $hasParams); - } + $this->assertIsBool($hasParams); } } @@ -82,13 +76,7 @@ public function testGetParametersSkipShortArrayCheck($testMarker, $targetType, $ $stackPtr = $this->getTargetToken($testMarker, [$targetType]); $result = PassedParameters::getParameters(self::$phpcsFile, $stackPtr, 0, true); - if (\method_exists($this, 'assertIsArray') === true) { - // PHPUnit 7.5+. - $this->assertIsArray($result); - } else { - // PHPUnit < 7.5. - $this->assertInternalType('array', $result); - } + $this->assertIsArray($result); // Start/end token position values in the expected array are set as offsets // in relation to the target token.