diff --git a/.gitattributes b/.gitattributes index 67ccd8e..a10e455 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,6 +14,7 @@ /.remarkignore export-ignore /.remarkrc export-ignore /phpunit.xml.dist export-ignore +/phpunit10.xml.dist export-ignore /tests/ export-ignore # diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e78719f..6680105 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,6 +15,8 @@ updates: prefix: "GH Actions:" labels: - "Type: chores/QA" + reviewers: + - "jrfnl" # Maintain dependencies for Composer. - package-ecosystem: "composer" @@ -27,3 +29,5 @@ updates: prefix: "Composer:" labels: - "Type: chores/QA" + reviewers: + - "jrfnl" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 01d05c7..9f220b6 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: - php: ['5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] + php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] continue-on-error: ${{ matrix.php == '8.3' }} @@ -36,6 +36,7 @@ jobs: php-version: ${{ matrix.php }} ini-values: zend.assertions=1, error_reporting=-1, display_errors=On coverage: none + tools: cs2pr - name: 'Composer: remove PHPUnit (not needed for lint)' run: composer remove phpunit/phpunit --no-update --no-interaction @@ -59,7 +60,7 @@ jobs: - name: "Lint PHP files against parse errors - PHP < 7.0" if: ${{ matrix.php < 7.0 }} - run: composer lint-lt70 + run: composer lint-lt70 -- --checkstyle | cs2pr - name: "Lint PHP files against parse errors - PHP 7.x" if: ${{ startsWith( matrix.php, '7' ) }} @@ -67,4 +68,4 @@ jobs: - name: "Lint PHP files against parse errors - PHP >= 8.0" if: ${{ matrix.php >= 8.0 }} - run: composer lint-gte80 + run: composer lint-gte80 -- --checkstyle | cs2pr diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml index d7b3435..7c50279 100644 --- a/.github/workflows/markdown.yml +++ b/.github/workflows/markdown.yml @@ -84,6 +84,7 @@ jobs: remark-preset-lint-markdown-style-guide remark-lint-checkbox-content-indent remark-lint-linebreak-style + remark-lint-no-dead-urls remark-lint-no-empty-url remark-lint-no-heading-like-paragraph remark-lint-no-reference-like-url @@ -94,7 +95,6 @@ jobs: remark-lint-list-item-punctuation remark-lint-match-punctuation remark-lint-no-hr-after-heading - remark-lint-are-links-valid-alive remark-lint-are-links-valid-duplicate remark-validate-links diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9f54d16..6fd555f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,64 +20,92 @@ jobs: strategy: matrix: - php: ['5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] + php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] phpunit: ['auto'] + coverage: [true] experimental: [false] include: # Test against a version on the low-end of the PHPUnit versions supported for each PHP version. - # On PHP 5.4 and 5.5, only PHPUnit 4.x is supported and the lowest and the - # highest supported version would be the same. # Using the Composer `--prefer-lowest` option is, unfortunately, not viable, as - # PHPUnit 4.8.36 doesn't have proper PHP restrictions, which means that it - # would always be installed as "low", which would break the builds for PHP 7.2+. + # it would result PHP 5.6 - 7.4 all using PHPUnit 5.7.21, 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.. - php: '5.6' phpunit: '5.7.21' + coverage: true experimental: false - php: '7.0' phpunit: '5.7.27' + coverage: true experimental: false - php: '7.1' phpunit: '5.7.21' + coverage: true experimental: false - php: '7.2' phpunit: '6.3.1' + coverage: true experimental: false - php: '7.3' phpunit: '7.2.7' + coverage: true experimental: false - php: '7.4' phpunit: '8.1.6' + coverage: true experimental: false - php: '8.0' phpunit: '8.5.16' + # PHPUnit 8.x does not support code coverage on PHP 8.x. + coverage: false experimental: false - php: '8.0' phpunit: '9.3.0' + coverage: true experimental: false - php: '8.1' phpunit: '9.3.0' + coverage: true + experimental: false + - php: '8.1' + # Specifically set at 10.0.12 minimum to prevent needing a toggle in the tests for something + # related to the ArrayIsList polyfill, but not necessarily relevant. + phpunit: '10.0.12' + coverage: true experimental: false - php: '8.2' phpunit: '9.3.0' + coverage: true + experimental: false + - php: '8.2' + phpunit: '10.1.0' + coverage: true experimental: false # Experimental builds. - php: '8.3' - phpunit: 'auto' # PHPUnit 9.x. + phpunit: '^9.6' + coverage: false experimental: true - - - php: '8.1' - phpunit: '^10.0' + - php: '8.3' + phpunit: 'auto' # PHPUnit 10.x. + coverage: false experimental: true + - php: '8.2' - phpunit: '^10.0' + phpunit: 'dev-main' + coverage: false experimental: true name: "Tests: PHP ${{ matrix.php }} - PHPUnit: ${{matrix.phpunit}}" continue-on-error: ${{ matrix.experimental }} + env: + EXTRA_PHPUNIT_CLIARGS: '--fail-on-deprecation --fail-on-notice' + steps: - name: Checkout code uses: actions/checkout@v3 @@ -87,7 +115,7 @@ jobs: with: php-version: ${{ matrix.php }} ini-values: zend.assertions=1, error_reporting=-1, display_errors=On - coverage: none + coverage: ${{ matrix.coverage == true && 'xdebug' || 'none' }} - name: 'Composer: set PHPUnit version for tests' if: ${{ matrix.phpunit != 'auto' }} @@ -110,11 +138,68 @@ jobs: # Bust the cache at least once a month - output format: YYYY-MM. custom-cache-suffix: $(date -u "+%Y-%m") - - name: Run the unit tests - if: ${{ matrix.phpunit != '^10.0' }} + - name: Grab PHPUnit version + id: phpunit_version + run: echo "VERSION=$(vendor/bin/phpunit --version | grep --only-matching --max-count=1 --extended-regexp '\b[0-9]+\.[0-9]+')" >> $GITHUB_OUTPUT + + - name: "DEBUG: Show grabbed version" + run: echo ${{ steps.phpunit_version.outputs.VERSION }} + + - name: "Run the unit tests (PHPUnit < 10)" + if: ${{ matrix.coverage == false && ! startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }} run: composer test - - name: Trial run the unit tests against PHPUnit 10.0 - if: ${{ matrix.phpunit == '^10.0' }} + - name: "Run the unit tests with code coverage (PHPUnit < 10)" + if: ${{ matrix.coverage == true && ! startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }} + run: composer coverage + + # Migrate PHPUnit configuration to deal with changes in the coverage/source setting across PHPUnit 10.x + # versions as otherwise the warning about these would fail the build (which to me, feels like a bug). + - name: "Migrate configuration (PHPUnit 10.0+)" continue-on-error: true - run: composer test + if: ${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) && steps.phpunit_version.outputs.VERSION != '10.0' }} + run: vendor/bin/phpunit -c phpunit10.xml.dist --migrate-configuration + + - name: "Run the unit tests (PHPUnit 10.0+)" + if: ${{ matrix.coverage == false && startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }} + # Don't fail the build on a test run failure against a future PHPUnit version. + continue-on-error: ${{ matrix.phpunit == 'dev-main' }} + run: composer test10 -- ${{ steps.phpunit_version.outputs.VERSION != '10.0' && env.EXTRA_PHPUNIT_CLIARGS || '' }} + + - name: "Run the unit tests with code coverage (PHPUnit 10.0+)" + if: ${{ matrix.coverage == true && startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }} + # Don't fail the build on a test run failure against a future PHPUnit version. + continue-on-error: ${{ matrix.phpunit == 'dev-main' }} + run: composer coverage10 -- ${{ steps.phpunit_version.outputs.VERSION != '10.0' && env.EXTRA_PHPUNIT_CLIARGS || '' }} + + # PHP Coveralls doesn't fully support PHP 8.x yet, so switch the PHP version. + - name: Switch to PHP 7.4 + if: ${{ success() && matrix.coverage == true && startsWith( matrix.php, '8' ) }} + uses: shivammathur/setup-php@v2 + with: + php-version: 7.4 + coverage: none + + # Global install is used to prevent a conflict with the local composer.lock in PHP 8.0+. + - name: Install Coveralls + if: ${{ success() && matrix.coverage == true }} + run: composer global require php-coveralls/php-coveralls:"^2.5.3" --no-interaction + + - name: Upload coverage results to Coveralls + if: ${{ success() && matrix.coverage == true }} + env: + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }} + COVERALLS_PARALLEL: true + COVERALLS_FLAG_NAME: php-${{ matrix.php }}-phpunit-${{ matrix.phpunit }} + run: php-coveralls -v -x build/logs/clover.xml + + coveralls-finish: + needs: test + runs-on: ubuntu-latest + + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@v2 + with: + github-token: ${{ secrets.COVERALLS_TOKEN }} + parallel-finished: true diff --git a/.gitignore b/.gitignore index 179ad62..3e1a979 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,6 @@ vendor/ /phpcs.xml .cache/phpcs.cache /phpunit.xml +/phpunit10.xml /.phpunit.result.cache /build/ diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist index 96089f1..d55960a 100644 --- a/.phpcs.xml.dist +++ b/.phpcs.xml.dist @@ -130,12 +130,6 @@ /src/TestListeners/TestListenerDefaultImplementationPHPUnitGte7\.php$ - - - /src/Polyfills/AssertFileDirectory\.php$ - /src/Polyfills/ExpectException\.php$ - - /tests/*\.php$ diff --git a/.remarkrc b/.remarkrc index e54bb8b..a753aef 100644 --- a/.remarkrc +++ b/.remarkrc @@ -8,6 +8,14 @@ ["remark-lint-linebreak-style", "unix"], ["remark-lint-link-title-style", "\""], ["remark-lint-ordered-list-marker-style", "."], + [ + "remark-lint-no-dead-urls", + { + "skipUrlPatterns": [ + "^https?://github\\.com/Yoast/PHPUnit-Polyfills/compare/[0-9\\.]+?\\.{3}[0-9\\.]+" + ] + } + ], "remark-lint-no-duplicate-definitions", "remark-lint-no-empty-url", "remark-lint-no-file-name-consecutive-dashes", @@ -28,7 +36,6 @@ "remark-lint-list-item-punctuation", "remark-lint-match-punctuation", "remark-lint-no-hr-after-heading", - "remark-lint-are-links-valid-alive", "remark-lint-are-links-valid-duplicate", "remark-validate-links" ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 24a8c92..8825a53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,64 @@ This projects adheres to [Keep a CHANGELOG](http://keepachangelog.com/) and uses _Nothing yet._ +## [2.0.0] - 2023-06-06 + +### PHPUnit 10 support + +This release updates the PHPUnit Polyfills to allow for _"writing your tests for PHPUnit 10 and running them all the way back to PHPUnit 5"_. + +Please keep in mind that the PHPUnit Polyfills provide _forward_-compatibility. This means that features which PHPUnit no longer supports in PHPUnit 10.x, like expecting PHP deprecation notices or warnings, are also no longer supported in the 2.0 release of the PHPUnit Polyfills. + +Please refer to the [PHPUnit 10 release notification] and [PHPUnit 10 changelog] to inform your decision on whether or not to upgrade (yet). + +Projects which don't use any of the new or removed functionality in their test suite, can, of course, use the PHPUnit Polyfills 1.x and 2.x series side-by-side, like so `composer require --dev yoast/phpunit-polyfills:"^1.0 || ^2.0"`. + +[PHPUnit 10 release notification]: https://phpunit.de/announcements/phpunit-10.html +[PHPUnit 10 changelog]: https://github.com/sebastianbergmann/phpunit/blob/10.0.19/ChangeLog-10.0.md + +> :warning: **Important: about the TestListener polyfill** :warning: +> +> The TestListener polyfill in PHPUnit Polyfills 2.0 is **[not (yet) compatible with PHPUnit 10.0.0][polyfill-ticket]**. +> +> If you need the TestListener polyfill, it is recommended to stay on the PHPUnit Polyfills 1.x series for the time being and to watch the [related ticket][polyfill-ticket]. + +[polyfill-ticket]: https://github.com/Yoast/PHPUnit-Polyfills/issues/128 + + +### Changelog + +#### Added +* `Yoast\PHPUnitPolyfills\Polyfills\AssertIgnoringLineEndings` trait to polyfill the `Assert::assertStringEqualsStringIgnoringLineEndings()` and the `Assert::assertStringContainsStringIgnoringLineEndings()` methods as introduced in PHPUnit 10.0.0. PR [#109]. +* `Yoast\PHPUnitPolyfills\Polyfills\AssertIsList` trait to polyfill the `Assert::assertIsList()` method as introduced in PHPUnit 10.0.0. PR [#110]. +* `Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty` trait to polyfill the `Assert::assertObjectHasProperty()` and the `Assert::assertObjectNotHasProperty()` methods as introduced in PHPUnit 10.1.0. PR [#116]. + +#### Changed +* Composer: allow for installation of PHPUnit 10.x. PR [#130] +* Nearly all assertion methods are now `final`. This alignes them with the same change made upstream in PHPUnit 10.0.0. PR [#104]. +* General housekeeping. + +#### Removed +* Support for PHP < 5.6. PR [#102]. +* Support for PHPUnit < 5.7.21. PR [#102]. +* Support for expecting PHP deprecations, notices, warnings and error via the `Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException` trait. PR [#108]. + The trait has been removed completely as PHPUnit 10 no longer supports this functionality. +* The `Yoast\PHPUnitPolyfills\Polyfills\AssertNumericType` trait which is no longer needed now support for PHPUnit < 5.7 has been dropped. PR [#102]. +* The `Yoast\PHPUnitPolyfills\Polyfills\ExpectException` trait which is no longer needed now support for PHPUnit < 5.7 has been dropped. PR [#102]. +* The `Yoast\PHPUnitPolyfills\Polyfills\AssertFileDirectory` trait which is no longer needed now support for PHPUnit < 5.7 has been dropped. PR [#102]. + +[#102]: https://github.com/Yoast/PHPUnit-Polyfills/pull/102 +[#104]: https://github.com/Yoast/PHPUnit-Polyfills/pull/104 +[#108]: https://github.com/Yoast/PHPUnit-Polyfills/pull/108 +[#109]: https://github.com/Yoast/PHPUnit-Polyfills/pull/109 +[#110]: https://github.com/Yoast/PHPUnit-Polyfills/pull/110 +[#116]: https://github.com/Yoast/PHPUnit-Polyfills/pull/116 +[#130]: https://github.com/Yoast/PHPUnit-Polyfills/pull/130 + + ## [1.0.5] - 2023-03-31 ### Fixed -* A custom `$message` parameter passed to an assertion, will no longer overrule an emulated "assertion failed" message, but will be prefixed to it instead. PR [#97] +* A custom `$message` parameter passed to an assertion, will no longer overrule an emulated "assertion failed" message, but will be prefixed to it instead. PR [#97]. This applies to the following polyfills: - `assertIsClosedResource()` - `assertIsNotClosedResource()` @@ -27,9 +81,9 @@ _Nothing yet._ ### Changed * The `develop` branch has been removed. Development will now take place in the `1.x` and `2.x` branches. -* README: links to the PHPUnit manual now point explicitly to the PHPUnit 9.x documentation. PR [#94] -* README: new sub-section about PHPUnit version support. PR [#99] -* README: various minor improvements. PRs [#92], [#93] +* README: links to the PHPUnit manual now point explicitly to the PHPUnit 9.x documentation. PR [#94]. +* README: new sub-section about PHPUnit version support. PR [#99]. +* README: various minor improvements. PRs [#92], [#93]. * General housekeeping. [#92]: https://github.com/Yoast/PHPUnit-Polyfills/pull/92 @@ -70,14 +124,14 @@ This is a maintenance release. As of version 2.15.0 of the `shivammathur/setup-php` action for GitHub Actions, the PHPUnit Polyfills can be installed directly from this action using the `tools` key. ### Added -* README: FAQ section about installing and using the library via the `shivammathur/setup-php` action. PR [#52] +* README: FAQ section about installing and using the library via the `shivammathur/setup-php` action. PR [#52]. ### Changed * README: minor textual clarifications and improvements. PRs [#52], [#54], props [Pierre Gordon]. * General housekeeping. ### Fixed -* Autoloader: improved compatibility with packages which create a `class_alias` for the `PHPUnit_Runner_Version` or `PHPUnit\Runner\Version` class. PR [#59] +* Autoloader: improved compatibility with packages which create a `class_alias` for the `PHPUnit_Runner_Version` or `PHPUnit\Runner\Version` class. PR [#59]. [#52]: https://github.com/Yoast/PHPUnit-Polyfills/pull/52 [#54]: https://github.com/Yoast/PHPUnit-Polyfills/pull/54 @@ -156,6 +210,7 @@ Initial release. [Unreleased]: https://github.com/Yoast/PHPUnit-Polyfills/compare/main...HEAD +[2.0.0]: https://github.com/Yoast/PHPUnit-Polyfills/compare/1.0.5...2.0.0 [1.0.5]: https://github.com/Yoast/PHPUnit-Polyfills/compare/1.0.4...1.0.5 [1.0.4]: https://github.com/Yoast/PHPUnit-Polyfills/compare/1.0.3...1.0.4 [1.0.3]: https://github.com/Yoast/PHPUnit-Polyfills/compare/1.0.2...1.0.3 diff --git a/README.md b/README.md index 236c07c..9282c0b 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ PHPUnit Polyfills [![CS Build Status](https://github.com/Yoast/PHPUnit-Polyfills/actions/workflows/cs.yml/badge.svg)](https://github.com/Yoast/PHPUnit-Polyfills/actions/workflows/cs.yml) [![Lint Build Status](https://github.com/Yoast/PHPUnit-Polyfills/actions/workflows/lint.yml/badge.svg)](https://github.com/Yoast/PHPUnit-Polyfills/actions/workflows/lint.yml) [![Test Build Status](https://github.com/Yoast/PHPUnit-Polyfills/actions/workflows/test.yml/badge.svg)](https://github.com/Yoast/PHPUnit-Polyfills/actions/workflows/test.yml) +[![Coverage Status](https://coveralls.io/repos/github/Yoast/PHPUnit-Polyfills/badge.svg?branch=2.x)](https://coveralls.io/github/Yoast/PHPUnit-Polyfills?branch=2.x) + [![Minimum PHP Version](https://img.shields.io/packagist/php-v/yoast/phpunit-polyfills.svg?maxAge=3600)](https://packagist.org/packages/yoast/phpunit-polyfills) [![License: BSD3](https://poser.pugx.org/yoast/phpunit-polyfills/license)](https://github.com/Yoast/PHPUnit-Polyfills/blob/main/LICENSE) @@ -18,7 +20,7 @@ Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit - [PHPUnit support](#phpunit-support) * [Using this library](#using-this-library) - [Supported ways of calling the assertions](#supported-ways-of-calling-the-assertions) - - [Use with PHPUnit < 5.7.0](#use-with-phpunit--570) + - [Use with PHPUnit < 7.5.0](#use-with-phpunit--750) * [Features](#features) - [Polyfill traits](#polyfill-traits) - [Helper traits](#helper-traits) @@ -32,8 +34,8 @@ Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit Requirements ------------ -* PHP 5.4 or higher. -* [PHPUnit] 4.8 - 9.x (automatically required via Composer). +* PHP 5.6 or higher. +* [PHPUnit] 5.7 - 10.x (automatically required via Composer). [PHPUnit]: https://packagist.org/packages/phpunit/phpunit @@ -43,7 +45,7 @@ Installation To install this package, run: ```bash -composer require --dev yoast/phpunit-polyfills:"^1.0" +composer require --dev yoast/phpunit-polyfills:"^2.0" ``` To update this package, run: @@ -63,7 +65,7 @@ Why use the PHPUnit Polyfills? This library is set up to allow for creating PHPUnit cross-version compatible tests by offering a number of polyfills for functionality which was introduced, split up or renamed in PHPUnit. -### Write your tests for PHPUnit 9.x and run them on PHPUnit 4.8 - 9.x +### Write your tests for PHPUnit 10.x and run them on PHPUnit 5.7 - 10.x The polyfills have been setup to allow tests to be _forward_-compatible. What that means is, that your tests can use the assertions supported by the _latest_ PHPUnit version, even when running on older PHPUnit versions. @@ -81,7 +83,7 @@ This means that features which PHPUnit no longer supports in PHPUnit 10.x, like Please refer to the [PHPUnit 10 release notification] and [PHPUnit 10 changelog] to inform your decision on whether or not to upgrade (yet). [PHPUnit 10 release notification]: https://phpunit.de/announcements/phpunit-10.html -[PHPUnit 10 changelog]: https://github.com/sebastianbergmann/phpunit/blob/main/ChangeLog-10.0.md +[PHPUnit 10 changelog]: https://github.com/sebastianbergmann/phpunit/blob/10.0.19/ChangeLog-10.0.md Using this library @@ -146,43 +148,43 @@ The polyfills in this library support the first two ways of calling the assertio For the polyfills to work, a test class is **required** to be a (grand-)child of the PHPUnit native `TestCase` class. -[four ways of calling assertions]: https://docs.phpunit.de/en/9.6/assertions.html#static-vs-non-static-usage-of-assertion-methods +[four ways of calling assertions]: https://docs.phpunit.de/en/main/assertions.html#static-vs-non-static-usage-of-assertion-methods -### Use with PHPUnit < 5.7.0 +### Use with PHPUnit < 7.5.0 -If your library still needs to support PHP < 5.6 and therefore needs PHPUnit 4 for testing, there are a few caveats when using the traits stand-alone as we then enter "double-polyfill" territory. +If your library still needs to support PHP < 7.1 and therefore needs PHPUnit < 7 for testing, there are a few caveats when using the traits stand-alone as we then enter "double-polyfill" territory. To prevent _"conflicting method names"_ errors when a trait is `use`d multiple times in a class, the traits offered here do not attempt to solve this. You will need to make sure to `use` any additional traits needed for the polyfills to work. -| PHPUnit | When `use`-ing this trait | You also need to `use` this trait | -|-----------|---------------------------------|-----------------------------------| -| 4.8 < 5.2 | `ExpectExceptionObject` | `ExpectException` | -| 4.8 < 5.2 | `ExpectPHPException` | `ExpectException` | -| 4.8 < 5.2 | `ExpectExceptionMessageMatches` | `ExpectException` | -| 4.8 < 5.6 | `AssertionRenames` | `AssertFileDirectory` | +| PHPUnit | When `use`-ing this trait | You also need to `use` this trait | +|-----------|-----------------------------|-----------------------------------| +| 5.7 < 7.5 | `AssertIgnoringLineEndings` | `AssertStringContains` | _**Note: this only applies to the stand-alone use of the traits. The [`TestCase` classes](#testcases) provided by this library already take care of this automatically.**_ -Code example testing for a PHP native warning in a test which needs to be able to run on PHPUnit 4.8: +Code example for a test using the `AssertIgnoringLineEndings` trait, which needs to be able to run on PHPUnit 5.7: ```php expectWarningMessage( 'A non-numeric value encountered' ); + $this->assertStringContainsStringIgnoringLineEndings( + "something\nelse", + "this is something\r\nelse" + ); } } ``` @@ -193,72 +195,13 @@ Features ### Polyfill traits -#### PHPUnit < 5.0.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertNumericType` - -Polyfills the following methods: -| | | | -|----------------------------|------------------------------|-------------------------| -| [`Assert::assertFinite()`] | [`Assert::assertInfinite()`] | [`Assert::assertNan()`] | - -These methods were introduced in PHPUnit 5.0.0. - -[`Assert::assertFinite()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertinfinite -[`Assert::assertInfinite()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertinfinite -[`Assert::assertNan()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertnan - -#### PHPUnit < 5.2.0: `Yoast\PHPUnitPolyfills\Polyfills\ExpectException` - -Polyfills the following methods: -| | | -|-------------------------------------|----------------------------------------------| -| [`TestCase::expectException()`] | [`TestCase::expectExceptionMessage()`] | -| [`TestCase::expectExceptionCode()`] | [`TestCase::expectExceptionMessageRegExp()`] | - -These methods were introduced in PHPUnit 5.2.0 as alternatives to the `Testcase::setExpectedException()` method which was deprecated in PHPUnit 5.2.0 and the `Testcase::setExpectedExceptionRegExp()` method which was deprecated in 5.6.0. -Both these methods were removed in PHPUnit 6.0.0. - -[`TestCase::expectException()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-exceptions -[`TestCase::expectExceptionMessage()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-exceptions -[`TestCase::expectExceptionCode()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-exceptions -[`TestCase::expectExceptionMessageRegExp()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-exceptions - -#### PHPUnit < 5.6.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertFileDirectory` - -Polyfills the following methods: -| | | -|-----------------------------------------|--------------------------------------------| -| [`Assert::assertIsReadable()`] | [`Assert::assertNotIsReadable()`] | -| [`Assert::assertIsWritable()`] | [`Assert::assertNotIsWritable()`] | -| [`Assert::assertDirectoryExists()`] | [`Assert::assertDirectoryNotExists()`] | -| [`Assert::assertDirectoryIsReadable()`] | [`Assert::assertDirectoryNotIsReadable()`] | -| [`Assert::assertDirectoryIsWritable()`] | [`Assert::assertDirectoryNotIsWritable()`] | -| [`Assert::assertFileIsReadable()`] | [`Assert::assertFileNotIsReadable()`] | -| [`Assert::assertFileIsWritable()`] | [`Assert::assertFileNotIsWritable()`] | - -These methods were introduced in PHPUnit 5.6.0. - -[`Assert::assertIsReadable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisreadable -[`Assert::assertNotIsReadable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisreadable -[`Assert::assertIsWritable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertiswritable -[`Assert::assertNotIsWritable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertiswritable -[`Assert::assertDirectoryExists()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertdirectoryexists -[`Assert::assertDirectoryNotExists()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertdirectoryexists -[`Assert::assertDirectoryIsReadable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertdirectoryisreadable -[`Assert::assertDirectoryNotIsReadable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertdirectoryisreadable -[`Assert::assertDirectoryIsWritable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertdirectoryiswritable -[`Assert::assertDirectoryNotIsWritable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertdirectoryiswritable -[`Assert::assertFileIsReadable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertfileisreadable -[`Assert::assertFileNotIsReadable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertfileisreadable -[`Assert::assertFileIsWritable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertfileiswritable -[`Assert::assertFileNotIsWritable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertfileiswritable - #### PHPUnit < 6.4.0: `Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionObject` Polyfills the [`TestCase::expectExceptionObject()`] method to test all aspects of an `Exception` by passing an object to the method. This method was introduced in PHPUnit 6.4.0. -[`TestCase::expectExceptionObject()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-exceptions +[`TestCase::expectExceptionObject()`]: https://docs.phpunit.de/en/main/writing-tests-for-phpunit.html#testing-exceptions #### PHPUnit < 7.5.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertIsType` @@ -276,28 +219,28 @@ Polyfills the following methods: These methods were introduced in PHPUnit 7.5.0 as alternatives to the `Assert::assertInternalType()` and `Assert::assertNotInternalType()` methods, which were soft deprecated in PHPUnit 7.5.0, hard deprecated (warning) in PHPUnit 8.0.0 and removed in PHPUnit 9.0.0. -[`Assert::assertIsArray()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisarray -[`Assert::assertIsNotArray()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisarray -[`Assert::assertIsBool()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisbool -[`Assert::assertIsNotBool()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisbool -[`Assert::assertIsFloat()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisfloat -[`Assert::assertIsNotFloat()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisfloat -[`Assert::assertIsInt()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisint -[`Assert::assertIsNotInt()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisint -[`Assert::assertIsNumeric()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisnumeric -[`Assert::assertIsNotNumeric()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisnumeric -[`Assert::assertIsObject()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisobject -[`Assert::assertIsNotObject()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisobject -[`Assert::assertIsResource()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisresource -[`Assert::assertIsNotResource()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisresource -[`Assert::assertIsString()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisstring -[`Assert::assertIsNotString()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisstring -[`Assert::assertIsScalar()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisscalar -[`Assert::assertIsNotScalar()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisscalar -[`Assert::assertIsCallable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertiscallable -[`Assert::assertIsNotCallable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertiscallable -[`Assert::assertIsIterable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisiterable -[`Assert::assertIsNotIterable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisiterable +[`Assert::assertIsArray()`]: https://docs.phpunit.de/en/main/assertions.html#assertisarray +[`Assert::assertIsNotArray()`]: https://docs.phpunit.de/en/main/assertions.html#assertisarray +[`Assert::assertIsBool()`]: https://docs.phpunit.de/en/main/assertions.html#assertisbool +[`Assert::assertIsNotBool()`]: https://docs.phpunit.de/en/main/assertions.html#assertisbool +[`Assert::assertIsFloat()`]: https://docs.phpunit.de/en/main/assertions.html#assertisfloat +[`Assert::assertIsNotFloat()`]: https://docs.phpunit.de/en/main/assertions.html#assertisfloat +[`Assert::assertIsInt()`]: https://docs.phpunit.de/en/main/assertions.html#assertisint +[`Assert::assertIsNotInt()`]: https://docs.phpunit.de/en/main/assertions.html#assertisint +[`Assert::assertIsNumeric()`]: https://docs.phpunit.de/en/main/assertions.html#assertisnumeric +[`Assert::assertIsNotNumeric()`]: https://docs.phpunit.de/en/main/assertions.html#assertisnumeric +[`Assert::assertIsObject()`]: https://docs.phpunit.de/en/main/assertions.html#assertisobject +[`Assert::assertIsNotObject()`]: https://docs.phpunit.de/en/main/assertions.html#assertisobject +[`Assert::assertIsResource()`]: https://docs.phpunit.de/en/main/assertions.html#assertisresource +[`Assert::assertIsNotResource()`]: https://docs.phpunit.de/en/main/assertions.html#assertisresource +[`Assert::assertIsString()`]: https://docs.phpunit.de/en/main/assertions.html#assertisstring +[`Assert::assertIsNotString()`]: https://docs.phpunit.de/en/main/assertions.html#assertisstring +[`Assert::assertIsScalar()`]: https://docs.phpunit.de/en/main/assertions.html#assertisscalar +[`Assert::assertIsNotScalar()`]: https://docs.phpunit.de/en/main/assertions.html#assertisscalar +[`Assert::assertIsCallable()`]: https://docs.phpunit.de/en/main/assertions.html#assertiscallable +[`Assert::assertIsNotCallable()`]: https://docs.phpunit.de/en/main/assertions.html#assertiscallable +[`Assert::assertIsIterable()`]: https://docs.phpunit.de/en/main/assertions.html#assertisiterable +[`Assert::assertIsNotIterable()`]: https://docs.phpunit.de/en/main/assertions.html#assertisiterable #### PHPUnit < 7.5.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains` @@ -309,10 +252,10 @@ Polyfills the following methods: These methods were introduced in PHPUnit 7.5.0 as alternatives to using `Assert::assertContains()` and `Assert::assertNotContains()` with string haystacks. Passing string haystacks to these methods was soft deprecated in PHPUnit 7.5.0, hard deprecated (warning) in PHPUnit 8.0.0 and removed in PHPUnit 9.0.0. -[`Assert::assertStringContainsString()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertstringcontainsstring -[`Assert::assertStringNotContainsString()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertstringcontainsstring -[`Assert::assertStringContainsStringIgnoringCase()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertstringcontainsstringignoringcase -[`Assert::assertStringNotContainsStringIgnoringCase()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertstringcontainsstringignoringcase +[`Assert::assertStringContainsString()`]: https://docs.phpunit.de/en/main/assertions.html#assertstringcontainsstring +[`Assert::assertStringNotContainsString()`]: https://docs.phpunit.de/en/main/assertions.html#assertstringcontainsstring +[`Assert::assertStringContainsStringIgnoringCase()`]: https://docs.phpunit.de/en/main/assertions.html#assertstringcontainsstringignoringcase +[`Assert::assertStringNotContainsStringIgnoringCase()`]: https://docs.phpunit.de/en/main/assertions.html#assertstringcontainsstringignoringcase #### PHPUnit < 7.5.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertEqualsSpecializations` @@ -325,38 +268,12 @@ Polyfills the following methods: These methods were introduced in PHPUnit 7.5.0 as alternatives to using `Assert::assertEquals()` and `Assert::assertNotEquals()` with these optional parameters. Passing the respective optional parameters to these methods was soft deprecated in PHPUnit 7.5.0, hard deprecated (warning) in PHPUnit 8.0.0 and removed in PHPUnit 9.0.0. -[`Assert::assertEqualsCanonicalizing()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertequalscanonicalizing -[`Assert::assertNotEqualsCanonicalizing()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertequalscanonicalizing -[`Assert::assertEqualsIgnoringCase()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertequalsignoringcase -[`Assert::assertNotEqualsIgnoringCase()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertequalsignoringcase -[`Assert::assertEqualsWithDelta()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertequalswithdelta -[`Assert::assertNotEqualsWithDelta()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertequalswithdelta - -#### PHPUnit < 8.4.0: `Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException` - -Polyfills the following methods: -| | | | -|-------------------------------------|--------------------------------|---------------------------------------| -| `TestCase::`[`expectError()`] | [`expectErrorMessage()`] | [`expectErrorMessageMatches()`] | -| `TestCase::`[`expectWarning()`] | [`expectWarningMessage()`] | [`expectWarningMessageMatches()`] | -| `TestCase::`[`expectNotice()`] | [`expectNoticeMessage()`] | [`expectNoticeMessageMatches()`] | -| `TestCase::`[`expectDeprecation()`] | [`expectDeprecationMessage()`] | [`expectDeprecationMessageMatches()`] | - -These methods were introduced in PHPUnit 8.4.0 as alternatives to using `TestCase::expectException()` et al for expecting PHP native errors, warnings and notices. -Using `TestCase::expectException*()` for testing PHP native notices was soft deprecated in PHPUnit 8.4.0, hard deprecated (warning) in PHPUnit 9.0.0 and (will be) removed in PHPUnit 10.0.0. - -[`expectError()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices -[`expectErrorMessage()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices -[`expectErrorMessageMatches()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices -[`expectWarning()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices -[`expectWarningMessage()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices -[`expectWarningMessageMatches()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices -[`expectNotice()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices -[`expectNoticeMessage()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices -[`expectNoticeMessageMatches()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices -[`expectDeprecation()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices -[`expectDeprecationMessage()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices -[`expectDeprecationMessageMatches()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-php-errors-warnings-and-notices +[`Assert::assertEqualsCanonicalizing()`]: https://docs.phpunit.de/en/main/assertions.html#assertequalscanonicalizing +[`Assert::assertNotEqualsCanonicalizing()`]: https://docs.phpunit.de/en/main/assertions.html#assertequalscanonicalizing +[`Assert::assertEqualsIgnoringCase()`]: https://docs.phpunit.de/en/main/assertions.html#assertequalsignoringcase +[`Assert::assertNotEqualsIgnoringCase()`]: https://docs.phpunit.de/en/main/assertions.html#assertequalsignoringcase +[`Assert::assertEqualsWithDelta()`]: https://docs.phpunit.de/en/main/assertions.html#assertequalswithdelta +[`Assert::assertNotEqualsWithDelta()`]: https://docs.phpunit.de/en/main/assertions.html#assertequalswithdelta #### PHPUnit < 8.4.0: `Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches` @@ -365,23 +282,28 @@ Polyfills the [`TestCase::expectExceptionMessageMatches()`] method. This method was introduced in PHPUnit 8.4.0 to improve the name of the `TestCase::expectExceptionMessageRegExp()` method. The `TestCase::expectExceptionMessageRegExp()` method was soft deprecated in PHPUnit 8.4.0, hard deprecated (warning) in PHPUnit 8.5.3 and removed in PHPUnit 9.0.0. -[`TestCase::expectExceptionMessageMatches()`]: https://docs.phpunit.de/en/9.6/writing-tests-for-phpunit.html#testing-exceptions +[`TestCase::expectExceptionMessageMatches()`]: https://docs.phpunit.de/en/main/writing-tests-for-phpunit.html#testing-exceptions #### PHPUnit < 8.5.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations` Polyfills the following methods: -| | | -|--------------------------------------------------|-----------------------------------------------------| -| `Assert::assertFileEqualsCanonicalizing()` | `Assert::assertFileNotEqualsCanonicalizing()` | -| `Assert::assertFileEqualsIgnoringCase()` | `Assert::assertFileNotEqualsIgnoringCase()` | -| `Assert::assertStringEqualsFileCanonicalizing()` | `Assert::assertStringNotEqualsFileCanonicalizing()` | -| `Assert::assertStringEqualsFileIgnoringCase()` | `Assert::assertStringNotEqualsFileIgnoringCase()` | +| | | +|----------------------------------------------------|-------------------------------------------------------| +| [`Assert::assertFileEqualsCanonicalizing()`] | [`Assert::assertFileNotEqualsCanonicalizing()`] | +| [`Assert::assertFileEqualsIgnoringCase()`] | [`Assert::assertFileNotEqualsIgnoringCase()`] | +| [`Assert::assertStringEqualsFileCanonicalizing()`] | [`Assert::assertStringNotEqualsFileCanonicalizing()`] | +| [`Assert::assertStringEqualsFileIgnoringCase()`] | [`Assert::assertStringNotEqualsFileIgnoringCase()`] | These methods were introduced in PHPUnit 8.5.0 as alternatives to using `Assert::assertFileEquals()` and `Assert::assertFileNotEquals()` with these optional parameters. Passing the respective optional parameters to these methods was hard deprecated in PHPUnit 8.5.0 and removed in PHPUnit 9.0.0. - +[`Assert::assertFileEqualsCanonicalizing()`]: https://docs.phpunit.de/en/main/assertions.html#assertfileequals +[`Assert::assertFileNotEqualsCanonicalizing()`]: https://docs.phpunit.de/en/main/assertions.html#assertfileequals +[`Assert::assertFileEqualsIgnoringCase()`]: https://docs.phpunit.de/en/main/assertions.html#assertfileequals +[`Assert::assertFileNotEqualsIgnoringCase()`]: https://docs.phpunit.de/en/main/assertions.html#assertfileequals +[`Assert::assertStringEqualsFileCanonicalizing()`]: https://docs.phpunit.de/en/main/assertions.html#assertfileequals +[`Assert::assertStringNotEqualsFileCanonicalizing()`]: https://docs.phpunit.de/en/main/assertions.html#assertfileequals +[`Assert::assertStringEqualsFileIgnoringCase()`]: https://docs.phpunit.de/en/main/assertions.html#assertfileequals +[`Assert::assertStringNotEqualsFileIgnoringCase()`]: https://docs.phpunit.de/en/main/assertions.html#assertfileequals #### PHPUnit < 9.0.0: `Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations` @@ -408,31 +330,30 @@ Polyfills the following renamed methods: * [`Assert::assertDoesNotMatchRegularExpression()`], introduced as alternative for `Assert::assertNotRegExp()`. These methods were introduced in PHPUnit 9.1.0. -The original methods these new methods replace were hard deprecated in PHPUnit 9.1.0 and (will be) removed in PHPUnit 10.0.0. - -[`Assert::assertIsNotReadable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertisreadable -[`Assert::assertIsNotWritable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertiswritable -[`Assert::assertDirectoryDoesNotExist()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertdirectoryexists -[`Assert::assertDirectoryIsNotReadable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertdirectoryisreadable -[`Assert::assertDirectoryIsNotWritable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertdirectoryiswritable -[`Assert::assertFileDoesNotExist()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertfileexists -[`Assert::assertFileIsNotReadable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertfileisreadable -[`Assert::assertFileIsNotWritable()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertfileiswritable -[`Assert::assertMatchesRegularExpression()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertmatchesregularexpression -[`Assert::assertDoesNotMatchRegularExpression()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertmatchesregularexpression +The original methods these new methods replace were hard deprecated in PHPUnit 9.1.0 and removed in PHPUnit 10.0.0. + +[`Assert::assertIsNotReadable()`]: https://docs.phpunit.de/en/main/assertions.html#assertisreadable +[`Assert::assertIsNotWritable()`]: https://docs.phpunit.de/en/main/assertions.html#assertiswritable +[`Assert::assertDirectoryDoesNotExist()`]: https://docs.phpunit.de/en/main/assertions.html#assertdirectoryexists +[`Assert::assertDirectoryIsNotReadable()`]: https://docs.phpunit.de/en/main/assertions.html#assertdirectoryisreadable +[`Assert::assertDirectoryIsNotWritable()`]: https://docs.phpunit.de/en/main/assertions.html#assertdirectoryiswritable +[`Assert::assertFileDoesNotExist()`]: https://docs.phpunit.de/en/main/assertions.html#assertfileexists +[`Assert::assertFileIsNotReadable()`]: https://docs.phpunit.de/en/main/assertions.html#assertfileisreadable +[`Assert::assertFileIsNotWritable()`]: https://docs.phpunit.de/en/main/assertions.html#assertfileiswritable +[`Assert::assertMatchesRegularExpression()`]: https://docs.phpunit.de/en/main/assertions.html#assertmatchesregularexpression +[`Assert::assertDoesNotMatchRegularExpression()`]: https://docs.phpunit.de/en/main/assertions.html#assertmatchesregularexpression #### PHPUnit < 9.3.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource` Polyfills the following methods: -| | | -|------------------------------------|---------------------------------------| -| `Assert::assertIsClosedResource()` | `Assert::assertIsNotClosedResource()` | +| | | +|--------------------------------------|-----------------------------------------| +| [`Assert::assertIsClosedResource()`] | [`Assert::assertIsNotClosedResource()`] | These methods were introduced in PHPUnit 9.3.0. - +[`Assert::assertIsClosedResource()`]: https://docs.phpunit.de/en/main/assertions.html#assertisresource +[`Assert::assertIsNotClosedResource()`]: https://docs.phpunit.de/en/main/assertions.html#assertisresource Additionally, this trait contains a helper method `shouldClosedResourceAssertionBeSkipped()`. @@ -477,7 +398,42 @@ The `assertObjectEquals()` assertion was introduced in PHPUnit 9.4.0. [limitations in how this assertion is implemented in PHPUnit]: https://github.com/sebastianbergmann/phpunit/issues/4707 -[`Assert::assertObjectEquals()`]: https://docs.phpunit.de/en/9.6/assertions.html#assertobjectequals +[`Assert::assertObjectEquals()`]: https://docs.phpunit.de/en/main/assertions.html#assertobjectequals + +#### PHPUnit < 10.0.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertIgnoringLineEndings` + +Polyfills the following methods: +| | | +|-----------------------------------------------------------|-------------------------------------------------------------| +| [`Assert::assertStringEqualsStringIgnoringLineEndings()`] | [`Assert::assertStringContainsStringIgnoringLineEndings()`] | + +These methods were introduced in PHPUnit 10.0.0. + +[`Assert::assertStringEqualsStringIgnoringLineEndings()`]: https://docs.phpunit.de/en/main/assertions.html#assertstringequalsstringignoringlineendings +[`Assert::assertStringContainsStringIgnoringLineEndings()`]: https://docs.phpunit.de/en/main/assertions.html#assertstringcontainsstringignoringlineendings + +#### PHPUnit < 10.0.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertIsList` + +Polyfills the following method: +| | +|----------------------------| +| [`Assert::assertIsList()`] | + +This method was introduced in PHPUnit 10.0.0. + +[`Assert::assertIsList()`]: https://docs.phpunit.de/en/main/assertions.html#assertislist + +#### PHPUnit < 10.1.0: `Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty` + +Polyfills the following method: +| | | +|---------------------------------------|------------------------------------------| +| [`Assert::assertObjectHasProperty()`] | [`Assert::assertObjectNotHasProperty()`] | + +These methods were introduced in PHPUnit 10.1.0 as alternatives to the `Assert::assertObjectHasAttribute()` and `Assert::assertObjectNotHasAttribute()` methods, which were hard deprecated (warning) in PHPUnit 9.6.1 and removed in PHPUnit 10.0.0. + +[`Assert::assertObjectHasProperty()`]: https://docs.phpunit.de/en/main/assertions.html#assertObjectHasProperty +[`Assert::assertObjectNotHasProperty()`]: https://docs.phpunit.de/en/main/assertions.html#assertObjectHasProperty ### Helper traits @@ -517,7 +473,7 @@ self::assertSame( $propertyName, self::getProperty( $objInstance, $propertyName PHPUnit 8.0.0 introduced a `void` return type declaration to the ["fixture" methods] - `setUpBeforeClass()`, `setUp()`, `tearDown()` and `tearDownAfterClass()`. As the `void` return type was not introduced until PHP 7.1, this makes it more difficult to create cross-version compatible tests when using fixtures, due to signature mismatches. -["fixture" methods]: https://docs.phpunit.de/en/9.6/fixtures.html +["fixture" methods]: https://docs.phpunit.de/en/main/fixtures.html This library contains two basic `TestCase` options to overcome this issue. @@ -581,10 +537,10 @@ This `TestCase` overcomes the signature mismatch by using the PHPUnit `@before[C When using this TestCase, overloaded fixture methods need to use the [`@beforeClass`], [`@before`], [`@after`] and [`@afterClass`] annotations. The naming of the overloaded methods is open as long as the method names don't conflict with the PHPUnit native method names. -[`@beforeClass`]: https://docs.phpunit.de/en/9.6/annotations.html#beforeclass -[`@before`]: https://docs.phpunit.de/en/9.6/annotations.html#before -[`@after`]: https://docs.phpunit.de/en/9.6/annotations.html#after -[`@afterClass`]: https://docs.phpunit.de/en/9.6/annotations.html#afterclass +[`@beforeClass`]: https://docs.phpunit.de/en/main/annotations.html#beforeclass +[`@before`]: https://docs.phpunit.de/en/main/annotations.html#before +[`@after`]: https://docs.phpunit.de/en/main/annotations.html#after +[`@afterClass`]: https://docs.phpunit.de/en/main/annotations.html#afterclass ```php use Yoast\PHPUnitPolyfills\TestCases\XTestCase; @@ -630,6 +586,16 @@ class MyTest extends XTestCase { ### TestListener +> :warning: **Important** :warning: +> +> The TestListener polyfill in PHPUnit Polyfills 2.0 is [not (yet) compatible with PHPUnit 10.0.0][polyfill-ticket]. +> +> If you need the TestListener polyfill, it is recommended to stay on the PHPUnit Polyfills 1.x series for the time being and to watch and upvote the [related ticket][polyfill-ticket]. +> +> The below documentation is for the PHPUnit 5.x-9.x TestListener polyfill implementation. + +[polyfill-ticket]: https://github.com/Yoast/PHPUnit-Polyfills/issues/128 + The method signatures in the PHPUnit `TestListener` interface have changed a number of times across versions. Additionally, the use of the TestListener principle has been deprecated in PHPUnit 7 in favour of using the [TestRunner hook interfaces](https://docs.phpunit.de/en/7.5/extending-phpunit.html#extending-the-testrunner). @@ -699,10 +665,10 @@ For frequently used, removed PHPUnit functionality, "helpers" may be provided. T #### Removed functionality without PHPUnit native replacement -| PHPUnit | Removed | Issue | Remarks | -|---------|-----------------------|-----------|------------------------| +| PHPUnit | Removed | Issue | Remarks | +|---------|-----------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 9.0.0 | `assertArraySubset()` | [#1][issue #1] | The [`dms/phpunit-arraysubset-asserts`](https://packagist.org/packages/dms/phpunit-arraysubset-asserts) package polyfills this functionality.
As of [version 0.3.0](https://github.com/rdohms/phpunit-arraysubset-asserts/releases/tag/v0.3.0) this package can be installed in combination with PHP 5.4 - current and PHPUnit 4.8.36/5.7.21 - current.
Alternatively, tests can be refactored using the patterns outlined in [issue #1]. | -| 9.0.0 | `assertAttribute*()` | [#2][issue #2] | Refactor the tests to not directly test private/protected properties.
As an interim solution, the [`Yoast\PHPUnitPolyfills\Helpers\AssertAttributeHelper`](#yoastphpunitpolyfillshelpersassertattributehelper) trait is available. | +| 9.0.0 | `assertAttribute*()` | [#2][issue #2] | Refactor the tests to not directly test private/protected properties.
As an interim solution, the [`Yoast\PHPUnitPolyfills\Helpers\AssertAttributeHelper`](#yoastphpunitpolyfillshelpersassertattributehelper) trait is available. | [issue #1]: https://github.com/Yoast/PHPUnit-Polyfills/issues/1 [issue #2]: https://github.com/Yoast/PHPUnit-Polyfills/issues/2 diff --git a/composer.json b/composer.json index 2af26d8..ce0fcfe 100644 --- a/composer.json +++ b/composer.json @@ -23,8 +23,8 @@ "minimum-stability": "dev", "prefer-stable": true, "require": { - "php": ">=5.4", - "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + "php": ">=5.6", + "phpunit/phpunit": "^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0" }, "require-dev": { "yoast/yoastcs": "^2.3.0" @@ -58,7 +58,7 @@ "@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 5.4-" + "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --runtime-set testVersion 5.6-" ], "fix-cs": [ "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf" @@ -69,8 +69,11 @@ "coverage": [ "@php ./vendor/phpunit/phpunit/phpunit" ], - "coverage-local": [ - "@php ./vendor/phpunit/phpunit/phpunit --coverage-html ./build/coverage-html" + "test10": [ + "@php ./vendor/phpunit/phpunit/phpunit -c phpunit10.xml.dist --no-coverage" + ], + "coverage10": [ + "@php ./vendor/phpunit/phpunit/phpunit -c phpunit10.xml.dist" ] } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 87165fd..dabf008 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -4,6 +4,7 @@ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.2/phpunit.xsd" backupGlobals="true" bootstrap="./tests/bootstrap.php" + beStrictAboutOutputDuringTests="true" beStrictAboutTestsThatDoNotTestAnything="true" colors="true" convertDeprecationsToExceptions="true" @@ -25,6 +26,7 @@ + diff --git a/phpunit10.xml.dist b/phpunit10.xml.dist new file mode 100644 index 0000000..8226c26 --- /dev/null +++ b/phpunit10.xml.dist @@ -0,0 +1,38 @@ + + + + + + ./tests/ + + + + + + ./src/ + + + src/Polyfills/AssertClosedResource_Empty.php + + + + + + + + diff --git a/phpunitpolyfills-autoload.php b/phpunitpolyfills-autoload.php index be62abf..20630be 100644 --- a/phpunitpolyfills-autoload.php +++ b/phpunitpolyfills-autoload.php @@ -2,6 +2,8 @@ namespace Yoast\PHPUnitPolyfills; +use PHPUnit\Framework\Assert; +use PHPUnit\Framework\TestCase; use PHPUnit\Runner\Version as PHPUnit_Version; use PHPUnit_Runner_Version; @@ -17,7 +19,7 @@ final class Autoload { * * @var string */ - const VERSION = '1.0.5'; + const VERSION = '2.0.0'; /** * Loads a class. @@ -49,18 +51,6 @@ public static function load( $className ) { } switch ( $className ) { - case 'Yoast\PHPUnitPolyfills\Polyfills\AssertNumericType': - self::loadAssertNumericType(); - return true; - - case 'Yoast\PHPUnitPolyfills\Polyfills\ExpectException': - self::loadExpectException(); - return true; - - case 'Yoast\PHPUnitPolyfills\Polyfills\AssertFileDirectory': - self::loadAssertFileDirectory(); - return true; - case 'Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionObject': self::loadExpectExceptionObject(); return true; @@ -77,10 +67,6 @@ public static function load( $className ) { self::loadAssertEqualsSpecializations(); return true; - case 'Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException': - self::loadExpectPHPException(); - return true; - case 'Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches': self::loadExpectExceptionMessageMatches(); return true; @@ -105,6 +91,18 @@ public static function load( $className ) { self::loadAssertObjectEquals(); return true; + case 'Yoast\PHPUnitPolyfills\Polyfills\AssertIsList': + self::loadAssertIsList(); + return true; + + case 'Yoast\PHPUnitPolyfills\Polyfills\AssertIgnoringLineEndings': + self::loadAssertIgnoringLineEndings(); + return true; + + case 'Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty': + self::loadAssertObjectProperty(); + return true; + case 'Yoast\PHPUnitPolyfills\TestCases\TestCase': self::loadTestCase(); return true; @@ -133,73 +131,6 @@ public static function load( $className ) { return false; } - /** - * Load the AssertNumericType polyfill or an empty trait with the same name - * if a PHPUnit version is used which already contains this functionality. - * - * @return void - */ - public static function loadAssertNumericType() { - if ( \method_exists( '\PHPUnit\Framework\Assert', 'assertNan' ) === false ) { - // PHPUnit < 5.0.0. - require_once __DIR__ . '/src/Polyfills/AssertNumericType.php'; - return; - } - - // PHPUnit >= 5.0.0. - require_once __DIR__ . '/src/Polyfills/AssertNumericType_Empty.php'; - } - - /** - * Load the ExpectException polyfill or an empty trait with the same name - * if a PHPUnit version is used which already contains this functionality. - * - * @return void - */ - public static function loadExpectException() { - /* - * Alias the PHPUnit 4/5 Exception class used to its PHPUnit >= 6 name. - * - * This allow for catching the potential exceptions thrown by the methods - * polyfilled in a cross-version compatible way. - * - * {@internal The `class_exists` wrappers are needed to play nice with - * PHPUnit bootstrap files of test suites implementing this library - * which may be creating cross-version compatibility in a similar manner.}} - */ - if ( \class_exists( 'PHPUnit_Framework_Exception' ) === true - && \class_exists( 'PHPUnit\Framework\Exception' ) === false - ) { - \class_alias( 'PHPUnit_Framework_Exception', 'PHPUnit\Framework\Exception' ); - } - - if ( \method_exists( '\PHPUnit\Framework\TestCase', 'expectException' ) === false ) { - // PHPUnit < 5.2.0. - require_once __DIR__ . '/src/Polyfills/ExpectException.php'; - return; - } - - // PHPUnit >= 5.2.0. - require_once __DIR__ . '/src/Polyfills/ExpectException_Empty.php'; - } - - /** - * Load the AssertFileDirectory polyfill or an empty trait with the same name - * if a PHPUnit version is used which already contains this functionality. - * - * @return void - */ - public static function loadAssertFileDirectory() { - if ( \method_exists( '\PHPUnit\Framework\Assert', 'assertIsReadable' ) === false ) { - // PHPUnit < 5.6.0. - require_once __DIR__ . '/src/Polyfills/AssertFileDirectory.php'; - return; - } - - // PHPUnit >= 5.6.0. - require_once __DIR__ . '/src/Polyfills/AssertFileDirectory_Empty.php'; - } - /** * Load the ExpectExceptionObject polyfill or an empty trait with the same name * if a PHPUnit version is used which already contains this functionality. @@ -207,7 +138,7 @@ public static function loadAssertFileDirectory() { * @return void */ public static function loadExpectExceptionObject() { - if ( \method_exists( '\PHPUnit\Framework\TestCase', 'expectExceptionObject' ) === false ) { + if ( \method_exists( TestCase::class, 'expectExceptionObject' ) === false ) { // PHPUnit < 6.4.0. require_once __DIR__ . '/src/Polyfills/ExpectExceptionObject.php'; return; @@ -224,7 +155,7 @@ public static function loadExpectExceptionObject() { * @return void */ public static function loadAssertIsType() { - if ( \method_exists( '\PHPUnit\Framework\Assert', 'assertIsArray' ) === false ) { + if ( \method_exists( Assert::class, 'assertIsArray' ) === false ) { // PHPUnit < 7.5.0. require_once __DIR__ . '/src/Polyfills/AssertIsType.php'; return; @@ -241,7 +172,7 @@ public static function loadAssertIsType() { * @return void */ public static function loadAssertStringContains() { - if ( \method_exists( '\PHPUnit\Framework\Assert', 'assertStringContainsString' ) === false ) { + if ( \method_exists( Assert::class, 'assertStringContainsString' ) === false ) { // PHPUnit < 7.5.0. require_once __DIR__ . '/src/Polyfills/AssertStringContains.php'; return; @@ -258,7 +189,7 @@ public static function loadAssertStringContains() { * @return void */ public static function loadAssertEqualsSpecializations() { - if ( \method_exists( '\PHPUnit\Framework\Assert', 'assertEqualsWithDelta' ) === false ) { + if ( \method_exists( Assert::class, 'assertEqualsWithDelta' ) === false ) { // PHPUnit < 7.5.0. require_once __DIR__ . '/src/Polyfills/AssertEqualsSpecializations.php'; return; @@ -268,57 +199,6 @@ public static function loadAssertEqualsSpecializations() { require_once __DIR__ . '/src/Polyfills/AssertEqualsSpecializations_Empty.php'; } - /** - * Load the ExpectPHPException polyfill or an empty trait with the same name - * if a PHPUnit version is used which already contains this functionality. - * - * Includes aliasing any PHPUnit native classes needed for this functionality - * which aren't available under their namespaced name in PHPUnit 4.x/5.x. - * - * @return void - */ - public static function loadExpectPHPException() { - /* - * Alias the PHPUnit 4/5 Error classes to their PHPUnit >= 6 name. - * - * {@internal The `class_exists` wrappers are needed to play nice with - * PHPUnit bootstrap files of test suites implementing this library - * which may be creating cross-version compatibility in a similar manner.}} - */ - if ( \class_exists( 'PHPUnit_Framework_Error' ) === true - && \class_exists( 'PHPUnit\Framework\Error\Error' ) === false - ) { - \class_alias( 'PHPUnit_Framework_Error', 'PHPUnit\Framework\Error\Error' ); - } - - if ( \class_exists( 'PHPUnit_Framework_Error_Warning' ) === true - && \class_exists( 'PHPUnit\Framework\Error\Warning' ) === false - ) { - \class_alias( 'PHPUnit_Framework_Error_Warning', 'PHPUnit\Framework\Error\Warning' ); - } - - if ( \class_exists( 'PHPUnit_Framework_Error_Notice' ) === true - && \class_exists( 'PHPUnit\Framework\Error\Notice' ) === false - ) { - \class_alias( 'PHPUnit_Framework_Error_Notice', 'PHPUnit\Framework\Error\Notice' ); - } - - if ( \class_exists( 'PHPUnit_Framework_Error_Deprecated' ) === true - && \class_exists( 'PHPUnit\Framework\Error\Deprecated' ) === false - ) { - \class_alias( 'PHPUnit_Framework_Error_Deprecated', 'PHPUnit\Framework\Error\Deprecated' ); - } - - if ( \method_exists( '\PHPUnit\Framework\TestCase', 'expectErrorMessage' ) === false ) { - // PHPUnit < 8.4.0. - require_once __DIR__ . '/src/Polyfills/ExpectPHPException.php'; - return; - } - - // PHPUnit >= 8.4.0. - require_once __DIR__ . '/src/Polyfills/ExpectPHPException_Empty.php'; - } - /** * Load the ExpectExceptionMessageMatches polyfill or an empty trait with the same name * if a PHPUnit version is used which already contains this functionality. @@ -326,7 +206,7 @@ public static function loadExpectPHPException() { * @return void */ public static function loadExpectExceptionMessageMatches() { - if ( \method_exists( '\PHPUnit\Framework\TestCase', 'expectExceptionMessageMatches' ) === false ) { + if ( \method_exists( TestCase::class, 'expectExceptionMessageMatches' ) === false ) { // PHPUnit < 8.4.0. require_once __DIR__ . '/src/Polyfills/ExpectExceptionMessageMatches.php'; return; @@ -343,7 +223,7 @@ public static function loadExpectExceptionMessageMatches() { * @return void */ public static function loadAssertFileEqualsSpecializations() { - if ( \method_exists( '\PHPUnit\Framework\Assert', 'assertFileEqualsIgnoringCase' ) === false ) { + if ( \method_exists( Assert::class, 'assertFileEqualsIgnoringCase' ) === false ) { // PHPUnit < 8.5.0. require_once __DIR__ . '/src/Polyfills/AssertFileEqualsSpecializations.php'; return; @@ -360,7 +240,7 @@ public static function loadAssertFileEqualsSpecializations() { * @return void */ public static function loadEqualToSpecializations() { - if ( \method_exists( '\PHPUnit\Framework\Assert', 'equalToWithDelta' ) === false ) { + if ( \method_exists( Assert::class, 'equalToWithDelta' ) === false ) { // PHPUnit < 9.0.0. require_once __DIR__ . '/src/Polyfills/EqualToSpecializations.php'; return; @@ -377,7 +257,7 @@ public static function loadEqualToSpecializations() { * @return void */ public static function loadAssertionRenames() { - if ( \method_exists( '\PHPUnit\Framework\Assert', 'assertMatchesRegularExpression' ) === false ) { + if ( \method_exists( Assert::class, 'assertMatchesRegularExpression' ) === false ) { // PHPUnit < 9.1.0. require_once __DIR__ . '/src/Polyfills/AssertionRenames.php'; return; @@ -394,7 +274,7 @@ public static function loadAssertionRenames() { * @return void */ public static function loadAssertClosedResource() { - if ( \method_exists( '\PHPUnit\Framework\Assert', 'assertIsClosedResource' ) === false ) { + if ( \method_exists( Assert::class, 'assertIsClosedResource' ) === false ) { // PHPUnit < 9.3.0. require_once __DIR__ . '/src/Polyfills/AssertClosedResource.php'; return; @@ -411,7 +291,7 @@ public static function loadAssertClosedResource() { * @return void */ public static function loadAssertObjectEquals() { - if ( \method_exists( '\PHPUnit\Framework\Assert', 'assertObjectEquals' ) === false ) { + if ( \method_exists( Assert::class, 'assertObjectEquals' ) === false ) { // PHPUnit < 9.4.0. require_once __DIR__ . '/src/Polyfills/AssertObjectEquals.php'; return; @@ -421,6 +301,57 @@ public static function loadAssertObjectEquals() { require_once __DIR__ . '/src/Polyfills/AssertObjectEquals_Empty.php'; } + /** + * Load the AssertIsList polyfill or an empty trait with the same name + * if a PHPUnit version is used which already contains this functionality. + * + * @return void + */ + public static function loadAssertIsList() { + if ( \method_exists( Assert::class, 'assertIsList' ) === false ) { + // PHPUnit < 10.0.0. + require_once __DIR__ . '/src/Polyfills/AssertIsList.php'; + return; + } + + // PHPUnit >= 10.0.0. + require_once __DIR__ . '/src/Polyfills/AssertIsList_Empty.php'; + } + + /** + * Load the AssertIgnoringLineEndings polyfill or an empty trait with the same name + * if a PHPUnit version is used which already contains this functionality. + * + * @return void + */ + public static function loadAssertIgnoringLineEndings() { + if ( \method_exists( Assert::class, 'assertStringEqualsStringIgnoringLineEndings' ) === false ) { + // PHPUnit < 10.0.0. + require_once __DIR__ . '/src/Polyfills/AssertIgnoringLineEndings.php'; + return; + } + + // PHPUnit >= 10.0.0. + require_once __DIR__ . '/src/Polyfills/AssertIgnoringLineEndings_Empty.php'; + } + + /** + * Load the AssertObjectProperty polyfill or an empty trait with the same name + * if a PHPUnit version is used which already contains this functionality. + * + * @return void + */ + public static function loadAssertObjectProperty() { + if ( \method_exists( Assert::class, 'assertObjectHasProperty' ) === false ) { + // PHPUnit < 10.1.0. + require_once __DIR__ . '/src/Polyfills/AssertObjectProperty.php'; + return; + } + + // PHPUnit >= 10.1.0. + require_once __DIR__ . '/src/Polyfills/AssertObjectProperty_Empty.php'; + } + /** * Load the appropriate TestCase class based on the PHPUnit version being used. * @@ -445,7 +376,7 @@ public static function loadTestCase() { public static function loadTestListenerDefaultImplementation() { if ( \version_compare( self::getPHPUnitVersion(), '6.0.0', '<' ) ) { /* - * Alias one particular PHPUnit 4/5 class to its PHPUnit >= 6 name. + * Alias one particular PHPUnit 5.x class to its PHPUnit >= 6 name. * * All other classes needed are part of the forward-compatibility layer. * diff --git a/src/Helpers/AssertAttributeHelper.php b/src/Helpers/AssertAttributeHelper.php index 4ae704c..ab33b2e 100644 --- a/src/Helpers/AssertAttributeHelper.php +++ b/src/Helpers/AssertAttributeHelper.php @@ -46,7 +46,7 @@ trait AssertAttributeHelper { * * @throws ReflectionException When a non-existent property is requested. */ - public static function getProperty( $objInstance, $propertyName ) { + final public static function getProperty( $objInstance, $propertyName ) { $reflect = new ReflectionObject( $objInstance ); $property = $reflect->getProperty( $propertyName ); $property->setAccessible( true ); @@ -62,7 +62,7 @@ public static function getProperty( $objInstance, $propertyName ) { * * @return mixed */ - public static function getPropertyValue( $objInstance, $propertyName ) { + final public static function getPropertyValue( $objInstance, $propertyName ) { $property = static::getProperty( $objInstance, $propertyName ); return $property->getValue( $objInstance ); diff --git a/src/Polyfills/AssertClosedResource.php b/src/Polyfills/AssertClosedResource.php index 799b6d9..04061f9 100644 --- a/src/Polyfills/AssertClosedResource.php +++ b/src/Polyfills/AssertClosedResource.php @@ -25,7 +25,7 @@ trait AssertClosedResource { * @return void */ public static function assertIsClosedResource( $actual, $message = '' ) { - $exporter = \class_exists( 'SebastianBergmann\Exporter\Exporter' ) ? new Exporter() : new Exporter_In_Phar(); + $exporter = \class_exists( Exporter::class ) ? new Exporter() : new Exporter_In_Phar(); $msg = \sprintf( 'Failed asserting that %s is of type "resource (closed)"', $exporter->export( $actual ) ); if ( $message !== '' ) { @@ -44,7 +44,7 @@ public static function assertIsClosedResource( $actual, $message = '' ) { * @return void */ public static function assertIsNotClosedResource( $actual, $message = '' ) { - $exporter = \class_exists( 'SebastianBergmann\Exporter\Exporter' ) ? new Exporter() : new Exporter_In_Phar(); + $exporter = \class_exists( Exporter::class ) ? new Exporter() : new Exporter_In_Phar(); $type = $exporter->export( $actual ); if ( $type === 'NULL' ) { $type = 'resource (closed)'; diff --git a/src/Polyfills/AssertEqualsSpecializations.php b/src/Polyfills/AssertEqualsSpecializations.php index d3a66dd..ac04cef 100644 --- a/src/Polyfills/AssertEqualsSpecializations.php +++ b/src/Polyfills/AssertEqualsSpecializations.php @@ -24,7 +24,7 @@ trait AssertEqualsSpecializations { * * @return void */ - public static function assertEqualsCanonicalizing( $expected, $actual, $message = '' ) { + final public static function assertEqualsCanonicalizing( $expected, $actual, $message = '' ) { static::assertEquals( $expected, $actual, $message, 0.0, 10, true ); } @@ -37,7 +37,7 @@ public static function assertEqualsCanonicalizing( $expected, $actual, $message * * @return void */ - public static function assertEqualsIgnoringCase( $expected, $actual, $message = '' ) { + final public static function assertEqualsIgnoringCase( $expected, $actual, $message = '' ) { static::assertEquals( $expected, $actual, $message, 0.0, 10, false, true ); } @@ -51,7 +51,7 @@ public static function assertEqualsIgnoringCase( $expected, $actual, $message = * * @return void */ - public static function assertEqualsWithDelta( $expected, $actual, $delta, $message = '' ) { + final public static function assertEqualsWithDelta( $expected, $actual, $delta, $message = '' ) { static::assertEquals( $expected, $actual, $message, $delta ); } @@ -64,7 +64,7 @@ public static function assertEqualsWithDelta( $expected, $actual, $delta, $messa * * @return void */ - public static function assertNotEqualsCanonicalizing( $expected, $actual, $message = '' ) { + final public static function assertNotEqualsCanonicalizing( $expected, $actual, $message = '' ) { static::assertNotEquals( $expected, $actual, $message, 0.0, 10, true ); } @@ -77,7 +77,7 @@ public static function assertNotEqualsCanonicalizing( $expected, $actual, $messa * * @return void */ - public static function assertNotEqualsIgnoringCase( $expected, $actual, $message = '' ) { + final public static function assertNotEqualsIgnoringCase( $expected, $actual, $message = '' ) { static::assertNotEquals( $expected, $actual, $message, 0.0, 10, false, true ); } @@ -91,7 +91,7 @@ public static function assertNotEqualsIgnoringCase( $expected, $actual, $message * * @return void */ - public static function assertNotEqualsWithDelta( $expected, $actual, $delta, $message = '' ) { + final public static function assertNotEqualsWithDelta( $expected, $actual, $delta, $message = '' ) { static::assertNotEquals( $expected, $actual, $message, $delta ); } } diff --git a/src/Polyfills/AssertFileDirectory.php b/src/Polyfills/AssertFileDirectory.php deleted file mode 100644 index 8ca4015..0000000 --- a/src/Polyfills/AssertFileDirectory.php +++ /dev/null @@ -1,261 +0,0 @@ -= 5.6.0 in which this polyfill is not needed. - */ -trait AssertFileDirectory {} diff --git a/src/Polyfills/AssertFileEqualsSpecializations.php b/src/Polyfills/AssertFileEqualsSpecializations.php index 744ebc9..1ddbbca 100644 --- a/src/Polyfills/AssertFileEqualsSpecializations.php +++ b/src/Polyfills/AssertFileEqualsSpecializations.php @@ -28,7 +28,7 @@ trait AssertFileEqualsSpecializations { * * @return void */ - public static function assertFileEqualsCanonicalizing( $expected, $actual, $message = '' ) { + final public static function assertFileEqualsCanonicalizing( $expected, $actual, $message = '' ) { static::assertFileEquals( $expected, $actual, $message, true ); } @@ -42,7 +42,7 @@ public static function assertFileEqualsCanonicalizing( $expected, $actual, $mess * * @return void */ - public static function assertFileEqualsIgnoringCase( $expected, $actual, $message = '' ) { + final public static function assertFileEqualsIgnoringCase( $expected, $actual, $message = '' ) { static::assertFileEquals( $expected, $actual, $message, false, true ); } @@ -56,7 +56,7 @@ public static function assertFileEqualsIgnoringCase( $expected, $actual, $messag * * @return void */ - public static function assertFileNotEqualsCanonicalizing( $expected, $actual, $message = '' ) { + final public static function assertFileNotEqualsCanonicalizing( $expected, $actual, $message = '' ) { static::assertFileNotEquals( $expected, $actual, $message, true ); } @@ -70,7 +70,7 @@ public static function assertFileNotEqualsCanonicalizing( $expected, $actual, $m * * @return void */ - public static function assertFileNotEqualsIgnoringCase( $expected, $actual, $message = '' ) { + final public static function assertFileNotEqualsIgnoringCase( $expected, $actual, $message = '' ) { static::assertFileNotEquals( $expected, $actual, $message, false, true ); } @@ -84,7 +84,7 @@ public static function assertFileNotEqualsIgnoringCase( $expected, $actual, $mes * * @return void */ - public static function assertStringEqualsFileCanonicalizing( $expectedFile, $actualString, $message = '' ) { + final public static function assertStringEqualsFileCanonicalizing( $expectedFile, $actualString, $message = '' ) { static::assertStringEqualsFile( $expectedFile, $actualString, $message, true ); } @@ -98,7 +98,7 @@ public static function assertStringEqualsFileCanonicalizing( $expectedFile, $act * * @return void */ - public static function assertStringEqualsFileIgnoringCase( $expectedFile, $actualString, $message = '' ) { + final public static function assertStringEqualsFileIgnoringCase( $expectedFile, $actualString, $message = '' ) { static::assertStringEqualsFile( $expectedFile, $actualString, $message, false, true ); } @@ -112,7 +112,7 @@ public static function assertStringEqualsFileIgnoringCase( $expectedFile, $actua * * @return void */ - public static function assertStringNotEqualsFileCanonicalizing( $expectedFile, $actualString, $message = '' ) { + final public static function assertStringNotEqualsFileCanonicalizing( $expectedFile, $actualString, $message = '' ) { static::assertStringNotEqualsFile( $expectedFile, $actualString, $message, true ); } @@ -126,7 +126,7 @@ public static function assertStringNotEqualsFileCanonicalizing( $expectedFile, $ * * @return void */ - public static function assertStringNotEqualsFileIgnoringCase( $expectedFile, $actualString, $message = '' ) { + final public static function assertStringNotEqualsFileIgnoringCase( $expectedFile, $actualString, $message = '' ) { static::assertStringNotEqualsFile( $expectedFile, $actualString, $message, false, true ); } } diff --git a/src/Polyfills/AssertIgnoringLineEndings.php b/src/Polyfills/AssertIgnoringLineEndings.php new file mode 100644 index 0000000..609abd5 --- /dev/null +++ b/src/Polyfills/AssertIgnoringLineEndings.php @@ -0,0 +1,131 @@ +export( $actual ), + $expected + ); + + if ( $message !== '' ) { + $msg = $message . \PHP_EOL . $msg; + } + + $actual = self::normalizeLineEndingsForIgnoringLineEndingsAssertions( (string) $actual ); + + static::assertSame( $expected, $actual, $msg ); + } + + /** + * Asserts that two variables are equal (ignoring case). + * + * @param string $needle The string to search for. + * @param string $haystack The string to treat as the haystack. + * @param string $message Optional failure message to display. + * + * @return void + * + * @throws TypeError When any of the passed arguments do not meet the required type. + */ + final public static function assertStringContainsStringIgnoringLineEndings( $needle, $haystack, $message = '' ) { + /* + * Parameter input validation. + * In PHPUnit this is done via PHP native type declarations. Emulating this for the polyfill. + * Note: using `is_scalar()` instead of `is_string()` as test files may not be using strict_types. + */ + if ( \is_scalar( $needle ) === false ) { + throw new TypeError( + \sprintf( + 'Argument 1 passed to assertStringContainsStringIgnoringLineEndings() must be of type string, %s given', + \gettype( $needle ) + ) + ); + } + if ( \is_scalar( $haystack ) === false ) { + throw new TypeError( + \sprintf( + 'Argument 2 passed to assertStringContainsStringIgnoringLineEndings() must be of type string, %s given', + \gettype( $haystack ) + ) + ); + } + + $needle = self::normalizeLineEndingsForIgnoringLineEndingsAssertions( (string) $needle ); + $haystack = self::normalizeLineEndingsForIgnoringLineEndingsAssertions( (string) $haystack ); + + static::assertStringContainsString( $needle, $haystack, $message ); + } + + /** + * Normalize line endings. + * + * @param string $value The text to normalize. + * + * @return string + */ + private static function normalizeLineEndingsForIgnoringLineEndingsAssertions( $value ) { + return \strtr( + $value, + [ + "\r\n" => "\n", + "\r" => "\n", + ] + ); + } +} diff --git a/src/Polyfills/AssertIgnoringLineEndings_Empty.php b/src/Polyfills/AssertIgnoringLineEndings_Empty.php new file mode 100644 index 0000000..d75154b --- /dev/null +++ b/src/Polyfills/AssertIgnoringLineEndings_Empty.php @@ -0,0 +1,10 @@ += 10.0.0 in which this polyfill is not needed. + * + * @since 2.0.0 + */ +trait AssertIgnoringLineEndings {} diff --git a/src/Polyfills/AssertIsList.php b/src/Polyfills/AssertIsList.php new file mode 100644 index 0000000..f1c4134 --- /dev/null +++ b/src/Polyfills/AssertIsList.php @@ -0,0 +1,102 @@ += 10.0.0 in which this polyfill is not needed. + * + * @since 2.0.0 + */ +trait AssertIsList {} diff --git a/src/Polyfills/AssertIsType.php b/src/Polyfills/AssertIsType.php index 2d42f01..34007d6 100644 --- a/src/Polyfills/AssertIsType.php +++ b/src/Polyfills/AssertIsType.php @@ -25,7 +25,7 @@ trait AssertIsType { * * @return void */ - public static function assertIsArray( $actual, $message = '' ) { + final public static function assertIsArray( $actual, $message = '' ) { static::assertInternalType( 'array', $actual, $message ); } @@ -37,7 +37,7 @@ public static function assertIsArray( $actual, $message = '' ) { * * @return void */ - public static function assertIsBool( $actual, $message = '' ) { + final public static function assertIsBool( $actual, $message = '' ) { static::assertInternalType( 'bool', $actual, $message ); } @@ -49,7 +49,7 @@ public static function assertIsBool( $actual, $message = '' ) { * * @return void */ - public static function assertIsFloat( $actual, $message = '' ) { + final public static function assertIsFloat( $actual, $message = '' ) { static::assertInternalType( 'float', $actual, $message ); } @@ -61,7 +61,7 @@ public static function assertIsFloat( $actual, $message = '' ) { * * @return void */ - public static function assertIsInt( $actual, $message = '' ) { + final public static function assertIsInt( $actual, $message = '' ) { static::assertInternalType( 'int', $actual, $message ); } @@ -73,7 +73,7 @@ public static function assertIsInt( $actual, $message = '' ) { * * @return void */ - public static function assertIsNumeric( $actual, $message = '' ) { + final public static function assertIsNumeric( $actual, $message = '' ) { static::assertInternalType( 'numeric', $actual, $message ); } @@ -85,7 +85,7 @@ public static function assertIsNumeric( $actual, $message = '' ) { * * @return void */ - public static function assertIsObject( $actual, $message = '' ) { + final public static function assertIsObject( $actual, $message = '' ) { static::assertInternalType( 'object', $actual, $message ); } @@ -97,7 +97,7 @@ public static function assertIsObject( $actual, $message = '' ) { * * @return void */ - public static function assertIsResource( $actual, $message = '' ) { + final public static function assertIsResource( $actual, $message = '' ) { static::assertInternalType( 'resource', $actual, $message ); } @@ -109,7 +109,7 @@ public static function assertIsResource( $actual, $message = '' ) { * * @return void */ - public static function assertIsString( $actual, $message = '' ) { + final public static function assertIsString( $actual, $message = '' ) { static::assertInternalType( 'string', $actual, $message ); } @@ -121,7 +121,7 @@ public static function assertIsString( $actual, $message = '' ) { * * @return void */ - public static function assertIsScalar( $actual, $message = '' ) { + final public static function assertIsScalar( $actual, $message = '' ) { static::assertInternalType( 'scalar', $actual, $message ); } @@ -133,7 +133,7 @@ public static function assertIsScalar( $actual, $message = '' ) { * * @return void */ - public static function assertIsCallable( $actual, $message = '' ) { + final public static function assertIsCallable( $actual, $message = '' ) { static::assertInternalType( 'callable', $actual, $message ); } @@ -152,7 +152,7 @@ public static function assertIsCallable( $actual, $message = '' ) { * * @return void */ - public static function assertIsIterable( $actual, $message = '' ) { + final public static function assertIsIterable( $actual, $message = '' ) { if ( \function_exists( 'is_iterable' ) === true ) { // PHP >= 7.1. // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.is_iterableFound @@ -173,7 +173,7 @@ public static function assertIsIterable( $actual, $message = '' ) { * * @return void */ - public static function assertIsNotArray( $actual, $message = '' ) { + final public static function assertIsNotArray( $actual, $message = '' ) { static::assertNotInternalType( 'array', $actual, $message ); } @@ -185,7 +185,7 @@ public static function assertIsNotArray( $actual, $message = '' ) { * * @return void */ - public static function assertIsNotBool( $actual, $message = '' ) { + final public static function assertIsNotBool( $actual, $message = '' ) { static::assertNotInternalType( 'bool', $actual, $message ); } @@ -197,7 +197,7 @@ public static function assertIsNotBool( $actual, $message = '' ) { * * @return void */ - public static function assertIsNotFloat( $actual, $message = '' ) { + final public static function assertIsNotFloat( $actual, $message = '' ) { static::assertNotInternalType( 'float', $actual, $message ); } @@ -209,7 +209,7 @@ public static function assertIsNotFloat( $actual, $message = '' ) { * * @return void */ - public static function assertIsNotInt( $actual, $message = '' ) { + final public static function assertIsNotInt( $actual, $message = '' ) { static::assertNotInternalType( 'int', $actual, $message ); } @@ -221,7 +221,7 @@ public static function assertIsNotInt( $actual, $message = '' ) { * * @return void */ - public static function assertIsNotNumeric( $actual, $message = '' ) { + final public static function assertIsNotNumeric( $actual, $message = '' ) { static::assertNotInternalType( 'numeric', $actual, $message ); } @@ -233,7 +233,7 @@ public static function assertIsNotNumeric( $actual, $message = '' ) { * * @return void */ - public static function assertIsNotObject( $actual, $message = '' ) { + final public static function assertIsNotObject( $actual, $message = '' ) { static::assertNotInternalType( 'object', $actual, $message ); } @@ -245,7 +245,7 @@ public static function assertIsNotObject( $actual, $message = '' ) { * * @return void */ - public static function assertIsNotResource( $actual, $message = '' ) { + final public static function assertIsNotResource( $actual, $message = '' ) { static::assertNotInternalType( 'resource', $actual, $message ); } @@ -257,7 +257,7 @@ public static function assertIsNotResource( $actual, $message = '' ) { * * @return void */ - public static function assertIsNotString( $actual, $message = '' ) { + final public static function assertIsNotString( $actual, $message = '' ) { static::assertNotInternalType( 'string', $actual, $message ); } @@ -269,7 +269,7 @@ public static function assertIsNotString( $actual, $message = '' ) { * * @return void */ - public static function assertIsNotScalar( $actual, $message = '' ) { + final public static function assertIsNotScalar( $actual, $message = '' ) { static::assertNotInternalType( 'scalar', $actual, $message ); } @@ -281,7 +281,7 @@ public static function assertIsNotScalar( $actual, $message = '' ) { * * @return void */ - public static function assertIsNotCallable( $actual, $message = '' ) { + final public static function assertIsNotCallable( $actual, $message = '' ) { static::assertNotInternalType( 'callable', $actual, $message ); } @@ -300,7 +300,7 @@ public static function assertIsNotCallable( $actual, $message = '' ) { * * @return void */ - public static function assertIsNotIterable( $actual, $message = '' ) { + final public static function assertIsNotIterable( $actual, $message = '' ) { if ( \function_exists( 'is_iterable' ) === true ) { // PHP >= 7.1. // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.is_iterableFound diff --git a/src/Polyfills/AssertNumericType.php b/src/Polyfills/AssertNumericType.php deleted file mode 100644 index 3fdc52d..0000000 --- a/src/Polyfills/AssertNumericType.php +++ /dev/null @@ -1,49 +0,0 @@ -= 5.0.0 in which this polyfill is not needed. - */ -trait AssertNumericType {} diff --git a/src/Polyfills/AssertObjectEquals.php b/src/Polyfills/AssertObjectEquals.php index f282a7f..0b2319e 100644 --- a/src/Polyfills/AssertObjectEquals.php +++ b/src/Polyfills/AssertObjectEquals.php @@ -50,7 +50,7 @@ trait AssertObjectEquals { * @throws TypeError When any of the passed arguments do not meet the required type. * @throws InvalidComparisonMethodException When the comparator method does not comply with the requirements. */ - public static function assertObjectEquals( $expected, $actual, $method = 'equals', $message = '' ) { + final public static function assertObjectEquals( $expected, $actual, $method = 'equals', $message = '' ) { /* * Parameter input validation. * In PHPUnit this is done via PHP native type declarations. Emulating this for the polyfill. diff --git a/src/Polyfills/AssertObjectProperty.php b/src/Polyfills/AssertObjectProperty.php new file mode 100644 index 0000000..59e7872 --- /dev/null +++ b/src/Polyfills/AssertObjectProperty.php @@ -0,0 +1,154 @@ +hasProperty( $propertyName ); + static::assertTrue( $hasProperty, $msg ); + } + + /** + * Asserts that an object does not have a specified property. + * + * @param string $propertyName The name of the property. + * @param object $object The object on which to check whether the property exists. + * @param string $message Optional failure message to display. + * + * @return void + * + * @throws TypeError When any of the passed arguments do not meet the required type. + */ + final public static function assertObjectNotHasProperty( $propertyName, $object, $message = '' ) { + /* + * Parameter input validation. + * In PHPUnit this is done via PHP native type declarations. Emulating this for the polyfill, + * including for those PHPUnit versions where we hand to a native PHPUnit alternative, as + * otherwise the method referenced in the error message would get very confusing and inconsistent. + */ + if ( \is_string( $propertyName ) === false ) { + throw new TypeError( + \sprintf( + 'Argument 1 passed to assertObjectNotHasProperty() must be of type string, %s given', + \gettype( $propertyName ) + ) + ); + } + if ( \is_object( $object ) === false ) { + throw new TypeError( + \sprintf( + 'Argument 2 passed to assertObjectNotHasProperty() must be of type object, %s given', + \gettype( $object ) + ) + ); + } + + if ( \method_exists( Assert::class, 'assertObjectNotHasAttribute' ) + && \version_compare( Autoload::getPHPUnitVersion(), '9.6.0', '<=' ) + ) { + // PHPUnit <= 9.6.0. + static::assertObjectNotHasAttribute( $propertyName, $object, $message ); + return; + } + + /* + * PHPUnit 9.6.1+ and PHPUnit 10.0.x. + * Note: letting this polyfill code kick in for PHPUnit 9.6.1+ as well + * to prevent the PHPUnit deprecation notice showing. + */ + $msg = self::assertObjectHasPropertyFailureDescription( $object ); + $msg .= \sprintf( ' does not have property "%s".', $propertyName ); + if ( $message !== '' ) { + $msg = $message . \PHP_EOL . $msg; + } + + $hasProperty = ( new ReflectionObject( $object ) )->hasProperty( $propertyName ); + static::assertFalse( $hasProperty, $msg ); + } + + /** + * Returns the description of the failure. + * + * @param object $object The object under test. + * + * @return string + */ + private static function assertObjectHasPropertyFailureDescription( $object ) { + return \sprintf( + 'Failed asserting that object of class "%s"', + \get_class( $object ) + ); + } +} diff --git a/src/Polyfills/AssertObjectProperty_Empty.php b/src/Polyfills/AssertObjectProperty_Empty.php new file mode 100644 index 0000000..6aad27e --- /dev/null +++ b/src/Polyfills/AssertObjectProperty_Empty.php @@ -0,0 +1,10 @@ += 10.1.0 in which this polyfill is not needed. + * + * @since 2.1.0 + */ +trait AssertObjectProperty {} diff --git a/src/Polyfills/AssertStringContains.php b/src/Polyfills/AssertStringContains.php index 1e6ec81..4d3c152 100644 --- a/src/Polyfills/AssertStringContains.php +++ b/src/Polyfills/AssertStringContains.php @@ -31,7 +31,7 @@ trait AssertStringContains { * * @return void */ - public static function assertStringContainsString( $needle, $haystack, $message = '' ) { + final public static function assertStringContainsString( $needle, $haystack, $message = '' ) { if ( $needle === '' ) { static::assertSame( $needle, $needle, $message ); return; @@ -49,7 +49,7 @@ public static function assertStringContainsString( $needle, $haystack, $message * * @return void */ - public static function assertStringContainsStringIgnoringCase( $needle, $haystack, $message = '' ) { + final public static function assertStringContainsStringIgnoringCase( $needle, $haystack, $message = '' ) { if ( $needle === '' ) { static::assertSame( $needle, $needle, $message ); return; @@ -67,7 +67,7 @@ public static function assertStringContainsStringIgnoringCase( $needle, $haystac * * @return void */ - public static function assertStringNotContainsString( $needle, $haystack, $message = '' ) { + final public static function assertStringNotContainsString( $needle, $haystack, $message = '' ) { if ( $needle === '' ) { $msg = "Failed asserting that '{$haystack}' does not contain \"\"."; if ( $message !== '' ) { @@ -89,7 +89,7 @@ public static function assertStringNotContainsString( $needle, $haystack, $messa * * @return void */ - public static function assertStringNotContainsStringIgnoringCase( $needle, $haystack, $message = '' ) { + final public static function assertStringNotContainsStringIgnoringCase( $needle, $haystack, $message = '' ) { if ( $needle === '' ) { $msg = "Failed asserting that '{$haystack}' does not contain \"\"."; if ( $message !== '' ) { diff --git a/src/Polyfills/AssertionRenames.php b/src/Polyfills/AssertionRenames.php index f199d58..c30480b 100644 --- a/src/Polyfills/AssertionRenames.php +++ b/src/Polyfills/AssertionRenames.php @@ -49,7 +49,7 @@ trait AssertionRenames { * * @return void */ - public static function assertIsNotReadable( $filename, $message = '' ) { + final public static function assertIsNotReadable( $filename, $message = '' ) { static::assertNotIsReadable( $filename, $message ); } @@ -61,7 +61,7 @@ public static function assertIsNotReadable( $filename, $message = '' ) { * * @return void */ - public static function assertIsNotWritable( $filename, $message = '' ) { + final public static function assertIsNotWritable( $filename, $message = '' ) { static::assertNotIsWritable( $filename, $message ); } @@ -73,7 +73,7 @@ public static function assertIsNotWritable( $filename, $message = '' ) { * * @return void */ - public static function assertDirectoryDoesNotExist( $directory, $message = '' ) { + final public static function assertDirectoryDoesNotExist( $directory, $message = '' ) { static::assertDirectoryNotExists( $directory, $message ); } @@ -85,7 +85,7 @@ public static function assertDirectoryDoesNotExist( $directory, $message = '' ) * * @return void */ - public static function assertDirectoryIsNotReadable( $directory, $message = '' ) { + final public static function assertDirectoryIsNotReadable( $directory, $message = '' ) { static::assertDirectoryNotIsReadable( $directory, $message ); } @@ -97,7 +97,7 @@ public static function assertDirectoryIsNotReadable( $directory, $message = '' ) * * @return void */ - public static function assertDirectoryIsNotWritable( $directory, $message = '' ) { + final public static function assertDirectoryIsNotWritable( $directory, $message = '' ) { static::assertDirectoryNotIsWritable( $directory, $message ); } @@ -109,7 +109,7 @@ public static function assertDirectoryIsNotWritable( $directory, $message = '' ) * * @return void */ - public static function assertFileDoesNotExist( $filename, $message = '' ) { + final public static function assertFileDoesNotExist( $filename, $message = '' ) { static::assertFileNotExists( $filename, $message ); } @@ -121,7 +121,7 @@ public static function assertFileDoesNotExist( $filename, $message = '' ) { * * @return void */ - public static function assertFileIsNotReadable( $file, $message = '' ) { + final public static function assertFileIsNotReadable( $file, $message = '' ) { static::assertFileNotIsReadable( $file, $message ); } @@ -133,7 +133,7 @@ public static function assertFileIsNotReadable( $file, $message = '' ) { * * @return void */ - public static function assertFileIsNotWritable( $file, $message = '' ) { + final public static function assertFileIsNotWritable( $file, $message = '' ) { static::assertFileNotIsWritable( $file, $message ); } @@ -146,7 +146,7 @@ public static function assertFileIsNotWritable( $file, $message = '' ) { * * @return void */ - public static function assertMatchesRegularExpression( $pattern, $string, $message = '' ) { + final public static function assertMatchesRegularExpression( $pattern, $string, $message = '' ) { static::assertRegExp( $pattern, $string, $message ); } @@ -159,7 +159,7 @@ public static function assertMatchesRegularExpression( $pattern, $string, $messa * * @return void */ - public static function assertDoesNotMatchRegularExpression( $pattern, $string, $message = '' ) { + final public static function assertDoesNotMatchRegularExpression( $pattern, $string, $message = '' ) { static::assertNotRegExp( $pattern, $string, $message ); } } diff --git a/src/Polyfills/EqualToSpecializations.php b/src/Polyfills/EqualToSpecializations.php index 2bce1ff..3b089c6 100644 --- a/src/Polyfills/EqualToSpecializations.php +++ b/src/Polyfills/EqualToSpecializations.php @@ -24,7 +24,7 @@ trait EqualToSpecializations { * * @return IsEqual|PHPUnit_Framework_Constraint_IsEqual An isEqual constraint instance. */ - public static function equalToCanonicalizing( $value ) { + final public static function equalToCanonicalizing( $value ) { return static::equalTo( $value, 0.0, 10, true, false ); } @@ -35,7 +35,7 @@ public static function equalToCanonicalizing( $value ) { * * @return IsEqual|PHPUnit_Framework_Constraint_IsEqual An isEqual constraint instance. */ - public static function equalToIgnoringCase( $value ) { + final public static function equalToIgnoringCase( $value ) { return static::equalTo( $value, 0.0, 10, false, true ); } @@ -47,7 +47,7 @@ public static function equalToIgnoringCase( $value ) { * * @return IsEqual|PHPUnit_Framework_Constraint_IsEqual An isEqual constraint instance. */ - public static function equalToWithDelta( $value, $delta ) { + final public static function equalToWithDelta( $value, $delta ) { return static::equalTo( $value, $delta, 10, false, false ); } } diff --git a/src/Polyfills/ExpectException.php b/src/Polyfills/ExpectException.php deleted file mode 100644 index 6ec0e7b..0000000 --- a/src/Polyfills/ExpectException.php +++ /dev/null @@ -1,124 +0,0 @@ -exceptionMessage = ''; - $this->exceptionCode = null; - } - - /** - * Set an expectation to receive a particular type of Exception. - * - * @param mixed $exception The name of the exception to expect. - * - * @return void - */ - public function expectException( $exception ) { - $this->setExpectedException( $exception, $this->exceptionMessage, $this->exceptionCode ); - } - - /** - * Set an expectation to receive an Exception with a particular error code. - * - * @param int|string $code The error code to expect. - * - * @return void - * - * @throws Exception When the received parameter is not of the expected input type. - */ - public function expectExceptionCode( $code ) { - if ( ! \is_int( $code ) && ! \is_string( $code ) ) { - throw PHPUnit_Util_InvalidArgumentHelper::factory( 1, 'integer or string' ); - } - - // Store the received code in case any of the other methods are called as well. - $this->exceptionCode = $code; - - $exception = $this->getExpectedException(); - $this->setExpectedException( $exception, $this->exceptionMessage, $code ); - } - - /** - * Set an expectation to receive an Exception with a particular error message. - * - * @param string $message The error message to expect. - * - * @return void - * - * @throws Exception When the received parameter is not of the expected input type. - */ - public function expectExceptionMessage( $message ) { - if ( ! \is_string( $message ) ) { - throw PHPUnit_Util_InvalidArgumentHelper::factory( 1, 'string' ); - } - - // Store the received message in case any of the other methods are called as well. - $this->exceptionMessage = $message; - - $exception = $this->getExpectedException(); - $this->setExpectedException( $exception, $message, $this->exceptionCode ); - } - - /** - * Set an expectation that an Exception message matches a pattern as per the regular expression. - * - * @param string $messageRegExp The regular expression pattern which the message should comply with. - * - * @return void - * - * @throws Exception When the received parameter is not of the expected input type. - */ - public function expectExceptionMessageRegExp( $messageRegExp ) { - if ( ! \is_string( $messageRegExp ) ) { - throw PHPUnit_Util_InvalidArgumentHelper::factory( 1, 'string' ); - } - - $exception = $this->getExpectedException(); - $this->setExpectedExceptionRegExp( $exception, $messageRegExp, $this->exceptionCode ); - } -} diff --git a/src/Polyfills/ExpectExceptionMessageMatches.php b/src/Polyfills/ExpectExceptionMessageMatches.php index 0a46c54..340605f 100644 --- a/src/Polyfills/ExpectExceptionMessageMatches.php +++ b/src/Polyfills/ExpectExceptionMessageMatches.php @@ -23,7 +23,7 @@ trait ExpectExceptionMessageMatches { * * @return void */ - public function expectExceptionMessageMatches( $regularExpression ) { + final public function expectExceptionMessageMatches( $regularExpression ) { $this->expectExceptionMessageRegExp( $regularExpression ); } } diff --git a/src/Polyfills/ExpectExceptionObject.php b/src/Polyfills/ExpectExceptionObject.php index 65e3408..682cfe6 100644 --- a/src/Polyfills/ExpectExceptionObject.php +++ b/src/Polyfills/ExpectExceptionObject.php @@ -20,7 +20,7 @@ trait ExpectExceptionObject { * * @return void */ - public function expectExceptionObject( Exception $exception ) { + final public function expectExceptionObject( Exception $exception ) { $this->expectException( \get_class( $exception ) ); $this->expectExceptionMessage( $exception->getMessage() ); $this->expectExceptionCode( $exception->getCode() ); diff --git a/src/Polyfills/ExpectException_Empty.php b/src/Polyfills/ExpectException_Empty.php deleted file mode 100644 index 2a67f6d..0000000 --- a/src/Polyfills/ExpectException_Empty.php +++ /dev/null @@ -1,8 +0,0 @@ -= 5.2.0 in which this polyfill is not needed. - */ -trait ExpectException {} diff --git a/src/Polyfills/ExpectPHPException.php b/src/Polyfills/ExpectPHPException.php deleted file mode 100644 index a264010..0000000 --- a/src/Polyfills/ExpectPHPException.php +++ /dev/null @@ -1,143 +0,0 @@ -expectException( '\PHPUnit\Framework\Error\Deprecated' ); - } - - /** - * Set expectation for the message when receiving a PHP native deprecation notice. - * - * @param string $message The message to expect. - * - * @return void - */ - public function expectDeprecationMessage( $message ) { - $this->expectExceptionMessage( $message ); - } - - /** - * Set expectation for the message when receiving a PHP native deprecation notice (regex based). - * - * @param string $regularExpression A regular expression which must match the message. - * - * @return void - */ - public function expectDeprecationMessageMatches( $regularExpression ) { - $this->expectExceptionMessageRegExp( $regularExpression ); - } - - /** - * Set expectation for receiving a PHP native notice. - * - * @return void - */ - public function expectNotice() { - $this->expectException( '\PHPUnit\Framework\Error\Notice' ); - } - - /** - * Set expectation for the message when receiving a PHP native notice. - * - * @param string $message The message to expect. - * - * @return void - */ - public function expectNoticeMessage( $message ) { - $this->expectExceptionMessage( $message ); - } - - /** - * Set expectation for the message when receiving a PHP native notice (regex based). - * - * @param string $regularExpression A regular expression which must match the message. - * - * @return void - */ - public function expectNoticeMessageMatches( $regularExpression ) { - $this->expectExceptionMessageRegExp( $regularExpression ); - } - - /** - * Set expectation for receiving a PHP native warning. - * - * @return void - */ - public function expectWarning() { - $this->expectException( '\PHPUnit\Framework\Error\Warning' ); - } - - /** - * Set expectation for the message when receiving a PHP native warning. - * - * @param string $message The message to expect. - * - * @return void - */ - public function expectWarningMessage( $message ) { - $this->expectExceptionMessage( $message ); - } - - /** - * Set expectation for the message when receiving a PHP native warning (regex based). - * - * @param string $regularExpression A regular expression which must match the message. - * - * @return void - */ - public function expectWarningMessageMatches( $regularExpression ) { - $this->expectExceptionMessageRegExp( $regularExpression ); - } - - /** - * Set expectation for receiving a PHP native error. - * - * @return void - */ - public function expectError() { - $this->expectException( '\PHPUnit\Framework\Error\Error' ); - } - - /** - * Set expectation for the message when receiving a PHP native error. - * - * @param string $message The message to expect. - * - * @return void - */ - public function expectErrorMessage( $message ) { - $this->expectExceptionMessage( $message ); - } - - /** - * Set expectation for the message when receiving a PHP native error (regex based). - * - * @param string $regularExpression A regular expression which must match the message. - * - * @return void - */ - public function expectErrorMessageMatches( $regularExpression ) { - $this->expectExceptionMessageRegExp( $regularExpression ); - } -} diff --git a/src/Polyfills/ExpectPHPException_Empty.php b/src/Polyfills/ExpectPHPException_Empty.php deleted file mode 100644 index 4d787b2..0000000 --- a/src/Polyfills/ExpectPHPException_Empty.php +++ /dev/null @@ -1,8 +0,0 @@ -= 8.4.0 in which this polyfill is not needed. - */ -trait ExpectPHPException {} diff --git a/src/TestCases/TestCasePHPUnitGte8.php b/src/TestCases/TestCasePHPUnitGte8.php index cfe397c..7d89e8a 100644 --- a/src/TestCases/TestCasePHPUnitGte8.php +++ b/src/TestCases/TestCasePHPUnitGte8.php @@ -6,11 +6,13 @@ use Yoast\PHPUnitPolyfills\Helpers\AssertAttributeHelper; use Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource; use Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations; +use Yoast\PHPUnitPolyfills\Polyfills\AssertIgnoringLineEndings; use Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames; +use Yoast\PHPUnitPolyfills\Polyfills\AssertIsList; use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals; +use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty; use Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException; /** * Basic test case for use with PHPUnit >= 8. @@ -26,11 +28,13 @@ abstract class TestCase extends PHPUnit_TestCase { use AssertAttributeHelper; use AssertClosedResource; use AssertFileEqualsSpecializations; + use AssertIgnoringLineEndings; use AssertionRenames; + use AssertIsList; use AssertObjectEquals; + use AssertObjectProperty; use EqualToSpecializations; use ExpectExceptionMessageMatches; - use ExpectPHPException; /** * This method is called before the first test of this test class is run. diff --git a/src/TestCases/TestCasePHPUnitLte7.php b/src/TestCases/TestCasePHPUnitLte7.php index 34cf29b..9fb9801 100644 --- a/src/TestCases/TestCasePHPUnitLte7.php +++ b/src/TestCases/TestCasePHPUnitLte7.php @@ -6,18 +6,17 @@ use Yoast\PHPUnitPolyfills\Helpers\AssertAttributeHelper; use Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource; use Yoast\PHPUnitPolyfills\Polyfills\AssertEqualsSpecializations; -use Yoast\PHPUnitPolyfills\Polyfills\AssertFileDirectory; use Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations; +use Yoast\PHPUnitPolyfills\Polyfills\AssertIgnoringLineEndings; use Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames; +use Yoast\PHPUnitPolyfills\Polyfills\AssertIsList; use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType; -use Yoast\PHPUnitPolyfills\Polyfills\AssertNumericType; use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals; +use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty; use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains; use Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionObject; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException; /** * Basic test case for use with PHPUnit <= 7. @@ -33,18 +32,17 @@ abstract class TestCase extends PHPUnit_TestCase { use AssertAttributeHelper; use AssertClosedResource; use AssertEqualsSpecializations; - use AssertFileDirectory; use AssertFileEqualsSpecializations; + use AssertIgnoringLineEndings; use AssertionRenames; + use AssertIsList; use AssertIsType; - use AssertNumericType; use AssertObjectEquals; + use AssertObjectProperty; use AssertStringContains; use EqualToSpecializations; - use ExpectException; use ExpectExceptionMessageMatches; use ExpectExceptionObject; - use ExpectPHPException; /** * This method is called before the first test of this test class is run. diff --git a/src/TestCases/XTestCase.php b/src/TestCases/XTestCase.php index 4db9148..4d4ea25 100644 --- a/src/TestCases/XTestCase.php +++ b/src/TestCases/XTestCase.php @@ -6,18 +6,17 @@ use Yoast\PHPUnitPolyfills\Helpers\AssertAttributeHelper; use Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource; use Yoast\PHPUnitPolyfills\Polyfills\AssertEqualsSpecializations; -use Yoast\PHPUnitPolyfills\Polyfills\AssertFileDirectory; use Yoast\PHPUnitPolyfills\Polyfills\AssertFileEqualsSpecializations; +use Yoast\PHPUnitPolyfills\Polyfills\AssertIgnoringLineEndings; use Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames; +use Yoast\PHPUnitPolyfills\Polyfills\AssertIsList; use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType; -use Yoast\PHPUnitPolyfills\Polyfills\AssertNumericType; use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals; +use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectProperty; use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains; use Yoast\PHPUnitPolyfills\Polyfills\EqualToSpecializations; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionObject; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException; /** * Basic test case for use with PHPUnit cross-version. @@ -35,18 +34,17 @@ abstract class XTestCase extends PHPUnit_TestCase { use AssertAttributeHelper; use AssertClosedResource; use AssertEqualsSpecializations; - use AssertFileDirectory; use AssertFileEqualsSpecializations; + use AssertIgnoringLineEndings; use AssertionRenames; + use AssertIsList; use AssertIsType; - use AssertNumericType; use AssertObjectEquals; + use AssertObjectProperty; use AssertStringContains; use EqualToSpecializations; - use ExpectException; use ExpectExceptionMessageMatches; use ExpectExceptionObject; - use ExpectPHPException; /** * This method is called before the first test of this test class is run. diff --git a/src/TestListeners/TestListenerDefaultImplementationPHPUnitLte5.php b/src/TestListeners/TestListenerDefaultImplementationPHPUnitLte5.php index 810ae4b..ba1a255 100644 --- a/src/TestListeners/TestListenerDefaultImplementationPHPUnitLte5.php +++ b/src/TestListeners/TestListenerDefaultImplementationPHPUnitLte5.php @@ -9,7 +9,7 @@ use PHPUnit_Framework_Warning; /** - * Basic TestListener implementation for use with PHPUnit 4.x and 5.x. + * Basic TestListener implementation for use with PHPUnit 5.x. * * This TestListener trait uses renamed (snakecase) methods for all standard methods in * a TestListener to get round the method signature changes in various PHPUnit versions. @@ -20,7 +20,7 @@ * {@internal While in essence this trait is no different from the PHPUnit 6.x version, this * version is necessary as the class/interface name type declarations used in the PHPUnit 6.x * file are based on the namespaced names. As both the namespaced names as well as the - * non-namespaced names exist in PHPUnit 4.8.36+/5.7.21+, we cannot create class aliases to + * non-namespaced names exist in PHPUnit 5.7.21+, we cannot create class aliases to * get round the signature mismatch and need this trait using the old names instead.} */ trait TestListenerDefaultImplementation { diff --git a/tests/Exceptions/InvalidComparisonMethodExceptionTest.php b/tests/Exceptions/InvalidComparisonMethodExceptionTest.php new file mode 100644 index 0000000..6572d18 --- /dev/null +++ b/tests/Exceptions/InvalidComparisonMethodExceptionTest.php @@ -0,0 +1,26 @@ +assertSame( $text . \PHP_EOL, (string) $obj ); + } +} diff --git a/tests/Helpers/AssertAttributesHelperTest.php b/tests/Helpers/AssertAttributesHelperTest.php index d699807..7e194ba 100644 --- a/tests/Helpers/AssertAttributesHelperTest.php +++ b/tests/Helpers/AssertAttributesHelperTest.php @@ -2,6 +2,7 @@ namespace Yoast\PHPUnitPolyfills\Tests\Helpers; +use ReflectionException; use Yoast\PHPUnitPolyfills\TestCases\TestCase; use Yoast\PHPUnitPolyfills\Tests\Helpers\Fixtures\ClassWithProperties; @@ -65,7 +66,7 @@ public function testOriginalStatePrivateProperty() { * @return void */ public function testOriginalStateDynamicProperty() { - $this->expectException( '\ReflectionException' ); + $this->expectException( ReflectionException::class ); $this->getPropertyValue( $this->instance, 'dynamic' ); } @@ -112,10 +113,7 @@ public function testPropertyValueOnceSetPrivateProperty() { public function testPropertyValueOnceSetDynamicProperty() { $this->instance->setProperties(); - $this->assertInstanceOf( - '\Yoast\PHPUnitPolyfills\Tests\Helpers\Fixtures\ClassWithProperties', - $this->getPropertyValue( $this->instance, 'dynamic' ) - ); + $this->assertInstanceOf( ClassWithProperties::class, $this->getPropertyValue( $this->instance, 'dynamic' ) ); $this->assertFalse( $this->getProperty( $this->instance, 'dynamic' )->isDefault() ); } } diff --git a/tests/Polyfills/AssertClosedResourceNotResourceTest.php b/tests/Polyfills/AssertClosedResourceNotResourceTest.php index 4b7445c..2ba9e9f 100644 --- a/tests/Polyfills/AssertClosedResourceNotResourceTest.php +++ b/tests/Polyfills/AssertClosedResourceNotResourceTest.php @@ -2,10 +2,11 @@ namespace Yoast\PHPUnitPolyfills\Tests\Polyfills; +use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_AssertionFailedError; use stdClass; use Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches; /** @@ -17,7 +18,6 @@ final class AssertClosedResourceNotResourceTest extends TestCase { use AssertClosedResource; - use ExpectException; // Needed for PHPUnit < 5.2.0 support. use ExpectExceptionMessageMatches; /** @@ -124,10 +124,10 @@ public static function dataNotResource() { * @return string */ public function getAssertionFailedExceptionName() { - $exception = 'PHPUnit\Framework\AssertionFailedError'; - if ( \class_exists( 'PHPUnit_Framework_AssertionFailedError' ) ) { + $exception = AssertionFailedError::class; + if ( \class_exists( PHPUnit_Framework_AssertionFailedError::class ) ) { // PHPUnit < 6. - $exception = 'PHPUnit_Framework_AssertionFailedError'; + $exception = PHPUnit_Framework_AssertionFailedError::class; } return $exception; diff --git a/tests/Polyfills/AssertClosedResourceTestCase.php b/tests/Polyfills/AssertClosedResourceTestCase.php index 876e9c6..ebc6d7d 100644 --- a/tests/Polyfills/AssertClosedResourceTestCase.php +++ b/tests/Polyfills/AssertClosedResourceTestCase.php @@ -2,9 +2,10 @@ namespace Yoast\PHPUnitPolyfills\Tests\Polyfills; +use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_AssertionFailedError; use Yoast\PHPUnitPolyfills\Polyfills\AssertClosedResource; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches; /** @@ -13,7 +14,6 @@ abstract class AssertClosedResourceTestCase extends TestCase { use AssertClosedResource; - use ExpectException; // Needed for PHPUnit < 5.2.0 support. use ExpectExceptionMessageMatches; /** @@ -58,10 +58,10 @@ public function isNotClosedResourceExpectExceptionOnClosedResource( $actual ) { * @return string */ public function getAssertionFailedExceptionName() { - $exception = 'PHPUnit\Framework\AssertionFailedError'; - if ( \class_exists( 'PHPUnit_Framework_AssertionFailedError' ) ) { + $exception = AssertionFailedError::class; + if ( \class_exists( PHPUnit_Framework_AssertionFailedError::class ) ) { // PHPUnit < 6. - $exception = 'PHPUnit_Framework_AssertionFailedError'; + $exception = PHPUnit_Framework_AssertionFailedError::class; } return $exception; diff --git a/tests/Polyfills/AssertFileDirectoryTest.php b/tests/Polyfills/AssertFileDirectoryTest.php deleted file mode 100644 index 8b52737..0000000 --- a/tests/Polyfills/AssertFileDirectoryTest.php +++ /dev/null @@ -1,529 +0,0 @@ -assertIsReadable( $path ); - } - - /** - * Test the "invalid argument" exception if a non-string exception code is passed. - * - * This exception was thrown until PHP 7.0.0. Since PHP 7.0.0, a PHP native TypeError will - * be thrown based on the type declaration. - */ - public function testAssertIsReadableException() { - try { - $this->assertIsReadable( null ); - } catch ( PHPUnit_Exception $e ) { - // PHPUnit < 7.0.0. - $this->assertMatchesRegularExpression( - '`^Argument #1 \([^)]+\) of [^:]+::assertIsReadable\(\) must be a string`', - $e->getMessage() - ); - return; - } catch ( TypeError $e ) { - // PHPUnit >= 7.0.0. - $regex = '`^Argument 1 passed to [^:]+::assertIsReadable\(\) must be of the type string`'; - if ( \PHP_MAJOR_VERSION === 8 ) { - $regex = '`^[^:]+::assertIsReadable\(\): Argument \#1 \([^)]+\) must be of type string`'; - } - - $this->assertMatchesRegularExpression( $regex, $e->getMessage() ); - return; - } - - $this->fail( 'Failed to assert that the expected "invalid argument" exception was thrown' ); - } - - /** - * Verify that the assertIsReadable() method fails a test with the correct custom failure message, - * when the custom $message parameter has been passed. - * - * @return void - */ - public function testAssertIsReadableFailsWithCustomMessage() { - $pattern = '`^This assertion failed for reason XYZ\s+Failed asserting that ".+?" is readable`'; - - $this->expectException( $this->getAssertionFailedExceptionName() ); - $this->expectExceptionMessageMatches( $pattern ); - - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting.php'; - $this->assertIsReadable( $path, 'This assertion failed for reason XYZ' ); - } - - /** - * Verify availability of the assertNotIsReadable() method. - * - * @requires PHPUnit < 9.1.0 - * - * @return void - */ - public function testAssertNotIsReadable() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting.php'; - static::assertNotIsReadable( $path ); - } - - /** - * Test the "invalid argument" exception if a non-string exception code is passed. - * - * This exception was thrown until PHP 7.0.0. Since PHP 7.0.0, a PHP native TypeError will - * be thrown based on the type declaration. - * - * @requires PHPUnit < 10.0.0 - */ - public function testAssertNotIsReadableException() { - try { - $this->assertNotIsReadable( [ 123 ] ); - } catch ( PHPUnit_Exception $e ) { - // PHPUnit < 7.0.0. - $this->assertMatchesRegularExpression( - '`^Argument #1 \([^)]+\) of [^:]+::assertNotIsReadable\(\) must be a string`', - $e->getMessage() - ); - return; - } catch ( TypeError $e ) { - // PHPUnit >= 7.0.0. - $regex = '`^Argument 1 passed to [^:]+::assertNotIsReadable\(\) must be of the type string`'; - if ( \PHP_MAJOR_VERSION === 8 ) { - $regex = '`^[^:]+::assertNotIsReadable\(\): Argument \#1 \([^)]+\) must be of type string`'; - } - - $this->assertMatchesRegularExpression( $regex, $e->getMessage() ); - return; - } - - $this->fail( 'Failed to assert that the expected "invalid argument" exception was thrown' ); - } - - /** - * Verify that the assertNotIsReadable() method fails a test with the correct custom failure message, - * when the custom $message parameter has been passed. - * - * @requires PHPUnit < 9.1.0 - * - * @return void - */ - public function testAssertNotIsReadableFailsWithCustomMessage() { - $pattern = '`^This assertion failed for reason XYZ\s+Failed asserting that ".+?" is not readable`'; - - $this->expectException( $this->getAssertionFailedExceptionName() ); - $this->expectExceptionMessageMatches( $pattern ); - - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'Fixtures/AssertFileDirectory_Readable.txt'; - $this->assertNotIsReadable( $path, 'This assertion failed for reason XYZ' ); - } - - /** - * Verify availability of the assertIsWritable() method. - * - * @return void - */ - public function testAssertIsWritable() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'Fixtures/AssertFileDirectory_Readable.txt'; - $this->assertIsWritable( $path ); - } - - /** - * Test the "invalid argument" exception if a non-string exception code is passed. - * - * This exception was thrown until PHP 7.0.0. Since PHP 7.0.0, a PHP native TypeError will - * be thrown based on the type declaration. - */ - public function testAssertIsWritableException() { - try { - self::assertIsWritable( new stdClass() ); - } catch ( PHPUnit_Exception $e ) { - // PHPUnit < 7.0.0. - $this->assertMatchesRegularExpression( - '`^Argument #1 \([^)]+\) of [^:]+::assertIsWritable\(\) must be a string`', - $e->getMessage() - ); - return; - } catch ( TypeError $e ) { - // PHPUnit >= 7.0.0. - $regex = '`^Argument 1 passed to [^:]+::assertIsWritable\(\) must be of the type string`'; - if ( \PHP_MAJOR_VERSION === 8 ) { - $regex = '`^[^:]+::assertIsWritable\(\): Argument \#1 \([^)]+\) must be of type string`'; - } - - $this->assertMatchesRegularExpression( $regex, $e->getMessage() ); - return; - } - - $this->fail( 'Failed to assert that the expected "invalid argument" exception was thrown' ); - } - - /** - * Verify that the assertIsWritable() method fails a test with the correct custom failure message, - * when the custom $message parameter has been passed. - * - * @return void - */ - public function testAssertIsWritableFailsWithCustomMessage() { - $pattern = '`^This assertion failed for reason XYZ\s+Failed asserting that ".+?" is writable`'; - - $this->expectException( $this->getAssertionFailedExceptionName() ); - $this->expectExceptionMessageMatches( $pattern ); - - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting' . \DIRECTORY_SEPARATOR; - $this->assertIsWritable( $path, 'This assertion failed for reason XYZ' ); - } - - /** - * Verify availability of the assertNotIsWritable() method. - * - * @requires PHPUnit < 9.1.0 - * - * @return void - */ - public function testAssertNotIsWritable() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting' . \DIRECTORY_SEPARATOR; - self::assertNotIsWritable( $path ); - } - - /** - * Test the "invalid argument" exception if a non-string exception code is passed. - * - * This exception was thrown until PHP 7.0.0. Since PHP 7.0.0, a PHP native TypeError will - * be thrown based on the type declaration. - * - * @requires PHPUnit < 10.0.0 - */ - public function testAssertNotIsWritableException() { - try { - $this->assertNotIsWritable( null ); - } catch ( PHPUnit_Exception $e ) { - // PHPUnit < 7.0.0. - $this->assertMatchesRegularExpression( - '`^Argument #1 \([^)]+\) of [^:]+::assertNotIsWritable\(\) must be a string`', - $e->getMessage() - ); - return; - } catch ( TypeError $e ) { - // PHPUnit >= 7.0.0. - $regex = '`^Argument 1 passed to [^:]+::assertNotIsWritable\(\) must be of the type string`'; - if ( \PHP_MAJOR_VERSION === 8 ) { - $regex = '`^[^:]+::assertNotIsWritable\(\): Argument \#1 \([^)]+\) must be of type string`'; - } - - $this->assertMatchesRegularExpression( $regex, $e->getMessage() ); - return; - } - - $this->fail( 'Failed to assert that the expected "invalid argument" exception was thrown' ); - } - - /** - * Verify that the assertNotIsWritable() method fails a test with the correct custom failure message, - * when the custom $message parameter has been passed. - * - * @requires PHPUnit < 9.1.0 - * - * @return void - */ - public function testAssertNotIsWritableFailsWithCustomMessage() { - $pattern = '`^This assertion failed for reason XYZ\s+Failed asserting that ".+?" is not writable`'; - - $this->expectException( $this->getAssertionFailedExceptionName() ); - $this->expectExceptionMessageMatches( $pattern ); - - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'Fixtures/AssertFileDirectory_Readable.txt'; - $this->assertNotIsWritable( $path, 'This assertion failed for reason XYZ' ); - } - - /** - * Verify availability of the assertDirectoryExists() method. - * - * @return void - */ - public function testAssertDirectoryExists() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'Fixtures' . \DIRECTORY_SEPARATOR; - $this->assertDirectoryExists( $path ); - } - - /** - * Test the "invalid argument" exception if a non-string exception code is passed. - * - * This exception was thrown until PHP 7.0.0. Since PHP 7.0.0, a PHP native TypeError will - * be thrown based on the type declaration. - */ - public function testAssertDirectoryExistsException() { - try { - $this->assertDirectoryExists( [] ); - } catch ( PHPUnit_Exception $e ) { - // PHPUnit < 7.0.0. - $this->assertMatchesRegularExpression( - '`^Argument #1 \([^)]+\) of [^:]+::assertDirectoryExists\(\) must be a string`', - $e->getMessage() - ); - return; - } catch ( TypeError $e ) { - // PHPUnit >= 7.0.0. - $regex = '`^Argument 1 passed to [^:]+::assertDirectoryExists\(\) must be of the type string`'; - if ( \PHP_MAJOR_VERSION === 8 ) { - $regex = '`^[^:]+::assertDirectoryExists\(\): Argument \#1 \([^)]+\) must be of type string`'; - } - - $this->assertMatchesRegularExpression( $regex, $e->getMessage() ); - return; - } - - $this->fail( 'Failed to assert that the expected "invalid argument" exception was thrown' ); - } - - /** - * Verify that the assertDirectoryExists() method fails a test with the correct custom failure message, - * when the custom $message parameter has been passed. - * - * @return void - */ - public function testAssertDirectoryExistsFailsWithCustomMessage() { - $pattern = '`^This assertion failed for reason XYZ\s+Failed asserting that directory ".+?" exists`'; - - $this->expectException( $this->getAssertionFailedExceptionName() ); - $this->expectExceptionMessageMatches( $pattern ); - - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting' . \DIRECTORY_SEPARATOR; - $this->assertDirectoryExists( $path, 'This assertion failed for reason XYZ' ); - } - - /** - * Verify availability of the assertDirectoryNotExists() method. - * - * @requires PHPUnit < 9.1.0 - * - * @return void - */ - public function testAssertDirectoryNotExists() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting' . \DIRECTORY_SEPARATOR; - static::assertDirectoryNotExists( $path ); - } - - /** - * Test the "invalid argument" exception if a non-string exception code is passed. - * - * This exception was thrown until PHP 7.0.0. Since PHP 7.0.0, a PHP native TypeError will - * be thrown based on the type declaration. - * - * @requires PHPUnit < 10.0.0 - */ - public function testAssertDirectoryNotExistsException() { - try { - $this->assertDirectoryNotExists( new stdClass() ); - } catch ( PHPUnit_Exception $e ) { - // PHPUnit < 7.0.0. - $this->assertMatchesRegularExpression( - '`^Argument #1 \([^)]+\) of [^:]+::assertDirectoryNotExists\(\) must be a string`', - $e->getMessage() - ); - return; - } catch ( TypeError $e ) { - // PHPUnit >= 7.0.0. - $regex = '`^Argument 1 passed to [^:]+::assertDirectoryNotExists\(\) must be of the type string`'; - if ( \PHP_MAJOR_VERSION === 8 ) { - $regex = '`^[^:]+::assertDirectoryNotExists\(\): Argument \#1 \([^)]+\) must be of type string`'; - } - - $this->assertMatchesRegularExpression( $regex, $e->getMessage() ); - return; - } - - $this->fail( 'Failed to assert that the expected "invalid argument" exception was thrown' ); - } - - /** - * Verify that the assertDirectoryNotExists() method fails a test with the correct custom failure message, - * when the custom $message parameter has been passed. - * - * @requires PHPUnit < 9.1.0 - * - * @return void - */ - public function testAssertDirectoryNotExistsFailsWithCustomMessage() { - $pattern = '`^This assertion failed for reason XYZ\s+Failed asserting that directory ".+?" does not exist`'; - - $this->expectException( $this->getAssertionFailedExceptionName() ); - $this->expectExceptionMessageMatches( $pattern ); - - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'Fixtures' . \DIRECTORY_SEPARATOR; - $this->assertDirectoryNotExists( $path, 'This assertion failed for reason XYZ' ); - } - - /** - * Verify availability of the assertDirectoryIsReadable() method. - * - * @return void - */ - public function testAssertDirectoryIsReadable() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'Fixtures' . \DIRECTORY_SEPARATOR; - $this->assertDirectoryIsReadable( $path ); - } - - /** - * Verify availability of the assertDirectoryNotIsReadable() method. - * - * @requires PHPUnit < 9.1.0 - * - * @return void - */ - public function testAssertDirectoryNotIsReadable() { - if ( \DIRECTORY_SEPARATOR === '\\' ) { - // The actual behaviour of the assertion cannot be tested on Windows. - $this->assertIsCallable( - [ $this, 'assertDirectoryNotIsReadable' ], - 'Assertion "assertDirectoryNotIsReadable()" is not callable' - ); - return; - } - - $dirName = \sys_get_temp_dir() . \DIRECTORY_SEPARATOR . \uniqid( 'unreadable_dir_', true ); - \mkdir( $dirName, \octdec( '0' ) ); - - $this->assertDirectoryNotIsReadable( $dirName ); - - \rmdir( $dirName ); - } - - /** - * Verify availability of the assertDirectoryIsWritable() method. - * - * @return void - */ - public function testAssertDirectoryIsWritable() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'Fixtures' . \DIRECTORY_SEPARATOR; - self::assertDirectoryIsWritable( $path ); - } - - /** - * Verify availability of the assertDirectoryNotIsWritable() method. - * - * @requires PHPUnit < 9.1.0 - * - * @return void - */ - public function testAssertDirectoryNotIsWritable() { - if ( \DIRECTORY_SEPARATOR === '\\' ) { - // The actual behaviour of the assertion cannot be tested on Windows. - $this->assertIsCallable( - [ $this, 'assertDirectoryNotIsWritable' ], - 'Assertion "assertDirectoryNotIsWritable()" is not callable' - ); - return; - } - - $dirName = \sys_get_temp_dir() . \DIRECTORY_SEPARATOR . \uniqid( 'not_writable_dir_', true ); - \mkdir( $dirName, \octdec( '444' ) ); - - $this->assertDirectoryNotIsWritable( $dirName ); - - \rmdir( $dirName ); - } - - /** - * Verify availability of the assertFileIsReadable() method. - * - * @return void - */ - public function testAssertFileIsReadable() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'Fixtures/AssertFileDirectory_Readable.txt'; - $this->assertFileIsReadable( $path ); - } - - /** - * Verify availability of the assertFileNotIsReadable() method. - * - * @requires PHPUnit < 9.1.0 - * - * @return void - */ - public function testAssertFileNotIsReadable() { - if ( \DIRECTORY_SEPARATOR === '\\' ) { - // The actual behaviour of the assertion cannot be tested on Windows. - $this->assertIsCallable( - [ $this, 'assertFileNotIsReadable' ], - 'Assertion "assertFileNotIsReadable()" is not callable' - ); - return; - } - - $tempFile = \tempnam( \sys_get_temp_dir(), 'unreadable' ); - \chmod( $tempFile, \octdec( '0' ) ); - - self::assertFileNotIsReadable( $tempFile ); - - \chmod( $tempFile, \octdec( '755' ) ); - \unlink( $tempFile ); - } - - /** - * Verify availability of the assertFileIsWritable() method. - * - * @return void - */ - public function testAssertFileIsWritable() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'Fixtures/AssertFileDirectory_Readable.txt'; - self::assertFileIsWritable( $path ); - } - - /** - * Verify availability of the assertFileNotIsWritable() method. - * - * @requires PHPUnit < 9.1.0 - * - * @return void - */ - public function testAssertFileNotIsWritable() { - $tempFile = \tempnam( \sys_get_temp_dir(), 'not_writable' ); - \chmod( $tempFile, \octdec( '0' ) ); - - $this->assertFileNotIsWritable( $tempFile ); - - \chmod( $tempFile, \octdec( '755' ) ); - \unlink( $tempFile ); - } - - /** - * Helper function: retrieve the name of the "assertion failed" exception to expect (PHPUnit cross-version). - * - * @return string - */ - public function getAssertionFailedExceptionName() { - $exception = 'PHPUnit\Framework\AssertionFailedError'; - if ( \class_exists( 'PHPUnit_Framework_AssertionFailedError' ) ) { - // PHPUnit < 6. - $exception = 'PHPUnit_Framework_AssertionFailedError'; - } - - return $exception; - } -} diff --git a/tests/Polyfills/AssertFileEqualsSpecializationsTest.php b/tests/Polyfills/AssertFileEqualsSpecializationsTest.php index 0732a47..a511d05 100644 --- a/tests/Polyfills/AssertFileEqualsSpecializationsTest.php +++ b/tests/Polyfills/AssertFileEqualsSpecializationsTest.php @@ -14,15 +14,15 @@ final class AssertFileEqualsSpecializationsTest extends TestCase { use AssertFileEqualsSpecializations; - const PATH_TO_EXPECTED = '/Fixtures/AssertFileEqualsSpecialization_Expected.txt'; + const PATH_TO_EXPECTED = __DIR__ . '/Fixtures/AssertFileEqualsSpecialization_Expected.txt'; - const PATH_TO_EQUALS = '/Fixtures/AssertFileEqualsSpecialization_Equals.txt'; + const PATH_TO_EQUALS = __DIR__ . '/Fixtures/AssertFileEqualsSpecialization_Equals.txt'; - const PATH_TO_NOT_EQUALS = '/Fixtures/AssertFileEqualsSpecialization_NotEquals.txt'; + const PATH_TO_NOT_EQUALS = __DIR__ . '/Fixtures/AssertFileEqualsSpecialization_NotEquals.txt'; - const PATH_TO_EQUALS_CI = '/Fixtures/AssertFileEqualsSpecialization_EqualsCI.txt'; + const PATH_TO_EQUALS_CI = __DIR__ . '/Fixtures/AssertFileEqualsSpecialization_EqualsCI.txt'; - const PATH_TO_NOT_EQUALS_CI = '/Fixtures/AssertFileEqualsSpecialization_NotEqualsCI.txt'; + const PATH_TO_NOT_EQUALS_CI = __DIR__ . '/Fixtures/AssertFileEqualsSpecialization_NotEqualsCI.txt'; /** * Verify availability of the assertFileEqualsCanonicalizing() method. @@ -30,9 +30,7 @@ final class AssertFileEqualsSpecializationsTest extends TestCase { * @return void */ public function testAssertFileEqualsCanonicalizing() { - $expected = __DIR__ . self::PATH_TO_EXPECTED; - $input = __DIR__ . self::PATH_TO_EQUALS; - $this->assertFileEqualsCanonicalizing( $expected, $input ); + $this->assertFileEqualsCanonicalizing( self::PATH_TO_EXPECTED, self::PATH_TO_EQUALS ); } /** @@ -41,9 +39,7 @@ public function testAssertFileEqualsCanonicalizing() { * @return void */ public function testAssertFileEqualsIgnoringCase() { - $expected = __DIR__ . self::PATH_TO_EXPECTED; - $input = __DIR__ . self::PATH_TO_EQUALS_CI; - self::assertFileEqualsIgnoringCase( $expected, $input ); + self::assertFileEqualsIgnoringCase( self::PATH_TO_EXPECTED, self::PATH_TO_EQUALS_CI ); } /** @@ -52,9 +48,7 @@ public function testAssertFileEqualsIgnoringCase() { * @return void */ public function testAssertFileNotEqualsCanonicalizing() { - $expected = __DIR__ . self::PATH_TO_EXPECTED; - $input = __DIR__ . self::PATH_TO_NOT_EQUALS; - static::assertFileNotEqualsCanonicalizing( $expected, $input ); + static::assertFileNotEqualsCanonicalizing( self::PATH_TO_EXPECTED, self::PATH_TO_NOT_EQUALS ); } /** @@ -63,9 +57,7 @@ public function testAssertFileNotEqualsCanonicalizing() { * @return void */ public function testAssertFileNotEqualsIgnoringCase() { - $expected = __DIR__ . self::PATH_TO_EXPECTED; - $input = __DIR__ . self::PATH_TO_NOT_EQUALS_CI; - $this->assertFileNotEqualsIgnoringCase( $expected, $input ); + $this->assertFileNotEqualsIgnoringCase( self::PATH_TO_EXPECTED, self::PATH_TO_NOT_EQUALS_CI ); } /** @@ -74,7 +66,7 @@ public function testAssertFileNotEqualsIgnoringCase() { * @return void */ public function testAssertStringEqualsFileCanonicalizing() { - static::assertStringEqualsFileCanonicalizing( __DIR__ . self::PATH_TO_EXPECTED, "testing 123\n" ); + static::assertStringEqualsFileCanonicalizing( self::PATH_TO_EXPECTED, "testing 123\n" ); } /** @@ -83,7 +75,7 @@ public function testAssertStringEqualsFileCanonicalizing() { * @return void */ public function testAssertStringEqualsFileIgnoringCase() { - self::assertStringEqualsFileIgnoringCase( __DIR__ . self::PATH_TO_EXPECTED, "Testing 123\n" ); + self::assertStringEqualsFileIgnoringCase( self::PATH_TO_EXPECTED, "Testing 123\n" ); } /** @@ -92,7 +84,7 @@ public function testAssertStringEqualsFileIgnoringCase() { * @return void */ public function testAssertStringNotEqualsFileCanonicalizing() { - $this->assertStringNotEqualsFileCanonicalizing( __DIR__ . self::PATH_TO_EXPECTED, "test 123\n" ); + $this->assertStringNotEqualsFileCanonicalizing( self::PATH_TO_EXPECTED, "test 123\n" ); } /** @@ -101,6 +93,6 @@ public function testAssertStringNotEqualsFileCanonicalizing() { * @return void */ public function testAssertStringNotEqualsFileIgnoringCase() { - $this->assertStringNotEqualsFileIgnoringCase( __DIR__ . self::PATH_TO_EXPECTED, "Test 123\n" ); + $this->assertStringNotEqualsFileIgnoringCase( self::PATH_TO_EXPECTED, "Test 123\n" ); } } diff --git a/tests/Polyfills/AssertIgnoringLineEndingsTest.php b/tests/Polyfills/AssertIgnoringLineEndingsTest.php new file mode 100644 index 0000000..e73dde0 --- /dev/null +++ b/tests/Polyfills/AssertIgnoringLineEndingsTest.php @@ -0,0 +1,391 @@ += 80100 + && \version_compare( PHPUnit_Version::id(), '10.0.0', '>=' ) + ) { + $msg = 'assertStringEqualsStringIgnoringLineEndings(): Argument #1 ($expected) must be of type string, '; + } + else { + // PHP 5/7. + $msg = 'Argument 1 passed to assertStringEqualsStringIgnoringLineEndings() must be of type string, '; + } + + $this->expectException( TypeError::class ); + $this->expectExceptionMessage( $msg ); + + self::assertStringEqualsStringIgnoringLineEndings( $input, 'string' ); + } + + /** + * Verify that the assertStringEqualsStringIgnoringLineEndings() method throws a TypeError + * when the $actual parameter is not a scalar. + * + * @dataProvider dataThrowsTypeErrorOnInvalidType + * + * @param mixed $input Non-string value. + * + * @return void + */ + public function testAssertStringEqualsStringIgnoringLineEndingsThrowsTypeErrorOnInvalidTypeArg2( $input ) { + if ( \PHP_VERSION_ID >= 80100 + && \version_compare( PHPUnit_Version::id(), '10.0.0', '>=' ) + ) { + $msg = 'assertStringEqualsStringIgnoringLineEndings(): Argument #2 ($actual) must be of type string, '; + } + else { + // PHP 5/7. + $msg = 'Argument 2 passed to assertStringEqualsStringIgnoringLineEndings() must be of type string, '; + } + + $this->expectException( TypeError::class ); + $this->expectExceptionMessage( $msg ); + + static::assertStringEqualsStringIgnoringLineEndings( 'string', $input ); + } + + /** + * Verify availability and functionality of the assertStringEqualsStringIgnoringLineEndings() method. + * + * @dataProvider dataAllLineEndingVariations + * @dataProvider dataAssertStringEqualsStringIgnoringLineEndingsTypeVariations + * + * @param mixed $expected Expected value. + * @param mixed $actual The value to test. + * + * @return void + */ + public function testAssertStringEqualsStringIgnoringLineEndings( $expected, $actual ) { + self::assertStringEqualsStringIgnoringLineEndings( $expected, $actual ); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAllLineEndingVariations() { + return [ + 'lf-crlf' => [ "a\nb", "a\r\nb" ], + 'cr-crlf' => [ "a\rb", "a\r\nb" ], + 'crlf-crlf' => [ "a\r\nb", "a\r\nb" ], + 'lf-cr' => [ "a\nb", "a\rb" ], + 'cr-cr' => [ "a\rb", "a\rb" ], + 'crlf-cr' => [ "a\r\nb", "a\rb" ], + 'lf-lf' => [ "a\nb", "a\nb" ], + 'cr-lf' => [ "a\rb", "a\nb" ], + 'crlf-lf' => [ "a\r\nb", "a\nb" ], + ]; + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAssertStringEqualsStringIgnoringLineEndingsTypeVariations() { + return [ + 'comparing int with string' => [ 10, '10' ], + 'comparing int with float' => [ 10, 10.0 ], + 'comparing bool false with string' => [ false, '' ], + 'comparing bool true with string' => [ true, '1' ], + 'comparing bool true with int' => [ true, 1 ], + ]; + } + + /** + * Verify handling of the lines endings for the assertStringEqualsStringIgnoringLineEndings() method. + * + * @dataProvider dataAssertStringEqualsStringIgnoringLineEndingsFails + * + * @param mixed $expected Expected value. + * @param mixed $actual The value to test. + * + * @return void + */ + public function testAssertStringEqualsStringIgnoringLineEndingsFails( $expected, $actual ) { + + $exporter = \class_exists( Exporter::class ) ? new Exporter() : new Exporter_In_Phar(); + $msg = \sprintf( + 'Failed asserting that %s is equal to "%s" ignoring line endings.', + $exporter->export( $actual ), + self::normalizeLineEndings( $expected ) + ); + + $this->expectException( $this->getAssertionFailedExceptionName() ); + $this->expectExceptionMessage( $msg ); + + $this->assertStringEqualsStringIgnoringLineEndings( $expected, $actual ); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAssertStringEqualsStringIgnoringLineEndingsFails() { + return [ + 'lf-none' => [ "a\nb", 'ab' ], + 'cr-none' => [ "a\rb", 'ab' ], + 'crlf-none' => [ "a\r\nb", 'ab' ], + 'none-lf' => [ 'ab', "a\nb" ], + 'none-cr' => [ 'ab', "a\rb" ], + 'none-crlf' => [ 'ab', "a\r\nb" ], + ]; + } + + /** + * Verify that the assertStringEqualsStringIgnoringLineEndings() method fails a test with the correct + * custom failure message, when the custom $message parameter has been passed. + * + * @return void + */ + public function testAssertStringEqualsStringIgnoringLineEndingsFailsWithCustomMessage() { + $actual = 'ab'; + $expected = "a b\n"; + + $exporter = \class_exists( Exporter::class ) ? new Exporter() : new Exporter_In_Phar(); + $msg = \sprintf( + 'Failed asserting that %s is equal to "%s" ignoring line endings.', + $exporter->export( $actual ), + self::normalizeLineEndings( $expected ) + ); + + $pattern = '`^This assertion failed for reason XYZ\s+' . \preg_quote( $msg, '`' ) . '`s'; + + $this->expectException( $this->getAssertionFailedExceptionName() ); + $this->expectExceptionMessageMatches( $pattern ); + + $this->assertStringEqualsStringIgnoringLineEndings( $expected, $actual, 'This assertion failed for reason XYZ' ); + } + + /** + * Verify that the assertStringContainsStringIgnoringLineEndings() method throws a TypeError + * when the $needle parameter is not a scalar. + * + * @dataProvider dataThrowsTypeErrorOnInvalidType + * + * @param mixed $input Non-string value. + * + * @return void + */ + public function testAssertStringContainsStringIgnoringLineEndingsThrowsTypeErrorOnInvalidTypeArg1( $input ) { + if ( \PHP_VERSION_ID >= 80100 + && \version_compare( PHPUnit_Version::id(), '10.0.0', '>=' ) + ) { + $msg = 'assertStringContainsStringIgnoringLineEndings(): Argument #1 ($needle) must be of type string, '; + } + else { + // PHP 5/7. + $msg = 'Argument 1 passed to assertStringContainsStringIgnoringLineEndings() must be of type string, '; + } + + $this->expectException( TypeError::class ); + $this->expectExceptionMessage( $msg ); + + static::assertStringContainsStringIgnoringLineEndings( $input, 'string' ); + } + + /** + * Verify that the assertStringContainsStringIgnoringLineEndings() method throws a TypeError + * when the $haystack parameter is not a scalar. + * + * @dataProvider dataThrowsTypeErrorOnInvalidType + * + * @param mixed $input Non-string value. + * + * @return void + */ + public function testAssertStringContainsStringIgnoringLineEndingsThrowsTypeErrorOnInvalidTypeArg2( $input ) { + if ( \PHP_VERSION_ID >= 80100 + && \version_compare( PHPUnit_Version::id(), '10.0.0', '>=' ) + ) { + $msg = 'assertStringContainsStringIgnoringLineEndings(): Argument #2 ($haystack) must be of type string, '; + } + else { + // PHP 5/7. + $msg = 'Argument 2 passed to assertStringContainsStringIgnoringLineEndings() must be of type string, '; + } + + $this->expectException( TypeError::class ); + $this->expectExceptionMessage( $msg ); + + self::assertStringContainsStringIgnoringLineEndings( 'string', $input ); + } + + /** + * Verify availability and functionality of the assertStringContainsStringIgnoringLineEndings() method. + * + * @dataProvider dataAssertStringContainsStringIgnoringLineEndings + * + * @param string $needle The string to search for. + * @param string $haystack The string to treat as the haystack. + * + * @return void + */ + public function testAssertStringContainsStringIgnoringLineEndings( $needle, $haystack ) { + $this->assertStringContainsStringIgnoringLineEndings( $needle, $haystack ); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAssertStringContainsStringIgnoringLineEndings() { + return [ + 'needle is empty string' => [ '', "b\r\nc" ], + 'same string' => [ "b\nc", "b\r\nc" ], + 'needle is substring 1' => [ 'b', "a\r\nb\r\nc\r\nd" ], + 'needle is substring 2' => [ "b\nc", "a\r\nb\r\nc\r\nd" ], + 'haystack is scalar non-string' => [ '10', 24310276 ], + 'needle is scalar non-string 1' => [ 10, '24310276' ], + 'needle is scalar non-string 2' => [ false, "something\nelse" ], + 'needle is scalar non-string 3' => [ true, '123' ], + ]; + } + + /** + * Verify that the assertStringContainsStringIgnoringLineEndings() method normalizes the line endings + * of both the haystack and the needle. + * + * @link https://github.com/sebastianbergmann/phpunit/pull/5279 + * + * @dataProvider dataAllLineEndingVariations + * + * @param string $needle The string to search for. + * @param string $haystack The string to treat as the haystack. + * + * @return void + */ + public function testAssertStringContainsStringIgnoringLineEndingsBug5279( $needle, $haystack ) { + if ( \version_compare( PHPUnit_Version::id(), '10.0.0', '>=' ) + && \version_compare( PHPUnit_Version::id(), '10.0.16', '<' ) + ) { + // This bug was fixed in PHPUnit 10.0.16. + $this->markTestSkipped( 'Skipping test on PHPUnit versions which contained the bug' ); + } + + $this->assertStringContainsStringIgnoringLineEndings( $needle, $haystack ); + } + + /** + * Verify that the assertStringContainsStringIgnoringLineEndings() method fails a test + * when the needle is not found in the haystack. + * + * @dataProvider dataAssertStringContainsStringIgnoringLineEndingsFails + * + * @param string $needle The string to search for. + * @param string $haystack The string to treat as the haystack. + * + * @return void + */ + public function testAssertStringContainsStringIgnoringLineEndingsFails( $needle, $haystack ) { + $exporter = \class_exists( Exporter::class ) ? new Exporter() : new Exporter_In_Phar(); + $msg = \sprintf( + 'Failed asserting that %s contains "%s".', + $exporter->export( $haystack ), + self::normalizeLineEndings( $needle ) + ); + + $this->expectException( $this->getAssertionFailedExceptionName() ); + $this->expectExceptionMessage( $msg ); + + $this->assertStringContainsStringIgnoringLineEndings( $needle, $haystack ); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAssertStringContainsStringIgnoringLineEndingsFails() { + return [ + 'not substring' => [ 'a', 'bc' ], + 'no line endings in needle' => [ 'bc', "b\nc" ], + 'no line endings in haystack' => [ "b\nc", 'bc' ], + 'different line endings count 1' => [ "b\nc", "b\n\n\nc" ], + 'different line endings count 2' => [ "b\n\n\nc", "b\nc" ], + ]; + } + + /** + * Data provider. + * + * @return array + */ + public static function dataThrowsTypeErrorOnInvalidType() { + return [ + 'null' => [ null ], + 'array' => [ [ 'a' ] ], + 'object' => [ new stdClass() ], + ]; + } + + /** + * Helper function: retrieve the name of the "assertion failed" exception to expect (PHPUnit cross-version). + * + * @return string + */ + public function getAssertionFailedExceptionName() { + $exception = AssertionFailedError::class; + if ( \class_exists( PHPUnit_Framework_AssertionFailedError::class ) ) { + // PHPUnit < 6. + $exception = PHPUnit_Framework_AssertionFailedError::class; + } + + return $exception; + } + + /** + * Normalize line endings. + * + * @param string $value The text to normalize. + * + * @return string + */ + private static function normalizeLineEndings( $value ) { + return \strtr( + $value, + [ + "\r\n" => "\n", + "\r" => "\n", + ] + ); + } +} diff --git a/tests/Polyfills/AssertIsListTest.php b/tests/Polyfills/AssertIsListTest.php new file mode 100644 index 0000000..9b891b3 --- /dev/null +++ b/tests/Polyfills/AssertIsListTest.php @@ -0,0 +1,213 @@ +expectException( $this->getAssertionFailedExceptionName() ); + $this->expectExceptionMessageMatches( '`^Failed asserting that ' . $type . ' is a list`' ); + + $this->assertIsList( $actual ); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAssertIsListFailsOnInvalidInputType() { + // Only testing closed resource to not leak an open resource. + $resource = \fopen( __DIR__ . '/Fixtures/test.txt', 'r' ); + \fclose( $resource ); + + return [ + 'null' => [ + 'actual' => null, + 'type' => '(a )?null', + ], + 'boolean' => [ + 'actual' => true, + 'type' => 'a boolean', + ], + 'integer' => [ + 'actual' => 10, + 'type' => 'an integer', + ], + 'float' => [ + 'actual' => 5.34, + 'type' => 'a float', + ], + 'string' => [ + 'actual' => 'text', + 'type' => 'a string', + ], + 'object' => [ + 'actual' => new stdClass(), + 'type' => 'an object', + ], + 'closed resource' => [ + 'actual' => $resource, + 'type' => ( \PHP_VERSION_ID > 70200 ) ? 'a (value of )?closed resource' : 'a value of unknown type', + ], + ]; + } + + /** + * Verify availability and functionality of the assertIsList() method. + * + * @dataProvider dataAssertIsListPass + * + * @param array $actual The value to test. + * + * @return void + */ + public function testAssertIsListPass( $actual ) { + $this->assertIsList( $actual ); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAssertIsListPass() { + return [ + 'empty array' => [ [] ], + 'array without keys (integer values)' => [ [ 0, 1, 2 ] ], + 'array without keys (mixed values)' => [ [ 'string', 1.5, new stdClass(), [], null ] ], + 'array with consecutive numeric keys (ascending)' => [ + [ + 0 => 0, + 1 => 1, + 2 => 2, + ], + ], + 'array with partial keys, starting at 0' => [ + [ + 0 => 'apple', + 'orange', + ], + ], + ]; + } + + /** + * Verify that the assertIsList() method throws an error when the passed $array is not a list. + * + * @dataProvider dataAssertIsListFail + * + * @param array $actual The value to test. + * + * @return void + */ + public function testAssertIsListFail( $actual ) { + $this->expectException( $this->getAssertionFailedExceptionName() ); + $this->expectExceptionMessage( 'Failed asserting that an array is a list' ); + + static::assertIsList( $actual ); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAssertIsListFail() { + return [ + 'array with non-consecutive numeric keys' => [ + [ + 0 => 0, + 2 => 2, + 3 => 3, + ], + ], + 'array with consecutive numeric keys not starting at 0' => [ + [ + 3 => 0, + 4 => 1, + 5 => 2, + ], + ], + 'array with consecutive numeric keys (descending)' => [ + [ + 0 => 0, + -1 => 1, + -2 => 2, + ], + ], + 'array with string keys' => [ + [ + 'a' => 0, + 'b' => 1, + ], + ], + 'array with partial string keys' => [ + [ + 'a' => 'apple', + 'orange', + ], + ], + ]; + } + + /** + * Verify that the assertIsList() method fails a test with a custom failure message, + * when the custom $message parameter has been passed. + * + * @return void + */ + public function testAssertIsListFailsWithCustomMessage() { + $pattern = '`^This assertion failed for reason XYZ\s+Failed asserting that an array is a list\.`'; + + $this->expectException( $this->getAssertionFailedExceptionName() ); + $this->expectExceptionMessageMatches( $pattern ); + + $array = [ + 0 => 0, + 2 => 2, + ]; + + $this->assertIsList( $array, 'This assertion failed for reason XYZ' ); + } + + /** + * Helper function: retrieve the name of the "assertion failed" exception to expect (PHPUnit cross-version). + * + * @return string + */ + public function getAssertionFailedExceptionName() { + $exception = AssertionFailedError::class; + if ( \class_exists( PHPUnit_Framework_AssertionFailedError::class ) ) { + // PHPUnit < 6. + $exception = PHPUnit_Framework_AssertionFailedError::class; + } + + return $exception; + } +} diff --git a/tests/Polyfills/AssertNumericTypeTest.php b/tests/Polyfills/AssertNumericTypeTest.php deleted file mode 100644 index d82d8ed..0000000 --- a/tests/Polyfills/AssertNumericTypeTest.php +++ /dev/null @@ -1,43 +0,0 @@ -assertFinite( 1 ); - } - - /** - * Verify availability of the assertInfinite() method. - * - * @return void - */ - public function testAssertInfinite() { - $this->assertInfinite( \log( 0 ) ); - } - - /** - * Verify availability of the assertNan() method. - * - * @return void - */ - public function testAssertNan() { - self::assertNan( \acos( 8 ) ); - } -} diff --git a/tests/Polyfills/AssertObjectEqualsPHPUnitLt940Test.php b/tests/Polyfills/AssertObjectEqualsPHPUnitLt940Test.php index eb27e10..f248324 100644 --- a/tests/Polyfills/AssertObjectEqualsPHPUnitLt940Test.php +++ b/tests/Polyfills/AssertObjectEqualsPHPUnitLt940Test.php @@ -2,11 +2,14 @@ namespace Yoast\PHPUnitPolyfills\Tests\Polyfills; +use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\TestCase; use PHPUnit\Runner\Version as PHPUnit_Version; +use PHPUnit_Framework_AssertionFailedError; use stdClass; +use TypeError; +use Yoast\PHPUnitPolyfills\Exceptions\InvalidComparisonMethodException; use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectNoReturnType; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectUnionNoReturnType; @@ -28,7 +31,6 @@ final class AssertObjectEqualsPHPUnitLt940Test extends TestCase { use AssertObjectEquals; - use ExpectException; // Needed for PHPUnit < 5.2.0 support. use ExpectExceptionMessageMatches; /** @@ -37,7 +39,7 @@ final class AssertObjectEqualsPHPUnitLt940Test extends TestCase { * * @var string */ - const COMPARATOR_EXCEPTION = 'Yoast\PHPUnitPolyfills\Exceptions\InvalidComparisonMethodException'; + const COMPARATOR_EXCEPTION = InvalidComparisonMethodException::class; /** * Check if these tests can run. @@ -86,7 +88,7 @@ public function testAssertObjectEqualsCustomMethodName() { public function testAssertObjectEqualsFailsOnExpectedNotObject() { $pattern = '`^Argument 1 passed to [^\s]*assertObjectEquals\(\) must be an object, string given`'; - $this->expectException( 'TypeError' ); + $this->expectException( TypeError::class ); $this->expectExceptionMessageMatches( $pattern ); $actual = new ValueObjectNoReturnType( 'test' ); @@ -101,7 +103,7 @@ public function testAssertObjectEqualsFailsOnExpectedNotObject() { public function testAssertObjectEqualsFailsOnActualNotObject() { $pattern = '`^Argument 2 passed to [^\s]*assertObjectEquals\(\) must be an object, string given`'; - $this->expectException( 'TypeError' ); + $this->expectException( TypeError::class ); $this->expectExceptionMessageMatches( $pattern ); $expected = new ValueObjectNoReturnType( 'test' ); @@ -117,7 +119,7 @@ public function testAssertObjectEqualsFailsOnActualNotObject() { public function testAssertObjectEqualsFailsOnMethodNotJuggleableToString() { $pattern = '`^Argument 3 passed to [^\s]*assertObjectEquals\(\) must be of the type string, array given`'; - $this->expectException( 'TypeError' ); + $this->expectException( TypeError::class ); $this->expectExceptionMessageMatches( $pattern ); $expected = new ValueObjectNoReturnType( 'test' ); @@ -320,10 +322,10 @@ public function testAssertObjectEqualsFailsAsNotEqualWithCustomMessage() { * @return string */ public function getAssertionFailedExceptionName() { - $exception = 'PHPUnit\Framework\AssertionFailedError'; - if ( \class_exists( 'PHPUnit_Framework_AssertionFailedError' ) ) { + $exception = AssertionFailedError::class; + if ( \class_exists( PHPUnit_Framework_AssertionFailedError::class ) ) { // PHPUnit < 6. - $exception = 'PHPUnit_Framework_AssertionFailedError'; + $exception = PHPUnit_Framework_AssertionFailedError::class; } return $exception; diff --git a/tests/Polyfills/AssertObjectEqualsTest.php b/tests/Polyfills/AssertObjectEqualsTest.php index 5899ec2..71d114a 100644 --- a/tests/Polyfills/AssertObjectEqualsTest.php +++ b/tests/Polyfills/AssertObjectEqualsTest.php @@ -2,11 +2,19 @@ namespace Yoast\PHPUnitPolyfills\Tests\Polyfills; +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\ComparisonMethodDoesNotAcceptParameterTypeException; +use PHPUnit\Framework\ComparisonMethodDoesNotDeclareBoolReturnTypeException; +use PHPUnit\Framework\ComparisonMethodDoesNotDeclareExactlyOneParameterException; +use PHPUnit\Framework\ComparisonMethodDoesNotDeclareParameterTypeException; +use PHPUnit\Framework\ComparisonMethodDoesNotExistException; use PHPUnit\Framework\TestCase; use PHPUnit\Runner\Version as PHPUnit_Version; +use PHPUnit_Framework_AssertionFailedError; use stdClass; +use TypeError; +use Yoast\PHPUnitPolyfills\Exceptions\InvalidComparisonMethodException; use Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ChildValueObject; use Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject; @@ -18,7 +26,7 @@ * Due to the use of return types in the classes under test (fixtures), these * tests can only run on PHP 7.0 and higher. * - * The `AssertObjectEqualsPHPUnitLt930Test` class mirrors this test class + * The `AssertObjectEqualsPHPUnitLt940Test` class mirrors this test class * and tests the polyfill method for PHP < 7.0. * * @covers \Yoast\PHPUnitPolyfills\Polyfills\AssertObjectEquals @@ -28,7 +36,6 @@ final class AssertObjectEqualsTest extends TestCase { use AssertObjectEquals; - use ExpectException; // Needed for PHPUnit < 5.2.0 support. use ExpectExceptionMessageMatches; /** @@ -37,7 +44,7 @@ final class AssertObjectEqualsTest extends TestCase { * * @var string */ - const COMPARATOR_EXCEPTION = 'Yoast\PHPUnitPolyfills\Exceptions\InvalidComparisonMethodException'; + const COMPARATOR_EXCEPTION = InvalidComparisonMethodException::class; /** * Verify availability of the assertObjectEquals() method. @@ -89,7 +96,7 @@ public function testAssertObjectEqualsActualChildOfExpected() { * @return void */ public function testAssertObjectEqualsFailsOnExpectedNotObject() { - $this->expectException( 'TypeError' ); + $this->expectException( TypeError::class ); if ( \PHP_VERSION_ID >= 80000 && \version_compare( PHPUnit_Version::id(), '9.4.0', '>=' ) @@ -113,7 +120,7 @@ public function testAssertObjectEqualsFailsOnExpectedNotObject() { * @return void */ public function testAssertObjectEqualsFailsOnActualNotObject() { - $this->expectException( 'TypeError' ); + $this->expectException( TypeError::class ); if ( \PHP_VERSION_ID >= 80000 && \version_compare( PHPUnit_Version::id(), '9.4.0', '>=' ) @@ -138,7 +145,7 @@ public function testAssertObjectEqualsFailsOnActualNotObject() { * @return void */ public function testAssertObjectEqualsFailsOnMethodNotJuggleableToString() { - $this->expectException( 'TypeError' ); + $this->expectException( TypeError::class ); if ( \PHP_VERSION_ID >= 80000 && \version_compare( PHPUnit_Version::id(), '9.4.0', '>=' ) @@ -167,9 +174,9 @@ public function testAssertObjectEqualsFailsOnMethodNotDeclared() { $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::doesNotExist() does not exist.'; $exception = self::COMPARATOR_EXCEPTION; - if ( \class_exists( 'PHPUnit\Framework\ComparisonMethodDoesNotExistException' ) ) { + if ( \class_exists( ComparisonMethodDoesNotExistException::class ) ) { // PHPUnit > 9.4.0. - $exception = 'PHPUnit\Framework\ComparisonMethodDoesNotExistException'; + $exception = ComparisonMethodDoesNotExistException::class; } $this->expectException( $exception ); @@ -189,9 +196,9 @@ public function testAssertObjectEqualsFailsOnMethodAllowsForMoreParams() { $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equalsTwoParams() does not declare exactly one parameter.'; $exception = self::COMPARATOR_EXCEPTION; - if ( \class_exists( 'PHPUnit\Framework\ComparisonMethodDoesNotDeclareExactlyOneParameterException' ) ) { + if ( \class_exists( ComparisonMethodDoesNotDeclareExactlyOneParameterException::class ) ) { // PHPUnit > 9.4.0. - $exception = 'PHPUnit\Framework\ComparisonMethodDoesNotDeclareExactlyOneParameterException'; + $exception = ComparisonMethodDoesNotDeclareExactlyOneParameterException::class; } $this->expectException( $exception ); @@ -211,9 +218,9 @@ public function testAssertObjectEqualsFailsOnMethodParamNotRequired() { $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equalsParamNotRequired() does not declare exactly one parameter.'; $exception = self::COMPARATOR_EXCEPTION; - if ( \class_exists( 'PHPUnit\Framework\ComparisonMethodDoesNotDeclareExactlyOneParameterException' ) ) { + if ( \class_exists( ComparisonMethodDoesNotDeclareExactlyOneParameterException::class ) ) { // PHPUnit > 9.4.0. - $exception = 'PHPUnit\Framework\ComparisonMethodDoesNotDeclareExactlyOneParameterException'; + $exception = ComparisonMethodDoesNotDeclareExactlyOneParameterException::class; } $this->expectException( $exception ); @@ -234,9 +241,9 @@ public function testAssertObjectEqualsFailsOnMethodParamMissingTypeDeclaration() $msg = 'Parameter of comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equalsParamNoType() does not have a declared type.'; $exception = self::COMPARATOR_EXCEPTION; - if ( \class_exists( 'PHPUnit\Framework\ComparisonMethodDoesNotDeclareParameterTypeException' ) ) { + if ( \class_exists( ComparisonMethodDoesNotDeclareParameterTypeException::class ) ) { // PHPUnit > 9.4.0. - $exception = 'PHPUnit\Framework\ComparisonMethodDoesNotDeclareParameterTypeException'; + $exception = ComparisonMethodDoesNotDeclareParameterTypeException::class; } $this->expectException( $exception ); @@ -259,9 +266,9 @@ public function testAssertObjectEqualsFailsOnMethodParamHasUnionTypeDeclaration( $msg = 'Parameter of comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObjectUnion::equalsParamUnionType() does not have a declared type.'; $exception = self::COMPARATOR_EXCEPTION; - if ( \class_exists( 'PHPUnit\Framework\ComparisonMethodDoesNotDeclareParameterTypeException' ) ) { + if ( \class_exists( ComparisonMethodDoesNotDeclareParameterTypeException::class ) ) { // PHPUnit > 9.4.0. - $exception = 'PHPUnit\Framework\ComparisonMethodDoesNotDeclareParameterTypeException'; + $exception = ComparisonMethodDoesNotDeclareParameterTypeException::class; } $this->expectException( $exception ); @@ -282,9 +289,9 @@ public function testAssertObjectEqualsFailsOnMethodParamNonClassTypeDeclaration( $msg = 'is not an accepted argument type for comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equalsParamNonClassType().'; $exception = self::COMPARATOR_EXCEPTION; - if ( \class_exists( 'PHPUnit\Framework\ComparisonMethodDoesNotAcceptParameterTypeException' ) ) { + if ( \class_exists( ComparisonMethodDoesNotAcceptParameterTypeException::class ) ) { // PHPUnit > 9.4.0. - $exception = 'PHPUnit\Framework\ComparisonMethodDoesNotAcceptParameterTypeException'; + $exception = ComparisonMethodDoesNotAcceptParameterTypeException::class; } $this->expectException( $exception ); @@ -305,9 +312,9 @@ public function testAssertObjectEqualsFailsOnMethodParamNonExistentClassTypeDecl $msg = 'is not an accepted argument type for comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equalsParamNonExistentClassType().'; $exception = self::COMPARATOR_EXCEPTION; - if ( \class_exists( 'PHPUnit\Framework\ComparisonMethodDoesNotAcceptParameterTypeException' ) ) { + if ( \class_exists( ComparisonMethodDoesNotAcceptParameterTypeException::class ) ) { // PHPUnit > 9.4.0. - $exception = 'PHPUnit\Framework\ComparisonMethodDoesNotAcceptParameterTypeException'; + $exception = ComparisonMethodDoesNotAcceptParameterTypeException::class; } $this->expectException( $exception ); @@ -328,9 +335,9 @@ public function testAssertObjectEqualsFailsOnMethodParamTypeMismatch() { $msg = 'is not an accepted argument type for comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equals().'; $exception = self::COMPARATOR_EXCEPTION; - if ( \class_exists( 'PHPUnit\Framework\ComparisonMethodDoesNotAcceptParameterTypeException' ) ) { + if ( \class_exists( ComparisonMethodDoesNotAcceptParameterTypeException::class ) ) { // PHPUnit > 9.4.0. - $exception = 'PHPUnit\Framework\ComparisonMethodDoesNotAcceptParameterTypeException'; + $exception = ComparisonMethodDoesNotAcceptParameterTypeException::class; } $this->expectException( $exception ); @@ -350,10 +357,10 @@ public function testAssertObjectEqualsFailsOnNonBooleanReturnValue() { $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equalsNonBooleanReturnType() does not return a boolean value.'; $exception = self::COMPARATOR_EXCEPTION; - if ( \class_exists( 'PHPUnit\Framework\ComparisonMethodDoesNotDeclareBoolReturnTypeException' ) ) { + if ( \class_exists( ComparisonMethodDoesNotDeclareBoolReturnTypeException::class ) ) { // PHPUnit > 9.4.0. $msg = 'Comparison method Yoast\PHPUnitPolyfills\Tests\Polyfills\Fixtures\ValueObject::equalsNonBooleanReturnType() does not declare bool return type.'; - $exception = 'PHPUnit\Framework\ComparisonMethodDoesNotDeclareBoolReturnTypeException'; + $exception = ComparisonMethodDoesNotDeclareBoolReturnTypeException::class; } $this->expectException( $exception ); @@ -404,10 +411,10 @@ public function testAssertObjectEqualsFailsAsNotEqualWithCustomMessage() { * @return string */ public function getAssertionFailedExceptionName() { - $exception = 'PHPUnit\Framework\AssertionFailedError'; - if ( \class_exists( 'PHPUnit_Framework_AssertionFailedError' ) ) { + $exception = AssertionFailedError::class; + if ( \class_exists( PHPUnit_Framework_AssertionFailedError::class ) ) { // PHPUnit < 6. - $exception = 'PHPUnit_Framework_AssertionFailedError'; + $exception = PHPUnit_Framework_AssertionFailedError::class; } return $exception; diff --git a/tests/Polyfills/AssertObjectPropertyTest.php b/tests/Polyfills/AssertObjectPropertyTest.php new file mode 100644 index 0000000..70c1489 --- /dev/null +++ b/tests/Polyfills/AssertObjectPropertyTest.php @@ -0,0 +1,323 @@ +=' ) ) { + $this->markTestSkipped( 'PHPUnit native implementation relies on strict_types and when not used will accept scalar inputs' ); + } + + if ( \PHP_VERSION_ID >= 80100 + && \version_compare( PHPUnit_Version::id(), '10.1.0', '>=' ) + ) { + $msg = 'assertObjectHasProperty(): Argument #1 ($propertyName) must be of type string, '; + } + else { + // PHP 5/7. + $msg = 'Argument 1 passed to assertObjectHasProperty() must be of type string, '; + } + + $this->expectException( TypeError::class ); + $this->expectExceptionMessage( $msg ); + + $this->assertObjectHasProperty( $input, new stdClass() ); + } + + /** + * Verify that the assertObjectNotHasProperty() method throws an error when the $propertyName parameter is not a scalar. + * + * @dataProvider dataAssertObjectPropertyFailsOnInvalidInputTypePropertyName + * + * @param mixed $input Non-scalar value. + * + * @return void + */ + public function testAssertObjectNotHasPropertyFailsOnInvalidInputTypePropertyName( $input ) { + if ( \is_scalar( $input ) && \version_compare( PHPUnit_Version::id(), '10.1.0', '>=' ) ) { + $this->markTestSkipped( 'PHPUnit native implementation relies on strict_types and when not used will accept scalar inputs' ); + } + + if ( \PHP_VERSION_ID >= 80100 + && \version_compare( PHPUnit_Version::id(), '10.1.0', '>=' ) + ) { + $msg = 'assertObjectNotHasProperty(): Argument #1 ($propertyName) must be of type string, '; + } + else { + // PHP 5/7. + $msg = 'Argument 1 passed to assertObjectNotHasProperty() must be of type string, '; + } + + $this->expectException( TypeError::class ); + $this->expectExceptionMessage( $msg ); + + $this->assertObjectNotHasProperty( $input, new stdClass() ); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAssertObjectPropertyFailsOnInvalidInputTypePropertyName() { + // Only testing closed resource to not leak an open resource. + $resource = \fopen( __DIR__ . '/Fixtures/test.txt', 'r' ); + \fclose( $resource ); + + return [ + 'null' => [ null ], + 'boolean' => [ true ], + 'integer' => [ 10 ], + 'float' => [ 5.34 ], + 'array' => [ [ 1, 2, 3 ] ], + 'object' => [ new stdClass() ], + 'closed resource' => [ $resource ], + ]; + } + + /** + * Verify that the assertObjectHasProperty() method throws an error when the $object parameter is not an object. + * + * @dataProvider dataAssertObjectPropertyFailsOnInvalidInputTypeObject + * + * @param mixed $input Non-object value. + * + * @return void + */ + public function testAssertObjectHasPropertyFailsOnInvalidInputTypeObject( $input ) { + if ( \PHP_VERSION_ID >= 80100 + && \version_compare( PHPUnit_Version::id(), '10.1.0', '>=' ) + ) { + $msg = 'assertObjectHasProperty(): Argument #2 ($object) must be of type object, '; + } + else { + // PHP 5/7. + $msg = 'Argument 2 passed to assertObjectHasProperty() must be of type object, '; + } + + $this->expectException( TypeError::class ); + $this->expectExceptionMessage( $msg ); + + $this->assertObjectHasProperty( 'propertyName', $input ); + } + + /** + * Verify that the assertObjectNotHasProperty() method throws an error when the $object parameter is not an object. + * + * @dataProvider dataAssertObjectPropertyFailsOnInvalidInputTypeObject + * + * @param mixed $input Non-object value. + * + * @return void + */ + public function testAssertObjectNotHasPropertyFailsOnInvalidInputTypeObject( $input ) { + if ( \PHP_VERSION_ID >= 80100 + && \version_compare( PHPUnit_Version::id(), '10.1.0', '>=' ) + ) { + $msg = 'assertObjectNotHasProperty(): Argument #2 ($object) must be of type object, '; + } + else { + // PHP 5/7. + $msg = 'Argument 2 passed to assertObjectNotHasProperty() must be of type object, '; + } + + $this->expectException( TypeError::class ); + $this->expectExceptionMessage( $msg ); + + static::assertObjectNotHasProperty( 'propertyName', $input ); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAssertObjectPropertyFailsOnInvalidInputTypeObject() { + // Only testing closed resource to not leak an open resource. + $resource = \fopen( __DIR__ . '/Fixtures/test.txt', 'r' ); + \fclose( $resource ); + + return [ + 'null' => [ null ], + 'boolean' => [ true ], + 'integer' => [ 10 ], + 'float' => [ 5.34 ], + 'string' => [ 'text' ], + 'array' => [ [ 1, 2, 3 ] ], + 'closed resource' => [ $resource ], + ]; + } + + /** + * Verify availability and functionality of the assertObjectHasProperty() method. + * + * @dataProvider dataAssertObjectPropertyDeclaredProps + * + * @param string $name The property name to look for. + * + * @return void + */ + public function testAssertObjectHasPropertyPass( $name ) { + $this->assertObjectHasProperty( $name, new ObjectWithProperties() ); + } + + /** + * Verify availability and functionality of the assertObjectNotHasProperty() method. + * + * @dataProvider dataAssertObjectPropertyUnavailableProps + * + * @param string $name The property name to look for. + * + * @return void + */ + public function testAssertObjectNotHasPropertyPass( $name ) { + self::assertObjectNotHasProperty( $name, new ObjectWithProperties() ); + } + + /** + * Verify that the assertObjectHasProperty() method throws an error when the property does not exist on the object. + * + * @dataProvider dataAssertObjectPropertyUnavailableProps + * + * @param string $name The property name to look for. + * + * @return void + */ + public function testAssertObjectHasPropertyFails( $name ) { + $pattern = \sprintf( + '`^Failed asserting that object of class "[^\s]*ObjectWithProperties" has (?:property|attribute) "%s"\.`', + \preg_quote( $name, '`' ) + ); + + $this->expectException( $this->getAssertionFailedExceptionName() ); + $this->expectExceptionMessageMatches( $pattern ); + + static::assertObjectHasProperty( $name, new ObjectWithProperties() ); + } + + /** + * Verify that the assertObjectNotHasProperty() method throws an error when the property does exist on the object. + * + * @dataProvider dataAssertObjectPropertyDeclaredProps + * + * @param string $name The property name to look for. + * + * @return void + */ + public function testAssertObjectNotHasPropertyFails( $name ) { + $pattern = \sprintf( + '`^Failed asserting that object of class "[^\s]*ObjectWithProperties" does not have (?:property|attribute) "%s"\.`', + \preg_quote( $name, '`' ) + ); + + $this->expectException( $this->getAssertionFailedExceptionName() ); + $this->expectExceptionMessageMatches( $pattern ); + + $this->assertObjectNotHasProperty( $name, new ObjectWithProperties() ); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAssertObjectPropertyDeclaredProps() { + return [ + 'declared public property without default' => [ 'publicNoDefaultValue' ], + 'declared protected property without default' => [ 'protectedNoDefaultValue' ], + 'declared private property without default' => [ 'privateNoDefaultValue' ], + 'declared public property with default' => [ 'publicWithDefaultValue' ], + 'declared protected property with default' => [ 'protectedWithDefaultValue' ], + 'declared private property with default' => [ 'privateWithDefaultValue' ], + 'unset declared public property' => [ 'unsetPublic' ], + 'unset declared protected property' => [ 'unsetProtected' ], + 'unset declared private property' => [ 'unsetPrivate' ], + ]; + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAssertObjectPropertyUnavailableProps() { + return [ + 'property which is not declared' => [ 'doesNotExist' ], + ]; + } + + /** + * Verify that the assertObjectHasProperty() method fails a test with a custom failure message, + * when the custom $message parameter has been passed. + * + * @return void + */ + public function testAssertObjectHasPropertyFailsWithCustomMessage() { + $pattern = '`^This assertion failed for reason XYZ\s+Failed asserting that object of class `'; + + $this->expectException( $this->getAssertionFailedExceptionName() ); + $this->expectExceptionMessageMatches( $pattern ); + + $this->assertObjectHasProperty( 'doesNotExist', new ObjectWithProperties(), 'This assertion failed for reason XYZ' ); + } + + /** + * Verify that the assertObjectNotHasProperty() method fails a test with a custom failure message, + * when the custom $message parameter has been passed. + * + * @return void + */ + public function testAssertObjectNotHasPropertyFailsWithCustomMessage() { + $pattern = '`^This assertion failed for reason XYZ\s+Failed asserting that object of class `'; + + $this->expectException( $this->getAssertionFailedExceptionName() ); + $this->expectExceptionMessageMatches( $pattern ); + + $this->assertObjectNotHasProperty( 'protectedWithDefaultValue', new ObjectWithProperties(), 'This assertion failed for reason XYZ' ); + } + + /** + * Helper function: retrieve the name of the "assertion failed" exception to expect (PHPUnit cross-version). + * + * @return string + */ + public function getAssertionFailedExceptionName() { + $exception = AssertionFailedError::class; + if ( \class_exists( PHPUnit_Framework_AssertionFailedError::class ) ) { + // PHPUnit < 6. + $exception = PHPUnit_Framework_AssertionFailedError::class; + } + + return $exception; + } +} diff --git a/tests/Polyfills/AssertStringContainsTest.php b/tests/Polyfills/AssertStringContainsTest.php index 06d6308..ba89bc4 100644 --- a/tests/Polyfills/AssertStringContainsTest.php +++ b/tests/Polyfills/AssertStringContainsTest.php @@ -2,9 +2,10 @@ namespace Yoast\PHPUnitPolyfills\Tests\Polyfills; +use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_AssertionFailedError; use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches; /** @@ -15,7 +16,6 @@ final class AssertStringContainsTest extends TestCase { use AssertStringContains; - use ExpectException; // Needed for PHPUnit < 5.2.0 support. use ExpectExceptionMessageMatches; /** @@ -183,10 +183,10 @@ public function testssertStringNotContainsStringIgnoringCaseFailsWithCustomMessa * @return string */ public function getAssertionFailedExceptionName() { - $exception = 'PHPUnit\Framework\AssertionFailedError'; - if ( \class_exists( 'PHPUnit_Framework_AssertionFailedError' ) ) { + $exception = AssertionFailedError::class; + if ( \class_exists( PHPUnit_Framework_AssertionFailedError::class ) ) { // PHPUnit < 6. - $exception = 'PHPUnit_Framework_AssertionFailedError'; + $exception = PHPUnit_Framework_AssertionFailedError::class; } return $exception; diff --git a/tests/Polyfills/AssertionRenamesTest.php b/tests/Polyfills/AssertionRenamesTest.php index 8e47d58..e4baed3 100644 --- a/tests/Polyfills/AssertionRenamesTest.php +++ b/tests/Polyfills/AssertionRenamesTest.php @@ -3,7 +3,6 @@ namespace Yoast\PHPUnitPolyfills\Tests\Polyfills; use PHPUnit\Framework\TestCase; -use Yoast\PHPUnitPolyfills\Polyfills\AssertFileDirectory; use Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames; use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType; @@ -14,18 +13,20 @@ */ final class AssertionRenamesTest extends TestCase { - use AssertFileDirectory; // Needed for PHPUnit < 5.6.0 support. use AssertionRenames; use AssertIsType; + const NOT_EXISTENT_FILE = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting.php'; + + const NOT_EXISTENT_DIR = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting' . \DIRECTORY_SEPARATOR; + /** * Verify availability of the assertIsNotReadable() method. * * @return void */ public function testAssertIsNotReadable() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting.php'; - $this->assertIsNotReadable( $path ); + $this->assertIsNotReadable( self::NOT_EXISTENT_FILE ); } /** @@ -34,8 +35,7 @@ public function testAssertIsNotReadable() { * @return void */ public function testAssertIsNotWritable() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting' . \DIRECTORY_SEPARATOR; - self::assertIsNotWritable( $path ); + self::assertIsNotWritable( self::NOT_EXISTENT_DIR ); } /** @@ -44,8 +44,7 @@ public function testAssertIsNotWritable() { * @return void */ public function testAssertDirectoryDoesNotExist() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting' . \DIRECTORY_SEPARATOR; - static::assertDirectoryDoesNotExist( $path ); + static::assertDirectoryDoesNotExist( self::NOT_EXISTENT_DIR ); } /** @@ -100,8 +99,7 @@ public function testAssertDirectoryIsNotWritable() { * @return void */ public function testAssertFileDoesNotExist() { - $path = __DIR__ . \DIRECTORY_SEPARATOR . 'NotExisting.php'; - static::assertFileDoesNotExist( $path ); + static::assertFileDoesNotExist( self::NOT_EXISTENT_FILE ); } /** diff --git a/tests/Polyfills/ExpectExceptionMessageMatchesTest.php b/tests/Polyfills/ExpectExceptionMessageMatchesTest.php index b1a1ff0..c6cf0ba 100644 --- a/tests/Polyfills/ExpectExceptionMessageMatchesTest.php +++ b/tests/Polyfills/ExpectExceptionMessageMatchesTest.php @@ -4,7 +4,6 @@ use Exception; use PHPUnit\Framework\TestCase; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionMessageMatches; /** @@ -14,7 +13,6 @@ */ final class ExpectExceptionMessageMatchesTest extends TestCase { - use ExpectException; // Needed for PHPUnit < 5.2.0 support. use ExpectExceptionMessageMatches; /** @@ -25,7 +23,7 @@ final class ExpectExceptionMessageMatchesTest extends TestCase { * @throws Exception For testing purposes. */ public function testExpectExceptionMessageMatches() { - $this->expectException( '\Exception' ); // Needed for PHPUnit 4.x/5.x. + $this->expectException( Exception::class ); // Needed for PHPUnit 5.x. $this->expectExceptionMessageMatches( '`^a poly[a-z]+ [a-zA-Z0-9_]+ me(s){2}age$`i' ); throw new Exception( 'A polymorphic exception message' ); diff --git a/tests/Polyfills/ExpectExceptionObjectTest.php b/tests/Polyfills/ExpectExceptionObjectTest.php index 0be95b7..888b516 100644 --- a/tests/Polyfills/ExpectExceptionObjectTest.php +++ b/tests/Polyfills/ExpectExceptionObjectTest.php @@ -4,7 +4,6 @@ use Exception; use PHPUnit\Framework\TestCase; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionObject; /** @@ -14,7 +13,6 @@ */ final class ExpectExceptionObjectTest extends TestCase { - use ExpectException; // Needed for PHPUnit < 5.2.0 support. use ExpectExceptionObject; /** diff --git a/tests/Polyfills/ExpectExceptionTest.php b/tests/Polyfills/ExpectExceptionTest.php deleted file mode 100644 index ac2bf38..0000000 --- a/tests/Polyfills/ExpectExceptionTest.php +++ /dev/null @@ -1,382 +0,0 @@ -expectException( '\Exception' ); - - throw new Exception( 'message' ); - } - - /** - * Verify availability of the expectExceptionCode() method. - * - * @return void - * - * @throws Exception For testing purposes. - */ - public function testExpectExceptionCode() { - $this->expectException( '\Exception' ); - $this->expectExceptionCode( 404 ); - - throw new Exception( '', 404 ); - } - - /** - * Test the "invalid argument" exception if a non-int/string exception code is passed. - * - * This exception was thrown in PHPUnit < 7.0.0, after which it was removed. - * PHPUnit introduces parameter type declaration in PHPUnit 7.0.0, but didn't for - * this method as it needs union types. - * - * @requires PHPUnit < 7 - */ - public function testExpectExceptionCodeException() { - $test = new InvalidExceptionCodeTestCase( 'test' ); - $result = new TestResult(); - $test->run( $result ); - - $this->assertSame( 1, $this->getErrorCount( $result ) ); - $this->assertSame( 1, \count( $result ) ); - $this->assertMatchesRegularExpression( - '`^Argument #1 \([^)]+\) of [^:]+::expectExceptionCode\(\) must be a integer or string`', - $this->getMessageContent( $test ) - ); - } - - /** - * Verify availability of the expectExceptionMessage() method. - * - * @return void - * - * @throws Exception For testing purposes. - */ - public function testExpectExceptionMessage() { - $this->expectException( '\Exception' ); - $this->expectExceptionMessage( 'message' ); - - throw new Exception( 'message' ); - } - - /** - * Test the "invalid argument" exception if a non-string exception message is passed. - * - * This exception was thrown until PHP 7.0.0. Since PHP 7.0.0, a PHP native TypeError will - * be thrown based on the type declaration. - * - * @return void - */ - public function testExpectExceptionMessageException() { - $regex = '`^Argument #1 \([^)]+\) of [^:]+::expectExceptionMessage\(\) must be a string`'; - if ( \version_compare( PHPUnit_Version::id(), '7.0.0', '>=' ) ) { - $regex = '`^Argument 1 passed to [^:]+::expectExceptionMessage\(\) must be of the type string`'; - if ( \PHP_MAJOR_VERSION === 8 ) { - $regex = '`^[^:]+::expectExceptionMessage\(\): Argument \#1 \([^)]+\) must be of type string`'; - } - } - - $test = new InvalidExceptionMessageTestCase( 'test' ); - $result = new TestResult(); - $test->run( $result ); - - $this->assertSame( 1, $this->getErrorCount( $result ) ); - $this->assertSame( 1, \count( $result ) ); - $this->assertMatchesRegularExpression( $regex, $this->getMessageContent( $test ) ); - } - - /** - * Verify that when the expectations are set individually, the polyfill sets them - * correctly as combined for older PHPUnit versions. - * - * @return void - * - * @throws Exception For testing purposes. - */ - public function testExpectExceptionMessageAndCode() { - $this->expectException( '\Exception' ); - $this->expectExceptionMessage( 'message' ); - $this->expectExceptionCode( 404 ); - - throw new Exception( 'message', 404 ); - } - - /** - * Verify that when the expectations are set individually, the polyfill sets them - * correctly as combined for older PHPUnit versions and fails on one of the expectations - * not being matched. - * - * @return void - */ - public function testExpectExceptionMessageAndCodeFailOnCode() { - $test = new ThrowExceptionTestCase( 'test' ); - $test->expectException( '\Exception' ); - $test->expectExceptionMessage( 'A runtime error occurred' ); - $test->expectExceptionCode( 404 ); - - $result = new TestResult(); - $test->run( $result ); - - $this->assertSame( 1, $this->getFailureCount( $result ) ); - $this->assertSame( 1, \count( $result ) ); - $this->assertSame( - 'Failed asserting that 999 is equal to expected exception code 404.', - $this->getMessageContent( $test ) - ); - } - - /** - * Verify that when the expectations are set individually, the polyfill sets them - * correctly as combined for older PHPUnit versions and fails on one of the expectations - * not being matched. - * - * @return void - */ - public function testExpectExceptionMessageAndCodeFailOnMsg() { - $test = new ThrowExceptionTestCase( 'test' ); - $test->expectException( '\Exception' ); - $test->expectExceptionMessage( 'message' ); - $test->expectExceptionCode( 999 ); - - $result = new TestResult(); - $test->run( $result ); - - $this->assertSame( 1, $this->getFailureCount( $result ) ); - $this->assertSame( 1, \count( $result ) ); - $this->assertSame( - "Failed asserting that exception message 'A runtime error occurred' contains 'message'.", - $this->getMessageContent( $test ) - ); - } - - /** - * Verify availability of the expectExceptionMessageRegExp() method. - * - * This test only needs to run in the PHPUnit versions where this method was - * not yet deprecated. For newer PHPUnit versions, end-users should use the - * polyfill for the `TestCase::expectExceptionMessageMatches()` method. - * - * @requires PHPUnit < 8.4.0 - * - * @return void - * - * @throws Exception For testing purposes. - */ - public function testExpectExceptionMessageRegExp() { - $this->expectException( '\Exception' ); - $this->expectExceptionMessageRegExp( '/^foo/' ); - - throw new Exception( 'foobar' ); - } - - /** - * Test the "invalid argument" exception if a non-string exception message regex is passed. - * - * This exception was thrown until PHP 7.0.0. Since PHP 7.0.0, a PHP native TypeError will - * be thrown based on the type declaration. - * - * This test only needs to run in the PHPUnit versions where this method was - * not yet deprecated. For newer PHPUnit versions, end-users should use the - * polyfill for the `TestCase::expectExceptionMessageMatches()` method. - * - * @requires PHPUnit < 8.4.0 - * - * @return void - */ - public function testExpectExceptionMessageRegExpException() { - try { - $this->expectExceptionMessageRegExp( null ); - } catch ( PHPUnit_Exception $e ) { - // PHPUnit < 7.0.0. - $this->assertMatchesRegularExpression( - '`^Argument #1 \([^)]+\) of [^:]+::expectExceptionMessageRegExp\(\) must be a string`', - $e->getMessage() - ); - return; - } catch ( TypeError $e ) { - // PHPUnit >= 7.0.0. - $regex = '`^Argument 1 passed to [^:]+::expectExceptionMessageRegExp\(\) must be of the type string`'; - if ( \PHP_MAJOR_VERSION === 8 ) { - // Just in case someone tries to run the tests with PHPUnit < 8.4 on PHP 8. - $regex = '`^[^:]+::expectExceptionMessageRegExp\(\): Argument \#1 \([^)]+\) must be of type string`'; - } - - $this->assertMatchesRegularExpression( $regex, $e->getMessage() ); - return; - } - - $this->fail( 'Failed to assert that the expected "invalid argument" exception was thrown' ); - } - - /** - * Verify that when the expectations are set individually, the polyfill sets them - * correctly as combined for older PHPUnit versions. - * - * This test only needs to run in the PHPUnit versions where this method was - * not yet deprecated. For newer PHPUnit versions, end-users should use the - * polyfill for the `TestCase::expectExceptionMessageMatches()` method. - * - * @requires PHPUnit < 8.4.0 - * - * @return void - * - * @throws Exception For testing purposes. - */ - public function testExpectExceptionMessageRegExpAndCode() { - $this->expectException( '\Exception' ); - $this->expectExceptionMessageRegExp( '/^foo/' ); - $this->expectExceptionCode( 404 ); - - throw new Exception( 'foobar', 404 ); - } - - /** - * Verify that when the expectations are set individually, the polyfill sets them - * correctly as combined for older PHPUnit versions and fails on one of the expectations - * not being matched. - * - * This test only needs to run in the PHPUnit versions where this method was - * not yet deprecated. For newer PHPUnit versions, end-users should use the - * polyfill for the `TestCase::expectExceptionMessageMatches()` method. - * - * @requires PHPUnit < 8.4.0 - * - * @return void - */ - public function testExpectExceptionMessageRegExpAndCodeFailOnCode() { - $test = new ThrowExceptionTestCase( 'test' ); - $test->expectException( '\Exception' ); - $test->expectExceptionMessageRegExp( '/^A runtime/' ); - $test->expectExceptionCode( 404 ); - - $result = new TestResult(); - $test->run( $result ); - - $this->assertSame( 1, $this->getFailureCount( $result ) ); - $this->assertSame( 1, \count( $result ) ); - $this->assertSame( - 'Failed asserting that 999 is equal to expected exception code 404.', - $this->getMessageContent( $test ) - ); - } - - /** - * Verify that when the expectations are set individually, the polyfill sets them - * correctly as combined for older PHPUnit versions and fails on one of the expectations - * not being matched. - * - * This test only needs to run in the PHPUnit versions where this method was - * not yet deprecated. For newer PHPUnit versions, end-users should use the - * polyfill for the `TestCase::expectExceptionMessageMatches()` method. - * - * @requires PHPUnit < 8.4.0 - * - * @return void - */ - public function testExpectExceptionMessageRegExpAndCodeFailOnMsg() { - $test = new ThrowExceptionTestCase( 'test' ); - $test->expectException( '\Exception' ); - $test->expectExceptionMessageRegExp( '/^foo/' ); - $test->expectExceptionCode( 999 ); - - $result = new TestResult(); - $test->run( $result ); - - $this->assertSame( 1, $this->getFailureCount( $result ) ); - $this->assertSame( 1, \count( $result ) ); - $this->assertSame( - "Failed asserting that exception message 'A runtime error occurred' matches '/^foo/'.", - $this->getMessageContent( $test ) - ); - } - - /** - * Helper method to retrieve the status message in a PHPUnit cross-version compatible manner. - * - * @param TestCase $test The test object. - * - * @return string - */ - private function getMessageContent( $test ) { - if ( \method_exists( $test, 'getStatusMessage' ) === false ) { - // PHPUnit >= 10.0.0. - return $test->status()->message(); - } - else { - // PHPUnit < 10.0.0. - return $test->getStatusMessage(); - } - - return ''; - } - - /** - * Helper method to retrieve the error count in a PHPUnit cross-version compatible manner. - * - * @param TestResult $result The test result object. - * - * @return int - */ - private function getErrorCount( $result ) { - if ( \method_exists( $result, 'errorCount' ) === false ) { - // PHPUnit >= 10.0.0. - return \count( $result->errors() ); - } - else { - // PHPUnit < 10.0.0. - return $result->errorCount(); - } - - // Make sure the number will never match if the count could not be determined. - return -1; - } - - /** - * Helper method to retrieve the failure count in a PHPUnit cross-version compatible manner. - * - * @param TestResult $result The test result object. - * - * @return int - */ - private function getFailureCount( $result ) { - if ( \method_exists( $result, 'failureCount' ) === false ) { - // PHPUnit >= 10.0.0. - return \count( $result->failures() ); - } - else { - // PHPUnit < 10.0.0. - return $result->failureCount(); - } - - // Make sure the number will never match if the count could not be determined. - return -1; - } -} diff --git a/tests/Polyfills/ExpectPHPExceptionTest.php b/tests/Polyfills/ExpectPHPExceptionTest.php deleted file mode 100644 index 7c77068..0000000 --- a/tests/Polyfills/ExpectPHPExceptionTest.php +++ /dev/null @@ -1,70 +0,0 @@ -expectDeprecation(); - $this->expectDeprecationMessage( 'foo' ); - $this->expectDeprecationMessageMatches( '/foo/' ); - - \trigger_error( 'foo', \E_USER_DEPRECATED ); - } - - /** - * Verify availability of the expectNotice*() methods. - * - * @return void - */ - public function testNoticeCanBeExpected() { - $this->expectNotice(); - $this->expectNoticeMessage( 'foo' ); - $this->expectNoticeMessageMatches( '/foo/' ); - - \trigger_error( 'foo', \E_USER_NOTICE ); - } - - /** - * Verify availability of the expectWarning*() methods. - * - * @return void - */ - public function testWarningCanBeExpected() { - $this->expectWarning(); - $this->expectWarningMessage( 'foo' ); - $this->expectWarningMessageMatches( '/foo/' ); - - \trigger_error( 'foo', \E_USER_WARNING ); - } - - /** - * Verify availability of the expectError*() methods. - * - * @return void - */ - public function testErrorCanBeExpected() { - $this->expectError(); - $this->expectErrorMessage( 'foo' ); - $this->expectErrorMessageMatches( '/foo/' ); - - \trigger_error( 'foo', \E_USER_ERROR ); - } -} diff --git a/tests/Polyfills/Fixtures/AssertFileDirectory_Readable.txt b/tests/Polyfills/Fixtures/AssertFileDirectory_Readable.txt deleted file mode 100644 index e489534..0000000 --- a/tests/Polyfills/Fixtures/AssertFileDirectory_Readable.txt +++ /dev/null @@ -1 +0,0 @@ -testing 123 diff --git a/tests/Polyfills/Fixtures/InvalidExceptionCodeTestCase.php b/tests/Polyfills/Fixtures/InvalidExceptionCodeTestCase.php deleted file mode 100644 index 240984b..0000000 --- a/tests/Polyfills/Fixtures/InvalidExceptionCodeTestCase.php +++ /dev/null @@ -1,28 +0,0 @@ -expectExceptionCode( null ); - - throw new Exception( 'A runtime error occurred', 999 ); - } -} diff --git a/tests/Polyfills/Fixtures/InvalidExceptionMessageTestCase.php b/tests/Polyfills/Fixtures/InvalidExceptionMessageTestCase.php deleted file mode 100644 index 99a25eb..0000000 --- a/tests/Polyfills/Fixtures/InvalidExceptionMessageTestCase.php +++ /dev/null @@ -1,28 +0,0 @@ -expectExceptionMessage( [ 1, 2, 3 ] ); - - throw new Exception( 'A runtime error occurred', 999 ); - } -} diff --git a/tests/Polyfills/Fixtures/ObjectWithProperties.php b/tests/Polyfills/Fixtures/ObjectWithProperties.php new file mode 100644 index 0000000..99bb0fd --- /dev/null +++ b/tests/Polyfills/Fixtures/ObjectWithProperties.php @@ -0,0 +1,83 @@ +existsButUnsetPublic, + $this->existsButUnsetProtected, + $this->existsButUnsetPrivate + ); + } +} diff --git a/tests/Polyfills/Fixtures/ThrowExceptionTestCase.php b/tests/Polyfills/Fixtures/ThrowExceptionTestCase.php deleted file mode 100644 index 794bb73..0000000 --- a/tests/Polyfills/Fixtures/ThrowExceptionTestCase.php +++ /dev/null @@ -1,28 +0,0 @@ -expectExceptionObject( $exception ); @@ -43,7 +44,7 @@ public function testAvailabilityExpectExceptionObjectTrait() { * * @return void */ - public function testAvailabilityAssertIsTypeTrait() { + final public function testAvailabilityAssertIsTypeTrait() { self::assertIsInt( self::$beforeClass ); } @@ -52,7 +53,7 @@ public function testAvailabilityAssertIsTypeTrait() { * * @return void */ - public function testAvailabilityAssertStringContainsTrait() { + final public function testAvailabilityAssertStringContainsTrait() { $this->assertStringContainsString( 'foo', 'foobar' ); } @@ -61,21 +62,10 @@ public function testAvailabilityAssertStringContainsTrait() { * * @return void */ - public function testAvailabilityAssertEqualsSpecializationsTrait() { + final public function testAvailabilityAssertEqualsSpecializationsTrait() { static::assertEqualsIgnoringCase( 'a', 'A' ); } - /** - * Test availability of trait polyfilled PHPUnit methods [5]. - * - * @return void - */ - public function testAvailabilityExpectPHPExceptionTrait() { - $this->expectDeprecation(); - - \trigger_error( 'foo', \E_USER_DEPRECATED ); - } - /** * Test availability of trait polyfilled PHPUnit methods [6]. * @@ -83,8 +73,8 @@ public function testAvailabilityExpectPHPExceptionTrait() { * * @throws Exception For testing purposes. */ - public function testAvailabilityExpectExceptionMessageMatchesTrait() { - $this->expectException( '\Exception' ); + final public function testAvailabilityExpectExceptionMessageMatchesTrait() { + $this->expectException( Exception::class ); $this->expectExceptionMessageMatches( '`^a poly[a-z]+ [a-zA-Z0-9_]+ me(s){2}age$`i' ); throw new Exception( 'A polymorphic exception message' ); @@ -95,9 +85,9 @@ public function testAvailabilityExpectExceptionMessageMatchesTrait() { * * @return void */ - public function testAvailabilityAssertFileEqualsSpecializationsTrait() { + final public function testAvailabilityAssertFileEqualsSpecializationsTrait() { self::assertStringEqualsFileIgnoringCase( - \dirname( __DIR__ ) . '/Polyfills' . AssertFileEqualsSpecializationsTest::PATH_TO_EXPECTED, + AssertFileEqualsSpecializationsTest::PATH_TO_EXPECTED, "Testing 123\n" ); } @@ -107,74 +97,71 @@ public function testAvailabilityAssertFileEqualsSpecializationsTrait() { * * @return void */ - public function testAvailabilityAssertionRenamesTrait() { + final public function testAvailabilityAssertionRenamesTrait() { $this->assertMatchesRegularExpression( '/foo/', 'foobar' ); } /** - * Verify availability of trait polyfilled PHPUnit methods [9]. + * Verify availability of trait polyfilled PHPUnit methods [12]. * * @return void */ - public function testAvailabilityAssertNumericTypeTrait() { - self::assertNan( \acos( 8 ) ); + final public function testAvailabilityAssertClosedResource() { + $resource = \fopen( __FILE__, 'r' ); + \fclose( $resource ); + + $this->assertIsClosedResource( $resource ); } /** - * Test availability of trait polyfilled PHPUnit methods [10]. + * Verify availability of trait polyfilled PHPUnit methods [13]. * * @return void - * - * @throws Exception For testing purposes. */ - public function testAvailabilityExpectExceptionTrait() { - $this->expectException( '\Exception' ); - $this->expectExceptionMessage( 'message' ); - - throw new Exception( 'message' ); + final public function testAvailabilityEqualToSpecializations() { + self::assertThat( [ 2, 3, 1 ], $this->equalToCanonicalizing( [ 3, 2, 1 ] ) ); } /** - * Verify availability of trait polyfilled PHPUnit methods [11]. + * Verify availability of trait polyfilled PHPUnit methods [14]. + * + * @requires PHP 7.0 * * @return void */ - public function testAvailabilityAssertFileDirectory() { - $path = __DIR__ . \DIRECTORY_SEPARATOR; - $this->assertDirectoryExists( $path ); + final public function testAvailabilityAssertObjectEquals() { + $expected = new ValueObject( 'test' ); + $actual = new ValueObject( 'test' ); + $this->assertObjectEquals( $expected, $actual ); } /** - * Verify availability of trait polyfilled PHPUnit methods [12]. + * Verify availability of trait polyfilled PHPUnit methods [15]. * * @return void */ - public function testAvailabilityAssertClosedResource() { - $resource = \fopen( __FILE__, 'r' ); - \fclose( $resource ); - - $this->assertIsClosedResource( $resource ); + final public function testAvailabilityAssertIgnoringLineEndings() { + self::assertStringContainsStringIgnoringLineEndings( "b\nc", "a\r\nb\r\nc\r\nd" ); } /** - * Verify availability of trait polyfilled PHPUnit methods [13]. + * Verify availability of trait polyfilled PHPUnit methods [16]. * * @return void */ - public function testAvailabilityEqualToSpecializations() { - self::assertThat( [ 2, 3, 1 ], $this->equalToCanonicalizing( [ 3, 2, 1 ] ) ); + final public function testAvailabilityAssertIsList() { + static::assertIsList( [ 0, 1, 2 ] ); } /** - * Verify availability of trait polyfilled PHPUnit methods [14]. - * - * @requires PHP 7.0 + * Verify availability of trait polyfilled PHPUnit methods [17]. * * @return void */ - public function testAvailabilityAssertObjectEquals() { - $expected = new ValueObject( 'test' ); - $actual = new ValueObject( 'test' ); - $this->assertObjectEquals( $expected, $actual ); + final public function testAvailabilityAssertObjectProperty() { + $object = new stdClass(); + $object->prop = true; + + self::assertObjectHasProperty( 'prop', $object ); } } diff --git a/tests/TestListeners/TestListenerTest.php b/tests/TestListeners/TestListenerTest.php index 7d7d805..9f95f63 100644 --- a/tests/TestListeners/TestListenerTest.php +++ b/tests/TestListeners/TestListenerTest.php @@ -13,6 +13,8 @@ * * @covers \Yoast\PHPUnitPolyfills\TestListeners\TestListenerDefaultImplementation * @covers \Yoast\PHPUnitPolyfills\TestListeners\TestListenerSnakeCaseMethods + * + * @requires PHPUnit < 10 */ final class TestListenerTest extends TestCase {