From 55446cfd6ca6a5b8eb3007e732c02da268640e5e Mon Sep 17 00:00:00 2001 From: Oleg Zhulnev Date: Wed, 13 Oct 2021 14:19:27 +0300 Subject: [PATCH] Run Infection on PHP 8.1. (#1535) * Run Infection on PHP 8.1 * update symfony deps, add ReturnTypeWillChange attribute * add check on VariadicPlaceholder * remove conflict with symfony/console 4.1.5 * try to fix Return type of Mock_SplFileInfo_8d3a072c::getPath() should either be compatible with SplFileInfo::getPath() on 8.1 * whitelist PHP 8.1 constants in scoper.inc.php * Add MockSplFileInfo mocks to work with Unit tests * Increase possible direct issues * fix another bunch of tests * export SYMFONY_DEPRECATIONS_HELPER env variable as part of CI pipeline * cast to int explicitly to avoid "Implicit conversion from float to int loses precision" * fix pipeline * remove continue-on-error on PHP 8.1 * remove ignore-platform-req from pipeline * clean up pipeline * import ReturnTypeWillChange to use section --- .github/workflows/autoreview.yaml | 3 +- .github/workflows/ci.yaml | 29 +- .github/workflows/mt-annotations.yaml | 3 +- .github/workflows/mt.yaml | 6 +- composer.json | 5 +- composer.lock | 269 +++++++++--------- scoper.inc.php | 5 + .../Iterator/RealPathFilterIterator.php | 2 + src/Mutator/Extensions/BCMath.php | 8 + src/Mutator/Extensions/MBString.php | 6 +- src/Mutator/Regex/AbstractPregMatch.php | 13 +- src/Mutator/Regex/PregMatchMatches.php | 4 + src/Mutator/Regex/PregQuote.php | 4 + src/Mutator/Unwrap/AbstractUnwrapMutator.php | 4 + .../JUnit/TestLocationBucketSorter.php | 2 +- .../phpunit/FileSystem/FileSystemTestCase.php | 10 +- .../FileSystem/SourceFileFilterTest.php | 22 +- .../Fixtures/Finder/MockSplFileInfo.php | 38 +++ tests/phpunit/Fixtures/MockSplFileInfo.php | 34 +++ tests/phpunit/IterableCounterTest.php | 3 +- .../Mutation/MutationGeneratorTest.php | 5 +- .../Runner/MutationTestingRunnerTest.php | 7 +- .../Coverage/BufferedSourceFileFilterTest.php | 14 +- .../TestFramework/Coverage/ProxyTraceTest.php | 41 +-- .../Coverage/UncoveredTraceProviderTest.php | 6 +- .../XmlReport/XmlCoverageParserTest.php | 9 +- 26 files changed, 327 insertions(+), 225 deletions(-) create mode 100644 tests/phpunit/Fixtures/Finder/MockSplFileInfo.php create mode 100644 tests/phpunit/Fixtures/MockSplFileInfo.php diff --git a/.github/workflows/autoreview.yaml b/.github/workflows/autoreview.yaml index 98873d03a..10fed5907 100644 --- a/.github/workflows/autoreview.yaml +++ b/.github/workflows/autoreview.yaml @@ -38,9 +38,8 @@ jobs: uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} - key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}-${{ matrix.dependencies }} + key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }} restore-keys: | - composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}- composer-${{ runner.os }}-${{ matrix.php-version }}- composer-${{ runner.os }}- composer- diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4e1f54298..fa8a50ec8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,16 +18,15 @@ jobs: matrix: operating-system: [ubuntu-latest] php-version: ['7.4'] - dependencies: [''] coverage-driver: [pcov, xdebug] e2e-runner: ['bin/infection'] include: - - { operating-system: 'windows-latest', php-version: '7.4', dependencies: '', coverage-driver: 'xdebug' } - - { operating-system: 'ubuntu-latest', php-version: '7.4', dependencies: '', coverage-driver: 'pcov' } - - { operating-system: 'ubuntu-latest', php-version: '8.0', dependencies: '--ignore-platform-req=php', coverage-driver: 'pcov', e2e-runner: 'build/infection.phar' } + - { operating-system: 'windows-latest', php-version: '7.4', coverage-driver: 'xdebug' } + - { operating-system: 'ubuntu-latest', php-version: '7.4', coverage-driver: 'pcov' } + - { operating-system: 'ubuntu-latest', php-version: '8.0', coverage-driver: 'pcov', e2e-runner: 'build/infection.phar' } + - { operating-system: 'ubuntu-latest', php-version: '8.1', coverage-driver: 'pcov' } - continue-on-error: ${{ matrix.php-version == '8.0' }} - name: CI on ${{ matrix.operating-system }} with PHP ${{ matrix.php-version }}, using ${{ matrix.coverage-driver }} ${{ matrix.dependencies }} with ${{ matrix.e2e-runner }} + name: CI on ${{ matrix.operating-system }} with PHP ${{ matrix.php-version }}, using ${{ matrix.coverage-driver }} with ${{ matrix.e2e-runner }} steps: - name: Checkout code @@ -49,7 +48,7 @@ jobs: uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} - key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}-${{ matrix.dependencies }} + key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }} restore-keys: | composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}- composer-${{ runner.os }}-${{ matrix.php-version }}- @@ -58,16 +57,26 @@ jobs: - name: Install dependencies run: | - composer install --no-interaction --prefer-dist --no-progress ${{ matrix.dependencies }} + composer install --no-interaction --prefer-dist --no-progress - name: Run tests shell: bash run: | + # Required as long as "PHPUnit\Runner\DefaultTestResultCache implements the Serializable interface, which is deprecated. + # Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary)" is not fixed + if [[ "${{ matrix.php-version }}" == '8.1' ]]; then + export SYMFONY_DEPRECATIONS_HELPER=max[direct]=1 + fi + make test-unit - name: Run integration tests shell: bash run: | + if [[ "${{ matrix.php-version }}" == '8.1' ]]; then + export SYMFONY_DEPRECATIONS_HELPER=max[direct]=1 + fi + make test-unit PHPUNIT_GROUP=integration - name: Cache E2E tests dependencies @@ -75,7 +84,7 @@ jobs: uses: actions/cache@v2 with: path: tests/e2e/*/vendor - key: e2e-vendor-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('tests/e2e/*/composer.json') }}-${{ matrix.dependencies }} + key: e2e-vendor-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('tests/e2e/*/composer.json') }} restore-keys: | e2e-vendor-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('tests/e2e/*/composer.json') }}- e2e-vendor-${{ runner.os }}-${{ matrix.php-version }}- @@ -86,7 +95,7 @@ jobs: shell: bash run: | ls tests/e2e/*/composer.json | xargs dirname | - xargs -I{} composer --working-dir={} install --no-interaction --prefer-dist --no-progress ${{ matrix.dependencies }} + xargs -I{} composer --working-dir={} install --no-interaction --prefer-dist --no-progress - name: Run a subset of E2E tests if: runner.os == 'Windows' diff --git a/.github/workflows/mt-annotations.yaml b/.github/workflows/mt-annotations.yaml index 889b24fc2..2b69cfa0b 100644 --- a/.github/workflows/mt-annotations.yaml +++ b/.github/workflows/mt-annotations.yaml @@ -35,9 +35,8 @@ jobs: uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} - key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}-${{ matrix.dependencies }} + key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }} restore-keys: | - composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}- composer-${{ runner.os }}-${{ matrix.php-version }}- composer-${{ runner.os }}- composer- diff --git a/.github/workflows/mt.yaml b/.github/workflows/mt.yaml index c4c7cbdc5..3182a0b3e 100644 --- a/.github/workflows/mt.yaml +++ b/.github/workflows/mt.yaml @@ -22,7 +22,6 @@ jobs: matrix: operating-system: [ubuntu-latest, windows-latest] php-version: ['7.4'] - dependencies: [''] coverage-driver: [pcov] name: Mutation testing on ${{ matrix.operating-system }} with PHP ${{ matrix.php-version }}, using ${{ matrix.coverage-driver }} @@ -46,16 +45,15 @@ jobs: uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} - key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}-${{ matrix.dependencies }} + key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }} restore-keys: | - composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}- composer-${{ runner.os }}-${{ matrix.php-version }}- composer-${{ runner.os }}- composer- - name: Install dependencies run: | - composer update --no-interaction --prefer-dist --no-progress ${{ matrix.dependencies }} + composer update --no-interaction --prefer-dist --no-progress - name: Collect coverage report run: | diff --git a/composer.json b/composer.json index 42b2db2e5..29a1d8bda 100644 --- a/composer.json +++ b/composer.json @@ -52,7 +52,7 @@ "infection/extension-installer": "^0.1.0", "infection/include-interceptor": "^0.2.5", "justinrainbow/json-schema": "^5.2.10", - "nikic/php-parser": "^4.10.3", + "nikic/php-parser": "^4.13", "ondram/ci-detector": "^3.3.0", "sanmai/later": "^0.1.1", "sanmai/pipeline": "^5.1", @@ -67,8 +67,7 @@ "webmozart/path-util": "^2.3" }, "conflict": { - "phpunit/php-code-coverage": ">9 <9.1.4", - "symfony/console": "=4.1.5" + "phpunit/php-code-coverage": ">9 <9.1.4" }, "require-dev": { "ext-simplexml": "*", diff --git a/composer.lock b/composer.lock index c45b565d8..7f8b469c7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "55fa7bca5ebc5358d21b6298a0838d3b", + "content-hash": "eee58fb60bde377494b081031918eee5", "packages": [ { "name": "composer/xdebug-handler", @@ -309,16 +309,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.10.4", + "version": "v4.13.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" + "reference": "50953a2691a922aa1769461637869a0a2faa3f53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", - "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53", + "reference": "50953a2691a922aa1769461637869a0a2faa3f53", "shasum": "" }, "require": { @@ -359,9 +359,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0" }, - "time": "2020-12-20T10:01:03+00:00" + "time": "2021-09-20T12:20:58+00:00" }, { "name": "ondram/ci-detector", @@ -437,27 +437,22 @@ }, { "name": "psr/container", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -470,7 +465,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -484,22 +479,22 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/master" + "source": "https://github.com/php-fig/container/tree/1.1.1" }, - "time": "2017-02-14T16:28:37+00:00" + "time": "2021-03-05T17:36:06+00:00" }, { "name": "psr/log", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", "shasum": "" }, "require": { @@ -523,7 +518,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for logging libraries", @@ -534,9 +529,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.3" + "source": "https://github.com/php-fig/log/tree/1.1.4" }, - "time": "2020-03-23T09:12:05+00:00" + "time": "2021-05-03T11:20:27+00:00" }, { "name": "sanmai/later", @@ -792,16 +787,16 @@ }, { "name": "symfony/console", - "version": "v5.3.6", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "51b71afd6d2dc8f5063199357b9880cea8d8bfe2" + "reference": "8b1008344647462ae6ec57559da166c2bfa5e16a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/51b71afd6d2dc8f5063199357b9880cea8d8bfe2", - "reference": "51b71afd6d2dc8f5063199357b9880cea8d8bfe2", + "url": "https://api.github.com/repos/symfony/console/zipball/8b1008344647462ae6ec57559da166c2bfa5e16a", + "reference": "8b1008344647462ae6ec57559da166c2bfa5e16a", "shasum": "" }, "require": { @@ -871,7 +866,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.6" + "source": "https://github.com/symfony/console/tree/v5.3.7" }, "funding": [ { @@ -887,20 +882,20 @@ "type": "tidelift" } ], - "time": "2021-07-27T19:10:22+00:00" + "time": "2021-08-25T20:02:16+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.2.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" + "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", + "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", "shasum": "" }, "require": { @@ -909,7 +904,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -938,7 +933,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/master" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0" }, "funding": [ { @@ -954,25 +949,26 @@ "type": "tidelift" } ], - "time": "2020-09-07T11:33:47+00:00" + "time": "2021-03-23T23:28:01+00:00" }, { "name": "symfony/filesystem", - "version": "v5.2.1", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d" + "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/fa8f8cab6b65e2d99a118e082935344c5ba8c60d", - "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/343f4fe324383ca46792cae728a3b6e2f708fb32", + "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8" + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -997,10 +993,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Filesystem Component", + "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.2.1" + "source": "https://github.com/symfony/filesystem/tree/v5.3.4" }, "funding": [ { @@ -1016,24 +1012,25 @@ "type": "tidelift" } ], - "time": "2020-11-30T17:05:38+00:00" + "time": "2021-07-21T12:40:44+00:00" }, { "name": "symfony/finder", - "version": "v5.2.1", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "0b9231a5922fd7287ba5b411893c0ecd2733e5ba" + "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/0b9231a5922fd7287ba5b411893c0ecd2733e5ba", - "reference": "0b9231a5922fd7287ba5b411893c0ecd2733e5ba", + "url": "https://api.github.com/repos/symfony/finder/zipball/a10000ada1e600d109a6c7632e9ac42e8bf2fb93", + "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93", "shasum": "" }, "require": { - "php": ">=7.2.5" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -1058,10 +1055,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Finder Component", + "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.2.1" + "source": "https://github.com/symfony/finder/tree/v5.3.7" }, "funding": [ { @@ -1077,20 +1074,20 @@ "type": "tidelift" } ], - "time": "2020-12-08T17:02:38+00:00" + "time": "2021-08-04T21:20:46+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.20.0", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", "shasum": "" }, "require": { @@ -1102,7 +1099,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1140,7 +1137,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" }, "funding": [ { @@ -1156,20 +1153,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.20.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c" + "reference": "16880ba9c5ebe3642d1995ab866db29270b36535" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c", - "reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/16880ba9c5ebe3642d1995ab866db29270b36535", + "reference": "16880ba9c5ebe3642d1995ab866db29270b36535", "shasum": "" }, "require": { @@ -1181,7 +1178,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1221,7 +1218,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.23.1" }, "funding": [ { @@ -1237,20 +1234,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-05-27T12:26:48+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.20.0", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "727d1096295d807c309fb01a851577302394c897" + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897", - "reference": "727d1096295d807c309fb01a851577302394c897", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", "shasum": "" }, "require": { @@ -1262,7 +1259,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1305,7 +1302,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.23.0" }, "funding": [ { @@ -1321,20 +1318,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.20.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", "shasum": "" }, "require": { @@ -1346,7 +1343,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1385,7 +1382,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" }, "funding": [ { @@ -1401,20 +1398,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-05-27T12:26:48+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.20.0", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed" + "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed", - "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010", + "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010", "shasum": "" }, "require": { @@ -1423,7 +1420,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1464,7 +1461,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.23.0" }, "funding": [ { @@ -1480,20 +1477,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.20.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", - "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", "shasum": "" }, "require": { @@ -1502,7 +1499,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1547,7 +1544,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" }, "funding": [ { @@ -1563,20 +1560,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-07-28T13:41:28+00:00" }, { "name": "symfony/process", - "version": "v5.3.4", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "d16634ee55b895bd85ec714dadc58e4428ecf030" + "reference": "38f26c7d6ed535217ea393e05634cb0b244a1967" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d16634ee55b895bd85ec714dadc58e4428ecf030", - "reference": "d16634ee55b895bd85ec714dadc58e4428ecf030", + "url": "https://api.github.com/repos/symfony/process/zipball/38f26c7d6ed535217ea393e05634cb0b244a1967", + "reference": "38f26c7d6ed535217ea393e05634cb0b244a1967", "shasum": "" }, "require": { @@ -1609,7 +1606,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.3.4" + "source": "https://github.com/symfony/process/tree/v5.3.7" }, "funding": [ { @@ -1625,25 +1622,25 @@ "type": "tidelift" } ], - "time": "2021-07-23T15:54:19+00:00" + "time": "2021-08-04T21:20:46+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.2.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" + "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", + "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.0" + "psr/container": "^1.1" }, "suggest": { "symfony/service-implementation": "" @@ -1651,7 +1648,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -1688,7 +1685,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/master" + "source": "https://github.com/symfony/service-contracts/tree/v2.4.0" }, "funding": [ { @@ -1704,20 +1701,20 @@ "type": "tidelift" } ], - "time": "2020-09-07T11:33:47+00:00" + "time": "2021-04-01T10:43:52+00:00" }, { "name": "symfony/string", - "version": "v5.2.1", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed" + "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", - "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", + "url": "https://api.github.com/repos/symfony/string/zipball/8d224396e28d30f81969f083a58763b8b9ceb0a5", + "reference": "8d224396e28d30f81969f083a58763b8b9ceb0a5", "shasum": "" }, "require": { @@ -1760,7 +1757,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony String component", + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", "homepage": "https://symfony.com", "keywords": [ "grapheme", @@ -1771,7 +1768,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.2.1" + "source": "https://github.com/symfony/string/tree/v5.3.7" }, "funding": [ { @@ -1787,7 +1784,7 @@ "type": "tidelift" } ], - "time": "2020-12-05T07:33:16+00:00" + "time": "2021-08-26T08:00:08+00:00" }, { "name": "thecodingmachine/safe", @@ -4352,26 +4349,26 @@ }, { "name": "symfony/phpunit-bridge", - "version": "v5.2.1", + "version": "v5.3.8", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "235823f6d215c9bd930a47a496e62c1354cde55b" + "reference": "e9c0548d8d7abcd257f18f0adc0517895996a9c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/235823f6d215c9bd930a47a496e62c1354cde55b", - "reference": "235823f6d215c9bd930a47a496e62c1354cde55b", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/e9c0548d8d7abcd257f18f0adc0517895996a9c1", + "reference": "e9c0548d8d7abcd257f18f0adc0517895996a9c1", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": ">=7.1.3", + "symfony/deprecation-contracts": "^2.1" }, "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0|<6.4,>=6.0|9.1.2" + "phpunit/phpunit": "<7.5|9.1.2" }, "require-dev": { - "symfony/deprecation-contracts": "^2.1", "symfony/error-handler": "^4.4|^5.0" }, "suggest": { @@ -4412,10 +4409,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony PHPUnit Bridge", + "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v5.2.1" + "source": "https://github.com/symfony/phpunit-bridge/tree/v5.3.8" }, "funding": [ { @@ -4431,20 +4428,20 @@ "type": "tidelift" } ], - "time": "2020-12-14T22:27:17+00:00" + "time": "2021-09-14T13:57:08+00:00" }, { "name": "symfony/yaml", - "version": "v5.2.1", + "version": "v5.3.6", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "290ea5e03b8cf9b42c783163123f54441fb06939" + "reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/290ea5e03b8cf9b42c783163123f54441fb06939", - "reference": "290ea5e03b8cf9b42c783163123f54441fb06939", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7", + "reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7", "shasum": "" }, "require": { @@ -4487,10 +4484,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Yaml Component", + "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.2.1" + "source": "https://github.com/symfony/yaml/tree/v5.3.6" }, "funding": [ { @@ -4506,7 +4503,7 @@ "type": "tidelift" } ], - "time": "2020-12-08T17:02:38+00:00" + "time": "2021-07-29T06:20:01+00:00" }, { "name": "thecodingmachine/phpstan-safe-rule", diff --git a/scoper.inc.php b/scoper.inc.php index 7956807b4..f43a0e56b 100644 --- a/scoper.inc.php +++ b/scoper.inc.php @@ -51,6 +51,11 @@ 'T_MATCH', 'T_NULLSAFE_OBJECT_OPERATOR', 'T_ATTRIBUTE', + // PHP 8.1 + 'T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG', + 'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG', + 'T_ENUM', + 'T_READONLY', ], 'files-whitelist' => \array_map( static function ($file) { diff --git a/src/FileSystem/Finder/Iterator/RealPathFilterIterator.php b/src/FileSystem/Finder/Iterator/RealPathFilterIterator.php index 9def76fff..c1e40ab41 100644 --- a/src/FileSystem/Finder/Iterator/RealPathFilterIterator.php +++ b/src/FileSystem/Finder/Iterator/RealPathFilterIterator.php @@ -37,6 +37,7 @@ use const DIRECTORY_SEPARATOR; use function preg_quote; +use ReturnTypeWillChange; use function str_replace; use Symfony\Component\Finder\Iterator\MultiplePcreFilterIterator; @@ -50,6 +51,7 @@ final class RealPathFilterIterator extends MultiplePcreFilterIterator * * @return bool true if the value should be kept, false otherwise */ + #[ReturnTypeWillChange] public function accept() { $filename = $this->current()->getRealPath(); diff --git a/src/Mutator/Extensions/BCMath.php b/src/Mutator/Extensions/BCMath.php index d73472401..921d32f4b 100644 --- a/src/Mutator/Extensions/BCMath.php +++ b/src/Mutator/Extensions/BCMath.php @@ -217,6 +217,10 @@ private static function makeCastToStringMapper(Closure $converter): Closure private static function makeBinaryOperatorMapper(string $operator): Closure { return static function (Node\Expr\FuncCall $node) use ($operator): iterable { + if ($node->args[0] instanceof Node\VariadicPlaceholder || $node->args[1] instanceof Node\VariadicPlaceholder) { + return []; + } + yield new $operator($node->args[0]->value, $node->args[1]->value); }; } @@ -237,6 +241,10 @@ private static function makeSquareRootsMapper(): Closure private static function makePowerModuloMapper(): Closure { return static function (Node\Expr\FuncCall $node): iterable { + if ($node->args[2] instanceof Node\VariadicPlaceholder) { + return []; + } + yield new Node\Expr\BinaryOp\Mod( new Node\Expr\FuncCall( new Node\Name('\pow'), diff --git a/src/Mutator/Extensions/MBString.php b/src/Mutator/Extensions/MBString.php index 7bf119981..10742cac3 100644 --- a/src/Mutator/Extensions/MBString.php +++ b/src/Mutator/Extensions/MBString.php @@ -202,6 +202,10 @@ private static function getConvertCaseModeValue(Node\Expr\FuncCall $node): ?int return null; } + if ($node->args[1] instanceof Node\VariadicPlaceholder) { + return null; + } + $mode = $node->args[1]->value; if ($mode instanceof Node\Scalar\LNumber) { @@ -244,7 +248,7 @@ private static function isInMbCaseMode(int $mode, string ...$cases): bool } /** - * @param Node\Arg[] $args + * @param array $args */ private static function mapFunctionCall(Node\Expr\FuncCall $node, string $newFuncName, array $args): Node\Expr\FuncCall { diff --git a/src/Mutator/Regex/AbstractPregMatch.php b/src/Mutator/Regex/AbstractPregMatch.php index 0d46860f9..cf5824386 100644 --- a/src/Mutator/Regex/AbstractPregMatch.php +++ b/src/Mutator/Regex/AbstractPregMatch.php @@ -60,14 +60,16 @@ abstract class AbstractPregMatch implements Mutator */ public function mutate(Node $node): iterable { - $arguments = $node->args; - $firstArgument = $arguments[0]; - $originalRegex = $this->pullOutRegex($firstArgument); + if ($node->args[0] instanceof Node\VariadicPlaceholder) { + return []; + } + + $originalRegex = $this->pullOutRegex($node->args[0]); foreach ($this->mutateRegex($originalRegex) as $mutatedRegex) { - $newArgument = $this->getNewRegexArgument($mutatedRegex, $firstArgument); + $newArgument = $this->getNewRegexArgument($mutatedRegex, $node->args[0]); - yield new FuncCall($node->name, [$newArgument] + $arguments, $node->getAttributes()); + yield new FuncCall($node->name, [$newArgument] + $node->args, $node->getAttributes()); } } @@ -76,6 +78,7 @@ public function canMutate(Node $node): bool return $node instanceof FuncCall && $node->name instanceof Node\Name && strtolower((string) $node->name) === 'preg_match' + && $node->args[0] instanceof Node\Arg && $node->args[0]->value instanceof Node\Scalar\String_ && $this->isProperRegexToMutate($this->pullOutRegex($node->args[0])); } diff --git a/src/Mutator/Regex/PregMatchMatches.php b/src/Mutator/Regex/PregMatchMatches.php index a7b328dca..310af0e3b 100644 --- a/src/Mutator/Regex/PregMatchMatches.php +++ b/src/Mutator/Regex/PregMatchMatches.php @@ -89,6 +89,10 @@ public static function getDefinition(): ?Definition */ public function mutate(Node $node): iterable { + if ($node->args[2] instanceof Node\VariadicPlaceholder) { + return []; + } + yield new Node\Expr\Cast\Int_(new Node\Expr\Assign($node->args[2]->value, new Node\Expr\Array_())); } diff --git a/src/Mutator/Regex/PregQuote.php b/src/Mutator/Regex/PregQuote.php index f6dbb3db2..072cf1d8d 100644 --- a/src/Mutator/Regex/PregQuote.php +++ b/src/Mutator/Regex/PregQuote.php @@ -84,6 +84,10 @@ public static function getDefinition(): ?Definition */ public function mutate(Node $node): iterable { + if ($node->args[0] instanceof Node\VariadicPlaceholder) { + return []; + } + yield $node->args[0]; } diff --git a/src/Mutator/Unwrap/AbstractUnwrapMutator.php b/src/Mutator/Unwrap/AbstractUnwrapMutator.php index 6fb42c683..f9c48ae31 100644 --- a/src/Mutator/Unwrap/AbstractUnwrapMutator.php +++ b/src/Mutator/Unwrap/AbstractUnwrapMutator.php @@ -58,6 +58,10 @@ abstract class AbstractUnwrapMutator implements Mutator final public function mutate(Node $node): iterable { foreach ($this->getParameterIndexes($node) as $index) { + if ($node->args[$index] instanceof Node\VariadicPlaceholder) { + continue; + } + if ($node->args[$index]->unpack) { continue; } diff --git a/src/TestFramework/Coverage/JUnit/TestLocationBucketSorter.php b/src/TestFramework/Coverage/JUnit/TestLocationBucketSorter.php index 5cf461cf7..77d9f5fb5 100644 --- a/src/TestFramework/Coverage/JUnit/TestLocationBucketSorter.php +++ b/src/TestFramework/Coverage/JUnit/TestLocationBucketSorter.php @@ -78,7 +78,7 @@ public static function bucketSort(array $uniqueTestLocations): iterable // This is a very hot path. Factoring here another method just to test this math may not be as good idea. // Quick drop off lower bits, reducing precision to 8th of a second - $msTime = ($location->getExecutionTime() ?? 0) * 1024 >> 7; // * 1024 / 128 + $msTime = (int) (($location->getExecutionTime() ?? 0) * 1024) >> 7; // * 1024 / 128 // For anything above 4 seconds reduce precision to 4 seconds if ($msTime > 32) { diff --git a/tests/phpunit/FileSystem/FileSystemTestCase.php b/tests/phpunit/FileSystem/FileSystemTestCase.php index 6885cfbd7..89a7799a0 100644 --- a/tests/phpunit/FileSystem/FileSystemTestCase.php +++ b/tests/phpunit/FileSystem/FileSystemTestCase.php @@ -52,15 +52,9 @@ abstract class FileSystemTestCase extends TestCase { private const TMP_DIR_NAME = 'infection-test'; - /** - * @var string - */ - protected $cwd; + protected string $cwd = ''; - /** - * @var string - */ - protected $tmp; + protected string $tmp = ''; public static function tearDownAfterClass(): void { diff --git a/tests/phpunit/FileSystem/SourceFileFilterTest.php b/tests/phpunit/FileSystem/SourceFileFilterTest.php index 228c7af7a..4137b2cc4 100644 --- a/tests/phpunit/FileSystem/SourceFileFilterTest.php +++ b/tests/phpunit/FileSystem/SourceFileFilterTest.php @@ -38,10 +38,10 @@ use function array_values; use Infection\FileSystem\SourceFileFilter; use Infection\TestFramework\Coverage\Trace; +use Infection\Tests\Fixtures\MockSplFileInfo; use IteratorIterator; use PHPUnit\Framework\TestCase; use function Pipeline\take; -use SplFileInfo; use Traversable; final class SourceFileFilterTest extends TestCase @@ -210,7 +210,7 @@ private function assertFiltersExpectedInput( $actual = take($actual) ->map(static function ($traceOrFileInfo) { - /* @var Trace|SplFileInfo */ + /* @var Trace|MockSplFileInfo */ return $traceOrFileInfo->getRealPath(); }) ->toArray(); @@ -221,19 +221,17 @@ private function assertFiltersExpectedInput( /** * @param string[] $filePaths * - * @return Traversable + * @return Traversable */ private function createSplFileInfosTraversable(array $filePaths): Traversable { return take($filePaths) - ->map(function (string $filename) { - $traceMock = $this->createMock(SplFileInfo::class); - $traceMock - ->method('getRealPath') - ->willReturn($filename) - ; - - return $traceMock; + ->map(static function (string $realPath): MockSplFileInfo { + return new MockSplFileInfo([ + 'realPath' => $realPath, + 'type' => 'file', + 'mode' => 'r+', + ]); }) ; } @@ -246,7 +244,7 @@ private function createSplFileInfosTraversable(array $filePaths): Traversable private function createTracesTraversable(array $filePaths): Traversable { return take($filePaths) - ->map(function (string $filename) { + ->map(function (string $filename): Trace { $traceMock = $this->createMock(Trace::class); $traceMock ->method('getRealPath') diff --git a/tests/phpunit/Fixtures/Finder/MockSplFileInfo.php b/tests/phpunit/Fixtures/Finder/MockSplFileInfo.php new file mode 100644 index 000000000..88d61d458 --- /dev/null +++ b/tests/phpunit/Fixtures/Finder/MockSplFileInfo.php @@ -0,0 +1,38 @@ + 'file.txt', + 'realPath' => false, + 'relativePath' => '', + 'relativePathname' => '', + ]; + $defaults = array_merge($defaults, $param); + parent::__construct($defaults['name'], $defaults['relativePath'], $defaults['name']); + + $this->realPath = $defaults['realPath']; + } else { + throw new RuntimeException(sprintf('Incorrect parameter "%s"', $param)); + } + } + + #[ReturnTypeWillChange] + public function getRealPath() + { + return $this->realPath; + } +} diff --git a/tests/phpunit/Fixtures/MockSplFileInfo.php b/tests/phpunit/Fixtures/MockSplFileInfo.php new file mode 100644 index 000000000..d0883c013 --- /dev/null +++ b/tests/phpunit/Fixtures/MockSplFileInfo.php @@ -0,0 +1,34 @@ + 'file.txt', + 'realPath' => false, + ]; + $defaults = array_merge($defaults, $param); + parent::__construct($defaults['name']); + + $this->realPath = $defaults['realPath']; + } else { + throw new RuntimeException(sprintf('Incorrect parameter "%s"', $param)); + } + } + + #[ReturnTypeWillChange] + public function getRealPath() + { + return $this->realPath; + } +} diff --git a/tests/phpunit/IterableCounterTest.php b/tests/phpunit/IterableCounterTest.php index d5299d00b..7353f8a7c 100644 --- a/tests/phpunit/IterableCounterTest.php +++ b/tests/phpunit/IterableCounterTest.php @@ -35,6 +35,7 @@ namespace Infection\Tests; +use ArrayIterator; use Infection\IterableCounter; use Iterator; use PHPUnit\Framework\TestCase; @@ -43,7 +44,7 @@ final class IterableCounterTest extends TestCase { public function test_it_does_not_count_when_not_asked(): void { - $iterator = $this->createMock(Iterator::class); + $iterator = new ArrayIterator(); $count = IterableCounter::bufferAndCountIfNeeded($iterator, true); diff --git a/tests/phpunit/Mutation/MutationGeneratorTest.php b/tests/phpunit/Mutation/MutationGeneratorTest.php index 3682b54bb..a82113bfc 100644 --- a/tests/phpunit/Mutation/MutationGeneratorTest.php +++ b/tests/phpunit/Mutation/MutationGeneratorTest.php @@ -46,6 +46,7 @@ use Infection\Mutator\IgnoreMutator; use Infection\TestFramework\Coverage\ProxyTrace; use Infection\TestFramework\Coverage\TraceProvider; +use Infection\Tests\Fixtures\Finder\MockSplFileInfo; use Infection\Tests\Fixtures\Mutator\FakeMutator; use Infection\Tests\Fixtures\PhpParser\FakeIgnorer; use function Later\now; @@ -60,7 +61,9 @@ final class MutationGeneratorTest extends TestCase public function test_it_returns_all_the_mutations_generated_for_each_files(): void { - $fileInfo = $this->createMock(SplFileInfo::class); + $fileInfo = new MockSplFileInfo([ + 'file' => 'test.txt', + ]); // Prophecy compares arguments on equality, therefore these have to be somewhat unique $proxyTraceA = new ProxyTrace($fileInfo, now(1)); diff --git a/tests/phpunit/Process/Runner/MutationTestingRunnerTest.php b/tests/phpunit/Process/Runner/MutationTestingRunnerTest.php index 26c07524d..e712d7dd6 100644 --- a/tests/phpunit/Process/Runner/MutationTestingRunnerTest.php +++ b/tests/phpunit/Process/Runner/MutationTestingRunnerTest.php @@ -56,7 +56,6 @@ use Infection\Tests\Fixtures\Event\EventDispatcherCollector; use Infection\Tests\Mutant\MutantBuilder; use Infection\Tests\Mutator\MutatorName; -use Iterator; use PhpParser\Node\Stmt\Nop; use PHPUnit\Framework\Constraint\Callback; use PHPUnit\Framework\MockObject\MockObject; @@ -372,11 +371,7 @@ public function test_it_does_not_create_processes_when_code_is_ignored_by_regex( public function test_it_passes_through_iterables_when_concurrent_execution_requested(): void { - $mutations = $this->createMock(Iterator::class); - $mutations - ->expects($this->never()) - ->method($this->anything()) - ; + $mutations = new ArrayIterator(); $this->mutantFactoryMock ->expects($this->never()) diff --git a/tests/phpunit/TestFramework/Coverage/BufferedSourceFileFilterTest.php b/tests/phpunit/TestFramework/Coverage/BufferedSourceFileFilterTest.php index 4fb1a2270..3f76fa61a 100644 --- a/tests/phpunit/TestFramework/Coverage/BufferedSourceFileFilterTest.php +++ b/tests/phpunit/TestFramework/Coverage/BufferedSourceFileFilterTest.php @@ -39,9 +39,9 @@ use Infection\FileSystem\FileFilter; use Infection\TestFramework\Coverage\BufferedSourceFileFilter; use Infection\TestFramework\Coverage\Trace; +use Infection\Tests\Fixtures\Finder\MockSplFileInfo; use function iterator_to_array; use PHPUnit\Framework\TestCase; -use Symfony\Component\Finder\SplFileInfo; final class BufferedSourceFileFilterTest extends TestCase { @@ -96,14 +96,10 @@ private function createTraceMock(string $filename): Trace return $traceMock; } - private function createFileInfoMock(string $filename): SplFileInfo + private function createFileInfoMock(string $filename): MockSplFileInfo { - $fileInfoMock = $this->createMock(SplFileInfo::class); - $fileInfoMock - ->method('getRealPath') - ->willReturn($filename) - ; - - return $fileInfoMock; + return new MockSplFileInfo([ + 'realPath' => $filename, + ]); } } diff --git a/tests/phpunit/TestFramework/Coverage/ProxyTraceTest.php b/tests/phpunit/TestFramework/Coverage/ProxyTraceTest.php index 234d30d0a..3526a98fa 100644 --- a/tests/phpunit/TestFramework/Coverage/ProxyTraceTest.php +++ b/tests/phpunit/TestFramework/Coverage/ProxyTraceTest.php @@ -40,34 +40,31 @@ use Infection\TestFramework\Coverage\ProxyTrace; use Infection\TestFramework\Coverage\SourceMethodLineRange; use Infection\TestFramework\Coverage\TestLocations; +use Infection\Tests\Fixtures\Finder\MockSplFileInfo; use function iterator_to_array; use function Later\now; use PHPUnit\Framework\TestCase; -use Symfony\Component\Finder\SplFileInfo; final class ProxyTraceTest extends TestCase { public function test_it_exposes_its_source_file_file_info(): void { - $fileInfoMock = $this->createMock(SplFileInfo::class); + $fileInfoMock = new MockSplFileInfo([ + 'file' => 'test.txt', + ]); $actual = (new ProxyTrace($fileInfoMock))->getSourceFileInfo(); - $this->assertSame( - $fileInfoMock, - $actual - ); + $this->assertSame($fileInfoMock, $actual); } public function test_it_exposes_its_source_file_real_path(): void { $expected = 'Foo.php'; - $fileInfoMock = $this->createMock(SplFileInfo::class); - $fileInfoMock - ->method('getRealPath') - ->willReturn($expected) - ; + $fileInfoMock = new MockSplFileInfo([ + 'realPath' => $expected, + ]); $actual = (new ProxyTrace($fileInfoMock))->getRealPath(); @@ -76,12 +73,16 @@ public function test_it_exposes_its_source_file_real_path(): void public function test_it_can_retrieve_the_test_locations(): void { - $fileInfoMock = $this->createMock(SplFileInfo::class); + $fileInfoMock = new MockSplFileInfo([ + 'file' => 'test.txt', + ]); + $tests = new TestLocations(); $trace = new ProxyTrace($fileInfoMock, now($tests)); $actual = $trace->getTests(); + $this->assertSame($tests, $actual); // From cache @@ -91,7 +92,9 @@ public function test_it_can_retrieve_the_test_locations(): void public function test_it_has_no_tests_if_no_covered(): void { - $fileInfoMock = $this->createMock(SplFileInfo::class); + $fileInfoMock = new MockSplFileInfo([ + 'file' => 'test.txt', + ]); $trace = new ProxyTrace($fileInfoMock, now(new TestLocations())); @@ -100,7 +103,9 @@ public function test_it_has_no_tests_if_no_covered(): void public function test_it_returns_null_for_no_tests(): void { - $fileInfoMock = $this->createMock(SplFileInfo::class); + $fileInfoMock = new MockSplFileInfo([ + 'file' => 'test.txt', + ]); $trace = new ProxyTrace($fileInfoMock, null); @@ -111,7 +116,9 @@ public function test_it_returns_null_for_no_tests(): void public function test_it_returns_empty_iterable_for_no_tests(): void { - $fileInfoMock = $this->createMock(SplFileInfo::class); + $fileInfoMock = new MockSplFileInfo([ + 'file' => 'test.txt', + ]); $trace = new ProxyTrace($fileInfoMock, null); @@ -120,7 +127,9 @@ public function test_it_returns_empty_iterable_for_no_tests(): void public function test_it_exposes_its_test_locations(): void { - $fileInfoMock = $this->createMock(SplFileInfo::class); + $fileInfoMock = new MockSplFileInfo([ + 'file' => 'test.txt', + ]); $tests = new TestLocations( [ diff --git a/tests/phpunit/TestFramework/Coverage/UncoveredTraceProviderTest.php b/tests/phpunit/TestFramework/Coverage/UncoveredTraceProviderTest.php index 3d5279981..fd5c70cab 100644 --- a/tests/phpunit/TestFramework/Coverage/UncoveredTraceProviderTest.php +++ b/tests/phpunit/TestFramework/Coverage/UncoveredTraceProviderTest.php @@ -39,16 +39,18 @@ use Infection\TestFramework\Coverage\ProxyTrace; use Infection\TestFramework\Coverage\Trace; use Infection\TestFramework\Coverage\UncoveredTraceProvider; +use Infection\Tests\Fixtures\Finder\MockSplFileInfo; use function iterator_to_array; use PHPUnit\Framework\TestCase; -use Symfony\Component\Finder\SplFileInfo; final class UncoveredTraceProviderTest extends TestCase { public function test_it_provides_traces(): void { $filter = $this->createMock(BufferedSourceFileFilter::class); - $fileInfo = $this->createMock(SplFileInfo::class); + $fileInfo = new MockSplFileInfo([ + 'file' => 'test.txt', + ]); $filter ->expects($this->once()) diff --git a/tests/phpunit/TestFramework/Coverage/XmlReport/XmlCoverageParserTest.php b/tests/phpunit/TestFramework/Coverage/XmlReport/XmlCoverageParserTest.php index 0a796d9af..c7dd996a3 100644 --- a/tests/phpunit/TestFramework/Coverage/XmlReport/XmlCoverageParserTest.php +++ b/tests/phpunit/TestFramework/Coverage/XmlReport/XmlCoverageParserTest.php @@ -38,21 +38,18 @@ use Infection\TestFramework\Coverage\XmlReport\SourceFileInfoProvider; use Infection\TestFramework\Coverage\XmlReport\XmlCoverageParser; use Infection\TestFramework\Coverage\XmlReport\XPathFactory; +use Infection\Tests\Fixtures\Finder\MockSplFileInfo; use Infection\Tests\Fixtures\TestFramework\PhpUnit\Coverage\XmlCoverageFixtures; use Infection\Tests\TestFramework\Coverage\TestLocationsNormalizer; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Symfony\Component\Finder\SplFileInfo; /** * @group integration */ final class XmlCoverageParserTest extends TestCase { - /** - * @var XmlCoverageParser - */ - private $parser; + private XmlCoverageParser $parser; protected function setUp(): void { @@ -186,7 +183,7 @@ private function createSourceFileInfoProvider(string $xml) $providerMock ->expects($this->once()) ->method('provideFileInfo') - ->willReturn($this->createMock(SplFileInfo::class)) + ->willReturn(new MockSplFileInfo(['file' => 'test.txt'])) ; $providerMock