diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index 59c33e0cbe..cdf5d02fa5 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -30,7 +30,6 @@ concurrency: env: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: ${{ true }} - COMPOSER_INSTALL: ${{ false }} # Controls which NPM script to use for running PHPUnit tests. Options ar `php` and `php-composer`. PHPUNIT_SCRIPT: php LOCAL_PHP_MEMCACHED: ${{ false }} @@ -133,11 +132,9 @@ jobs: - name: Get composer cache directory id: composer-cache - if: ${{ env.COMPOSER_INSTALL == true || env.LOCAL_PHP == '8.0-fpm' }} run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache Composer dependencies - if: ${{ env.COMPOSER_INSTALL == true || env.LOCAL_PHP == '8.0-fpm' }} uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 env: cache-name: cache-composer-dependencies @@ -146,7 +143,6 @@ jobs: key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }} - name: Install Composer dependencies - if: ${{ env.COMPOSER_INSTALL == true || env.LOCAL_PHP == '8.0-fpm' }} run: | docker-compose run --rm php composer --version @@ -156,6 +152,12 @@ jobs: if [ ${{ env.LOCAL_PHP }} == '8.0-fpm' ]; then docker-compose run --rm php composer install --ignore-platform-reqs echo "PHPUNIT_SCRIPT=php-composer" >> $GITHUB_ENV + elif [ ${{ env.LOCAL_PHP }} == '7.1-fpm' ]; then + docker-compose run --rm php composer update + git checkout -- composer.lock + elif [[ ${{ env.LOCAL_PHP }} == '5.6.20-fpm' || ${{ env.LOCAL_PHP }} == '7.0-fpm' ]]; then + docker-compose run --rm php composer require --dev phpunit/phpunit:"^5.7" --update-with-dependencies + git checkout -- composer.lock composer.json else docker-compose run --rm php composer install fi diff --git a/.github/workflows/test-coverage.yml b/.github/workflows/test-coverage.yml index ad413bc0c0..f9733c5a93 100644 --- a/.github/workflows/test-coverage.yml +++ b/.github/workflows/test-coverage.yml @@ -18,7 +18,6 @@ on: env: PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: ${{ true }} - COMPOSER_INSTALL: ${{ false }} # Controls which NPM script to use for running PHPUnit tests. Options ar `php` and `php-composer`. PHPUNIT_SCRIPT: php LOCAL_PHP: '7.4-fpm' @@ -97,6 +96,23 @@ jobs: - name: Install Dependencies run: npm ci + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache Composer dependencies + uses: actions/cache@26968a09c0ea4f3e233fdddbafd1166051a095f6 # v2.1.4 + env: + cache-name: cache-composer-dependencies + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }} + + - name: Install Composer dependencies + run: | + docker-compose run --rm php composer --version + docker-compose run --rm php composer install + - name: Docker debug information run: | docker -v diff --git a/composer.json b/composer.json index 4997175bfe..430c1069eb 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0", "wp-coding-standards/wpcs": "~2.3.0", "phpcompatibility/phpcompatibility-wp": "^2.1.0", - "phpunit/phpunit": "^7.5" + "phpunit/phpunit": "^7.5", + "yoast/phpunit-polyfills": "^1.0.1" }, "autoload-dev": { "files": [ diff --git a/composer.lock b/composer.lock index 007bbf83ea..e7dafe626b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "463db2b4afb439fb63d93173c0852e27", + "content-hash": "d8bcbf1466f6595287a44721f525844d", "packages": [], "packages-dev": [ { @@ -1827,6 +1827,69 @@ "wordpress" ], "time": "2020-05-13T23:57:56+00:00" + }, + { + "name": "yoast/phpunit-polyfills", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", + "reference": "f014fb21c2b0038fd329515d59025af42fb98715" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/f014fb21c2b0038fd329515d59025af42fb98715", + "reference": "f014fb21c2b0038fd329515d59025af42fb98715", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + }, + "require-dev": { + "php-parallel-lint/php-console-highlighter": "^0.5", + "php-parallel-lint/php-parallel-lint": "^1.3.0", + "yoast/yoastcs": "^2.1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev", + "dev-develop": "1.x-dev" + } + }, + "autoload": { + "files": [ + "phpunitpolyfills-autoload.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Team Yoast", + "email": "support@yoast.com", + "homepage": "https://yoast.com" + }, + { + "name": "Contributors", + "homepage": "https://github.com/Yoast/PHPUnit-Polyfills/graphs/contributors" + } + ], + "description": "Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit cross-version compatible tests", + "homepage": "https://github.com/Yoast/PHPUnit-Polyfills", + "keywords": [ + "phpunit", + "polyfill", + "testing" + ], + "support": { + "issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues", + "source": "https://github.com/Yoast/PHPUnit-Polyfills" + }, + "time": "2021-08-09T16:28:08+00:00" } ], "aliases": [], @@ -1838,5 +1901,5 @@ "php": ">=5.6" }, "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.1.0" } diff --git a/tests/phpunit/includes/bootstrap.php b/tests/phpunit/includes/bootstrap.php index f059590ac1..ab32c13d0e 100644 --- a/tests/phpunit/includes/bootstrap.php +++ b/tests/phpunit/includes/bootstrap.php @@ -44,15 +44,122 @@ if ( defined( 'WP_RUN_CORE_TESTS' ) && WP_RUN_CORE_TESTS && ! is_dir( ABSPATH ) $phpunit_version = tests_get_phpunit_version(); -if ( version_compare( $phpunit_version, '5.4', '<' ) || version_compare( $phpunit_version, '8.0', '>=' ) ) { +if ( version_compare( $phpunit_version, '5.7.21', '<' ) || version_compare( $phpunit_version, '8.0', '>=' ) ) { printf( - "Error: Looks like you're using PHPUnit %s. WordPress requires at least PHPUnit 5.4 and is currently only compatible with PHPUnit up to 7.x.\n", + "Error: Looks like you're using PHPUnit %s. WordPress requires at least PHPUnit 5.7.21 and is currently only compatible with PHPUnit up to 7.x.\n", $phpunit_version ); echo "Please use the latest PHPUnit version from the 7.x branch.\n"; exit( 1 ); } +/* + * Load the PHPUnit Polyfills autoloader. + * + * The PHPUnit Polyfills are a requirement for the WP test suite. + * + * For running the Core tests, the Make WordPress Core handbook contains step-by-step instructions + * on how to get up and running for a variety of supported workflows: + * {@link https://make.wordpress.org/core/handbook/testing/automated-testing/phpunit/#test-running-workflow-options} + * + * Plugin/theme integration tests can handle this in any of the following ways: + * - When using a full WP install: run `composer install` for the WP install prior to running the tests. + * - When using a partial WP test suite install: + * - Add a `yoast/phpunit-polyfills` (dev) requirement to the plugin/theme's own `composer.json` file. + * - And then: + * - Either load the PHPUnit Polyfills autoload file prior to running the WP core bootstrap file. + * - Or declare a `WP_TESTS_PHPUNIT_POLYFILLS_PATH` constant containing the absolute path to the + * root directory of the PHPUnit Polyfills installation. + * If the constant is used, it is strongly recommended to declare this constant in the plugin/theme's + * own test bootstrap file. + * The constant MUST be declared prior to calling this file. + */ +if ( ! class_exists( 'Yoast\PHPUnitPolyfills\Autoload' ) ) { + // Default location of the autoloader for WP core test runs. + $phpunit_polyfills_autoloader = dirname( dirname( dirname( __DIR__ ) ) ) . '/vendor/yoast/phpunit-polyfills/phpunitpolyfills-autoload.php'; + $phpunit_polyfills_error = false; + + // Allow for a custom installation location to be provided for plugin/theme integration tests. + if ( defined( 'WP_TESTS_PHPUNIT_POLYFILLS_PATH' ) ) { + $phpunit_polyfills_path = WP_TESTS_PHPUNIT_POLYFILLS_PATH; + + if ( is_string( WP_TESTS_PHPUNIT_POLYFILLS_PATH ) + && '' !== WP_TESTS_PHPUNIT_POLYFILLS_PATH + ) { + // Be tolerant to the path being provided including the filename. + if ( substr( $phpunit_polyfills_path, -29 ) !== 'phpunitpolyfills-autoload.php' ) { + $phpunit_polyfills_path = rtrim( $phpunit_polyfills_path, '/\\' ); + $phpunit_polyfills_path = $phpunit_polyfills_path . '/phpunitpolyfills-autoload.php'; + } + + $phpunit_polyfills_autoloader = $phpunit_polyfills_path; + } else { + $phpunit_polyfills_error = true; + } + } + + if ( $phpunit_polyfills_error || ! file_exists( $phpunit_polyfills_autoloader ) ) { + echo 'Error: The PHPUnit Polyfills library is a requirement for running the WP test suite.' . PHP_EOL; + if ( defined( 'WP_TESTS_PHPUNIT_POLYFILLS_PATH' ) ) { + printf( + 'The PHPUnit Polyfills autoload file was not found in "%s"' . PHP_EOL, + WP_TESTS_PHPUNIT_POLYFILLS_PATH + ); + echo 'Please verify that the file path provided in the WP_TESTS_PHPUNIT_POLYFILLS_PATH constant is correct.' . PHP_EOL; + echo 'The WP_TESTS_PHPUNIT_POLYFILLS_PATH constant should contain an absolute path to the root directory' + . ' of the PHPUnit Polyfills library.' . PHP_EOL; + } elseif ( defined( 'WP_RUN_CORE_TESTS' ) && WP_RUN_CORE_TESTS ) { + echo 'You need to run `composer install` before running the tests.' . PHP_EOL; + echo 'Once the dependencies are installed, you can run the tests using the Composer-installed version' + . ' of PHPUnit or using a PHPUnit phar file, but the dependencies do need to be installed' + . ' whichever way the tests are run.' . PHP_EOL; + } else { + echo 'If you are trying to run plugin/theme integration tests, make sure the PHPUnit Polyfills library' + . ' (https://github.com/Yoast/PHPUnit-Polyfills) is available and either load the autoload file' + . ' of this library in your own test bootstrap before calling the WP Core test bootstrap file;' + . ' or set the absolute path to the PHPUnit Polyfills library in a "WP_TESTS_PHPUNIT_POLYFILLS_PATH"' + . ' constant to allow the WP Core bootstrap to load the Polyfills.' . PHP_EOL . PHP_EOL; + echo 'If you are trying to run the WP Core tests, make sure to set the "WP_RUN_CORE_TESTS" constant' + . ' to 1 and run `composer install` before running the tests.' . PHP_EOL; + echo 'Once the dependencies are installed, you can run the tests using the Composer-installed' + . ' version of PHPUnit or using a PHPUnit phar file, but the dependencies do need to be' + . ' installed whichever way the tests are run.' . PHP_EOL; + } + exit( 1 ); + } + + require_once $phpunit_polyfills_autoloader; +} +unset( $phpunit_polyfills_autoloader, $phpunit_polyfills_error, $phpunit_polyfills_path ); + +/* + * Minimum version of the PHPUnit Polyfills package as declared in `composer.json`. + * Only needs updating when new polyfill features start being used in the test suite. + */ +$phpunit_polyfills_minimum_version = '1.0.1'; +if ( class_exists( '\Yoast\PHPUnitPolyfills\Autoload' ) + && ( defined( '\Yoast\PHPUnitPolyfills\Autoload::VERSION' ) === false + || version_compare( Yoast\PHPUnitPolyfills\Autoload::VERSION, $phpunit_polyfills_minimum_version, '<' ) ) +) { + printf( + 'Error: Version mismatch detected for the PHPUnit Polyfills.' + . ' Please ensure that PHPUnit Polyfills %s or higher is loaded. Found version: %s' . PHP_EOL, + $phpunit_polyfills_minimum_version, + defined( '\Yoast\PHPUnitPolyfills\Autoload::VERSION' ) ? Yoast\PHPUnitPolyfills\Autoload::VERSION : '1.0.0 or lower' + ); + if ( defined( 'WP_TESTS_PHPUNIT_POLYFILLS_PATH' ) ) { + printf( + 'Please ensure that the PHPUnit Polyfill installation in "%s" is updated to version %s or higher.' . PHP_EOL, + WP_TESTS_PHPUNIT_POLYFILLS_PATH, + $phpunit_polyfills_minimum_version + ); + } elseif ( defined( 'WP_RUN_CORE_TESTS' ) && WP_RUN_CORE_TESTS ) { + echo 'Please run `composer install` to install the latest version.' . PHP_EOL; + } + exit( 1 ); +} +unset( $phpunit_polyfills_minimum_version ); + // If running core tests, check if all the required PHP extensions are loaded before running the test suite. if ( defined( 'WP_RUN_CORE_TESTS' ) && WP_RUN_CORE_TESTS ) { $required_extensions = array( diff --git a/tests/phpunit/includes/phpunit7/testcase.php b/tests/phpunit/includes/phpunit7/testcase.php index 84ddbd5be1..1174b85494 100644 --- a/tests/phpunit/includes/phpunit7/testcase.php +++ b/tests/phpunit/includes/phpunit7/testcase.php @@ -1,5 +1,21 @@