diff --git a/.gitattributes b/.gitattributes index 298934e4..6d4ec2e7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -15,7 +15,9 @@ phpcs.xml.dist export-ignore phpdoc.dist.xml export-ignore phpdoc.xml.dist export-ignore +phpstan.neon.dist export-ignore phpunit.xml.dist export-ignore +phpunit10.xml.dist export-ignore /.github/ export-ignore /docs/ export-ignore /Tests/ export-ignore diff --git a/.github/GHPages/UpdateWebsite.php b/.github/GHPages/UpdateWebsite.php index d8d6ddcf..2ff48611 100644 --- a/.github/GHPages/UpdateWebsite.php +++ b/.github/GHPages/UpdateWebsite.php @@ -120,12 +120,12 @@ public function run(): int */ private function setPaths(): void { - $realRoot = \realpath(self::PROJECT_ROOT) . '/'; + $realRoot = \realpath(self::PROJECT_ROOT); if ($realRoot === false) { - throw new RuntimeException(\sprintf('Failed to find the %s directory.', $realRoot)); + throw new RuntimeException(\sprintf('Failed to find the %s directory.', self::PROJECT_ROOT)); } - $this->realRoot = $realRoot; + $this->realRoot = $realRoot . '/'; // Check if the target directory exists and if not, create it. $targetDir = $this->realRoot . self::TARGET_DIR; diff --git a/.github/SECURITY.md b/.github/SECURITY.md deleted file mode 100644 index 383da734..00000000 --- a/.github/SECURITY.md +++ /dev/null @@ -1,22 +0,0 @@ -# Security Policy - -## Supported Versions - -The latest patch version of the `1.x` release series is supported for security updates. - -## Reporting a Vulnerability - -PHPCSUtils is a developer tool and should generally not be used in a production (web accessible) environment. - -Having said that, responsible disclosure of security issues is highly appreciated. - -**Please do not report or discuss security vulnerabilities through public GitHub issues, discussions, or pull requests.** - -Issues can be reported privately to the maintainers by opening a [Security vulnerability report](https://github.com/PHPCSStandards/PHPCSUtils/security/advisories/new). - -### Preferences - -* Please provide detailed reports with reproducible steps and a clearly defined impact. -* Include the version number of the vulnerable package in your report. -* Fixes are most welcome. - A private PR can be created from the security report to work on and discuss the patch. diff --git a/.github/dependabot.yml b/.github/dependabot.yml index fa4063ba..08a065ec 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,7 +8,7 @@ updates: - package-ecosystem: "composer" directory: "/" schedule: - interval: "daily" + interval: "weekly" open-pull-requests-limit: 5 # Set to 0 to (temporarily) disable. versioning-strategy: widen commit-message: @@ -20,7 +20,7 @@ updates: - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "daily" + interval: "weekly" open-pull-requests-limit: 5 commit-message: prefix: "GH Actions:" diff --git a/.github/workflows/basics.yml b/.github/workflows/basics.yml index 9e58809f..f1a7e15c 100644 --- a/.github/workflows/basics.yml +++ b/.github/workflows/basics.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install PHP uses: shivammathur/setup-php@v2 @@ -50,19 +50,25 @@ jobs: # Install dependencies and handle caching in one go. # @link https://github.com/marketplace/actions/install-php-dependencies-with-composer - name: Install Composer dependencies - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: # Bust the cache at least once a month - output format: YYYY-MM. custom-cache-suffix: $(date -u "+%Y-%m") + # Updating the lists can fail intermittently, typically after Microsoft has released a new package. + # This should not be blocking for this job, so ignore any errors from this step. + # Ref: https://github.com/dotnet/core/issues/4167 + - name: Update the available packages list + continue-on-error: true + run: sudo apt-get update + - name: Install xmllint - run: | - sudo apt-get update - sudo apt-get install --no-install-recommends -y libxml2-utils + run: sudo apt-get install --no-install-recommends -y libxml2-utils # Show XML violations inline in the file diff. # @link https://github.com/marketplace/actions/xmllint-problem-matcher - - uses: korelstar/xmllint-problem-matcher@v1 + - name: Enable showing XML issues inline + uses: korelstar/xmllint-problem-matcher@v1 # Validate the XML file. # @link http://xmlsoft.org/xmllint.html @@ -82,32 +88,48 @@ jobs: if: ${{ always() && steps.phpcs.outcome == 'failure' }} run: cs2pr ./phpcs-report.xml - markdownlint: - name: 'Lint Markdown' - runs-on: ubuntu-latest + phpstan: + name: "PHPStan" + runs-on: "ubuntu-latest" steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - # This action also handles the caching of the dependencies. - # https://github.com/actions/setup-node - - name: Set up node and enable caching of dependencies - uses: actions/setup-node@v3 + - name: Install PHP + uses: shivammathur/setup-php@v2 with: - node-version: '16' + php-version: 'latest' + coverage: none + tools: phpstan - # @link https://github.com/DavidAnson/markdownlint-cli2 - # @link https://github.com/DavidAnson/markdownlint - - name: Install Markdownlint CLI2 - run: npm install -g markdownlint-cli2 + # Install dependencies and handle caching in one go. + # Dependencies need to be installed to make sure the PHPCS and PHPUnit classes are recognized. + # @link https://github.com/marketplace/actions/install-php-dependencies-with-composer + - name: Install Composer dependencies + uses: "ramsey/composer-install@v3" + with: + # Bust the cache at least once a month - output format: YYYY-MM. + custom-cache-suffix: $(date -u "+%Y-%m") + + - name: Run PHPStan + run: phpstan analyse + + markdownlint: + name: 'Lint Markdown' + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 # @link https://github.com/marketplace/actions/problem-matcher-for-markdownlint-cli - name: Enable showing issue in PRs - uses: xt0rted/markdownlint-problem-matcher@v2 + uses: xt0rted/markdownlint-problem-matcher@v3 + # @link https://github.com/marketplace/actions/markdownlint-cli2-action - name: Check markdown with CLI2 - run: markdownlint-cli2 + uses: DavidAnson/markdownlint-cli2-action@v16 remark: name: 'QA Markdown' @@ -115,10 +137,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up node and enable caching of dependencies - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '16' @@ -177,7 +199,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Run Yamllint on all yaml files in repo run: yamllint . --format colored --strict diff --git a/.github/workflows/quicktest.yml b/.github/workflows/quicktest.yml index 9e29ce9a..c32176cf 100644 --- a/.github/workflows/quicktest.yml +++ b/.github/workflows/quicktest.yml @@ -40,7 +40,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 # On stable PHPCS versions, allow for PHP deprecation notices. # Unit tests don't need to fail on those for stable releases where those issues won't get fixed anymore. @@ -64,10 +64,14 @@ jobs: if: ${{ matrix.phpcs_version != 'lowest' }} run: composer require squizlabs/php_codesniffer:"${{ matrix.phpcs_version }}" --no-update --no-scripts --no-interaction + - name: "Composer: use lock file when necessary" + if: ${{ matrix.phpcs_version == 'lowest' }} + run: composer config --unset lock + # Install dependencies and handle caching in one go. # @link https://github.com/marketplace/actions/install-php-dependencies-with-composer - name: Install Composer dependencies - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: # Bust the cache at least once a month - output format: YYYY-MM. custom-cache-suffix: $(date -u "+%Y-%m") @@ -80,14 +84,32 @@ jobs: if: matrix.phpcs_version == 'dev-master' run: composer lint-lt72 + - name: Grab PHPUnit version + id: phpunit_version + # yamllint disable-line rule:line-length + run: echo "VERSION=$(vendor/bin/phpunit --version | grep --only-matching --max-count=1 --extended-regexp '\b[0-9]+\.[0-9]+')" >> $GITHUB_OUTPUT + + - name: Determine PHPUnit config file to use + id: phpunit_config + run: | + if [ "${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }}" == "true" ]; then + echo 'FILE=phpunit10.xml.dist' >> $GITHUB_OUTPUT + echo 'EXTRA_ARGS=' >> $GITHUB_OUTPUT + else + echo 'FILE=phpunit.xml.dist' >> $GITHUB_OUTPUT + echo 'EXTRA_ARGS= --repeat 2' >> $GITHUB_OUTPUT + fi + - name: Run the unit tests without caching - run: vendor/bin/phpunit --no-coverage + run: vendor/bin/phpunit -c ${{ steps.phpunit_config.outputs.FILE }} --no-coverage env: PHPCS_VERSION: ${{ matrix.phpcs_version }} PHPCSUTILS_USE_CACHE: false - name: Run the unit tests with caching - run: vendor/bin/phpunit --testsuite PHPCSUtils --no-coverage --repeat 2 + run: > + vendor/bin/phpunit -c ${{ steps.phpunit_config.outputs.FILE }} + --testsuite PHPCSUtils --no-coverage ${{ steps.phpunit_config.outputs.EXTRA_ARGS }} env: PHPCS_VERSION: ${{ matrix.phpcs_version }} PHPCSUTILS_USE_CACHE: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dbcc316f..324897f1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,15 +30,15 @@ jobs: strategy: matrix: - php: ['5.4', '7.0', '7.4', '8.0', '8.1', '8.2', '8.3'] + php: ['5.4', '7.0', '7.4', '8.0', '8.3', '8.4'] name: "Lint: PHP ${{ matrix.php }}" - continue-on-error: ${{ matrix.php == '8.3' }} + continue-on-error: ${{ matrix.php == '8.4' }} steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install PHP uses: shivammathur/setup-php@v2 @@ -49,16 +49,16 @@ jobs: tools: cs2pr - name: Install Composer dependencies - normal - if: ${{ matrix.php < 8.3 }} - uses: "ramsey/composer-install@v2" + if: ${{ matrix.php < 8.4 }} + uses: "ramsey/composer-install@v3" with: # Bust the cache at least once a month - output format: YYYY-MM. custom-cache-suffix: $(date -u "+%Y-%m") # For the PHP "nightly", we need to install with ignore platform reqs as not all dependencies allow it yet. - name: Install Composer dependencies - with ignore platform - if: ${{ matrix.php >= 8.3 }} - uses: "ramsey/composer-install@v2" + if: ${{ matrix.php >= 8.4 }} + uses: "ramsey/composer-install@v3" with: composer-options: --ignore-platform-req=php+ custom-cache-suffix: $(date -u "+%Y-%m") @@ -91,7 +91,7 @@ jobs: # IMPORTANT: test runs shouldn't fail because of PHPCS being incompatible with a PHP version. # # The matrix is set up so as not to duplicate the builds which are run for code coverage. - php: ['5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] + php: ['5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] phpcs_version: ['lowest', 'dev-master'] risky: [false] experimental: [false] @@ -109,7 +109,7 @@ jobs: extensions: ':iconv' # Run with iconv disabled. # Experimental builds. These are allowed to fail. - - php: '8.3' + - php: '8.4' phpcs_version: 'dev-master' risky: false experimental: true @@ -135,12 +135,12 @@ jobs: risky: true experimental: true - - php: '8.2' + - php: '8.3' phpcs_version: 'lowest' risky: true experimental: true - - php: '8.2' + - php: '8.3' phpcs_version: 'dev-master' risky: true experimental: true @@ -151,7 +151,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 # On stable PHPCS versions, allow for PHP deprecation notices. # Unit tests don't need to fail on those for stable releases where those issues won't get fixed anymore. @@ -180,19 +180,23 @@ jobs: - name: 'Composer: remove PHPCSDevCS' run: composer remove --dev --no-update phpcsstandards/phpcsdevcs + - name: "Composer: use lock file when necessary" + if: ${{ matrix.phpcs_version == 'lowest' }} + run: composer config --unset lock + # Install dependencies and handle caching in one go. # @link https://github.com/marketplace/actions/install-php-dependencies-with-composer - name: Install Composer dependencies - normal - if: ${{ matrix.php < 8.3 }} - uses: "ramsey/composer-install@v2" + if: ${{ matrix.php < 8.4 }} + uses: "ramsey/composer-install@v3" with: # Bust the cache at least once a month - output format: YYYY-MM. custom-cache-suffix: $(date -u "+%Y-%m") # For PHP "nightly", we need to install with ignore platform reqs as not all dependencies allow it yet. - name: Install Composer dependencies - with ignore platform - if: ${{ matrix.php >= 8.3 }} - uses: "ramsey/composer-install@v2" + if: ${{ matrix.php >= 8.4 }} + uses: "ramsey/composer-install@v3" with: composer-options: --ignore-platform-req=php+ custom-cache-suffix: $(date -u "+%Y-%m") @@ -201,16 +205,34 @@ jobs: if: ${{ matrix.phpcs_version == 'lowest' }} run: composer update squizlabs/php_codesniffer --prefer-lowest --no-scripts --no-interaction + - name: Grab PHPUnit version + id: phpunit_version + # yamllint disable-line rule:line-length + run: echo "VERSION=$(vendor/bin/phpunit --version | grep --only-matching --max-count=1 --extended-regexp '\b[0-9]+\.[0-9]+')" >> $GITHUB_OUTPUT + + - name: Determine PHPUnit config file to use + id: phpunit_config + run: | + if [ "${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }}" == "true" ]; then + echo 'FILE=phpunit10.xml.dist' >> $GITHUB_OUTPUT + echo 'EXTRA_ARGS=' >> $GITHUB_OUTPUT + else + echo 'FILE=phpunit.xml.dist' >> $GITHUB_OUTPUT + echo 'EXTRA_ARGS= --repeat 2' >> $GITHUB_OUTPUT + fi + - name: Run the unit tests without caching (non-risky) if: ${{ matrix.risky == false }} - run: vendor/bin/phpunit --no-coverage + run: vendor/bin/phpunit -c ${{ steps.phpunit_config.outputs.FILE }} --no-coverage env: PHPCS_VERSION: ${{ matrix.phpcs_version == '4.0.x-dev' && '4.0.0' || matrix.phpcs_version }} PHPCSUTILS_USE_CACHE: false - name: Run the unit tests with caching (non-risky) if: ${{ matrix.risky == false }} - run: vendor/bin/phpunit --testsuite PHPCSUtils --no-coverage --repeat 2 + run: > + vendor/bin/phpunit -c ${{ steps.phpunit_config.outputs.FILE }} + --testsuite PHPCSUtils --no-coverage ${{ steps.phpunit_config.outputs.EXTRA_ARGS }} env: PHPCS_VERSION: ${{ matrix.phpcs_version == '4.0.x-dev' && '4.0.0' || matrix.phpcs_version }} PHPCSUTILS_USE_CACHE: true @@ -220,7 +242,7 @@ jobs: - name: Run the unit tests (risky, comparewithPHPCS) if: ${{ matrix.risky && matrix.phpcs_version == 'dev-master' }} # "nothing" is excluded to force PHPUnit to ignore the settings in phpunit.xml.dist. - run: vendor/bin/phpunit --no-coverage --group compareWithPHPCS --exclude-group nothing + run: vendor/bin/phpunit -c ${{ steps.phpunit_config.outputs.FILE }} --no-coverage --group compareWithPHPCS --exclude-group nothing env: PHPCS_VERSION: ${{ matrix.phpcs_version == '4.0.x-dev' && '4.0.0' || matrix.phpcs_version }} @@ -228,7 +250,7 @@ jobs: - name: Run the unit tests (risky, xtra) if: ${{ matrix.risky }} # "nothing" is excluded to force PHPUnit to ignore the settings in phpunit.xml.dist. - run: vendor/bin/phpunit --no-coverage --group xtra --exclude-group nothing + run: vendor/bin/phpunit -c ${{ steps.phpunit_config.outputs.FILE }} --no-coverage --group xtra --exclude-group nothing env: PHPCS_VERSION: ${{ matrix.phpcs_version == '4.0.x-dev' && '4.0.0' || matrix.phpcs_version }} @@ -248,9 +270,9 @@ jobs: strategy: matrix: include: - - php: '8.2' + - php: '8.3' phpcs_version: 'dev-master' - - php: '8.2' + - php: '8.3' phpcs_version: 'lowest' extensions: ':iconv' # Run one build with iconv disabled. - php: '5.4' @@ -262,7 +284,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 # On stable PHPCS versions, allow for PHP deprecation notices. # Unit tests don't need to fail on those for stable releases where those issues won't get fixed anymore. @@ -290,8 +312,12 @@ jobs: if: ${{ matrix.phpcs_version != 'lowest' }} run: composer require squizlabs/php_codesniffer:"${{ matrix.phpcs_version }}" --no-update --no-scripts --no-interaction + - name: "Composer: use lock file when necessary" + if: ${{ matrix.phpcs_version == 'lowest' }} + run: composer config --unset lock + - name: Install Composer dependencies - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: # Bust the cache at least once a month - output format: YYYY-MM. custom-cache-suffix: $(date -u "+%Y-%m") @@ -312,45 +338,33 @@ jobs: # As of PHPUnit 9.3.4, a cache warming option is available. # Using that option prevents issues with PHP-Parser backfilling PHP tokens when PHPCS does not (yet), # which would otherwise cause tests to fail on tokens being available when they shouldn't be. + # As coverage is only run on high/low PHP, the high PHP version will use PHPUnit 10, so just check for that. - name: "Warm the PHPUnit cache (PHPUnit 9.3+)" - if: ${{ steps.phpunit_version.outputs.VERSION >= '9.3' }} - run: vendor/bin/phpunit --coverage-cache ./build/phpunit-cache --warm-coverage-cache + if: ${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }} + run: vendor/bin/phpunit -c phpunit10.xml.dist --coverage-cache ./build/phpunit-cache --warm-coverage-cache - - name: "Run the unit tests without caching with code coverage (PHPUnit < 9.3)" - if: ${{ steps.phpunit_version.outputs.VERSION < '9.3' }} + - name: "Run the unit tests without caching with code coverage (PHPUnit < 10)" + if: ${{ ! startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }} run: vendor/bin/phpunit env: PHPCS_VERSION: ${{ matrix.phpcs_version }} PHPCSUTILS_USE_CACHE: false - - name: "Run the unit tests without caching with code coverage (PHPUnit 9.3+)" - if: ${{ steps.phpunit_version.outputs.VERSION >= '9.3' }} - run: vendor/bin/phpunit --coverage-cache ./build/phpunit-cache + - name: "Run the unit tests without caching with code coverage (PHPUnit 10+)" + if: ${{ startsWith( steps.phpunit_version.outputs.VERSION, '10.' ) }} + run: vendor/bin/phpunit -c phpunit10.xml.dist --coverage-cache ./build/phpunit-cache env: PHPCS_VERSION: ${{ matrix.phpcs_version }} PHPCSUTILS_USE_CACHE: false - # Uploading the results with PHP Coveralls v1 won't work from GH Actions, so switch the PHP version. - # Also PHP Coveralls itself (still) isn't fully compatible with PHP 8.0+. - - name: Switch to PHP 7.4 - if: ${{ success() && matrix.php != '7.4' }} - 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() }} - run: composer global require php-coveralls/php-coveralls:"^2.5.3" --no-interaction - - name: Upload coverage results to Coveralls if: ${{ success() }} - env: - COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }} - COVERALLS_PARALLEL: true - COVERALLS_FLAG_NAME: php-${{ matrix.php }}-phpcs-${{ matrix.phpcs_version }} - run: php-coveralls -v -x build/logs/clover.xml + uses: coverallsapp/github-action@v2 + with: + format: clover + file: build/logs/clover.xml + flag-name: php-${{ matrix.php }}-phpcs-${{ matrix.phpcs_version }} + parallel: true coveralls-finish: needs: coverage @@ -362,5 +376,4 @@ jobs: - name: Coveralls Finished uses: coverallsapp/github-action@v2 with: - github-token: ${{ secrets.COVERALLS_TOKEN }} parallel-finished: true diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml index 3253c6cc..40bd015d 100644 --- a/.github/workflows/update-docs.yml +++ b/.github/workflows/update-docs.yml @@ -58,7 +58,7 @@ jobs: fi - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ steps.base_branch.outputs.BRANCH }} # fetch-depth is needed to allow for retrieving the last tag for a non-tag workflow run. @@ -68,7 +68,7 @@ jobs: uses: shivammathur/setup-php@v2 with: # Use a version known to be safe for last phpDocumentor release. - php-version: '8.0' + php-version: '8.1' ini-file: 'development' coverage: none # Install the latest phpDocumentor release as a PHAR. @@ -112,7 +112,7 @@ jobs: # Retention is normally 90 days, but this artifact is only for reviewing # and debugging the generated files for the website. - name: Upload the generated files - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: generated-files path: ./docs/ @@ -120,7 +120,7 @@ jobs: retention-days: 5 - name: Setup GH Pages - uses: actions/configure-pages@v3 + uses: actions/configure-pages@v5 - name: Build the GH Pages site with Jekyll uses: actions/jekyll-build-pages@v1 @@ -129,12 +129,12 @@ jobs: destination: ./docs/_site - name: Upload GH Pages artifact - uses: actions/upload-pages-artifact@v1 + uses: actions/upload-pages-artifact@v3 with: path: ./docs/_site - name: Check GitHub Pages status - uses: crazy-max/ghaction-github-status@v3 + uses: crazy-max/ghaction-github-status@v4 with: pages_threshold: major_outage @@ -153,4 +153,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v2 + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/update-phpcs-versionnr.yml b/.github/workflows/update-phpcs-versionnr.yml index fc512d18..6ffeae45 100644 --- a/.github/workflows/update-phpcs-versionnr.yml +++ b/.github/workflows/update-phpcs-versionnr.yml @@ -29,7 +29,7 @@ jobs: uses: octokit/request-action@v2.x id: get_latest_release with: - route: GET /repos/squizlabs/PHP_CodeSniffer/releases/latest + route: GET /repos/PHPCSStandards/PHP_CodeSniffer/releases/latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -52,7 +52,7 @@ jobs: echo "PR_BRANCH=feature/getversiontest-update-phpcs-version" >> $GITHUB_OUTPUT - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ steps.branches.outputs.BASE }} @@ -68,7 +68,7 @@ jobs: run: git status -vv --untracked=all - name: Create pull request - uses: peter-evans/create-pull-request@v5 + uses: peter-evans/create-pull-request@v6 with: base: ${{ steps.branches.outputs.BASE }} branch: ${{ steps.branches.outputs.PR_BRANCH }} diff --git a/.gitignore b/.gitignore index c88cda6f..20a89389 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ vendor/ /.phpunit.result.cache /docs/phpdoc/ !/docs/phpdoc/.nojekyll +phpstan.neon diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml index d5a5197c..c38c0c40 100644 --- a/.markdownlint-cli2.yaml +++ b/.markdownlint-cli2.yaml @@ -13,6 +13,9 @@ globs: - "**/*.md" - ".github/**/*.md" +# Show found files on stdout (only valid at root) +showFound: true + # Define glob expressions to ignore. ignores: - "docs/index.md" # This file is kept in sync with the README, so will inherit all changes. diff --git a/.remarkrc b/.remarkrc index 95c4c322..9cda9e5e 100644 --- a/.remarkrc +++ b/.remarkrc @@ -8,7 +8,14 @@ ["remark-lint-linebreak-style", "unix"], ["remark-lint-link-title-style", "\""], ["remark-lint-ordered-list-marker-style", "."], - "remark-lint-no-dead-urls", + [ + "remark-lint-no-dead-urls", + { + "skipUrlPatterns": [ + "^https?://github\\.com/PHPCSStandards/PHPCSUtils/compare/[0-9\\.]+?\\.{3}[0-9\\.]+" + ] + } + ], "remark-lint-no-duplicate-defined-urls", "remark-lint-no-duplicate-definitions", "remark-lint-no-empty-url", diff --git a/.yamllint.yml b/.yamllint.yml index 8dc953ff..b5c4202d 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -6,6 +6,7 @@ yaml-files: - '*.yaml' - '*.yml' - '.yamllint' + - 'phpstan.neon*' # Rule documentation: https://yamllint.readthedocs.io/en/stable/rules.html rules: diff --git a/CHANGELOG.md b/CHANGELOG.md index fd8bab48..b9f163ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,168 @@ This projects adheres to [Keep a CHANGELOG](https://keepachangelog.com/) and use _Nothing yet._ +## [1.0.12] - 2024-05-20 + +### Added + +#### PHPCS BackCompat + +* `BCFile::getMemberProperties()`: sync with PHPCS 3.10.0 - support for PHP 8.2 DNF types. [#604] +* `BCFile::getMethodProperties()`: sync with PHPCS 3.10.0 - support for PHP 8.2 DNF types. [#604] +* `BCFile::getMethodParameters()`: sync with PHPCS 3.10.0 - support for PHP 8.2 DNF types. [#604] + +#### Utils + +* `FunctionDeclarations::getParameters()`: support for PHP 8.2 DNF types. [#604] +* `FunctionDeclarations::getProperties()`: support for PHP 8.2 DNF types. [#604] +* `Variables::getMemberProperties()`: support for PHP 8.2 DNF types. [#604] + +### Changed + +#### Tokens + +* `Collections::parameterTypeTokens()`, `Collections::propertyTypeTokens()` and `Collections::returnTypeTokens()`: now include the new `T_TYPE_OPEN_PARENTHESIS` and `T_TYPE_CLOSE_PARENTHESIS` tokens for PHP 8.2 DNF type support. [#604] + +#### Utils + +* `ControlStructures::getCaughtExceptions()`: will now silently ignore parse errors in the code under scan which prevent the method from analyzing a `catch` statement. [#594] + The method will now return an empty array instead of throwing a `PHP_CodeSniffer\Exceptions\RuntimeException`. + +#### Other + +* Dropped support for [PHP_CodeSniffer] < 3.10.0. [#603] + Please ensure you run `composer update phpcsstandards/phpcsutils --with-dependencies` to benefit from this. +* Various housekeeping and documentation improvements. + +### Fixed + +#### Utils + +* `UseStatements::splitImportUseStatement()`: the values in the return array will now never include a leading backslash. [#590] + Previously the behaviour around import `use` statements declared with a leading backslash was undefined and the backslash would be included in the return value. + +[#590]: https://github.com/PHPCSStandards/PHPCSUtils/pull/590 +[#594]: https://github.com/PHPCSStandards/PHPCSUtils/pull/594 +[#603]: https://github.com/PHPCSStandards/PHPCSUtils/pull/603 +[#604]: https://github.com/PHPCSStandards/PHPCSUtils/pull/604 + + +## [1.0.11] - 2024-04-24 + +### Changed + +#### Other + +* Various housekeeping and documentation improvements. Includes a contribution from [@fredden]. + +### Fixed + +#### PHPCS BackCompat + +* `BCFile::getMethodProperties()`: small performance improvement & more defensive coding, in line with same fix in PHPCS 3.9.2. [#573] + +#### Utils + +* `FunctionDeclarations::getProperties()`: small performance improvement & more defensive coding, in line with same fix in PHPCS 3.9.2. [#573] + +[#573]: https://github.com/PHPCSStandards/PHPCSUtils/pull/573 + + +## [1.0.10] - 2024-03-18 + +### Changed + +#### Other + +* Dropped support for [PHP_CodeSniffer] < 3.9.0. [#561] + Please ensure you run `composer update phpcsstandards/phpcsutils --with-dependencies` to benefit from this. +* Various housekeeping and documentation improvements. + +### Deprecated + +#### Utils + +* `NamingConventions::AZ_UPPER` constant. [#563] +* `NamingConventions::AZ_LOWER` constant. [#563] + +### Fixed + +#### PHPCS BackCompat + +* `BackCompat\Helper::getEncoding()`: PHP 8.4 deprecation notice. [#568] +* `BackCompat\Helper::ignoreAnnotations()`: PHP 8.4 deprecation notice. [#568] + +[#561]: https://github.com/PHPCSStandards/PHPCSUtils/pull/561 +[#563]: https://github.com/PHPCSStandards/PHPCSUtils/pull/563 +[#568]: https://github.com/PHPCSStandards/PHPCSUtils/pull/568 + + +## [1.0.9] - 2023-12-08 + +### Added + +#### PHPCS BackCompat + +* `BCFile::getMemberProperties()`: sync with PHPCS 3.8.0 - support for PHP 8.2 `true` type. [#524] +* `BCFile::getMethodProperties()`: sync with PHPCS 3.8.0 - support for PHP 8.2 `true` type. [#524] +* `BCFile::getMethodParameters()`: sync with PHPCS 3.8.0 - support for PHP 8.2 `true` type. [#524] + +### Changed + +#### TestUtils + +* Significant performance improvement for the [`UtilityMethodTestCase`]. [#525] + +#### Other + +* Dropped support for [PHP_CodeSniffer] < 3.8.0. [#523] + Please ensure you run `composer update phpcsstandards/phpcsutils --with-dependencies` to benefit from this. +* Small improvements to the documentation website generation. Includes a contribution from [@fredden]. +* Various housekeeping and documentation improvements. Includes a contribution from [@fredden]. + +[#523]: https://github.com/PHPCSStandards/PHPCSUtils/pull/523 +[#524]: https://github.com/PHPCSStandards/PHPCSUtils/pull/524 +[#525]: https://github.com/PHPCSStandards/PHPCSUtils/pull/525 + + +## [1.0.8] - 2023-07-17 + +### Changed + +#### PHPCS BackCompat + +* `BCFile::getDeclarationName()`: sync with PHPCS 3.8.0 - support for functions called `self`, `parent` or `static` which return by reference. [#494] + +#### Other + +* Various housekeeping and minor documentation improvements. + +### Fixed + +#### Fixers + +* The [`SpacesFixer`] will no longer throw an (incorrect) exception when the second pointer passed is a comment token and this comment token is the last content in a file. [#493] + +[#493]: https://github.com/PHPCSStandards/PHPCSUtils/pull/493 +[#494]: https://github.com/PHPCSStandards/PHPCSUtils/pull/494 + + +## [1.0.7] - 2023-07-10 + +### Changed + +#### Other + +* Various housekeeping and maintenance updates, including making the test suite compatible with PHPUnit 10. + +### Fixed + +#### Utils + +* The `Arrays::getDoubleArrowPtr()` method could previously get confused over a double arrow in a keyed list used as an array value. [#485] + +[#485]: https://github.com/PHPCSStandards/PHPCSUtils/pull/485 + ## [1.0.6] - 2023-05-27 @@ -382,7 +544,7 @@ Please report any bugs/oversights you encounter! All properties have a replacement which should be used instead, in most cases this will be a method with the same name as the previously used property, | Deprecated | Replacement | PR | Remarks | -|---------------------------------------------------------------|------------------------------------------------------------------------------------------------------|----------------|------------------------------------------| +| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------------- | ---------------------------------------- | | `Collections::$alternativeControlStructureSyntaxTokens` | `Collections::alternativeControlStructureSyntaxes()` | [#311] | Mind the change in the name! | | `Collections::$alternativeControlStructureSyntaxCloserTokens` | `Collections::alternativeControlStructureSyntaxClosers()` | [#311] | Mind the change in the name! | | `Collections::$arrayTokens` | `Collections::arrayTokens()` | [#311] | | @@ -415,7 +577,7 @@ All properties have a replacement which should be used instead, in most cases th Additionally, the following methods in the `Collections` class have been deprecated: | Deprecated | Replacement | PR | -|----------------------------------------------|--------------------------------------------|--------| +| -------------------------------------------- | ------------------------------------------ | ------ | | `Collections::arrowFunctionTokensBC()` | Use the `T_FN` token instead. | [#347] | | `Collections::functionDeclarationTokensBC()` | `Collections::functionDeclarationTokens()` | [#347] | | `Collections::parameterTypeTokensBC()` | `Collections::parameterTypeTokens()` | [#347] | @@ -889,6 +1051,12 @@ This initial alpha release contains the following utility classes: [Unreleased]: https://github.com/PHPCSStandards/PHPCSUtils/compare/stable...HEAD +[1.0.12]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.11...1.0.12 +[1.0.11]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.10...1.0.11 +[1.0.10]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.9...1.0.10 +[1.0.9]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.8...1.0.9 +[1.0.8]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.7...1.0.8 +[1.0.7]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.6...1.0.7 [1.0.6]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.5...1.0.6 [1.0.5]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.4...1.0.5 [1.0.4]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.3...1.0.4 @@ -902,6 +1070,7 @@ This initial alpha release contains the following utility classes: [1.0.0-alpha2]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.0-alpha1...1.0.0-alpha2 [Composer PHPCS plugin]: https://github.com/PHPCSStandards/composer-installer +[PHP_CodeSniffer]: https://github.com/PHPCSStandards/PHP_CodeSniffer [`AbstractArrayDeclarationSniff`]: https://phpcsutils.com/phpdoc/classes/PHPCSUtils-AbstractSniffs-AbstractArrayDeclarationSniff.html [`BCFile`]: https://phpcsutils.com/phpdoc/classes/PHPCSUtils-BackCompat-BCFile.html @@ -932,5 +1101,6 @@ This initial alpha release contains the following utility classes: [`UseStatements`]: https://phpcsutils.com/phpdoc/classes/PHPCSUtils-Utils-UseStatements.html [`Variables`]: https://phpcsutils.com/phpdoc/classes/PHPCSUtils-Utils-Variables.html +[@fredden]: https://github.com/fredden [@GaryJones]: https://github.com/GaryJones [@szepeviktor]: https://github.com/szepeviktor diff --git a/PHPCSUtils/AbstractSniffs/AbstractArrayDeclarationSniff.php b/PHPCSUtils/AbstractSniffs/AbstractArrayDeclarationSniff.php index 21420a8e..b79a3fdc 100644 --- a/PHPCSUtils/AbstractSniffs/AbstractArrayDeclarationSniff.php +++ b/PHPCSUtils/AbstractSniffs/AbstractArrayDeclarationSniff.php @@ -42,7 +42,7 @@ abstract class AbstractArrayDeclarationSniff implements Sniff * * @since 1.0.0 * - * @var array + * @var array> */ protected $tokens; @@ -79,7 +79,7 @@ abstract class AbstractArrayDeclarationSniff implements Sniff * * @since 1.0.0 * - * @var array + * @var array> */ protected $arrayItems; @@ -108,7 +108,7 @@ abstract class AbstractArrayDeclarationSniff implements Sniff * * @since 1.0.0 * - * @var array + * @var array */ private $acceptedTokens = [ \T_NULL => \T_NULL, @@ -152,7 +152,7 @@ final public function __construct() * * @codeCoverageIgnore * - * @return array + * @return array */ public function register() { diff --git a/PHPCSUtils/BackCompat/BCFile.php b/PHPCSUtils/BackCompat/BCFile.php index 0491138f..8c063439 100644 --- a/PHPCSUtils/BackCompat/BCFile.php +++ b/PHPCSUtils/BackCompat/BCFile.php @@ -29,7 +29,7 @@ * @author Klaus Purer * * @copyright 2006-2019 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */ namespace PHPCSUtils\BackCompat; @@ -48,7 +48,9 @@ * * Additionally, this class works round the following tokenizer issues for * any affected utility functions: - * - None at this time. + * - `readonly` classes. + * - Constructor property promotion with `readonly` without visibility. + * - OO methods called `self`, `parent` or `static`. * * Most functions in this class will have a related twin-function in the relevant * class in the `PHPCSUtils\Utils` namespace. @@ -74,7 +76,7 @@ final class BCFile * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - The upstream method has received no significant updates since PHPCS 3.7.1. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::getDeclarationName() Original source. * @see \PHPCSUtils\Utils\ObjectDeclarations::getName() PHPCSUtils native improved version. @@ -122,7 +124,7 @@ public static function getDeclarationName(File $phpcsFile, $stackPtr) * // or FALSE if there is no type hint. * 'type_hint_end_token' => integer|false, // The stack pointer to the end of the type hint * // or FALSE if there is no type hint. - * 'nullable_type' => boolean, // TRUE if the var type is preceded by the nullability + * 'nullable_type' => boolean, // TRUE if the param type is preceded by the nullability * // operator. * 'comma_token' => integer|false, // The stack pointer to the comma after the param * // or FALSE if this is the last param. @@ -139,9 +141,9 @@ public static function getDeclarationName(File $phpcsFile, $stackPtr) * Parameters declared using PHP 8 constructor property promotion, have these additional array indexes: * ```php * 'property_visibility' => string, // The property visibility as declared. - * 'visibility_token' => integer,|false // The stack pointer to the visibility modifier token. + * 'visibility_token' => integer|false, // The stack pointer to the visibility modifier token. * // or FALSE if the visibility is not explicitly declared. - * 'property_readonly' => bool, // TRUE if the readonly keyword was found. + * 'property_readonly' => boolean, // TRUE if the readonly keyword was found. * 'readonly_token' => integer, // The stack pointer to the readonly modifier token. * // This index will only be set if the property is readonly. * ``` @@ -162,7 +164,7 @@ public static function getDeclarationName(File $phpcsFile, $stackPtr) * @param int $stackPtr The position in the stack of the function token * to acquire the parameters for. * - * @return array + * @return array> * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified `$stackPtr` is not of * type `T_FUNCTION`, `T_CLOSURE`, `T_USE`, @@ -226,7 +228,9 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) // it's likely to be an array which might have arguments in it. This // could cause problems in our parsing below, so lets just skip to the // end of it. - if (isset($tokens[$i]['parenthesis_opener']) === true) { + if ($tokens[$i]['code'] !== T_TYPE_OPEN_PARENTHESIS + && isset($tokens[$i]['parenthesis_opener']) === true + ) { // Don't do this if it's the close parenthesis for the method. if ($i !== $tokens[$i]['parenthesis_closer']) { $i = ($tokens[$i]['parenthesis_closer'] + 1); @@ -322,7 +326,10 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) case T_NS_SEPARATOR: case T_TYPE_UNION: case T_TYPE_INTERSECTION: + case T_TYPE_OPEN_PARENTHESIS: + case T_TYPE_CLOSE_PARENTHESIS: case T_FALSE: + case T_TRUE: case T_NULL: // Part of a type hint or default value. if ($defaultStart === null) { @@ -459,7 +466,7 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - The upstream method has received no significant updates since PHPCS 3.7.1. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::getMethodProperties() Original source. * @see \PHPCSUtils\Utils\FunctionDeclarations::getProperties() PHPCSUtils native improved version. @@ -470,7 +477,7 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) * @param int $stackPtr The position in the stack of the function token to * acquire the properties for. * - * @return array + * @return array * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified position is not a * `T_FUNCTION`, `T_CLOSURE`, or `T_FN` token. @@ -504,7 +511,7 @@ public static function getMethodProperties(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - The upstream method has received no significant updates since PHPCS 3.7.1. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::getMemberProperties() Original source. * @see \PHPCSUtils\Utils\Variables::getMemberProperties() PHPCSUtils native improved version. @@ -515,7 +522,7 @@ public static function getMethodProperties(File $phpcsFile, $stackPtr) * @param int $stackPtr The position in the stack of the `T_VARIABLE` token to * acquire the properties for. * - * @return array + * @return array * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified position is not a * `T_VARIABLE` token, or if the position is not @@ -534,7 +541,7 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr) * array( * 'is_abstract' => boolean, // TRUE if the abstract keyword was found. * 'is_final' => boolean, // TRUE if the final keyword was found. - * 'is_readonly' => false, // TRUE if the readonly keyword was found. + * 'is_readonly' => boolean, // TRUE if the readonly keyword was found. * ); * ``` * @@ -542,69 +549,25 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 1.3.0. - * - PHPCS 3.8.0: Added support for PHP 8.2 `readonly` classes. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::getClassProperties() Original source. * @see \PHPCSUtils\Utils\ObjectDeclarations::getClassProperties() PHPCSUtils native improved version. * * @since 1.0.0 - * @since 1.0.6 Sync with PHPCS 3.8.0, support for readonly classes. PHPCS#3686. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position in the stack of the `T_CLASS` * token to acquire the properties for. * - * @return array + * @return array * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified position is not a * `T_CLASS` token. */ public static function getClassProperties(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - - if ($tokens[$stackPtr]['code'] !== T_CLASS) { - throw new RuntimeException('$stackPtr must be of type T_CLASS'); - } - - $valid = [ - T_FINAL => T_FINAL, - T_ABSTRACT => T_ABSTRACT, - T_READONLY => T_READONLY, - T_WHITESPACE => T_WHITESPACE, - T_COMMENT => T_COMMENT, - T_DOC_COMMENT => T_DOC_COMMENT, - ]; - - $isAbstract = false; - $isFinal = false; - $isReadonly = false; - - for ($i = ($stackPtr - 1); $i > 0; $i--) { - if (isset($valid[$tokens[$i]['code']]) === false) { - break; - } - - switch ($tokens[$i]['code']) { - case T_ABSTRACT: - $isAbstract = true; - break; - - case T_FINAL: - $isFinal = true; - break; - - case T_READONLY: - $isReadonly = true; - break; - } - } - - return [ - 'is_abstract' => $isAbstract, - 'is_final' => $isFinal, - 'is_readonly' => $isReadonly, - ]; + return $phpcsFile->getClassProperties($stackPtr); } /** @@ -614,7 +577,7 @@ public static function getClassProperties(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - The upstream method has received no significant updates since PHPCS 3.7.1. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::isReference() Original source. * @see \PHPCSUtils\Utils\Operators::isReference() PHPCSUtils native improved version. @@ -640,7 +603,7 @@ public static function isReference(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - The upstream method has received no significant updates since PHPCS 3.7.1. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::getTokensAsString() Original source. * @see \PHPCSUtils\Utils\GetTokensAsString Related set of functions. @@ -669,15 +632,15 @@ public static function getTokensAsString(File $phpcsFile, $start, $length, $orig * * Changelog for the PHPCS native function: * - Introduced in PHPCS 2.1.0. - * - The upstream method has received no significant updates since PHPCS 3.7.1. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::findStartOfStatement() Original source. * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. - * @param int $start The position to start searching from in the token stack. - * @param int|string|array $ignore Token types that should not be considered stop points. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $start The position to start searching from in the token stack. + * @param int|string|array $ignore Token types that should not be considered stop points. * * @return int */ @@ -693,15 +656,15 @@ public static function findStartOfStatement(File $phpcsFile, $start, $ignore = n * * Changelog for the PHPCS native function: * - Introduced in PHPCS 2.1.0. - * - The upstream method has received no significant updates since PHPCS 3.7.1. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::findEndOfStatement() Original source. * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. - * @param int $start The position to start searching from in the token stack. - * @param int|string|array $ignore Token types that should not be considered stop points. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $start The position to start searching from in the token stack. + * @param int|string|array $ignore Token types that should not be considered stop points. * * @return int */ @@ -717,16 +680,16 @@ public static function findEndOfStatement(File $phpcsFile, $start, $ignore = nul * * Changelog for the PHPCS native function: * - Introduced in PHPCS 0.0.5. - * - The upstream method has received no significant updates since PHPCS 3.7.1. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::hasCondition() Original source. * @see \PHPCSUtils\Utils\Conditions::hasCondition() PHPCSUtils native alternative. * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $types The type(s) of tokens to search for. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $types The type(s) of tokens to search for. * * @return bool */ @@ -742,7 +705,7 @@ public static function hasCondition(File $phpcsFile, $stackPtr, $types) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 1.3.0. - * - The upstream method has received no significant updates since PHPCS 3.7.1. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::getCondition() Original source. * @see \PHPCSUtils\Utils\Conditions::getCondition() More versatile alternative. @@ -773,7 +736,7 @@ public static function getCondition(File $phpcsFile, $stackPtr, $type, $first = * * Changelog for the PHPCS native function: * - Introduced in PHPCS 1.2.0. - * - The upstream method has received no significant updates since PHPCS 3.7.1. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::findExtendedClassName() Original source. * @see \PHPCSUtils\Utils\ObjectDeclarations::findExtendedClassName() PHPCSUtils native improved version. @@ -798,7 +761,7 @@ public static function findExtendedClassName(File $phpcsFile, $stackPtr) * * Changelog for the PHPCS native function: * - Introduced in PHPCS 2.7.0. - * - The upstream method has received no significant updates since PHPCS 3.7.1. + * - The upstream method has received no significant updates since PHPCS 3.10.0. * * @see \PHP_CodeSniffer\Files\File::findImplementedInterfaceNames() Original source. * @see \PHPCSUtils\Utils\ObjectDeclarations::findImplementedInterfaceNames() PHPCSUtils native improved version. @@ -808,8 +771,8 @@ public static function findExtendedClassName(File $phpcsFile, $stackPtr) * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The stack position of the class or enum token. * - * @return array|false Array with names of the implemented interfaces or `FALSE` on - * error or if there are no implemented interface names. + * @return array|false Array with names of the implemented interfaces or `FALSE` on + * error or if there are no implemented interface names. */ public static function findImplementedInterfaceNames(File $phpcsFile, $stackPtr) { diff --git a/PHPCSUtils/BackCompat/BCTokens.php b/PHPCSUtils/BackCompat/BCTokens.php index 78591164..2d6a72fd 100644 --- a/PHPCSUtils/BackCompat/BCTokens.php +++ b/PHPCSUtils/BackCompat/BCTokens.php @@ -74,15 +74,15 @@ final class BCTokens /** * Handle calls to (undeclared) methods for token arrays which haven't received any - * changes since PHPCS 3.7.1. + * changes since PHPCS 3.10.0. * * @since 1.0.0 * - * @param string $name The name of the method which has been called. - * @param array $args Any arguments passed to the method. - * Unused as none of the methods take arguments. + * @param string $name The name of the method which has been called. + * @param array $args Any arguments passed to the method. + * Unused as none of the methods take arguments. * - * @return array => Token array + * @return array Token array * * @throws \PHPCSUtils\Exceptions\InvalidTokenArray When an invalid token array is requested. */ @@ -110,7 +110,7 @@ public static function __callStatic($name, $args) * * @since 1.0.0 * - * @return array => Token array. + * @return array Token array. */ public static function functionNameTokens() { diff --git a/PHPCSUtils/BackCompat/Helper.php b/PHPCSUtils/BackCompat/Helper.php index c3a30257..aa033e92 100644 --- a/PHPCSUtils/BackCompat/Helper.php +++ b/PHPCSUtils/BackCompat/Helper.php @@ -52,7 +52,7 @@ public static function getVersion() * @since 1.0.0 * * @param string $key The name of the config value. - * @param string|null $value The value to set. If `null`, the config entry + * @param mixed $value The value to set. If `null`, the config entry * is deleted, reverting it to the default value. * @param bool $temp Set this config data temporarily for this script run. * This will not write the config data to the config file. @@ -143,13 +143,14 @@ public static function getTabWidth(File $phpcsFile) * command-line or the ruleset. * * @since 1.0.0 + * @since 1.0.10 The `File` type declaration has been removed from the parameter declaration. * * @param \PHP_CodeSniffer\Files\File|null $phpcsFile Optional. The current file being processed. * * @return string Encoding. Defaults to the PHPCS native default, which is 'utf-8' * for PHPCS 3.x. */ - public static function getEncoding(File $phpcsFile = null) + public static function getEncoding($phpcsFile = null) { $default = 'utf-8'; @@ -176,14 +177,18 @@ public static function getEncoding(File $phpcsFile = null) * Check whether the "--ignore-annotations" option is in effect. * * @since 1.0.0 + * @since 1.0.10 The `File` type declaration has been removed from the parameter declaration. * * @param \PHP_CodeSniffer\Files\File|null $phpcsFile Optional. The current file being processed. * * @return bool `TRUE` if annotations should be ignored, `FALSE` otherwise. */ - public static function ignoreAnnotations(File $phpcsFile = null) + public static function ignoreAnnotations($phpcsFile = null) { - if (isset($phpcsFile, $phpcsFile->config->annotations)) { + if (isset($phpcsFile) + && $phpcsFile instanceof File + && isset($phpcsFile->config->annotations) + ) { return ! $phpcsFile->config->annotations; } diff --git a/PHPCSUtils/Exceptions/TestTargetNotFound.php b/PHPCSUtils/Exceptions/TestTargetNotFound.php index 0e9eed68..4f9e5b4e 100644 --- a/PHPCSUtils/Exceptions/TestTargetNotFound.php +++ b/PHPCSUtils/Exceptions/TestTargetNotFound.php @@ -29,12 +29,12 @@ final class TestTargetNotFound extends OutOfBoundsException * @param string $content The (optional) target token content. * @param string $file The file in which the target token was not found. * - * @return \PHPCSUtils\Exceptions\TestMarkerNotFound + * @return \PHPCSUtils\Exceptions\TestTargetNotFound */ public static function create($marker, $content, $file) { $contentPhrase = ''; - if ($content !== null) { + if (\is_string($content)) { $contentPhrase = ' with token content: ' . $content; } diff --git a/PHPCSUtils/Fixers/SpacesFixer.php b/PHPCSUtils/Fixers/SpacesFixer.php index 168a2078..ff85ace9 100644 --- a/PHPCSUtils/Fixers/SpacesFixer.php +++ b/PHPCSUtils/Fixers/SpacesFixer.php @@ -133,7 +133,7 @@ public static function checkAndFix( } $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($ptrA + 1), null, true); - if ($nextNonEmpty < $ptrB) { + if ($nextNonEmpty !== false && $nextNonEmpty < $ptrB) { throw new RuntimeException( 'The $stackPtr and the $secondPtr token must be adjacent tokens separated only' . ' by whitespace and/or comments' diff --git a/PHPCSUtils/Internal/Cache.php b/PHPCSUtils/Internal/Cache.php index 3843f03d..2f7873fe 100644 --- a/PHPCSUtils/Internal/Cache.php +++ b/PHPCSUtils/Internal/Cache.php @@ -68,7 +68,8 @@ final class Cache * * @since 1.0.0 * - * @var array> Format: $cache[$loop][$fileName][$key][$id] = mixed $value; + * @var array>>> + * Format: $cache[$loop][$fileName][$key][$id] = mixed $value; */ private static $cache = []; @@ -144,7 +145,7 @@ public static function get(File $phpcsFile, $key, $id) * @param string $key The key to identify a particular set of results. * It is recommended to pass __METHOD__ to this parameter. * - * @return array + * @return array */ public static function getForFile(File $phpcsFile, $key) { diff --git a/PHPCSUtils/Internal/IsShortArrayOrList.php b/PHPCSUtils/Internal/IsShortArrayOrList.php index f056d623..36eb7a42 100644 --- a/PHPCSUtils/Internal/IsShortArrayOrList.php +++ b/PHPCSUtils/Internal/IsShortArrayOrList.php @@ -114,7 +114,7 @@ final class IsShortArrayOrList * * @since 1.0.0 * - * @var array + * @var array> */ private $tokens; @@ -161,14 +161,14 @@ final class IsShortArrayOrList * * @var string */ - private $phpcsVersion; + private $phpcsVersion; // @phpstan-ignore-line /** * Tokens which can open a short array or short list (PHPCS cross-version compatible). * * @since 1.0.0 * - * @return array => + * @var array */ private $openBrackets; @@ -362,27 +362,7 @@ private function isSquareBracket() private function isShortArrayBracket() { if ($this->tokens[$this->opener]['code'] === \T_OPEN_SQUARE_BRACKET) { - if (\version_compare($this->phpcsVersion, '3.7.2', '>=') === true) { - // These will just be properly tokenized, plain square brackets. No need for further checks. - return false; - } - - /* - * BC: Work around a bug in the tokenizer of PHPCS < 3.7.2, where a `[` would be - * tokenized as T_OPEN_SQUARE_BRACKET instead of T_OPEN_SHORT_ARRAY if it was - * preceded by the close parenthesis of a non-braced control structure. - * - * @link https://github.com/squizlabs/PHP_CodeSniffer/issues/3632 - */ - if ($this->tokens[$this->beforeOpener]['code'] === \T_CLOSE_PARENTHESIS - && isset($this->tokens[$this->beforeOpener]['parenthesis_owner']) === true - // phpcs:ignore Generic.Files.LineLength.TooLong - && isset(Tokens::$scopeOpeners[$this->tokens[$this->tokens[$this->beforeOpener]['parenthesis_owner']]['code']]) === true - ) { - return true; - } - - // These are really just plain square brackets. + // Currently there are no known issues with the tokenization in PHPCS 3.9.0 and higher. return false; } diff --git a/PHPCSUtils/Internal/IsShortArrayOrListWithCache.php b/PHPCSUtils/Internal/IsShortArrayOrListWithCache.php index 72f854f0..b4772bb5 100644 --- a/PHPCSUtils/Internal/IsShortArrayOrListWithCache.php +++ b/PHPCSUtils/Internal/IsShortArrayOrListWithCache.php @@ -58,7 +58,7 @@ final class IsShortArrayOrListWithCache * * @since 1.0.0 * - * @var array + * @var array> */ private $tokens; @@ -138,7 +138,7 @@ public static function isShortList(File $phpcsFile, $stackPtr) * * @return string|false The type of construct this bracket was determined to be. * Either 'short array', 'short list' or 'square brackets'. - * Or FALSE is this was not a bracket token. + * Or FALSE if this was not a bracket token. */ public static function getType(File $phpcsFile, $stackPtr) { diff --git a/PHPCSUtils/Internal/NoFileCache.php b/PHPCSUtils/Internal/NoFileCache.php index 6e7d08dd..2f7a2478 100644 --- a/PHPCSUtils/Internal/NoFileCache.php +++ b/PHPCSUtils/Internal/NoFileCache.php @@ -116,7 +116,7 @@ public static function get($key, $id) * @param string $key The key to identify a particular set of results. * It is recommended to pass `__METHOD__` to this parameter. * - * @return array + * @return array */ public static function getForKey($key) { diff --git a/PHPCSUtils/Internal/StableCollections.php b/PHPCSUtils/Internal/StableCollections.php index 7d8d92f0..593392df 100644 --- a/PHPCSUtils/Internal/StableCollections.php +++ b/PHPCSUtils/Internal/StableCollections.php @@ -46,7 +46,7 @@ final class StableCollections * * @since 1.0.2 * - * @var array => + * @var array */ public static $shortArrayListOpenTokensBC = [ \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, @@ -64,7 +64,7 @@ final class StableCollections * * @since 1.0.2 * - * @var array => + * @var array */ public static $shortArrayListTokensBC = [ \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, diff --git a/PHPCSUtils/TestUtils/UtilityMethodTestCase.php b/PHPCSUtils/TestUtils/UtilityMethodTestCase.php index fcc1e75a..8242002b 100644 --- a/PHPCSUtils/TestUtils/UtilityMethodTestCase.php +++ b/PHPCSUtils/TestUtils/UtilityMethodTestCase.php @@ -10,14 +10,18 @@ namespace PHPCSUtils\TestUtils; +use PHP_CodeSniffer\Config; use PHP_CodeSniffer\Exceptions\TokenizerException; +use PHP_CodeSniffer\Files\DummyFile; use PHP_CodeSniffer\Files\File; +use PHP_CodeSniffer\Ruleset; use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Exceptions\TestFileNotFound; use PHPCSUtils\Exceptions\TestMarkerNotFound; use PHPCSUtils\Exceptions\TestTargetNotFound; use PHPUnit\Framework\TestCase; use ReflectionClass; +use ReflectionProperty; /** * Base class for use when testing utility methods for PHP_CodeSniffer. @@ -80,7 +84,7 @@ * * * * @return array * * / - * public function dataMyMethod() + * public static function dataMyMethod() * { * return array( * array('/* testTestCaseDescription * /', false), @@ -154,7 +158,7 @@ abstract class UtilityMethodTestCase extends TestCase * * @since 1.0.0 * - * @var \PHP_CodeSniffer\Files\File + * @var \PHP_CodeSniffer\Files\File|null */ protected static $phpcsFile; @@ -168,7 +172,7 @@ abstract class UtilityMethodTestCase extends TestCase * * @since 1.0.0 * - * @var array + * @var array */ protected static $selectedSniff = ['Dummy.Dummy.Dummy']; @@ -208,9 +212,22 @@ public static function setUpTestFile() $contents = \file_get_contents($caseFile); - $config = new \PHP_CodeSniffer\Config(); + /* + * Set the static properties in the Config class to specific values for performance + * and to clear out values from other tests. + */ + self::setStaticConfigProperty('executablePaths', []); + + // Set to values which prevent the test-runner user's `CodeSniffer.conf` file + // from being read and influencing the tests. Also prevent an `exec()` call to stty. + self::setStaticConfigProperty('configData', ['report_width' => 80]); + self::setStaticConfigProperty('configDataFile', ''); + + $config = new Config(); /* + * Set to a usable value to circumvent Config trying to find a phpcs.xml config file. + * * We just need to provide a standard so PHPCS will tokenize the file. * The standard itself doesn't actually matter for testing utility methods, * so use the smallest one to get the fastest results. @@ -229,12 +246,12 @@ public static function setUpTestFile() // Also set a tab-width to enable testing tab-replaced vs `orig_content`. $config->tabWidth = static::$tabWidth; - $ruleset = new \PHP_CodeSniffer\Ruleset($config); + $ruleset = new Ruleset($config); // Make sure the file gets parsed correctly based on the file type. $contents = 'phpcs_input_file: ' . $caseFile . \PHP_EOL . $contents; - self::$phpcsFile = new \PHP_CodeSniffer\Files\DummyFile($contents, $ruleset, $config); + self::$phpcsFile = new DummyFile($contents, $ruleset, $config); // Only tokenize the file, do not process it. try { @@ -298,6 +315,29 @@ public static function resetTestFile() self::$tabWidth = 4; self::$phpcsFile = null; self::$selectedSniff = ['Dummy.Dummy.Dummy']; + + // Reset the static properties in the Config class to their defaults to prevent tests influencing each other. + self::setStaticConfigProperty('executablePaths', []); + self::setStaticConfigProperty('configData', null); + self::setStaticConfigProperty('configDataFile', null); + } + + /** + * Helper function to set the value of a private static property on the PHPCS Config class. + * + * @since 1.0.9 + * + * @param string $name The name of the property to set. + * @param mixed $value The value to set the property to. + * + * @return void + */ + public static function setStaticConfigProperty($name, $value) + { + $property = new ReflectionProperty('PHP_CodeSniffer\Config', $name); + $property->setAccessible(true); + $property->setValue(null, $value); + $property->setAccessible(false); } /** @@ -329,10 +369,10 @@ public static function usesPhp8NameTokens() * * @since 1.0.0 * - * @param string $commentString The complete delimiter comment to look for as a string. - * This string should include the comment opener and closer. - * @param int|string|array $tokenType The type of token(s) to look for. - * @param string $tokenContent Optional. The token content for the target token. + * @param string $commentString The complete delimiter comment to look for as a string. + * This string should include the comment opener and closer. + * @param int|string|array $tokenType The type of token(s) to look for. + * @param string|null $tokenContent Optional. The token content for the target token. * * @return int * diff --git a/PHPCSUtils/Tokens/Collections.php b/PHPCSUtils/Tokens/Collections.php index 09ed84b4..3a40fdcd 100644 --- a/PHPCSUtils/Tokens/Collections.php +++ b/PHPCSUtils/Tokens/Collections.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tokens; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Exceptions\InvalidTokenArray; /** @@ -67,7 +66,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::alternativeControlStructureSyntaxes()} method for access. * - * @var array => + * @var array */ private static $alternativeControlStructureSyntaxes = [ \T_IF => \T_IF, @@ -85,7 +84,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::alternativeControlStructureSyntaxClosers()} method for access. * - * @var array => + * @var array */ private static $alternativeControlStructureSyntaxClosers = [ \T_ENDIF => \T_ENDIF, @@ -109,7 +108,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::arrayOpenTokensBC()} method for access. * - * @var array => + * @var array */ private static $arrayOpenTokensBC = [ \T_ARRAY => \T_ARRAY, @@ -128,7 +127,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::arrayTokens()} method for access. * - * @var array => + * @var array */ private static $arrayTokens = [ \T_ARRAY => \T_ARRAY, @@ -141,7 +140,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::classModifierKeywords()} method for access. * - * @var array => + * @var array */ private static $classModifierKeywords = [ \T_FINAL => \T_FINAL, @@ -160,7 +159,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::closedScopes()} method for access. * - * @var array => + * @var array */ private static $closedScopes = [ \T_CLASS => \T_CLASS, @@ -180,7 +179,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::constantModifierKeywords()} method for access. * - * @var array => + * @var array */ private static $constantModifierKeywords = [ \T_PUBLIC => \T_PUBLIC, @@ -194,7 +193,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::controlStructureTokens()} method for access. * - * @var array => + * @var array */ private static $controlStructureTokens = [ \T_IF => \T_IF, @@ -214,7 +213,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::functionDeclarationTokens()} method for access. * - * @var array => + * @var array */ private static $functionDeclarationTokens = [ \T_FUNCTION => \T_FUNCTION, @@ -227,7 +226,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::incrementDecrementOperators()} method for access. * - * @var array => + * @var array */ private static $incrementDecrementOperators = [ \T_DEC => \T_DEC, @@ -247,7 +246,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::listOpenTokensBC()} method for access. * - * @var array => + * @var array */ private static $listOpenTokensBC = [ \T_LIST => \T_LIST, @@ -264,7 +263,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::listTokens()} method for access. * - * @var array => + * @var array */ private static $listTokens = [ \T_LIST => \T_LIST, @@ -277,7 +276,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::namespaceDeclarationClosers()} method for access. * - * @var array => + * @var array */ private static $namespaceDeclarationClosers = [ \T_SEMICOLON => \T_SEMICOLON, @@ -298,7 +297,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::nameTokens()} method for access. * - * @var array => + * @var array */ private static $nameTokens = [ \T_STRING => \T_STRING, @@ -312,7 +311,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::objectOperators()} method for access. * - * @var array => + * @var array */ private static $objectOperators = [ \T_DOUBLE_COLON => \T_DOUBLE_COLON, @@ -325,7 +324,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::ooCanExtend()} method for access. * - * @var array => + * @var array */ private static $ooCanExtend = [ \T_CLASS => \T_CLASS, @@ -338,7 +337,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::ooCanImplement()} method for access. * - * @var array => + * @var array */ private static $ooCanImplement = [ \T_CLASS => \T_CLASS, @@ -353,7 +352,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::ooConstantScopes()} method for access. * - * @var array => + * @var array */ private static $ooConstantScopes = [ \T_CLASS => \T_CLASS, @@ -370,7 +369,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::ooHierarchyKeywords()} method for access. * - * @var array => + * @var array */ private static $ooHierarchyKeywords = [ \T_PARENT => \T_PARENT, @@ -385,7 +384,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::ooPropertyScopes()} method for access. * - * @var array => + * @var array */ private static $ooPropertyScopes = [ \T_CLASS => \T_CLASS, @@ -398,17 +397,19 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::parameterTypeTokens()} method for access. * - * @var array => + * @var array */ private static $parameterTypeTokens = [ - \T_CALLABLE => \T_CALLABLE, - \T_SELF => \T_SELF, - \T_PARENT => \T_PARENT, - \T_FALSE => \T_FALSE, - \T_TRUE => \T_TRUE, - \T_NULL => \T_NULL, - \T_TYPE_UNION => \T_TYPE_UNION, - \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, + \T_CALLABLE => \T_CALLABLE, + \T_SELF => \T_SELF, + \T_PARENT => \T_PARENT, + \T_FALSE => \T_FALSE, + \T_TRUE => \T_TRUE, + \T_NULL => \T_NULL, + \T_TYPE_UNION => \T_TYPE_UNION, + \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, + \T_TYPE_OPEN_PARENTHESIS => \T_TYPE_OPEN_PARENTHESIS, + \T_TYPE_CLOSE_PARENTHESIS => \T_TYPE_CLOSE_PARENTHESIS, ]; /** @@ -416,7 +417,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::phpOpenTags()} method for access. * - * @var array => + * @var array */ private static $phpOpenTags = [ \T_OPEN_TAG => \T_OPEN_TAG, @@ -428,7 +429,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::propertyModifierKeywords()} method for access. * - * @var array => + * @var array */ private static $propertyModifierKeywords = [ \T_PUBLIC => \T_PUBLIC, @@ -444,17 +445,19 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::propertyTypeTokens()} method for access. * - * @var array => + * @var array */ private static $propertyTypeTokens = [ - \T_CALLABLE => \T_CALLABLE, - \T_SELF => \T_SELF, - \T_PARENT => \T_PARENT, - \T_FALSE => \T_FALSE, - \T_TRUE => \T_TRUE, - \T_NULL => \T_NULL, - \T_TYPE_UNION => \T_TYPE_UNION, - \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, + \T_CALLABLE => \T_CALLABLE, // Not allowed in PHP, but in this list to allow for flagging code errors. + \T_SELF => \T_SELF, + \T_PARENT => \T_PARENT, + \T_FALSE => \T_FALSE, + \T_TRUE => \T_TRUE, + \T_NULL => \T_NULL, + \T_TYPE_UNION => \T_TYPE_UNION, + \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, + \T_TYPE_OPEN_PARENTHESIS => \T_TYPE_OPEN_PARENTHESIS, + \T_TYPE_CLOSE_PARENTHESIS => \T_TYPE_CLOSE_PARENTHESIS, ]; /** @@ -462,15 +465,17 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::returnTypeTokens()} method for access. * - * @var array => + * @var array */ private static $returnTypeTokens = [ - \T_CALLABLE => \T_CALLABLE, - \T_FALSE => \T_FALSE, - \T_TRUE => \T_TRUE, - \T_NULL => \T_NULL, - \T_TYPE_UNION => \T_TYPE_UNION, - \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, + \T_CALLABLE => \T_CALLABLE, + \T_FALSE => \T_FALSE, + \T_TRUE => \T_TRUE, + \T_NULL => \T_NULL, + \T_TYPE_UNION => \T_TYPE_UNION, + \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, + \T_TYPE_OPEN_PARENTHESIS => \T_TYPE_OPEN_PARENTHESIS, + \T_TYPE_CLOSE_PARENTHESIS => \T_TYPE_CLOSE_PARENTHESIS, ]; /** @@ -481,7 +486,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::shortArrayListOpenTokensBC()} method for access. * - * @var array => + * @var array */ private static $shortArrayListOpenTokensBC = [ \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, @@ -494,7 +499,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::shortArrayTokens()} method for access. * - * @var array => + * @var array */ private static $shortArrayTokens = [ \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, @@ -508,7 +513,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::shortListTokens()} method for access. * - * @var array => + * @var array */ private static $shortListTokens = [ \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, @@ -520,7 +525,7 @@ final class Collections * * @since 1.0.0 Use the {@see Collections::textStringStartTokens()} method for access. * - * @var array => + * @var array */ private static $textStringStartTokens = [ \T_START_HEREDOC => \T_START_HEREDOC, @@ -534,11 +539,11 @@ final class Collections * * @since 1.0.0 * - * @param string $name The name of the method which has been called. - * @param array $args Any arguments passed to the method. - * Unused as none of the methods take arguments. + * @param string $name The name of the method which has been called. + * @param array $args Any arguments passed to the method. + * Unused as none of the methods take arguments. * - * @return array => Token array + * @return array Token array * * @throws \PHPCSUtils\Exceptions\InvalidTokenArray When an invalid token array is requested. */ @@ -592,17 +597,11 @@ private static function triggerDeprecation($method, $version, $replacement) * * @since 1.0.0 * - * @return array => + * @return array */ public static function arrayOpenTokensBC() { - $tokens = self::$arrayOpenTokensBC; - - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $tokens[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - } - - return $tokens; + return self::$arrayOpenTokensBC; } /** @@ -619,18 +618,11 @@ public static function arrayOpenTokensBC() * * @since 1.0.0 * - * @return array => + * @return array */ public static function arrayTokensBC() { - $tokens = self::$arrayTokens; - - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $tokens[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - $tokens[\T_CLOSE_SQUARE_BRACKET] = \T_CLOSE_SQUARE_BRACKET; - } - - return $tokens; + return self::$arrayTokens; } /** @@ -640,7 +632,7 @@ public static function arrayTokensBC() * * @since 1.0.0 * - * @return array => + * @return array */ public static function functionCallTokens() { @@ -669,17 +661,11 @@ public static function functionCallTokens() * * @since 1.0.0 * - * @return array => + * @return array */ public static function listOpenTokensBC() { - $tokens = self::$listOpenTokensBC; - - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $tokens[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - } - - return $tokens; + return self::$listOpenTokensBC; } /** @@ -694,18 +680,11 @@ public static function listOpenTokensBC() * * @since 1.0.0 * - * @return array => + * @return array */ public static function listTokensBC() { - $tokens = self::$listTokens; - - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $tokens[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - $tokens[\T_CLOSE_SQUARE_BRACKET] = \T_CLOSE_SQUARE_BRACKET; - } - - return $tokens; + return self::$listTokens; } /** @@ -718,7 +697,7 @@ public static function listTokensBC() * * @since 1.0.0 * - * @return array => + * @return array */ public static function namespacedNameTokens() { @@ -739,7 +718,7 @@ public static function namespacedNameTokens() * * @since 1.0.0 * - * @return array => + * @return array */ public static function parameterPassingTokens() { @@ -761,7 +740,7 @@ public static function parameterPassingTokens() * * @since 1.0.0 * - * @return array => + * @return array */ public static function parameterTypeTokens() { @@ -776,7 +755,7 @@ public static function parameterTypeTokens() * * @since 1.0.0 * - * @return array => + * @return array */ public static function propertyTypeTokens() { @@ -791,7 +770,7 @@ public static function propertyTypeTokens() * * @since 1.0.0 * - * @return array => + * @return array */ public static function returnTypeTokens() { @@ -811,17 +790,11 @@ public static function returnTypeTokens() * * @since 1.0.0 * - * @return array => + * @return array */ public static function shortArrayListOpenTokensBC() { - $tokens = self::$shortArrayListOpenTokensBC; - - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $tokens[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - } - - return $tokens; + return self::$shortArrayListOpenTokensBC; } /** @@ -836,18 +809,11 @@ public static function shortArrayListOpenTokensBC() * * @since 1.0.0 * - * @return array => + * @return array */ public static function shortArrayTokensBC() { - $tokens = self::$shortArrayTokens; - - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $tokens[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - $tokens[\T_CLOSE_SQUARE_BRACKET] = \T_CLOSE_SQUARE_BRACKET; - } - - return $tokens; + return self::$shortArrayTokens; } /** @@ -862,17 +828,10 @@ public static function shortArrayTokensBC() * * @since 1.0.0 * - * @return array => + * @return array */ public static function shortListTokensBC() { - $tokens = self::$shortListTokens; - - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $tokens[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - $tokens[\T_CLOSE_SQUARE_BRACKET] = \T_CLOSE_SQUARE_BRACKET; - } - - return $tokens; + return self::$shortListTokens; } } diff --git a/PHPCSUtils/Utils/Arrays.php b/PHPCSUtils/Utils/Arrays.php index ce321b04..1e228413 100644 --- a/PHPCSUtils/Utils/Arrays.php +++ b/PHPCSUtils/Utils/Arrays.php @@ -29,7 +29,7 @@ final class Arrays * * @since 1.0.0 * - * @var array => + * @var array */ private static $doubleArrowTargets = [ \T_DOUBLE_ARROW => \T_DOUBLE_ARROW, @@ -39,6 +39,7 @@ final class Arrays \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, // Inline function, control structures and other things to skip over. + \T_LIST => \T_LIST, \T_FN => \T_FN, \T_MATCH => \T_MATCH, \T_ATTRIBUTE => \T_ATTRIBUTE, @@ -85,15 +86,15 @@ public static function isShortArray(File $phpcsFile, $stackPtr) * tokens in an array. * Use with care. * - * @return array|false An array with the token pointers; or `FALSE` if this is not a - * (short) array token or if the opener/closer could not be determined. - * The format of the array return value is: - * ```php - * array( - * 'opener' => integer, // Stack pointer to the array open bracket. - * 'closer' => integer, // Stack pointer to the array close bracket. - * ) - * ``` + * @return array|false An array with the token pointers; or `FALSE` if this is not a + * (short) array token or if the opener/closer could not be determined. + * The format of the array return value is: + * ```php + * array( + * 'opener' => integer, // Stack pointer to the array open bracket. + * 'closer' => integer, // Stack pointer to the array close bracket. + * ) + * ``` */ public static function getOpenClose(File $phpcsFile, $stackPtr, $isShortArray = null) { @@ -208,6 +209,14 @@ public static function getDoubleArrowPtr(File $phpcsFile, $start, $end) continue; } + // Skip over potentially keyed long lists. + if ($tokens[$doubleArrow]['code'] === \T_LIST + && isset($tokens[$doubleArrow]['parenthesis_closer']) + ) { + $doubleArrow = $tokens[$doubleArrow]['parenthesis_closer']; + continue; + } + // Start of nested long/short array. break; } while ($doubleArrow < $end); diff --git a/PHPCSUtils/Utils/Conditions.php b/PHPCSUtils/Utils/Conditions.php index aba769e3..76f0e885 100644 --- a/PHPCSUtils/Utils/Conditions.php +++ b/PHPCSUtils/Utils/Conditions.php @@ -39,12 +39,12 @@ final class Conditions * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $types Optional. The type(s) of tokens to search for. - * @param bool $first Optional. Whether to search for the first (outermost) - * (`true`) or the last (innermost) condition (`false`) of - * the specified type(s). + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $types Optional. The type(s) of tokens to search for. + * @param bool $first Optional. Whether to search for the first (outermost) + * (`true`) or the last (innermost) condition (`false`) of + * the specified type(s). * * @return int|false Integer stack pointer to the condition; or `FALSE` if the token * does not have the condition or has no conditions at all. @@ -103,9 +103,9 @@ public static function getCondition(File $phpcsFile, $stackPtr, $types = [], $fi * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $types The type(s) of tokens to search for. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $types The type(s) of tokens to search for. * * @return bool */ @@ -122,9 +122,9 @@ public static function hasCondition(File $phpcsFile, $stackPtr, $types) * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $types Optional. The type(s) of tokens to search for. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $types Optional. The type(s) of tokens to search for. * * @return int|false Integer stack pointer to the condition; or `FALSE` if the token * does not have the condition or has no conditions at all. @@ -142,9 +142,9 @@ public static function getFirstCondition(File $phpcsFile, $stackPtr, $types = [] * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $types Optional. The type(s) of tokens to search for. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $types Optional. The type(s) of tokens to search for. * * @return int|false Integer stack pointer to the condition; or `FALSE` if the token * does not have the condition or has no conditions at all. diff --git a/PHPCSUtils/Utils/Context.php b/PHPCSUtils/Utils/Context.php index c0f1f947..b488060c 100644 --- a/PHPCSUtils/Utils/Context.php +++ b/PHPCSUtils/Utils/Context.php @@ -209,7 +209,7 @@ public static function inForCondition(File $phpcsFile, $stackPtr) if ($tokens[$i]['level'] !== $level || \count($tokens[$i]['nested_parenthesis']) !== $parens ) { - // Disregard semi-colons at lower nesting/condition levels. + // Disregard semicolons at lower nesting/condition levels. continue; } diff --git a/PHPCSUtils/Utils/ControlStructures.php b/PHPCSUtils/Utils/ControlStructures.php index 44bc053d..02bbf02c 100644 --- a/PHPCSUtils/Utils/ControlStructures.php +++ b/PHPCSUtils/Utils/ControlStructures.php @@ -199,7 +199,8 @@ public static function isElseIf(File $phpcsFile, $stackPtr) * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the token we are checking. * - * @return array Array with information about the caught Exception(s). + * @return array> + * Array with information about the caught Exception(s). * The returned array will contain the following information for * each caught exception: * ```php @@ -213,8 +214,6 @@ public static function isElseIf(File $phpcsFile, $stackPtr) * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified `$stackPtr` is not of * type `T_CATCH` or doesn't exist. - * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If no parenthesis opener or closer can be - * determined (parse error). */ public static function getCaughtExceptions(File $phpcsFile, $stackPtr) { @@ -227,7 +226,7 @@ public static function getCaughtExceptions(File $phpcsFile, $stackPtr) } if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) { - throw new RuntimeException('Parentheses opener/closer of the T_CATCH could not be determined'); + return []; } $opener = $tokens[$stackPtr]['parenthesis_opener']; diff --git a/PHPCSUtils/Utils/FunctionDeclarations.php b/PHPCSUtils/Utils/FunctionDeclarations.php index 153bce45..353ffdb1 100644 --- a/PHPCSUtils/Utils/FunctionDeclarations.php +++ b/PHPCSUtils/Utils/FunctionDeclarations.php @@ -43,7 +43,7 @@ final class FunctionDeclarations * * @since 1.0.0 * - * @var array => + * @var array */ public static $magicFunctions = [ '__autoload' => 'autoload', @@ -59,7 +59,7 @@ final class FunctionDeclarations * * @since 1.0.0 * - * @var array => + * @var array */ public static $magicMethods = [ '__construct' => 'construct', @@ -94,7 +94,7 @@ final class FunctionDeclarations * * @since 1.0.0 * - * @var array => + * @var array */ public static $methodsDoubleUnderscore = [ '__dorequest' => 'SOAPClient', @@ -148,7 +148,6 @@ public static function getName(File $phpcsFile, $stackPtr) * - Defensive coding against incorrect calls to this method. * - More efficient checking whether a function has a body. * - Support for PHP 8.0 identifier name tokens in return types, cross-version PHP & PHPCS. - * - Support for the PHP 8.2 `true` type. * - The results of this function call are cached during a PHPCS run for faster response times. * * @see \PHP_CodeSniffer\Files\File::getMethodProperties() Original source. @@ -160,7 +159,7 @@ public static function getName(File $phpcsFile, $stackPtr) * @param int $stackPtr The position in the stack of the function token to * acquire the properties for. * - * @return array Array with information about a function declaration. + * @return array Array with information about a function declaration. * The format of the return value is: * ```php * array( @@ -248,12 +247,6 @@ public static function getProperties(File $phpcsFile, $stackPtr) $hasBody = false; $returnTypeTokens = Collections::returnTypeTokens(); - /* - * BC PHPCS < 3.x.x: The union type separator is not (yet) retokenized correctly - * for union types containing the `true` type. - */ - $returnTypeTokens[\T_BITWISE_OR] = \T_BITWISE_OR; - $parenthesisCloser = null; if (isset($tokens[$stackPtr]['parenthesis_closer']) === true) { $parenthesisCloser = $tokens[$stackPtr]['parenthesis_closer']; @@ -277,6 +270,25 @@ public static function getProperties(File $phpcsFile, $stackPtr) break; } + if ($tokens[$i]['code'] === \T_USE) { + // Skip over closure use statements. + for ( + $j = ($i + 1); + $j < $phpcsFile->numTokens && isset(Tokens::$emptyTokens[$tokens[$j]['code']]) === true; + $j++ + ); + + if ($tokens[$j]['code'] === \T_OPEN_PARENTHESIS) { + if (isset($tokens[$j]['parenthesis_closer']) === false) { + // Live coding/parse error, stop parsing. + break; + } + + $i = $tokens[$j]['parenthesis_closer']; + continue; + } + } + if ($tokens[$i]['code'] === \T_NULLABLE) { $nullableReturnType = true; } @@ -367,7 +379,6 @@ public static function getProperties(File $phpcsFile, $stackPtr) * - More efficient and more stable looping of the default value. * - Clearer exception message when a non-closure use token was passed to the function. * - Support for PHP 8.0 identifier name tokens in parameter types, cross-version PHP & PHPCS. - * - Support for the PHP 8.2 `true` type. * - The results of this function call are cached during a PHPCS run for faster response times. * * @see \PHP_CodeSniffer\Files\File::getMethodParameters() Original source. @@ -379,7 +390,7 @@ public static function getProperties(File $phpcsFile, $stackPtr) * @param int $stackPtr The position in the stack of the function token * to acquire the parameters for. * - * @return array + * @return array> * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified $stackPtr is not of * type `T_FUNCTION`, `T_CLOSURE` or `T_USE`, @@ -447,12 +458,6 @@ public static function getParameters(File $phpcsFile, $stackPtr) $parameterTypeTokens = Collections::parameterTypeTokens(); - /* - * BC PHPCS < 3.x.x: The union type separator is not (yet) retokenized correctly - * for union types containing the `true` type. - */ - $parameterTypeTokens[\T_BITWISE_OR] = \T_BITWISE_OR; - for ($i = $paramStart; $i <= $closer; $i++) { if (isset($parameterTypeTokens[$tokens[$i]['code']]) === true /* diff --git a/PHPCSUtils/Utils/Lists.php b/PHPCSUtils/Utils/Lists.php index baf2c02a..167d6508 100644 --- a/PHPCSUtils/Utils/Lists.php +++ b/PHPCSUtils/Utils/Lists.php @@ -33,7 +33,7 @@ final class Lists * * @since 1.0.0 * - * @var array + * @var array */ private static $listItemDefaults = [ 'raw' => '', @@ -87,15 +87,15 @@ public static function isShortList(File $phpcsFile, $stackPtr) * tokens in a list. * Use with care. * - * @return array|false An array with the token pointers; or `FALSE` if this is not a (short) list - * token or if the opener/closer could not be determined. - * The format of the array return value is: - * ```php - * array( - * 'opener' => integer, // Stack pointer to the list open bracket. - * 'closer' => integer, // Stack pointer to the list close bracket. - * ) - * ``` + * @return array|false An array with the token pointers; or `FALSE` if this is not a (short) list + * token or if the opener/closer could not be determined. + * The format of the array return value is: + * ```php + * array( + * 'opener' => integer, // Stack pointer to the list open bracket. + * 'closer' => integer, // Stack pointer to the list close bracket. + * ) + * ``` */ public static function getOpenClose(File $phpcsFile, $stackPtr, $isShortList = null) { @@ -190,7 +190,8 @@ public static function getOpenClose(File $phpcsFile, $stackPtr, $isShortList = n * @param int $stackPtr The position in the stack of the function token * to acquire the parameters for. * - * @return array An array with information on each assignment made, including skipped assignments (empty), + * @return array> + * An array with information on each assignment made, including skipped assignments (empty), * or an empty array if no assignments are made at all (fatal error in PHP >= 7.0). * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified $stackPtr is not of diff --git a/PHPCSUtils/Utils/MessageHelper.php b/PHPCSUtils/Utils/MessageHelper.php index 388f2a09..eb7c1505 100644 --- a/PHPCSUtils/Utils/MessageHelper.php +++ b/PHPCSUtils/Utils/MessageHelper.php @@ -34,7 +34,7 @@ final class MessageHelper * Defaults to true (error). * @param string $code The error code for the message. * Defaults to 'Found'. - * @param array $data Optional input for the data replacements. + * @param scalar[] $data Optional input for the data replacements. * @param int $severity Optional. Severity level. Defaults to 0 which will * translate to the PHPCS default severity level. * @@ -70,7 +70,7 @@ public static function addMessage( * Defaults to true (error). * @param string $code The error code for the message. * Defaults to 'Found'. - * @param array $data Optional input for the data replacements. + * @param scalar[] $data Optional input for the data replacements. * @param int $severity Optional. Severity level. Defaults to 0 which will * translate to the PHPCS default severity level. * diff --git a/PHPCSUtils/Utils/NamingConventions.php b/PHPCSUtils/Utils/NamingConventions.php index c13d0a21..cec7a27f 100644 --- a/PHPCSUtils/Utils/NamingConventions.php +++ b/PHPCSUtils/Utils/NamingConventions.php @@ -40,7 +40,8 @@ final class NamingConventions /** * Uppercase A-Z. * - * @since 1.0.0 + * @since 1.0.0 + * @deprecated 1.0.10 * * @var string */ @@ -49,7 +50,8 @@ final class NamingConventions /** * Lowercase a-z. * - * @since 1.0.0 + * @since 1.0.0 + * @deprecated 1.0.10 * * @var string */ @@ -108,10 +110,7 @@ public static function isEqual($nameA, $nameB) return true; } - // OK, so these may be different names or they may be the same name with case differences. - $nameA = \strtr($nameA, self::AZ_UPPER, self::AZ_LOWER); - $nameB = \strtr($nameB, self::AZ_UPPER, self::AZ_LOWER); - - return ($nameA === $nameB); + // Comparing via strcasecmp will only compare ASCII letters case-insensitively. + return (\strcasecmp($nameA, $nameB) === 0); } } diff --git a/PHPCSUtils/Utils/Numbers.php b/PHPCSUtils/Utils/Numbers.php index 053643d7..69ec4ef0 100644 --- a/PHPCSUtils/Utils/Numbers.php +++ b/PHPCSUtils/Utils/Numbers.php @@ -106,7 +106,7 @@ final class Numbers * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of a T_LNUMBER or T_DNUMBER token. * - * @return array An array with information about the number. + * @return array An array with information about the number. * The format of the array return value is: * ```php * array( diff --git a/PHPCSUtils/Utils/ObjectDeclarations.php b/PHPCSUtils/Utils/ObjectDeclarations.php index e284224c..ffa346ae 100644 --- a/PHPCSUtils/Utils/ObjectDeclarations.php +++ b/PHPCSUtils/Utils/ObjectDeclarations.php @@ -147,7 +147,7 @@ public static function getName(File $phpcsFile, $stackPtr) * @param int $stackPtr The position in the stack of the `T_CLASS` * token to acquire the properties for. * - * @return array Array with implementation properties of a class. + * @return array Array with implementation properties of a class. * The format of the return value is: * ```php * array( @@ -272,8 +272,8 @@ public static function findExtendedClassName(File $phpcsFile, $stackPtr) * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The stack position of the class or enum token. * - * @return array|false Array with names of the implemented interfaces or `FALSE` on - * error or if there are no implemented interface names. + * @return array|false Array with names of the implemented interfaces or `FALSE` on + * error or if there are no implemented interface names. */ public static function findImplementedInterfaceNames(File $phpcsFile, $stackPtr) { @@ -290,8 +290,8 @@ public static function findImplementedInterfaceNames(File $phpcsFile, $stackPtr) * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. * @param int $stackPtr The stack position of the interface keyword. * - * @return array|false Array with names of the extended interfaces or `FALSE` on - * error or if there are no extended interface names. + * @return array|false Array with names of the extended interfaces or `FALSE` on + * error or if there are no extended interface names. */ public static function findExtendedInterfaceNames(File $phpcsFile, $stackPtr) { @@ -309,16 +309,16 @@ public static function findExtendedInterfaceNames(File $phpcsFile, $stackPtr) * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The stack position of the - * class/interface declaration keyword. - * @param int $keyword The token constant for the keyword to examine. - * Either `T_EXTENDS` or `T_IMPLEMENTS`. - * @param array $allowedFor Array of OO types for which use of the keyword - * is allowed. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The stack position of the + * class/interface declaration keyword. + * @param int $keyword The token constant for the keyword to examine. + * Either `T_EXTENDS` or `T_IMPLEMENTS`. + * @param array $allowedFor Array of OO types for which use of the keyword + * is allowed. * - * @return array|false Returns an array of names or `FALSE` on error or when the object - * being declared does not extend/implement another object. + * @return array|false Returns an array of names or `FALSE` on error or when the object + * being declared does not extend/implement another object. */ private static function findNames(File $phpcsFile, $stackPtr, $keyword, array $allowedFor) { diff --git a/PHPCSUtils/Utils/Operators.php b/PHPCSUtils/Utils/Operators.php index ae155c13..562440fe 100644 --- a/PHPCSUtils/Utils/Operators.php +++ b/PHPCSUtils/Utils/Operators.php @@ -35,7 +35,7 @@ final class Operators * * @since 1.0.0 * - * @var array => + * @var array Note: value is irrelevant, only key is used. */ private static $extraUnaryIndicators = [ \T_STRING_CONCAT => true, diff --git a/PHPCSUtils/Utils/Parentheses.php b/PHPCSUtils/Utils/Parentheses.php index 2e7384e0..998b64f9 100644 --- a/PHPCSUtils/Utils/Parentheses.php +++ b/PHPCSUtils/Utils/Parentheses.php @@ -34,7 +34,7 @@ final class Parentheses * * @since 1.0.0 * - * @var array => + * @var array */ private static $extraParenthesesOwners = [ \T_ISSET => \T_ISSET, @@ -95,10 +95,10 @@ public static function getOwner(File $phpcsFile, $stackPtr) * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position of `T_OPEN/CLOSE_PARENTHESIS` token. - * @param int|string|array $validOwners Array of token constants for the owners - * which should be considered valid. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position of `T_OPEN/CLOSE_PARENTHESIS` token. + * @param int|string|array $validOwners Array of token constants for the owners + * which should be considered valid. * * @return bool `TRUE` if the owner is within the list of `$validOwners`; `FALSE` if not and * if the parenthesis does not have a (direct) owner. @@ -121,10 +121,10 @@ public static function isOwnerIn(File $phpcsFile, $stackPtr, $validOwners) * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $validOwners Array of token constants for the owners - * which should be considered valid. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $validOwners Array of token constants for the owners + * which should be considered valid. * * @return bool */ @@ -143,10 +143,10 @@ public static function hasOwner(File $phpcsFile, $stackPtr, $validOwners) * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $validOwners Array of token constants for the owners - * which should be considered valid. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $validOwners Array of token constants for the owners + * which should be considered valid. * * @return int|false Integer stack pointer to the parentheses opener; or `FALSE` if the token * does not have parentheses owned by any of the valid owners or if @@ -167,10 +167,10 @@ public static function getFirstOpener(File $phpcsFile, $stackPtr, $validOwners = * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $validOwners Array of token constants for the owners - * which should be considered valid. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $validOwners Array of token constants for the owners + * which should be considered valid. * * @return int|false Integer stack pointer to the parentheses closer; or `FALSE` if the token * does not have parentheses owned by any of the valid owners or if @@ -197,10 +197,10 @@ public static function getFirstCloser(File $phpcsFile, $stackPtr, $validOwners = * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $validOwners Array of token constants for the owners - * which should be considered valid. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $validOwners Array of token constants for the owners + * which should be considered valid. * * @return int|false Integer stack pointer to the parentheses owner; or `FALSE` if the token * does not have parentheses owned by any of the valid owners or if @@ -226,10 +226,10 @@ public static function getFirstOwner(File $phpcsFile, $stackPtr, $validOwners = * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $validOwners Array of token constants for the owners - * which should be considered valid. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $validOwners Array of token constants for the owners + * which should be considered valid. * * @return int|false Integer stack pointer to the parentheses opener; or `FALSE` if the token * does not have parentheses owned by any of the valid owners or if @@ -250,10 +250,10 @@ public static function getLastOpener(File $phpcsFile, $stackPtr, $validOwners = * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $validOwners Array of token constants for the owners - * which should be considered valid. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $validOwners Array of token constants for the owners + * which should be considered valid. * * @return int|false Integer stack pointer to the parentheses closer; or `FALSE` if the token * does not have parentheses owned by any of the valid owners or if @@ -280,10 +280,10 @@ public static function getLastCloser(File $phpcsFile, $stackPtr, $validOwners = * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $validOwners Array of token constants for the owners - * which should be considered valid. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $validOwners Array of token constants for the owners + * which should be considered valid. * * @return int|false Integer stack pointer to the parentheses owner; or `FALSE` if the token * does not have parentheses owned by any of the valid owners or if @@ -305,11 +305,11 @@ public static function getLastOwner(File $phpcsFile, $stackPtr, $validOwners = [ * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position in the stack of the - * token to verify. - * @param int|string|array $validOwners Array of token constants for the owners - * which should be considered valid. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position in the stack of the + * token to verify. + * @param int|string|array $validOwners Array of token constants for the owners + * which should be considered valid. * * @return int|false Integer stack pointer to the valid parentheses owner; or `FALSE` if * the token was not wrapped in parentheses or if the outermost set @@ -333,11 +333,11 @@ public static function firstOwnerIn(File $phpcsFile, $stackPtr, $validOwners) * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position in the stack of the - * token to verify. - * @param int|string|array $validOwners Array of token constants for the owners - * which should be considered valid. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position in the stack of the + * token to verify. + * @param int|string|array $validOwners Array of token constants for the owners + * which should be considered valid. * * @return int|false Integer stack pointer to the valid parentheses owner; or `FALSE` if * the token was not wrapped in parentheses or if the innermost set @@ -363,13 +363,13 @@ public static function lastOwnerIn(File $phpcsFile, $stackPtr, $validOwners) * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position of the token we are checking. - * @param int|string|array $validOwners Optional. Array of token constants for the owners - * which should be considered valid. - * @param bool $reverse Optional. Whether to search for the first/outermost - * (`false`) or the last/innermost (`true`) set of - * parentheses with the specified owner(s). + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position of the token we are checking. + * @param int|string|array $validOwners Optional. Array of token constants for the owners + * which should be considered valid. + * @param bool $reverse Optional. Whether to search for the first/outermost + * (`false`) or the last/innermost (`true`) set of + * parentheses with the specified owner(s). * * @return int|false Integer stack pointer to the parentheses opener; or `FALSE` if the token * does not have parentheses owned by any of the valid owners or if diff --git a/PHPCSUtils/Utils/PassedParameters.php b/PHPCSUtils/Utils/PassedParameters.php index f73ee8c4..0d65b8e4 100644 --- a/PHPCSUtils/Utils/PassedParameters.php +++ b/PHPCSUtils/Utils/PassedParameters.php @@ -33,7 +33,7 @@ final class PassedParameters * * @since 1.0.0 * - * @var array => + * @var array */ private static $callParsingStopPoints = [ \T_COMMA => \T_COMMA, @@ -49,12 +49,11 @@ final class PassedParameters * * - If passed a `T_STRING`, `T_NAME_FULLY_QUALIFIED`, `T_NAME_RELATIVE`, `T_NAME_QUALIFIED`, * or `T_VARIABLE` stack pointer, it will treat it as a function call. - * If a `T_STRING` or `T_VARIABLE` which is *not* a function call is passed, the behaviour is - * undetermined. + * If a token which is *not* a function call is passed, the behaviour is undetermined. * - If passed a `T_ANON_CLASS` stack pointer, it will accept it as a class instantiation. * - If passed a `T_SELF`, `T_STATIC` or `T_PARENT` stack pointer, it will accept it as a - * class instantiation function call when used like `new self()` (with or without parenthesis). - * When these hierarchiecal keywords are not preceded by the `new` keyword, parenthesis + * class instantiation function call when used like `new self()` (with or without parentheses). + * When these hierarchiecal keywords are not preceded by the `new` keyword, parentheses * will be required for the token to be accepted. * - If passed a `T_ARRAY` or `T_OPEN_SHORT_ARRAY` stack pointer, it will detect * whether the array has values or is empty. @@ -170,7 +169,8 @@ public static function hasParameters(File $phpcsFile, $stackPtr, $isShortArray = * Efficiency tweak for when this has already been established, * Use with EXTREME care. * - * @return array A multi-dimentional array with information on each parameter/array item. + * @return array> + * A multi-dimentional array with information on each parameter/array item. * The information gathered about each parameter/array item is in the following format: * ```php * 1 => array( @@ -366,7 +366,7 @@ public static function getParameters(File $phpcsFile, $stackPtr, $limit = 0, $is * @param int $stackPtr The position of function call name, * language construct or array open token. * @param int $paramOffset The 1-based index position of the parameter to retrieve. - * @param string|string[] $paramNames Optional. Either the name of the target parameter + * @param string|array $paramNames Optional. Either the name of the target parameter * to retrieve as a string or an array of names for the * same target parameter. * Only relevant for function calls. @@ -379,11 +379,11 @@ public static function getParameters(File $phpcsFile, $stackPtr, $limit = 0, $is * always pass both the offset as well as the parameter * name when examining function calls. * - * @return array|false Array with information on the parameter/array item at the specified offset, - * or with the specified name. - * Or `FALSE` if the specified parameter/array item is not found. - * See {@see PassedParameters::getParameters()} for the format of the returned - * (single-dimensional) array. + * @return array|false Array with information on the parameter/array item at the specified + * offset, or with the specified name. + * Or `FALSE` if the specified parameter/array item is not found. + * See {@see PassedParameters::getParameters()} for the format of the + * returned (single-dimensional) array. * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the token passed is not one of the * accepted types or doesn't exist. @@ -452,20 +452,23 @@ public static function getParameterCount(File $phpcsFile, $stackPtr) * * @since 1.0.0 * - * @param array $parameters The output of a previous call to {@see PassedParameters::getParameters()}. - * @param int $paramOffset The 1-based index position of the parameter to retrieve. - * @param string|string[] $paramNames Either the name of the target parameter to retrieve - * as a string or an array of names for the same target parameter. - * An array of names is supported to allow for functions - * for which the parameter names have undergone name - * changes over time. - * The name will take precedence over the offset. + * @param array> $parameters The output of a previous call to + * {@see PassedParameters::getParameters()}. + * @param int $paramOffset The 1-based index position of the parameter + * to retrieve. + * @param string|array $paramNames Either the name of the target parameter to retrieve + * as a string or an array of names for the same target + * parameter. + * An array of names is supported to allow for functions + * for which the parameter names have undergone name + * changes over time. + * The name will take precedence over the offset. * - * @return array|false Array with information on the parameter at the specified offset, - * or with the specified name. - * Or `FALSE` if the specified parameter is not found. - * See {@see PassedParameters::getParameters()} for the format of the returned - * (single-dimensional) array. + * @return array|false Array with information on the parameter at the specified offset, + * or with the specified name. + * Or `FALSE` if the specified parameter is not found. + * See {@see PassedParameters::getParameters()} for the format of the + * returned (single-dimensional) array. * * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the `$paramNames` parameter is not passed * and the requested parameter was not passed diff --git a/PHPCSUtils/Utils/Scopes.php b/PHPCSUtils/Utils/Scopes.php index 32947c9e..99011fba 100644 --- a/PHPCSUtils/Utils/Scopes.php +++ b/PHPCSUtils/Utils/Scopes.php @@ -30,11 +30,11 @@ final class Scopes * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position in the stack of the - * token to verify. - * @param int|string|array $validScopes Array of token constants representing - * the scopes considered valid. + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position in the stack of the + * token to verify. + * @param int|string|array $validScopes Array of token constants representing + * the scopes considered valid. * * @return int|false Integer stack pointer to the valid direct scope; or `FALSE` if * no valid direct scope was found. diff --git a/PHPCSUtils/Utils/UseStatements.php b/PHPCSUtils/Utils/UseStatements.php index 4e917322..6e29f5f8 100644 --- a/PHPCSUtils/Utils/UseStatements.php +++ b/PHPCSUtils/Utils/UseStatements.php @@ -156,7 +156,8 @@ public static function isTraitUse(File $phpcsFile, $stackPtr) * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. * @param int $stackPtr The position in the stack of the `T_USE` token. * - * @return array A multi-level array containing information about the use statement. + * @return array> + * A multi-level array containing information about the use statement. * The first level is `'name'`, `'function'` and `'const'`. These keys will always exist. * If any statements are found for any of these categories, the second level * will contain the alias/name as the key and the full original use name as the @@ -191,10 +192,6 @@ public static function splitImportUseStatement(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); - if (isset($tokens[$stackPtr]) === false || $tokens[$stackPtr]['code'] !== \T_USE) { - throw new RuntimeException('$stackPtr must be of type T_USE'); - } - if (self::isImportUse($phpcsFile, $stackPtr) === false) { throw new RuntimeException('$stackPtr must be an import use statement'); } @@ -300,9 +297,9 @@ public static function splitImportUseStatement(File $phpcsFile, $stackPtr) case \T_COMMA: if ($name !== '') { if ($useGroup === true) { - $statements[$type][$alias] = $baseName . $name; + $statements[$type][$alias] = \ltrim($baseName, '\\') . $name; } else { - $statements[$type][$alias] = $name; + $statements[$type][$alias] = \ltrim($name, '\\'); } } @@ -358,16 +355,18 @@ public static function splitImportUseStatement(File $phpcsFile, $stackPtr) * * @since 1.0.0 * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. - * @param int $stackPtr The position in the stack of the `T_USE` token. - * @param array $previousUseStatements The import `use` statements collected so far. - * This should be either the output of a - * previous call to this method or the output of - * an earlier call to the - * {@see UseStatements::splitImportUseStatement()} - * method. - * - * @return array A multi-level array containing information about the current `use` statement combined with + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The position in the stack of the + * `T_USE` token. + * @param array> $previousUseStatements The import `use` statements collected so far. + * This should be either the output of a + * previous call to this method or the output of + * an earlier call to the + * {@see UseStatements::splitImportUseStatement()} + * method. + * + * @return array> + * A multi-level array containing information about the current `use` statement combined with * the previously collected `use` statement information. * See {@see UseStatements::splitImportUseStatement()} for more details about the array format. */ @@ -393,19 +392,20 @@ public static function splitAndMergeImportUseStatement(File $phpcsFile, $stackPt * * @since 1.0.0 * - * @param array $previousUseStatements The import `use` statements collected so far. - * This should be either the output of a - * previous call to this method or the output of - * an earlier call to the - * {@see UseStatements::splitImportUseStatement()} - * method. - * @param array $currentUseStatement The parsed import `use` statements to merge with - * the previously collected use statements. - * This should be the output of a call to the - * {@see UseStatements::splitImportUseStatement()} - * method. - * - * @return array A multi-level array containing information about the current `use` statement combined with + * @param array> $previousUseStatements The import `use` statements collected so far. + * This should be either the output of a + * previous call to this method or the output of + * an earlier call to the + * {@see UseStatements::splitImportUseStatement()} + * method. + * @param array> $currentUseStatement The parsed import `use` statements to merge with + * the previously collected use statements. + * This should be the output of a call to the + * {@see UseStatements::splitImportUseStatement()} + * method. + * + * @return array> + * A multi-level array containing information about the current `use` statement combined with * the previously collected `use` statement information. * See {@see UseStatements::splitImportUseStatement()} for more details about the array format. */ diff --git a/PHPCSUtils/Utils/Variables.php b/PHPCSUtils/Utils/Variables.php index 4c92e1ed..a97135f4 100644 --- a/PHPCSUtils/Utils/Variables.php +++ b/PHPCSUtils/Utils/Variables.php @@ -41,7 +41,7 @@ final class Variables * * @since 1.0.0 * - * @var array => + * @var array */ public static $phpReservedVars = [ '_SERVER' => true, @@ -82,7 +82,6 @@ final class Variables * other non-property variables passed to the method. * - Defensive coding against incorrect calls to this method. * - Support PHP 8.0 identifier name tokens in property types, cross-version PHP & PHPCS. - * - Support for the PHP 8.2 `true` type. * - The results of this function call are cached during a PHPCS run for faster response times. * * @see \PHP_CodeSniffer\Files\File::getMemberProperties() Original source. @@ -94,7 +93,7 @@ final class Variables * @param int $stackPtr The position in the stack of the `T_VARIABLE` token * to acquire the properties for. * - * @return array Array with information about the class member variable. + * @return array Array with information about the class member variable. * The format of the return value is: * ```php * array( @@ -183,12 +182,6 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr) $nullableType = false; $propertyTypeTokens = Collections::propertyTypeTokens(); - /* - * BC PHPCS < 3.x.x: The union type separator is not (yet) retokenized correctly - * for union types containing the `true` type. - */ - $propertyTypeTokens[\T_BITWISE_OR] = \T_BITWISE_OR; - if ($i < $stackPtr) { // We've found a type. for ($i; $i < $stackPtr; $i++) { diff --git a/PHPCSUtils/ruleset.xml b/PHPCSUtils/ruleset.xml index f4365516..eefc6dbb 100644 --- a/PHPCSUtils/ruleset.xml +++ b/PHPCSUtils/ruleset.xml @@ -1,4 +1,4 @@ - + Utility methods for external PHPCS standards. diff --git a/README.md b/README.md index 20d2b200..c971fe4e 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,14 @@ [![Latest Unstable Version](https://img.shields.io/badge/unstable-dev--develop-e68718.svg?maxAge=2419200)](https://packagist.org/packages/phpcsstandards/phpcsutils#dev-develop) [![Last Commit to Unstable](https://img.shields.io/github/last-commit/PHPCSStandards/PHPCSUtils/develop.svg)](https://github.com/PHPCSStandards/PHPCSUtils/commits/develop) -[![Minimum PHP Version](https://img.shields.io/packagist/php-v/phpcsstandards/phpcsutils.svg?maxAge=3600)][phpcsutils-packagist] +[![Docs website](https://github.com/PHPCSStandards/PHPCSUtils/actions/workflows/update-docs.yml/badge.svg)][phpcsutils-web] [![CS Build Status](https://github.com/PHPCSStandards/PHPCSUtils/actions/workflows/basics.yml/badge.svg?branch=develop)](https://github.com/PHPCSStandards/PHPCSUtils/actions/workflows/basics.yml) [![Test Build Status](https://github.com/PHPCSStandards/PHPCSUtils/actions/workflows/test.yml/badge.svg?branch=develop)][phpcsutils-tests-gha] -[![Tested on PHP 5.4 to 8.2](https://img.shields.io/badge/tested%20on-PHP%205.4%20|%205.5%20|%205.6%20|%207.0%20|%207.1%20|%207.2%20|%207.3%20|%207.4%20|%208.0%20|%208.1%20|%208.2-brightgreen.svg?maxAge=2419200)][phpcsutils-tests-gha] [![Coverage Status](https://coveralls.io/repos/github/PHPCSStandards/PHPCSUtils/badge.svg?branch=develop)](https://coveralls.io/github/PHPCSStandards/PHPCSUtils?branch=develop) -[![Docs website](https://github.com/PHPCSStandards/PHPCSUtils/actions/workflows/update-docs.yml/badge.svg)][phpcsutils-web] +[![Minimum PHP Version](https://img.shields.io/packagist/php-v/phpcsstandards/phpcsutils.svg?maxAge=3600)][phpcsutils-packagist] +[![Tested on PHP 5.4 to 8.3](https://img.shields.io/badge/tested%20on-PHP%205.4%20|%205.5%20|%205.6%20|%207.0%20|%207.1%20|%207.2%20|%207.3%20|%207.4%20|%208.0%20|%208.1%20|%208.2%20|%208.3-brightgreen.svg?maxAge=2419200)][phpcsutils-tests-gha] + [![License: LGPLv3](https://poser.pugx.org/phpcsstandards/phpcsutils/license)](https://github.com/PHPCSStandards/PHPCSUtils/blob/stable/LICENSE) ![Awesome](https://img.shields.io/badge/awesome%3F-yes!-brightgreen.svg) @@ -45,7 +46,7 @@ Whether you need to split an `array` into the individual items, are trying to de Includes improved versions of the PHPCS native utility functions and plenty of new utility functions. -These functions are compatible with PHPCS 3.7.1 up to PHPCS `master`. +These functions are compatible with PHPCS 3.10.0 up to PHPCS `master`. ### A collection of static properties and methods for often-used token groups @@ -65,7 +66,7 @@ Supports PHPUnit 4.x up to 9.x. Normally to use the latest version of PHP_CodeSniffer native utility functions, you would have to raise the minimum requirements of your external PHPCS standard. -Now you won't have to anymore. This package allows you to use the latest version of those utility functions in all PHP_CodeSniffer versions from PHPCS 3.7.1 and up. +Now you won't have to anymore. This package allows you to use the latest version of those utility functions in all PHP_CodeSniffer versions from PHPCS 3.10.0 and up. ### Fully documented @@ -77,7 +78,7 @@ To see detailed information about all the available abstract sniffs, utility fun ## Minimum Requirements * PHP 5.4 or higher. -* [PHP_CodeSniffer] 3.7.1+. +* [PHP_CodeSniffer] 3.10.0+. * Recommended PHP extensions for optimal functionality: - PCRE with Unicode support (normally enabled by default) @@ -127,7 +128,7 @@ To use a non-Composer based installation for your sniff development environment, Your installation instructions for a non-Composer based installation will probably look similar to this: -> * Install [PHP_CodeSniffer] via [your preferred method](https://github.com/squizlabs/PHP_CodeSniffer#installation). +> * Install [PHP_CodeSniffer] via [your preferred method](https://github.com/PHPCSStandards/PHP_CodeSniffer#installation). > * Register the path to PHPCS in your system `$PATH` environment variable to make the `phpcs` command available from anywhere in your file system. > * Download the \[latest _YourStandardName_ release\] and unzip/untar it into an arbitrary directory. > You can also choose to clone the repository using git. @@ -164,11 +165,11 @@ For things to continue working when you add PHPCSUtils to your standard, you nee To support non-Composer based installs for running your sniff unit tests, you will need to adjust the PHPUnit `bootstrap.php` file to allow for passing an environment variable pointing to your PHPCSUtils installation.
- Example bootstrap code using a PHPCSUTILS_DIR environment variable + Example bootstrap code using a PHPCSUtils_DIR environment variable ```php // Get the PHPCS dir from an environment variable. -$phpcsUtilDir = getenv('PHPCSUTILS_DIR'); +$phpcsUtilDir = getenv('PHPCSUtils_DIR'); // This may be a Composer install. if ($phpcsUtilDir === false && file_exists(__DIR__ . '/vendor/autoload.php')) { @@ -191,7 +192,7 @@ if ($phpcsUtilDir === false && file_exists(__DIR__ . '/vendor/autoload.php')) { echo 'Uh oh... can\'t find PHPCSUtils. If you use Composer, please run `composer install`. -Otherwise, make sure you set a `PHPCSUTILS_DIR` environment variable in your phpunit.xml file +Otherwise, make sure you set a `PHPCSUtils_DIR` environment variable in your phpunit.xml file pointing to the PHPCS directory. '; @@ -208,7 +209,7 @@ Once that's done, you will need to make a small tweak to your own dev environmen ```xml - + ``` @@ -287,7 +288,7 @@ If you are unsure whether the changes you are proposing would be welcome, please This code is released under the [GNU Lesser General Public License (LGPLv3)](LICENSE). -[PHP_CodeSniffer]: https://github.com/squizlabs/PHP_CodeSniffer +[PHP_CodeSniffer]: https://github.com/PHPCSStandards/PHP_CodeSniffer [Composer PHPCS plugin]: https://github.com/PHPCSStandards/composer-installer [phpcsutils-repo]: https://github.com/PHPCSStandards/PHPCSUtils [phpcsutils-web]: https://phpcsutils.com/ diff --git a/Tests/AbstractSniffs/AbstractArrayDeclaration/AbstractArrayDeclarationSniffTest.php b/Tests/AbstractSniffs/AbstractArrayDeclaration/AbstractArrayDeclarationSniffTest.php index fbdf04f9..d83bb5c9 100644 --- a/Tests/AbstractSniffs/AbstractArrayDeclaration/AbstractArrayDeclarationSniffTest.php +++ b/Tests/AbstractSniffs/AbstractArrayDeclaration/AbstractArrayDeclarationSniffTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff * - * @group abstracts - * * @since 1.0.0 */ final class AbstractArrayDeclarationSniffTest extends PolyfilledTestCase @@ -31,7 +29,7 @@ final class AbstractArrayDeclarationSniffTest extends PolyfilledTestCase * Needed for PHPUnit cross-version support as PHPUnit 4.x does not have a * `setMethodsExcept()` method yet. * - * @var array + * @var array */ public $methodsToMock = [ 'processOpenClose', @@ -51,9 +49,7 @@ public function testShortList() { $target = $this->getTargetToken('/* testShortList */', Collections::arrayOpenTokensBC()); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->never()) ->method('processOpenClose'); @@ -86,9 +82,7 @@ public function testEmptyArray() { $target = $this->getTargetToken('/* testEmptyArray */', Collections::arrayOpenTokensBC()); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->once()) ->method('processOpenClose'); @@ -124,58 +118,52 @@ public function testSingleLineShortArrayNoKeysNoTrailingComma() Collections::arrayOpenTokensBC() ); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->once()) ->method('processOpenClose') ->with( $this->identicalTo(self::$phpcsFile), - $this->equalTo($target), - $this->equalTo($target + 5) + $this->identicalTo($target), + $this->identicalTo($target + 5) ); - $mockObj->expects($this->exactly(2)) - ->method('processNoKey') - ->withConsecutive( - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 1), $this->equalTo(1)], - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 3), $this->equalTo(2)] - ); + $this->setExpectationWithConsecutiveArgs( + $mockObj, + $this->exactly(2), + 'processNoKey', + [ + [self::$phpcsFile, $target + 1, 1], + [self::$phpcsFile, $target + 3, 2], + ] + ); - $mockObj->expects($this->exactly(2)) - ->method('processValue') - ->withConsecutive( - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 1), - $this->equalTo($target + 1), - $this->equalTo(1), - ], - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 3), - $this->equalTo($target + 4), - $this->equalTo(2), - ] - ); + $this->setExpectationWithConsecutiveArgs( + $mockObj, + $this->exactly(2), + 'processValue', + [ + [self::$phpcsFile, $target + 1, $target + 1, 1], + [self::$phpcsFile, $target + 3, $target + 4, 2], + ] + ); $mockObj->expects($this->once()) ->method('processComma') ->with( $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 2), - $this->equalTo(1) + $this->identicalTo($target + 2), + $this->identicalTo(1) ); $mockObj->process(self::$phpcsFile, $target); // Verify that the properties have been correctly set. - $this->assertAttributeValueSame($target, 'stackPtr', $mockObj); - $this->assertAttributeValueSame($target, 'arrayOpener', $mockObj); - $this->assertAttributeValueSame(($target + 5), 'arrayCloser', $mockObj); - $this->assertAttributeValueSame(2, 'itemCount', $mockObj); - $this->assertAttributeValueSame(true, 'singleLine', $mockObj); + $this->assertPropertySame($target, 'stackPtr', $mockObj); + $this->assertPropertySame($target, 'arrayOpener', $mockObj); + $this->assertPropertySame(($target + 5), 'arrayCloser', $mockObj); + $this->assertPropertySame(2, 'itemCount', $mockObj); + $this->assertPropertySame(true, 'singleLine', $mockObj); } /** @@ -191,88 +179,67 @@ public function testMultiLineLongArrayKeysTrailingComma() Collections::arrayOpenTokensBC() ); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->once()) ->method('processOpenClose') ->with( $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 1), - $this->equalTo($target + 35) - ); - - $mockObj->expects($this->exactly(3)) - ->method('processKey') - ->withConsecutive( - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 2), - $this->equalTo($target + 5), - $this->equalTo(1), - ], - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 10), - $this->equalTo($target + 13), - $this->equalTo(2), - ], - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 18), - $this->equalTo($target + 21), - $this->equalTo(3), - ] + $this->identicalTo($target + 1), + $this->identicalTo($target + 35) ); - $mockObj->expects($this->exactly(3)) - ->method('processArrow') - ->withConsecutive( - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 6), $this->equalTo(1)], - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 14), $this->equalTo(2)], - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 22), $this->equalTo(3)] - ); + $this->setExpectationWithConsecutiveArgs( + $mockObj, + $this->exactly(3), + 'processKey', + [ + [self::$phpcsFile, $target + 2, $target + 5, 1], + [self::$phpcsFile, $target + 10, $target + 13, 2], + [self::$phpcsFile, $target + 18, $target + 21, 3], + ] + ); - $mockObj->expects($this->exactly(3)) - ->method('processValue') - ->withConsecutive( - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 7), - $this->equalTo($target + 8), - $this->equalTo(1), - ], - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 15), - $this->equalTo($target + 16), - $this->equalTo(2), - ], - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 23), - $this->equalTo($target + 24), - $this->equalTo(3), - ] - ) - ->will($this->onConsecutiveCalls(null, null, true)); // Testing short-circuiting the loop. + $this->setExpectationWithConsecutiveArgs( + $mockObj, + $this->exactly(3), + 'processArrow', + [ + [self::$phpcsFile, $target + 6, 1], + [self::$phpcsFile, $target + 14, 2], + [self::$phpcsFile, $target + 22, 3], + ] + ); - $mockObj->expects($this->exactly(2)) - ->method('processComma') - ->withConsecutive( - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 9), $this->equalTo(1)], - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 17), $this->equalTo(2)] - ); + $this->setExpectationWithConsecutiveArgs( + $mockObj, + $this->exactly(3), + 'processValue', + [ + [self::$phpcsFile, $target + 7, $target + 8, 1], + [self::$phpcsFile, $target + 15, $target + 16, 2], + [self::$phpcsFile, $target + 23, $target + 24, 3], + ] + )->will($this->onConsecutiveCalls(null, null, true)); // Testing short-circuiting the loop. + + $this->setExpectationWithConsecutiveArgs( + $mockObj, + $this->exactly(2), + 'processComma', + [ + [self::$phpcsFile, $target + 9, 1], + [self::$phpcsFile, $target + 17, 2], + ] + ); $mockObj->process(self::$phpcsFile, $target); // Verify that the properties have been correctly set. - $this->assertAttributeValueSame($target, 'stackPtr', $mockObj); - $this->assertAttributeValueSame(($target + 1), 'arrayOpener', $mockObj); - $this->assertAttributeValueSame(($target + 35), 'arrayCloser', $mockObj); - $this->assertAttributeValueSame(4, 'itemCount', $mockObj); - $this->assertAttributeValueSame(false, 'singleLine', $mockObj); + $this->assertPropertySame($target, 'stackPtr', $mockObj); + $this->assertPropertySame(($target + 1), 'arrayOpener', $mockObj); + $this->assertPropertySame(($target + 35), 'arrayCloser', $mockObj); + $this->assertPropertySame(4, 'itemCount', $mockObj); + $this->assertPropertySame(false, 'singleLine', $mockObj); } /** @@ -288,87 +255,74 @@ public function testMultiLineShortArrayMixedKeysNoKeys() Collections::arrayOpenTokensBC() ); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->once()) ->method('processOpenClose') ->with( $this->identicalTo(self::$phpcsFile), - $this->equalTo($target), - $this->equalTo($target + 22) + $this->identicalTo($target), + $this->identicalTo($target + 22) ); - $mockObj->expects($this->exactly(2)) - ->method('processKey') - ->withConsecutive( - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 1), - $this->equalTo($target + 4), - $this->equalTo(1), - ], - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 13), - $this->equalTo($target + 16), - $this->equalTo(3), - ] - ); + $this->setExpectationWithConsecutiveArgs( + $mockObj, + $this->exactly(2), + 'processKey', + [ + [self::$phpcsFile, $target + 1, $target + 4, 1], + [self::$phpcsFile, $target + 13, $target + 16, 3], + ] + ); $mockObj->expects($this->once()) ->method('processNoKey') - ->withConsecutive( - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 9), $this->equalTo(2)] + ->with( + $this->identicalTo(self::$phpcsFile), + $this->identicalTo($target + 9), + $this->identicalTo(2) ); - $mockObj->expects($this->exactly(2)) - ->method('processArrow') - ->withConsecutive( - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 5), $this->equalTo(1)], - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 17), $this->equalTo(3)] - ); + $this->setExpectationWithConsecutiveArgs( + $mockObj, + $this->exactly(2), + 'processArrow', + [ + [self::$phpcsFile, $target + 5, 1], + [self::$phpcsFile, $target + 17, 3], + ] + ); - $mockObj->expects($this->exactly(3)) - ->method('processValue') - ->withConsecutive( - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 6), - $this->equalTo($target + 7), - $this->equalTo(1), - ], - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 9), - $this->equalTo($target + 11), - $this->equalTo(2), - ], - [ - $this->identicalTo(self::$phpcsFile), - $this->equalTo($target + 18), - $this->equalTo($target + 19), - $this->equalTo(3), - ] - ); + $this->setExpectationWithConsecutiveArgs( + $mockObj, + $this->exactly(3), + 'processValue', + [ + [self::$phpcsFile, $target + 6, $target + 7, 1], + [self::$phpcsFile, $target + 9, $target + 11, 2], + [self::$phpcsFile, $target + 18, $target + 19, 3], + ] + ); - $mockObj->expects($this->exactly(3)) - ->method('processComma') - ->withConsecutive( - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 8), $this->equalTo(1)], - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 12), $this->equalTo(2)], - [$this->identicalTo(self::$phpcsFile), $this->equalTo($target + 20), $this->equalTo(3)] - ); + $this->setExpectationWithConsecutiveArgs( + $mockObj, + $this->exactly(3), + 'processComma', + [ + [self::$phpcsFile, $target + 8, 1], + [self::$phpcsFile, $target + 12, 2], + [self::$phpcsFile, $target + 20, 3], + ] + ); $mockObj->process(self::$phpcsFile, $target); // Verify that the properties have been correctly set. - $this->assertAttributeValueSame($target, 'stackPtr', $mockObj); - $this->assertAttributeValueSame($target, 'arrayOpener', $mockObj); - $this->assertAttributeValueSame(($target + 22), 'arrayCloser', $mockObj); - $this->assertAttributeValueSame(3, 'itemCount', $mockObj); - $this->assertAttributeValueSame(false, 'singleLine', $mockObj); + $this->assertPropertySame($target, 'stackPtr', $mockObj); + $this->assertPropertySame($target, 'arrayOpener', $mockObj); + $this->assertPropertySame(($target + 22), 'arrayCloser', $mockObj); + $this->assertPropertySame(3, 'itemCount', $mockObj); + $this->assertPropertySame(false, 'singleLine', $mockObj); } /** @@ -380,9 +334,7 @@ public function testEmptyArrayItem() { $target = $this->getTargetToken('/* testEmptyArrayItem */', Collections::arrayOpenTokensBC()); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->once()) ->method('processOpenClose'); @@ -411,9 +363,7 @@ public function testShortCircuitOnProcessOpenClose() { $target = $this->getTargetToken('/* testShortCircuit */', Collections::arrayOpenTokensBC()); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->once()) ->method('processOpenClose') @@ -446,9 +396,7 @@ public function testShortCircuitOnProcessKey() { $target = $this->getTargetToken('/* testShortCircuit */', Collections::arrayOpenTokensBC()); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->once()) ->method('processOpenClose'); @@ -481,9 +429,7 @@ public function testShortCircuitOnProcessNoKey() { $target = $this->getTargetToken('/* testShortCircuit */', Collections::arrayOpenTokensBC()); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->once()) ->method('processOpenClose'); @@ -516,9 +462,7 @@ public function testShortCircuitOnProcessArrow() { $target = $this->getTargetToken('/* testShortCircuit */', Collections::arrayOpenTokensBC()); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->once()) ->method('processOpenClose'); @@ -551,9 +495,7 @@ public function testShortCircuitOnProcessValue() { $target = $this->getTargetToken('/* testShortCircuit */', Collections::arrayOpenTokensBC()); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->once()) ->method('processOpenClose'); @@ -586,9 +528,7 @@ public function testShortCircuitOnProcessComma() { $target = $this->getTargetToken('/* testShortCircuit */', Collections::arrayOpenTokensBC()); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->once()) ->method('processOpenClose'); @@ -621,9 +561,7 @@ public function testBowOutOnUnfinishedArray() { $target = $this->getTargetToken('/* testLiveCoding */', Collections::arrayOpenTokensBC()); - $mockObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff') - ->setMethods($this->methodsToMock) - ->getMockForAbstractClass(); + $mockObj = $this->getMockedClassUnderTest(); $mockObj->expects($this->never()) ->method('processOpenClose'); @@ -645,4 +583,30 @@ public function testBowOutOnUnfinishedArray() $mockObj->process(self::$phpcsFile, $target); } + + /** + * Helper method to retrieve a mock object for the abstract class. + * + * The `setMethods()` method was silently deprecated in PHPUnit 9 and removed in PHPUnit 10. + * + * Note: direct access to the `getMockBuilder()` method is soft deprecated as of PHPUnit 10, + * and expected to be hard deprecated in PHPUnit 11 and removed in PHPUnit 12. + * Dealing with that is something for a later iteration of the test suite. + * + * @return \PHPUnit\Framework\MockObject\MockObject + */ + private function getMockedClassUnderTest() + { + $mockedObj = $this->getMockBuilder('\PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff'); + + if (\method_exists($mockedObj, 'onlyMethods')) { + // PHPUnit 8+. + return $mockedObj->onlyMethods($this->methodsToMock) + ->getMockForAbstractClass(); + } + + // PHPUnit < 8. + return $mockedObj->setMethods($this->methodsToMock) + ->getMockForAbstractClass(); + } } diff --git a/Tests/AbstractSniffs/AbstractArrayDeclaration/ArrayDeclarationSniffTestDouble.php b/Tests/AbstractSniffs/AbstractArrayDeclaration/ArrayDeclarationSniffTestDouble.php index b006753c..efa0b653 100644 --- a/Tests/AbstractSniffs/AbstractArrayDeclaration/ArrayDeclarationSniffTestDouble.php +++ b/Tests/AbstractSniffs/AbstractArrayDeclaration/ArrayDeclarationSniffTestDouble.php @@ -24,7 +24,7 @@ final class ArrayDeclarationSniffTestDouble extends AbstractArrayDeclarationSnif /** * The token stack for the current file being examined. * - * @var array + * @var array> */ public $tokens; diff --git a/Tests/AbstractSniffs/AbstractArrayDeclaration/GetActualArrayKeyTest.php b/Tests/AbstractSniffs/AbstractArrayDeclaration/GetActualArrayKeyTest.php index ed3b2fe4..993cab77 100644 --- a/Tests/AbstractSniffs/AbstractArrayDeclaration/GetActualArrayKeyTest.php +++ b/Tests/AbstractSniffs/AbstractArrayDeclaration/GetActualArrayKeyTest.php @@ -20,8 +20,6 @@ * * @covers \PHPCSUtils\AbstractSniffs\AbstractArrayDeclarationSniff::getActualArrayKey * - * @group abstracts - * * @since 1.0.0 */ final class GetActualArrayKeyTest extends UtilityMethodTestCase @@ -57,8 +55,8 @@ public function testGetActualArrayKey($testMarker, $expected, $expectedFrom) $this->assertSame( $expected, $result, - 'Failed: actual key ' . $result . ' is not the same as the expected key ' . $expected - . ' for item number ' . $itemNr + 'Failed: actual key ' . \var_export($result, true) . ' is not the same as the expected key ' + . \var_export($expected, true) . ' for item number ' . $itemNr ); } } @@ -69,9 +67,9 @@ public function testGetActualArrayKey($testMarker, $expected, $expectedFrom) * * @see testGetActualArrayKey() For the array format. * - * @return array + * @return array> */ - public function dataGetActualArrayKey() + public static function dataGetActualArrayKey() { return [ 'unsupported-key-types' => [ @@ -135,8 +133,8 @@ public function testGetActualArrayKeyFromHeredocWithEscapedVarInKey() $this->assertSame( $expected[$itemNr], $result, - 'Failed: actual key ' . $result . ' is not the same as the expected key ' . $expected[$itemNr] - . ' for item number ' . $itemNr + 'Failed: actual key ' . \var_export($result, true) . ' is not the same as the expected key ' + . \var_export($expected[$itemNr], true) . ' for item number ' . $itemNr ); } } diff --git a/Tests/AssertAttributeSame.php b/Tests/AssertPropertySame.php similarity index 54% rename from Tests/AssertAttributeSame.php rename to Tests/AssertPropertySame.php index d8f7bfd2..a3ff44b5 100644 --- a/Tests/AssertAttributeSame.php +++ b/Tests/AssertPropertySame.php @@ -18,35 +18,35 @@ * PHPUnit cross-version compatibility helper. * * Backfills the PHPUnit native `assertAttributeSame()` method in PHPUnit 9.x and above in which - * the method was removed. Use `assertAttributeValueSame()` instead of `assertAttributeSame()` + * the method was removed. Use `assertPropertySame()` instead of `assertAttributeSame()` * for cross-version compatibility. * * @since 1.0.0 */ -trait AssertAttributeSame +trait AssertPropertySame { /** * PHPUnit cross-version helper method to test the value of class properties. * - * @param mixed $expected Expected property value. - * @param string $attributeName The name of the property to check. - * @param object $actualObject The object on which to check the property value. - * @param string $message Optional. Custom error message. + * @param mixed $expected Expected property value. + * @param string $propertyName The name of the property to check. + * @param object $actualObject The object on which to check the property value. + * @param string $message Optional. Custom error message. * * @return void */ - public function assertAttributeValueSame($expected, $attributeName, $actualObject, $message = '') + public function assertPropertySame($expected, $propertyName, $actualObject, $message = '') { // Will throw a warning on PHPUnit 8, but will still work. if (\method_exists($this, 'assertAttributeSame')) { - $this->assertAttributeSame($expected, $attributeName, $actualObject, $message); + $this->assertAttributeSame($expected, $propertyName, $actualObject, $message); return; } // PHPUnit 9.0+. try { - $actual = $this->getObjectAttributeValue($actualObject, $attributeName); + $actual = $this->getObjectPropertyValue($actualObject, $propertyName); } catch (Exception $e) { $this->fail($e->getMessage()); } @@ -55,31 +55,32 @@ public function assertAttributeValueSame($expected, $attributeName, $actualObjec } /** - * Retrieve the value of an object's attribute. - * This also works for attributes that are declared protected or private. + * Retrieve the value of an object property. + * + * This also works for properties that are declared protected or private. * * @param object|string $objectUnderTest The object or class on which to check the property value. - * @param string $attributeName The name of the property to check. + * @param string $propertyName The name of the property to check. * * @return mixed Property value. * * @throws \Exception */ - public static function getObjectAttributeValue($objectUnderTest, $attributeName) + public static function getObjectPropertyValue($objectUnderTest, $propertyName) { $reflector = new ReflectionObject($objectUnderTest); do { try { - $attribute = $reflector->getProperty($attributeName); + $property = $reflector->getProperty($propertyName); - if (!$attribute || $attribute->isPublic()) { - return $objectUnderTest->$attributeName; + if (!$property || $property->isPublic()) { + return $objectUnderTest->$propertyName; } - $attribute->setAccessible(true); - $value = $attribute->getValue($objectUnderTest); - $attribute->setAccessible(false); + $property->setAccessible(true); + $value = $property->getValue($objectUnderTest); + $property->setAccessible(false); return $value; } catch (ReflectionException $e) { @@ -88,8 +89,8 @@ public static function getObjectAttributeValue($objectUnderTest, $attributeName) throw new Exception( \sprintf( - 'Attribute "%s" not found in object.', - $attributeName + 'Property "%s" not found in object.', + $propertyName ) ); } diff --git a/Tests/BackCompat/BCFile/FindEndOfStatementTest.php b/Tests/BackCompat/BCFile/FindEndOfStatementTest.php index 1f42fd45..1f18c18f 100644 --- a/Tests/BackCompat/BCFile/FindEndOfStatementTest.php +++ b/Tests/BackCompat/BCFile/FindEndOfStatementTest.php @@ -17,7 +17,7 @@ * @author Phil Davis * * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */ namespace PHPCSUtils\Tests\BackCompat\BCFile; diff --git a/Tests/BackCompat/BCFile/FindExtendedClassNameTest.inc b/Tests/BackCompat/BCFile/FindExtendedClassNameTest.inc index 58b73505..d9885d27 100644 --- a/Tests/BackCompat/BCFile/FindExtendedClassNameTest.inc +++ b/Tests/BackCompat/BCFile/FindExtendedClassNameTest.inc @@ -3,26 +3,30 @@ /* testNotAClass */ function notAClass() {} -class testFECNClass {} +/* testNonExtendedClass */ +class testFECNNonExtendedClass {} -/* testExtendedClass */ +/* testExtendsUnqualifiedClass */ class testFECNExtendedClass extends testFECNClass {} -/* testNamespacedClass */ +/* testExtendsFullyQualifiedClass */ class testFECNNamespacedClass extends \PHP_CodeSniffer\Tests\Core\File\testFECNClass {} -/* testNonExtendedClass */ -class testFECNNonExtendedClass {} +/* testExtendsPartiallyQualifiedClass */ +class testFECNQualifiedClass extends Core\File\RelativeClass {} -/* testInterface */ +/* testNonExtendedInterface */ interface testFECNInterface {} -/* testInterfaceThatExtendsInterface */ +/* testInterfaceExtendsUnqualifiedInterface */ interface testInterfaceThatExtendsInterface extends testFECNInterface{} -/* testInterfaceThatExtendsFQCNInterface */ +/* testInterfaceExtendsFullyQualifiedInterface */ interface testInterfaceThatExtendsFQCNInterface extends \PHP_CodeSniffer\Tests\Core\File\testFECNInterface{} +/* testExtendedAnonClass */ +$anon = new class( $a, $b ) extends testFECNExtendedAnonClass {}; + /* testNestedExtendedClass */ class testFECNNestedExtendedClass { public function someMethod() { @@ -31,18 +35,12 @@ class testFECNNestedExtendedClass { } } -/* testNamespaceRelativeQualifiedClass */ -class testFECNQualifiedClass extends Core\File\RelativeClass {} - /* testClassThatExtendsAndImplements */ class testFECNClassThatExtendsAndImplements extends testFECNClass implements InterfaceA, InterfaceB {} /* testClassThatImplementsAndExtends */ class testFECNClassThatImplementsAndExtends implements InterfaceA, InterfaceB extends testFECNClass {} -/* testExtendedAnonClass */ -$anon = new class( $a, $b ) extends testFECNExtendedAnonClass {}; - /* testInterfaceMultiExtends */ interface Multi extends \Package\FooInterface, \BarInterface {}; diff --git a/Tests/BackCompat/BCFile/FindExtendedClassNameTest.php b/Tests/BackCompat/BCFile/FindExtendedClassNameTest.php index fb794dd5..254d99a8 100644 --- a/Tests/BackCompat/BCFile/FindExtendedClassNameTest.php +++ b/Tests/BackCompat/BCFile/FindExtendedClassNameTest.php @@ -19,7 +19,7 @@ * @author Phil Davis * * @copyright 2016-2019 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */ namespace PHPCSUtils\Tests\BackCompat\BCFile; @@ -81,8 +81,8 @@ public function testNotAClass() * * @dataProvider dataExtendedClass * - * @param string $identifier Comment which precedes the test case. - * @param bool $expected Expected function output. + * @param string $identifier Comment which precedes the test case. + * @param string|false $expected Expected function output. * * @return void */ @@ -100,70 +100,70 @@ public function testFindExtendedClassName($identifier, $expected) * * @see testFindExtendedClassName() * - * @return array + * @return array> */ - public function dataExtendedClass() + public static function dataExtendedClass() { return [ - [ - '/* testExtendedClass */', - 'testFECNClass', + 'class does not extend' => [ + 'identifier' => '/* testNonExtendedClass */', + 'expected' => false, ], - [ - '/* testNamespacedClass */', - '\PHP_CodeSniffer\Tests\Core\File\testFECNClass', + 'class extends unqualified class' => [ + 'identifier' => '/* testExtendsUnqualifiedClass */', + 'expected' => 'testFECNClass', ], - [ - '/* testNonExtendedClass */', - false, + 'class extends fully qualified class' => [ + 'identifier' => '/* testExtendsFullyQualifiedClass */', + 'expected' => '\PHP_CodeSniffer\Tests\Core\File\testFECNClass', ], - [ - '/* testInterface */', - false, + 'class extends partially qualified class' => [ + 'identifier' => '/* testExtendsPartiallyQualifiedClass */', + 'expected' => 'Core\File\RelativeClass', ], - [ - '/* testInterfaceThatExtendsInterface */', - 'testFECNInterface', + 'interface does not extend' => [ + 'identifier' => '/* testNonExtendedInterface */', + 'expected' => false, ], - [ - '/* testInterfaceThatExtendsFQCNInterface */', - '\PHP_CodeSniffer\Tests\Core\File\testFECNInterface', + 'interface extends unqualified interface' => [ + 'identifier' => '/* testInterfaceExtendsUnqualifiedInterface */', + 'expected' => 'testFECNInterface', ], - [ - '/* testNestedExtendedClass */', - false, + 'interface extends fully qualified interface' => [ + 'identifier' => '/* testInterfaceExtendsFullyQualifiedInterface */', + 'expected' => '\PHP_CodeSniffer\Tests\Core\File\testFECNInterface', ], - [ - '/* testNestedExtendedAnonClass */', - 'testFECNAnonClass', + 'anon class extends unqualified class' => [ + 'identifier' => '/* testExtendedAnonClass */', + 'expected' => 'testFECNExtendedAnonClass', ], - [ - '/* testNamespaceRelativeQualifiedClass */', - 'Core\File\RelativeClass', + 'class does not extend but contains anon class which extends' => [ + 'identifier' => '/* testNestedExtendedClass */', + 'expected' => false, ], - [ - '/* testClassThatExtendsAndImplements */', - 'testFECNClass', + 'anon class extends, nested in non-extended class' => [ + 'identifier' => '/* testNestedExtendedAnonClass */', + 'expected' => 'testFECNAnonClass', ], - [ - '/* testClassThatImplementsAndExtends */', - 'testFECNClass', + 'class extends and implements' => [ + 'identifier' => '/* testClassThatExtendsAndImplements */', + 'expected' => 'testFECNClass', ], - [ - '/* testExtendedAnonClass */', - 'testFECNExtendedAnonClass', + 'class implements and extends' => [ + 'identifier' => '/* testClassThatImplementsAndExtends */', + 'expected' => 'testFECNClass', ], - [ - '/* testInterfaceMultiExtends */', - '\Package\FooInterface', + 'interface extends multiple interfaces (not supported)' => [ + 'identifier' => '/* testInterfaceMultiExtends */', + 'expected' => '\Package\FooInterface', ], - [ - '/* testMissingExtendsName */', - false, + 'parse error - extends keyword, but no class name' => [ + 'identifier' => '/* testMissingExtendsName */', + 'expected' => false, ], - [ - '/* testParseError */', - false, + 'parse error - live coding - no curly braces' => [ + 'identifier' => '/* testParseError */', + 'expected' => false, ], ]; } diff --git a/Tests/BackCompat/BCFile/FindImplementedInterfaceNamesTest.inc b/Tests/BackCompat/BCFile/FindImplementedInterfaceNamesTest.inc index e1cc427a..3246efa2 100644 --- a/Tests/BackCompat/BCFile/FindImplementedInterfaceNamesTest.inc +++ b/Tests/BackCompat/BCFile/FindImplementedInterfaceNamesTest.inc @@ -3,24 +3,22 @@ /* testNotAClass */ function notAClass() {} -interface testFIINInterface2 {} - -/* testInterface */ +/* testPlainInterface */ interface testFIINInterface {} -/* testImplementedClass */ +/* testNonImplementedClass */ +class testFIINNonImplementedClass {} + +/* testClassImplementsSingle */ class testFIINImplementedClass implements testFIINInterface {} -/* testMultiImplementedClass */ +/* testClassImplementsMultiple */ class testFIINMultiImplementedClass implements testFIINInterface, testFIINInterface2 {} -/* testNamespacedClass */ +/* testImplementsFullyQualified */ class testFIINNamespacedClass implements \PHP_CodeSniffer\Tests\Core\File\testFIINInterface {} -/* testNonImplementedClass */ -class testFIINNonImplementedClass {} - -/* testNamespaceRelativeQualifiedClass */ +/* testImplementsPartiallyQualified */ class testFIINQualifiedClass implements Core\File\RelativeInterface {} /* testClassThatExtendsAndImplements */ @@ -32,13 +30,13 @@ class testFECNClassThatImplementsAndExtends implements \InterfaceA, InterfaceB e /* testBackedEnumWithoutImplements */ enum Suit:string {} -/* testEnumImplements */ +/* testEnumImplementsSingle */ enum Suit implements Colorful {} -/* testBackedEnumImplements */ +/* testBackedEnumImplementsMulti */ enum Suit: string implements Colorful, \Deck {} -/* testAnonClassImplements */ +/* testAnonClassImplementsSingle */ $anon = class() implements testFIINInterface {} /* testMissingImplementsName */ diff --git a/Tests/BackCompat/BCFile/FindImplementedInterfaceNamesTest.php b/Tests/BackCompat/BCFile/FindImplementedInterfaceNamesTest.php index ef44e19f..7b24f254 100644 --- a/Tests/BackCompat/BCFile/FindImplementedInterfaceNamesTest.php +++ b/Tests/BackCompat/BCFile/FindImplementedInterfaceNamesTest.php @@ -18,7 +18,7 @@ * @author Phil Davis * * @copyright 2016-2019 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */ namespace PHPCSUtils\Tests\BackCompat\BCFile; @@ -79,8 +79,8 @@ public function testNotAClass() * * @dataProvider dataImplementedInterface * - * @param string $identifier Comment which precedes the test case. - * @param bool $expected Expected function output. + * @param string $identifier Comment which precedes the test case. + * @param array|false $expected Expected function output. * * @return void */ @@ -98,78 +98,78 @@ public function testFindImplementedInterfaceNames($identifier, $expected) * * @see testFindImplementedInterfaceNames() * - * @return array + * @return array|false>> */ - public function dataImplementedInterface() + public static function dataImplementedInterface() { return [ - [ - '/* testImplementedClass */', - ['testFIINInterface'], + 'interface declaration, no implements' => [ + 'identifier' => '/* testPlainInterface */', + 'expected' => false, ], - [ - '/* testMultiImplementedClass */', - [ + 'class does not implement' => [ + 'identifier' => '/* testNonImplementedClass */', + 'expected' => false, + ], + 'class implements single interface, unqualified' => [ + 'identifier' => '/* testClassImplementsSingle */', + 'expected' => ['testFIINInterface'], + ], + 'class implements multiple interfaces' => [ + 'identifier' => '/* testClassImplementsMultiple */', + 'expected' => [ 'testFIINInterface', 'testFIINInterface2', ], ], - [ - '/* testNamespacedClass */', - ['\PHP_CodeSniffer\Tests\Core\File\testFIINInterface'], - ], - [ - '/* testNonImplementedClass */', - false, - ], - [ - '/* testInterface */', - false, + 'class implements single interface, fully qualified' => [ + 'identifier' => '/* testImplementsFullyQualified */', + 'expected' => ['\PHP_CodeSniffer\Tests\Core\File\testFIINInterface'], ], - [ - '/* testNamespaceRelativeQualifiedClass */', - ['Core\File\RelativeInterface'], + 'class implements single interface, partially qualified' => [ + 'identifier' => '/* testImplementsPartiallyQualified */', + 'expected' => ['Core\File\RelativeInterface'], ], - [ - '/* testClassThatExtendsAndImplements */', - [ + 'class extends and implements' => [ + 'identifier' => '/* testClassThatExtendsAndImplements */', + 'expected' => [ 'InterfaceA', '\NameSpaced\Cat\InterfaceB', ], ], - [ - '/* testClassThatImplementsAndExtends */', - [ + 'class implements and extends' => [ + 'identifier' => '/* testClassThatImplementsAndExtends */', + 'expected' => [ '\InterfaceA', 'InterfaceB', ], ], - [ - '/* testBackedEnumWithoutImplements */', - false, + 'enum does not implement' => [ + 'identifier' => '/* testBackedEnumWithoutImplements */', + 'expected' => false, ], - [ - '/* testEnumImplements */', - ['Colorful'], + 'enum implements single interface, unqualified' => [ + 'identifier' => '/* testEnumImplementsSingle */', + 'expected' => ['Colorful'], ], - [ - '/* testBackedEnumImplements */', - [ + 'enum implements multiple interfaces, unqualified + fully qualified' => [ + 'identifier' => '/* testBackedEnumImplementsMulti */', + 'expected' => [ 'Colorful', '\Deck', ], ], - [ - '/* testAnonClassImplements */', - ['testFIINInterface'], + 'anon class implements single interface, unqualified' => [ + 'identifier' => '/* testAnonClassImplementsSingle */', + 'expected' => ['testFIINInterface'], ], - [ - '/* testMissingImplementsName */', - false, + 'parse error - implements keyword, but no interface name' => [ + 'identifier' => '/* testMissingImplementsName */', + 'expected' => false, ], - [ - '/* testParseError */', - false, + 'parse error - live coding - no curly braces' => [ + 'identifier' => '/* testParseError */', + 'expected' => false, ], ]; } diff --git a/Tests/BackCompat/BCFile/FindStartOfStatementTest.inc b/Tests/BackCompat/BCFile/FindStartOfStatementTest.inc index 7061c473..148d8103 100644 --- a/Tests/BackCompat/BCFile/FindStartOfStatementTest.inc +++ b/Tests/BackCompat/BCFile/FindStartOfStatementTest.inc @@ -1,9 +1,5 @@ Test ', foo(), ''; -?> $song->url()) diff --git a/Tests/BackCompat/BCFile/FindStartOfStatementTest.php b/Tests/BackCompat/BCFile/FindStartOfStatementTest.php index de3d91ec..8f6aeeb6 100644 --- a/Tests/BackCompat/BCFile/FindStartOfStatementTest.php +++ b/Tests/BackCompat/BCFile/FindStartOfStatementTest.php @@ -485,9 +485,9 @@ public function testObjectCallPrecededByArrowFunctionAsFunctionCallParameterInAr * * @dataProvider dataFindStartInsideSwitchCaseDefaultStatements * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array|string|int $targets The token to search for after the test marker. - * @param string|int $expectedTarget Token code of the expected start of statement stack pointer. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targets The token to search for after the test marker. + * @param string|int $expectedTarget Token code of the expected start of statement stack pointer. * * @return void */ @@ -504,7 +504,7 @@ public function testFindStartInsideSwitchCaseDefaultStatements($testMarker, $tar /** * Data provider. * - * @return array + * @return array> */ public static function dataFindStartInsideSwitchCaseDefaultStatements() { diff --git a/Tests/BackCompat/BCFile/GetClassPropertiesTest.php b/Tests/BackCompat/BCFile/GetClassPropertiesTest.php index 9121c5b4..df30cd02 100644 --- a/Tests/BackCompat/BCFile/GetClassPropertiesTest.php +++ b/Tests/BackCompat/BCFile/GetClassPropertiesTest.php @@ -40,8 +40,8 @@ class GetClassPropertiesTest extends UtilityMethodTestCase * * @dataProvider dataNotAClassException * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $tokenType The type of token to look for after the marker. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $tokenType The type of token to look for after the marker. * * @return void */ @@ -59,22 +59,22 @@ public function testNotAClassException($testMarker, $tokenType) * * @see testNotAClassException() For the array format. * - * @return array + * @return array> */ - public function dataNotAClassException() + public static function dataNotAClassException() { return [ 'interface' => [ - '/* testNotAClass */', - \T_INTERFACE, + 'testMarker' => '/* testNotAClass */', + 'tokenType' => \T_INTERFACE, ], 'anon-class' => [ - '/* testAnonClass */', - \T_ANON_CLASS, + 'testMarker' => '/* testAnonClass */', + 'tokenType' => \T_ANON_CLASS, ], 'enum' => [ - '/* testEnum */', - \T_ENUM, + 'testMarker' => '/* testEnum */', + 'tokenType' => \T_ENUM, ], ]; } @@ -84,8 +84,8 @@ public function dataNotAClassException() * * @dataProvider dataGetClassProperties * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected Expected function output. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected Expected function output. * * @return void */ @@ -104,14 +104,14 @@ public function testGetClassProperties($testMarker, $expected) * * @see testGetClassProperties() For the array format. * - * @return array + * @return array>> */ - public function dataGetClassProperties() + public static function dataGetClassProperties() { return [ 'no-properties' => [ - '/* testClassWithoutProperties */', - [ + 'testMarker' => '/* testClassWithoutProperties */', + 'expected' => [ 'is_abstract' => false, 'abstract_token' => false, 'is_final' => false, @@ -121,8 +121,8 @@ public function dataGetClassProperties() ], ], 'abstract' => [ - '/* testAbstractClass */', - [ + 'testMarker' => '/* testAbstractClass */', + 'expected' => [ 'is_abstract' => true, 'abstract_token' => -2, 'is_final' => false, @@ -132,8 +132,8 @@ public function dataGetClassProperties() ], ], 'final' => [ - '/* testFinalClass */', - [ + 'testMarker' => '/* testFinalClass */', + 'expected' => [ 'is_abstract' => false, 'abstract_token' => false, 'is_final' => true, @@ -143,8 +143,8 @@ public function dataGetClassProperties() ], ], 'readonly' => [ - '/* testReadonlyClass */', - [ + 'testMarker' => '/* testReadonlyClass */', + 'expected' => [ 'is_abstract' => false, 'abstract_token' => false, 'is_final' => false, @@ -154,8 +154,8 @@ public function dataGetClassProperties() ], ], 'final-readonly' => [ - '/* testFinalReadonlyClass */', - [ + 'testMarker' => '/* testFinalReadonlyClass */', + 'expected' => [ 'is_abstract' => false, 'abstract_token' => false, 'is_final' => true, @@ -165,8 +165,8 @@ public function dataGetClassProperties() ], ], 'readonly-final' => [ - '/* testReadonlyFinalClass */', - [ + 'testMarker' => '/* testReadonlyFinalClass */', + 'expected' => [ 'is_abstract' => false, 'abstract_token' => false, 'is_final' => true, @@ -176,8 +176,8 @@ public function dataGetClassProperties() ], ], 'abstract-readonly' => [ - '/* testAbstractReadonlyClass */', - [ + 'testMarker' => '/* testAbstractReadonlyClass */', + 'expected' => [ 'is_abstract' => true, 'abstract_token' => -4, 'is_final' => false, @@ -187,8 +187,8 @@ public function dataGetClassProperties() ], ], 'readonly-abstract' => [ - '/* testReadonlyAbstractClass */', - [ + 'testMarker' => '/* testReadonlyAbstractClass */', + 'expected' => [ 'is_abstract' => true, 'abstract_token' => -2, 'is_final' => false, @@ -198,8 +198,8 @@ public function dataGetClassProperties() ], ], 'comments-and-new-lines' => [ - '/* testWithCommentsAndNewLines */', - [ + 'testMarker' => '/* testWithCommentsAndNewLines */', + 'expected' => [ 'is_abstract' => true, 'abstract_token' => -6, 'is_final' => false, @@ -209,8 +209,8 @@ public function dataGetClassProperties() ], ], 'no-properties-with-docblock' => [ - '/* testWithDocblockWithoutProperties */', - [ + 'testMarker' => '/* testWithDocblockWithoutProperties */', + 'expected' => [ 'is_abstract' => false, 'abstract_token' => false, 'is_final' => false, @@ -220,8 +220,8 @@ public function dataGetClassProperties() ], ], 'abstract-final-parse-error' => [ - '/* testParseErrorAbstractFinal */', - [ + 'testMarker' => '/* testParseErrorAbstractFinal */', + 'expected' => [ 'is_abstract' => true, 'abstract_token' => -5, 'is_final' => true, diff --git a/Tests/BackCompat/BCFile/GetConditionTest.php b/Tests/BackCompat/BCFile/GetConditionTest.php index 077cddb6..c66b24e9 100644 --- a/Tests/BackCompat/BCFile/GetConditionTest.php +++ b/Tests/BackCompat/BCFile/GetConditionTest.php @@ -44,7 +44,7 @@ class GetConditionTest extends UtilityMethodTestCase * - The startPoint token is left out as it is tested separately. * - The key is the type of token to look for after the test marker. * - * @var array => + * @var array */ protected static $testTargets = [ \T_VARIABLE => '/* testSeriouslyNestedMethod */', @@ -56,7 +56,7 @@ class GetConditionTest extends UtilityMethodTestCase /** * List of all the condition markers in the test case file. * - * @var string[] + * @var array */ protected $conditionMarkers = [ '/* condition 0: namespace */', @@ -92,7 +92,7 @@ class GetConditionTest extends UtilityMethodTestCase * This array isn't auto-generated based on the array in Tokens as for these * tests we want to have access to the token constant names, not just their values. * - * @var array => + * @var array */ protected $conditionDefaults = [ 'T_CLASS' => false, @@ -124,21 +124,21 @@ class GetConditionTest extends UtilityMethodTestCase /** * Cache for the test token stack pointers. * - * @var array => + * @var array */ protected static $testTokens = []; /** * Cache for the marker token stack pointers. * - * @var array => + * @var array */ protected static $markerTokens = []; /** * OO scope tokens array. * - * @var => + * @var array */ protected $ooScopeTokens = []; @@ -212,9 +212,9 @@ public function testNonConditionalToken() * * @dataProvider dataGetCondition * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expectedResults Array with the condition token type to search for as key - * and the marker for the expected stack pointer result as a value. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expectedResults Array with the condition token type to search for as key + * and the marker for the expected stack pointer result as a value. * * @return void */ @@ -227,7 +227,7 @@ public function testGetCondition($testMarker, $expectedResults) $expectedResults += $this->conditionDefaults; foreach ($expectedResults as $conditionType => $expected) { - if ($expected !== false) { + if (\is_string($expected)) { $expected = self::$markerTokens[$expected]; } @@ -249,14 +249,14 @@ public function testGetCondition($testMarker, $expectedResults) * * @see testGetCondition() For the array format. * - * @return array + * @return array>> */ public static function dataGetCondition() { return [ 'testSeriouslyNestedMethod' => [ - '/* testSeriouslyNestedMethod */', - [ + 'testMarker' => '/* testSeriouslyNestedMethod */', + 'expectedResults' => [ 'T_CLASS' => '/* condition 5: nested class */', 'T_NAMESPACE' => '/* condition 0: namespace */', 'T_FUNCTION' => '/* condition 2: function */', @@ -265,8 +265,8 @@ public static function dataGetCondition() ], ], 'testDeepestNested' => [ - '/* testDeepestNested */', - [ + 'testMarker' => '/* testDeepestNested */', + 'expectedResults' => [ 'T_CLASS' => '/* condition 5: nested class */', 'T_ANON_CLASS' => '/* condition 11-1: nested anonymous class */', 'T_NAMESPACE' => '/* condition 0: namespace */', @@ -280,8 +280,8 @@ public static function dataGetCondition() ], ], 'testInException' => [ - '/* testInException */', - [ + 'testMarker' => '/* testInException */', + 'expectedResults' => [ 'T_CLASS' => '/* condition 5: nested class */', 'T_NAMESPACE' => '/* condition 0: namespace */', 'T_FUNCTION' => '/* condition 2: function */', @@ -295,8 +295,8 @@ public static function dataGetCondition() ], ], 'testInDefault' => [ - '/* testInDefault */', - [ + 'testMarker' => '/* testInDefault */', + 'expectedResults' => [ 'T_CLASS' => '/* condition 5: nested class */', 'T_NAMESPACE' => '/* condition 0: namespace */', 'T_FUNCTION' => '/* condition 2: function */', @@ -314,9 +314,9 @@ public static function dataGetCondition() * * @dataProvider dataGetConditionReversed * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expectedResults Array with the condition token type to search for as key - * and the marker for the expected stack pointer result as a value. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expectedResults Array with the condition token type to search for as key + * and the marker for the expected stack pointer result as a value. * * @return void */ @@ -329,7 +329,7 @@ public function testGetConditionReversed($testMarker, $expectedResults) $expectedResults += $this->conditionDefaults; foreach ($expectedResults as $conditionType => $expected) { - if ($expected !== false) { + if (\is_string($expected)) { $expected = self::$markerTokens[$expected]; } @@ -351,23 +351,23 @@ public function testGetConditionReversed($testMarker, $expectedResults) * * @see testGetConditionReversed() For the array format. * - * @return array + * @return array>> */ public static function dataGetConditionReversed() { $data = self::dataGetCondition(); // Set up the data for the reversed results. - $data['testSeriouslyNestedMethod'][1]['T_IF'] = '/* condition 4: if */'; + $data['testSeriouslyNestedMethod']['expectedResults']['T_IF'] = '/* condition 4: if */'; - $data['testDeepestNested'][1]['T_FUNCTION'] = '/* condition 12: nested anonymous class method */'; - $data['testDeepestNested'][1]['T_IF'] = '/* condition 10-1: if */'; + $data['testDeepestNested']['expectedResults']['T_FUNCTION'] = '/* condition 12: nested anonymous class method */'; + $data['testDeepestNested']['expectedResults']['T_IF'] = '/* condition 10-1: if */'; - $data['testInException'][1]['T_FUNCTION'] = '/* condition 6: class method */'; - $data['testInException'][1]['T_IF'] = '/* condition 4: if */'; + $data['testInException']['expectedResults']['T_FUNCTION'] = '/* condition 6: class method */'; + $data['testInException']['expectedResults']['T_IF'] = '/* condition 4: if */'; - $data['testInDefault'][1]['T_FUNCTION'] = '/* condition 6: class method */'; - $data['testInDefault'][1]['T_IF'] = '/* condition 4: if */'; + $data['testInDefault']['expectedResults']['T_FUNCTION'] = '/* condition 6: class method */'; + $data['testInDefault']['expectedResults']['T_IF'] = '/* condition 4: if */'; return $data; } @@ -377,9 +377,9 @@ public static function dataGetConditionReversed() * * @dataProvider dataHasCondition * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expectedResults Array with the condition token type to search for as key - * and the expected result as a value. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expectedResults Array with the condition token type to search for as key + * and the expected result as a value. * * @return void */ @@ -410,14 +410,14 @@ public function testHasCondition($testMarker, $expectedResults) * * @see testHasCondition() For the array format. * - * @return array + * @return array>> */ public static function dataHasCondition() { return [ 'testSeriouslyNestedMethod' => [ - '/* testSeriouslyNestedMethod */', - [ + 'testMarker' => '/* testSeriouslyNestedMethod */', + 'expectedResults' => [ 'T_CLASS' => true, 'T_NAMESPACE' => true, 'T_FUNCTION' => true, @@ -426,8 +426,8 @@ public static function dataHasCondition() ], ], 'testDeepestNested' => [ - '/* testDeepestNested */', - [ + 'testMarker' => '/* testDeepestNested */', + 'expectedResults' => [ 'T_CLASS' => true, 'T_ANON_CLASS' => true, 'T_NAMESPACE' => true, @@ -441,8 +441,8 @@ public static function dataHasCondition() ], ], 'testInException' => [ - '/* testInException */', - [ + 'testMarker' => '/* testInException */', + 'expectedResults' => [ 'T_CLASS' => true, 'T_NAMESPACE' => true, 'T_FUNCTION' => true, @@ -456,8 +456,8 @@ public static function dataHasCondition() ], ], 'testInDefault' => [ - '/* testInDefault */', - [ + 'testMarker' => '/* testInDefault */', + 'expectedResults' => [ 'T_CLASS' => true, 'T_NAMESPACE' => true, 'T_FUNCTION' => true, diff --git a/Tests/BackCompat/BCFile/GetDeclarationNameJSTest.php b/Tests/BackCompat/BCFile/GetDeclarationNameJSTest.php index b34e2b70..c1245a3c 100644 --- a/Tests/BackCompat/BCFile/GetDeclarationNameJSTest.php +++ b/Tests/BackCompat/BCFile/GetDeclarationNameJSTest.php @@ -67,14 +67,14 @@ public function testGetDeclarationNameNull($testMarker, $targetType) * * @see GetDeclarationNameTest::testGetDeclarationNameNull() * - * @return array + * @return array> */ - public function dataGetDeclarationNameNull() + public static function dataGetDeclarationNameNull() { return [ 'closure' => [ - '/* testClosure */', - \T_CLOSURE, + 'testMarker' => '/* testClosure */', + 'targetType' => \T_CLOSURE, ], ]; } @@ -84,9 +84,9 @@ public function dataGetDeclarationNameNull() * * @dataProvider dataGetDeclarationName * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param string $expected Expected function output. - * @param int|string $targetType Token type of the token to get as stackPtr. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param string $expected Expected function output. + * @param array|null $targetType Token type of the token to get as stackPtr. * * @return void */ @@ -106,23 +106,23 @@ public function testGetDeclarationName($testMarker, $expected, $targetType = nul * * @see GetDeclarationNameTest::testGetDeclarationName() * - * @return array + * @return array>> */ - public function dataGetDeclarationName() + public static function dataGetDeclarationName() { return [ 'function' => [ - '/* testFunction */', - 'functionName', + 'testMarker' => '/* testFunction */', + 'expected' => 'functionName', ], 'class' => [ - '/* testClass */', - 'ClassName', - [\T_CLASS, \T_STRING], + 'testMarker' => '/* testClass */', + 'expected' => 'ClassName', + 'targetType' => [\T_CLASS, \T_STRING], ], 'function-unicode-name' => [ - '/* testFunctionUnicode */', - 'π', + 'testMarker' => '/* testFunctionUnicode */', + 'expected' => 'π', ], ]; } diff --git a/Tests/BackCompat/BCFile/GetDeclarationNameTest.inc b/Tests/BackCompat/BCFile/GetDeclarationNameTest.inc index eba7b48c..14902245 100644 --- a/Tests/BackCompat/BCFile/GetDeclarationNameTest.inc +++ b/Tests/BackCompat/BCFile/GetDeclarationNameTest.inc @@ -88,6 +88,15 @@ enum Suit: int implements Colorful, CardGame {} /* testFunctionReturnByRefWithReservedKeywordEach */ function &each() {} +/* testFunctionReturnByRefWithReservedKeywordParent */ +function &parent() {} + +/* testFunctionReturnByRefWithReservedKeywordSelf */ +function &self() {} + +/* testFunctionReturnByRefWithReservedKeywordStatic */ +function &static() {} + /* testLiveCoding */ // Intentional parse error. This has to be the last test in the file. function // Comment. diff --git a/Tests/BackCompat/BCFile/GetDeclarationNameTest.php b/Tests/BackCompat/BCFile/GetDeclarationNameTest.php index 11de6a2c..466ec7a6 100644 --- a/Tests/BackCompat/BCFile/GetDeclarationNameTest.php +++ b/Tests/BackCompat/BCFile/GetDeclarationNameTest.php @@ -60,34 +60,34 @@ public function testGetDeclarationNameNull($testMarker, $targetType) * * @see testGetDeclarationNameNull() For the array format. * - * @return array + * @return array> */ - public function dataGetDeclarationNameNull() + public static function dataGetDeclarationNameNull() { return [ 'closure' => [ - '/* testClosure */', - \T_CLOSURE, + 'testMarker' => '/* testClosure */', + 'targetType' => \T_CLOSURE, ], 'anon-class-with-parentheses' => [ - '/* testAnonClassWithParens */', - \T_ANON_CLASS, + 'testMarker' => '/* testAnonClassWithParens */', + 'targetType' => \T_ANON_CLASS, ], 'anon-class-with-parentheses-2' => [ - '/* testAnonClassWithParens2 */', - \T_ANON_CLASS, + 'testMarker' => '/* testAnonClassWithParens2 */', + 'targetType' => \T_ANON_CLASS, ], 'anon-class-without-parentheses' => [ - '/* testAnonClassWithoutParens */', - \T_ANON_CLASS, + 'testMarker' => '/* testAnonClassWithoutParens */', + 'targetType' => \T_ANON_CLASS, ], 'anon-class-extends-without-parentheses' => [ - '/* testAnonClassExtendsWithoutParens */', - \T_ANON_CLASS, + 'testMarker' => '/* testAnonClassExtendsWithoutParens */', + 'targetType' => \T_ANON_CLASS, ], 'live-coding' => [ - '/* testLiveCoding */', - \T_FUNCTION, + 'testMarker' => '/* testLiveCoding */', + 'targetType' => \T_FUNCTION, ], ]; } @@ -97,9 +97,9 @@ public function dataGetDeclarationNameNull() * * @dataProvider dataGetDeclarationName * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param string $expected Expected function output. - * @param int|string $targetType Token type of the token to get as stackPtr. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param string $expected Expected function output. + * @param int|string|null $targetType Token type of the token to get as stackPtr. * * @return void */ @@ -119,82 +119,94 @@ public function testGetDeclarationName($testMarker, $expected, $targetType = nul * * @see testGetDeclarationName() For the array format. * - * @return array + * @return array> */ - public function dataGetDeclarationName() + public static function dataGetDeclarationName() { return [ 'function' => [ - '/* testFunction */', - 'functionName', + 'testMarker' => '/* testFunction */', + 'expected' => 'functionName', ], 'function-return-by-reference' => [ - '/* testFunctionReturnByRef */', - 'functionNameByRef', + 'testMarker' => '/* testFunctionReturnByRef */', + 'expected' => 'functionNameByRef', ], 'class' => [ - '/* testClass */', - 'ClassName', + 'testMarker' => '/* testClass */', + 'expected' => 'ClassName', ], 'method' => [ - '/* testMethod */', - 'methodName', + 'testMarker' => '/* testMethod */', + 'expected' => 'methodName', ], 'abstract-method' => [ - '/* testAbstractMethod */', - 'abstractMethodName', + 'testMarker' => '/* testAbstractMethod */', + 'expected' => 'abstractMethodName', ], 'method-return-by-reference' => [ - '/* testMethodReturnByRef */', - 'MethodNameByRef', + 'testMarker' => '/* testMethodReturnByRef */', + 'expected' => 'MethodNameByRef', ], 'extended-class' => [ - '/* testExtendedClass */', - 'ExtendedClass', + 'testMarker' => '/* testExtendedClass */', + 'expected' => 'ExtendedClass', ], 'interface' => [ - '/* testInterface */', - 'InterfaceName', + 'testMarker' => '/* testInterface */', + 'expected' => 'InterfaceName', ], 'trait' => [ - '/* testTrait */', - 'TraitName', + 'testMarker' => '/* testTrait */', + 'expected' => 'TraitName', ], 'function-name-ends-with-number' => [ - '/* testFunctionEndingWithNumber */', - 'ValidNameEndingWithNumber5', + 'testMarker' => '/* testFunctionEndingWithNumber */', + 'expected' => 'ValidNameEndingWithNumber5', ], 'class-with-numbers-in-name' => [ - '/* testClassWithNumber */', - 'ClassWith1Number', + 'testMarker' => '/* testClassWithNumber */', + 'expected' => 'ClassWith1Number', ], 'interface-with-numbers-in-name' => [ - '/* testInterfaceWithNumbers */', - 'InterfaceWith12345Numbers', + 'testMarker' => '/* testInterfaceWithNumbers */', + 'expected' => 'InterfaceWith12345Numbers', ], 'class-with-comments-and-new-lines' => [ - '/* testClassWithCommentsAndNewLines */', - 'ClassWithCommentsAndNewLines', + 'testMarker' => '/* testClassWithCommentsAndNewLines */', + 'expected' => 'ClassWithCommentsAndNewLines', ], 'function-named-fn' => [ - '/* testFunctionFn */', - 'fn', + 'testMarker' => '/* testFunctionFn */', + 'expected' => 'fn', ], 'enum-pure' => [ - '/* testPureEnum */', - 'Foo', + 'testMarker' => '/* testPureEnum */', + 'expected' => 'Foo', ], 'enum-backed-space-between-name-and-colon' => [ - '/* testBackedEnumSpaceBetweenNameAndColon */', - 'Hoo', + 'testMarker' => '/* testBackedEnumSpaceBetweenNameAndColon */', + 'expected' => 'Hoo', ], 'enum-backed-no-space-between-name-and-colon' => [ - '/* testBackedEnumNoSpaceBetweenNameAndColon */', - 'Suit', + 'testMarker' => '/* testBackedEnumNoSpaceBetweenNameAndColon */', + 'expected' => 'Suit', ], 'function-return-by-reference-with-reserved-keyword-each' => [ - '/* testFunctionReturnByRefWithReservedKeywordEach */', - 'each', + 'testMarker' => '/* testFunctionReturnByRefWithReservedKeywordEach */', + 'expected' => 'each', + ], + 'function-return-by-reference-with-reserved-keyword-parent' => [ + 'testMarker' => '/* testFunctionReturnByRefWithReservedKeywordParent */', + 'expected' => 'parent', + ], + 'function-return-by-reference-with-reserved-keyword-self' => [ + 'testMarker' => '/* testFunctionReturnByRefWithReservedKeywordSelf */', + 'expected' => 'self', + ], + 'function-return-by-reference-with-reserved-keyword-static' => [ + 'testMarker' => '/* testFunctionReturnByRefWithReservedKeywordStatic */', + 'expected' => 'static', ], ]; } diff --git a/Tests/BackCompat/BCFile/GetMemberPropertiesTest.inc b/Tests/BackCompat/BCFile/GetMemberPropertiesTest.inc index 743db513..058ba484 100644 --- a/Tests/BackCompat/BCFile/GetMemberPropertiesTest.inc +++ b/Tests/BackCompat/BCFile/GetMemberPropertiesTest.inc @@ -213,6 +213,7 @@ $anon = class() { /* testPHP8UnionTypesIllegalTypes */ // Intentional fatal error - types which are not allowed for properties, but that's not the concern of the method. + // Note: static is also not allowed as a type, but using static for a property type is not supported by the tokenizer. public callable|static|void $unionTypesIllegalTypes; /* testPHP8UnionTypesNullable */ @@ -220,11 +221,11 @@ $anon = class() { public ?int|float $unionTypesNullable; /* testPHP8PseudoTypeNull */ - // Intentional fatal error - null pseudotype is only allowed in union types, but that's not the concern of the method. + // PHP 8.0 - 8.1: Intentional fatal error - null pseudotype is only allowed in union types, but that's not the concern of the method. public null $pseudoTypeNull; /* testPHP8PseudoTypeFalse */ - // Intentional fatal error - false pseudotype is only allowed in union types, but that's not the concern of the method. + // PHP 8.0 - 8.1: Intentional fatal error - false pseudotype is only allowed in union types, but that's not the concern of the method. public false $pseudoTypeFalse; /* testPHP8PseudoTypeFalseAndBool */ @@ -316,6 +317,21 @@ $anon = class() { public ?Foo&Bar $nullableIntersectionType; }; +$anon = class() { + /* testPHP82PseudoTypeTrue */ + public true $pseudoTypeTrue; + + /* testPHP82NullablePseudoTypeTrue */ + static protected ?true $pseudoTypeNullableTrue; + + /* testPHP82PseudoTypeTrueInUnion */ + private int|string|true $pseudoTypeTrueInUnion; + + /* testPHP82PseudoTypeFalseAndTrue */ + // Intentional fatal error - Type contains both true and false, bool should be used instead, but that's not the concern of the method. + readonly true|FALSE $pseudoTypeFalseAndTrue; +}; + class WhitespaceAndCommentsInTypes { /* testUnionTypeWithWhitespaceAndComment */ public int | /*comment*/ string $hasWhitespaceAndComment; @@ -323,3 +339,18 @@ class WhitespaceAndCommentsInTypes { /* testIntersectionTypeWithWhitespaceAndComment */ public \Foo /*comment*/ & Bar $hasWhitespaceAndComment; } + +trait DNFTypes { + /* testPHP82DNFTypeStatic */ + public static (Foo&\Bar)|bool $propA; + + /* testPHP82DNFTypeReadonlyA */ + protected readonly float|(Partially\Qualified&Traversable) $propB; + + /* testPHP82DNFTypeReadonlyB */ + private readonly (namespace\Foo&Bar)|string $propC; + + /* testPHP82DNFTypeIllegalNullable */ + // Intentional fatal error - nullable operator cannot be combined with DNF. + var ?(A&\Pck\B)|bool $propD; +} diff --git a/Tests/BackCompat/BCFile/GetMemberPropertiesTest.php b/Tests/BackCompat/BCFile/GetMemberPropertiesTest.php index 1101384d..60ee29db 100644 --- a/Tests/BackCompat/BCFile/GetMemberPropertiesTest.php +++ b/Tests/BackCompat/BCFile/GetMemberPropertiesTest.php @@ -17,7 +17,7 @@ * @author Phil Davis * * @copyright 2017-2019 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */ namespace PHPCSUtils\Tests\BackCompat\BCFile; @@ -51,8 +51,8 @@ class GetMemberPropertiesTest extends UtilityMethodTestCase * * @dataProvider dataGetMemberProperties * - * @param string $identifier Comment which precedes the test case. - * @param bool $expected Expected function output. + * @param string $identifier Comment which precedes the test case. + * @param array $expected Expected function output. * * @return void */ @@ -63,10 +63,11 @@ public function testGetMemberProperties($identifier, $expected) $variable = $this->getTargetToken($identifier, T_VARIABLE); $result = $testClass::getMemberProperties(self::$phpcsFile, $variable); - if (isset($expected['type_token']) && $expected['type_token'] !== false) { + // Convert offsets to absolute positions in the token stream. + if (isset($expected['type_token']) && \is_int($expected['type_token']) === true) { $expected['type_token'] += $variable; } - if (isset($expected['type_end_token']) && $expected['type_end_token'] !== false) { + if (isset($expected['type_end_token']) && \is_int($expected['type_end_token']) === true) { $expected['type_end_token'] += $variable; } @@ -76,18 +77,22 @@ public function testGetMemberProperties($identifier, $expected) /** * Data provider. * + * Note: the `expected - type_token` and `expected - type_end_token` indexes should + * contain either `false` (no type) or the _offset_ of the type start/end token in + * relation to the `T_VARIABLE` token which is passed to the getMemberProperties() method. + * * @see testGetMemberProperties() * - * @return array + * @return array>> */ - public function dataGetMemberProperties() + public static function dataGetMemberProperties() { $php8Names = parent::usesPhp8NameTokens(); return [ 'var-modifier' => [ - '/* testVar */', - [ + 'identifier' => '/* testVar */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => false, 'is_static' => false, @@ -99,21 +104,21 @@ public function dataGetMemberProperties() ], ], 'var-modifier-and-type' => [ - '/* testVarType */', - [ + 'identifier' => '/* testVarType */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => false, 'is_static' => false, 'is_readonly' => false, 'type' => '?int', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'public-modifier' => [ - '/* testPublic */', - [ + 'identifier' => '/* testPublic */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, @@ -125,21 +130,21 @@ public function dataGetMemberProperties() ], ], 'public-modifier-and-type' => [ - '/* testPublicType */', - [ + 'identifier' => '/* testPublicType */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'string', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'protected-modifier' => [ - '/* testProtected */', - [ + 'identifier' => '/* testProtected */', + 'expected' => [ 'scope' => 'protected', 'scope_specified' => true, 'is_static' => false, @@ -151,21 +156,21 @@ public function dataGetMemberProperties() ], ], 'protected-modifier-and-type' => [ - '/* testProtectedType */', - [ + 'identifier' => '/* testProtectedType */', + 'expected' => [ 'scope' => 'protected', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'bool', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'private-modifier' => [ - '/* testPrivate */', - [ + 'identifier' => '/* testPrivate */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, @@ -177,21 +182,21 @@ public function dataGetMemberProperties() ], ], 'private-modifier-and-type' => [ - '/* testPrivateType */', - [ + 'identifier' => '/* testPrivateType */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'array', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'static-modifier' => [ - '/* testStatic */', - [ + 'identifier' => '/* testStatic */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => false, 'is_static' => true, @@ -203,21 +208,21 @@ public function dataGetMemberProperties() ], ], 'static-modifier-and-type' => [ - '/* testStaticType */', - [ + 'identifier' => '/* testStaticType */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => false, 'is_static' => true, 'is_readonly' => false, 'type' => '?string', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'static-and-var-modifier' => [ - '/* testStaticVar */', - [ + 'identifier' => '/* testStaticVar */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => false, 'is_static' => true, @@ -229,8 +234,8 @@ public function dataGetMemberProperties() ], ], 'var-and-static-modifier' => [ - '/* testVarStatic */', - [ + 'identifier' => '/* testVarStatic */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => false, 'is_static' => true, @@ -242,8 +247,8 @@ public function dataGetMemberProperties() ], ], 'public-static-modifiers' => [ - '/* testPublicStatic */', - [ + 'identifier' => '/* testPublicStatic */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => true, @@ -255,8 +260,8 @@ public function dataGetMemberProperties() ], ], 'protected-static-modifiers' => [ - '/* testProtectedStatic */', - [ + 'identifier' => '/* testProtectedStatic */', + 'expected' => [ 'scope' => 'protected', 'scope_specified' => true, 'is_static' => true, @@ -268,8 +273,8 @@ public function dataGetMemberProperties() ], ], 'private-static-modifiers' => [ - '/* testPrivateStatic */', - [ + 'identifier' => '/* testPrivateStatic */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => true, @@ -281,8 +286,8 @@ public function dataGetMemberProperties() ], ], 'no-modifier' => [ - '/* testNoPrefix */', - [ + 'identifier' => '/* testNoPrefix */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => false, 'is_static' => false, @@ -294,8 +299,8 @@ public function dataGetMemberProperties() ], ], 'public-and-static-modifier-with-docblock' => [ - '/* testPublicStaticWithDocblock */', - [ + 'identifier' => '/* testPublicStaticWithDocblock */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => true, @@ -307,8 +312,8 @@ public function dataGetMemberProperties() ], ], 'protected-and-static-modifier-with-docblock' => [ - '/* testProtectedStaticWithDocblock */', - [ + 'identifier' => '/* testProtectedStaticWithDocblock */', + 'expected' => [ 'scope' => 'protected', 'scope_specified' => true, 'is_static' => true, @@ -320,8 +325,8 @@ public function dataGetMemberProperties() ], ], 'private-and-static-modifier-with-docblock' => [ - '/* testPrivateStaticWithDocblock */', - [ + 'identifier' => '/* testPrivateStaticWithDocblock */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => true, @@ -333,60 +338,60 @@ public function dataGetMemberProperties() ], ], 'property-group-simple-type-prop-1' => [ - '/* testGroupType 1 */', - [ + 'identifier' => '/* testGroupType 1 */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'float', - 'type_token' => -6, // Offset from the T_VARIABLE token. - 'type_end_token' => -6, // Offset from the T_VARIABLE token. + 'type_token' => -6, + 'type_end_token' => -6, 'nullable_type' => false, ], ], 'property-group-simple-type-prop-2' => [ - '/* testGroupType 2 */', - [ + 'identifier' => '/* testGroupType 2 */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'float', - 'type_token' => -13, // Offset from the T_VARIABLE token. - 'type_end_token' => -13, // Offset from the T_VARIABLE token. + 'type_token' => -13, + 'type_end_token' => -13, 'nullable_type' => false, ], ], 'property-group-nullable-type-prop-1' => [ - '/* testGroupNullableType 1 */', - [ + 'identifier' => '/* testGroupNullableType 1 */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => true, 'is_readonly' => false, 'type' => '?string', - 'type_token' => -6, // Offset from the T_VARIABLE token. - 'type_end_token' => -6, // Offset from the T_VARIABLE token. + 'type_token' => -6, + 'type_end_token' => -6, 'nullable_type' => true, ], ], 'property-group-nullable-type-prop-2' => [ - '/* testGroupNullableType 2 */', - [ + 'identifier' => '/* testGroupNullableType 2 */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => true, 'is_readonly' => false, 'type' => '?string', - 'type_token' => -17, // Offset from the T_VARIABLE token. - 'type_end_token' => -17, // Offset from the T_VARIABLE token. + 'type_token' => -17, + 'type_end_token' => -17, 'nullable_type' => true, ], ], 'property-group-protected-static-prop-1' => [ - '/* testGroupProtectedStatic 1 */', - [ + 'identifier' => '/* testGroupProtectedStatic 1 */', + 'expected' => [ 'scope' => 'protected', 'scope_specified' => true, 'is_static' => true, @@ -398,8 +403,8 @@ public function dataGetMemberProperties() ], ], 'property-group-protected-static-prop-2' => [ - '/* testGroupProtectedStatic 2 */', - [ + 'identifier' => '/* testGroupProtectedStatic 2 */', + 'expected' => [ 'scope' => 'protected', 'scope_specified' => true, 'is_static' => true, @@ -411,8 +416,8 @@ public function dataGetMemberProperties() ], ], 'property-group-protected-static-prop-3' => [ - '/* testGroupProtectedStatic 3 */', - [ + 'identifier' => '/* testGroupProtectedStatic 3 */', + 'expected' => [ 'scope' => 'protected', 'scope_specified' => true, 'is_static' => true, @@ -424,8 +429,8 @@ public function dataGetMemberProperties() ], ], 'property-group-private-prop-1' => [ - '/* testGroupPrivate 1 */', - [ + 'identifier' => '/* testGroupPrivate 1 */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, @@ -437,8 +442,8 @@ public function dataGetMemberProperties() ], ], 'property-group-private-prop-2' => [ - '/* testGroupPrivate 2 */', - [ + 'identifier' => '/* testGroupPrivate 2 */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, @@ -450,8 +455,8 @@ public function dataGetMemberProperties() ], ], 'property-group-private-prop-3' => [ - '/* testGroupPrivate 3 */', - [ + 'identifier' => '/* testGroupPrivate 3 */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, @@ -463,8 +468,8 @@ public function dataGetMemberProperties() ], ], 'property-group-private-prop-4' => [ - '/* testGroupPrivate 4 */', - [ + 'identifier' => '/* testGroupPrivate 4 */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, @@ -476,8 +481,8 @@ public function dataGetMemberProperties() ], ], 'property-group-private-prop-5' => [ - '/* testGroupPrivate 5 */', - [ + 'identifier' => '/* testGroupPrivate 5 */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, @@ -489,8 +494,8 @@ public function dataGetMemberProperties() ], ], 'property-group-private-prop-6' => [ - '/* testGroupPrivate 6 */', - [ + 'identifier' => '/* testGroupPrivate 6 */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, @@ -502,8 +507,8 @@ public function dataGetMemberProperties() ], ], 'property-group-private-prop-7' => [ - '/* testGroupPrivate 7 */', - [ + 'identifier' => '/* testGroupPrivate 7 */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, @@ -515,73 +520,73 @@ public function dataGetMemberProperties() ], ], 'messy-nullable-type' => [ - '/* testMessyNullableType */', - [ + 'identifier' => '/* testMessyNullableType */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => '?array', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'fqn-type' => [ - '/* testNamespaceType */', - [ + 'identifier' => '/* testNamespaceType */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => '\MyNamespace\MyClass', - 'type_token' => ($php8Names === true) ? -2 : -5, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => ($php8Names === true) ? -2 : -5, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'nullable-classname-type' => [ - '/* testNullableNamespaceType 1 */', - [ + 'identifier' => '/* testNullableNamespaceType 1 */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => '?ClassName', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'nullable-namespace-relative-class-type' => [ - '/* testNullableNamespaceType 2 */', - [ + 'identifier' => '/* testNullableNamespaceType 2 */', + 'expected' => [ 'scope' => 'protected', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => '?Folder\ClassName', - 'type_token' => ($php8Names === true) ? -2 : -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => ($php8Names === true) ? -2 : -4, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'multiline-namespaced-type' => [ - '/* testMultilineNamespaceType */', - [ + 'identifier' => '/* testMultilineNamespaceType */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => '\MyNamespace\MyClass\Foo', - 'type_token' => ($php8Names === true) ? -15 : -18, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => ($php8Names === true) ? -15 : -18, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'property-after-method' => [ - '/* testPropertyAfterMethod */', - [ + 'identifier' => '/* testPropertyAfterMethod */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => true, @@ -593,12 +598,12 @@ public function dataGetMemberProperties() ], ], 'invalid-property-in-interface' => [ - '/* testInterfaceProperty */', - [], + 'identifier' => '/* testInterfaceProperty */', + 'expected' => [], ], 'property-in-nested-class-1' => [ - '/* testNestedProperty 1 */', - [ + 'identifier' => '/* testNestedProperty 1 */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, @@ -610,8 +615,8 @@ public function dataGetMemberProperties() ], ], 'property-in-nested-class-2' => [ - '/* testNestedProperty 2 */', - [ + 'identifier' => '/* testNestedProperty 2 */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, @@ -623,295 +628,295 @@ public function dataGetMemberProperties() ], ], 'php8-mixed-type' => [ - '/* testPHP8MixedTypeHint */', - [ + 'identifier' => '/* testPHP8MixedTypeHint */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => true, 'is_readonly' => false, 'type' => 'miXed', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-nullable-mixed-type' => [ - '/* testPHP8MixedTypeHintNullable */', - [ + 'identifier' => '/* testPHP8MixedTypeHintNullable */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => '?mixed', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'namespace-operator-type-declaration' => [ - '/* testNamespaceOperatorTypeHint */', - [ + 'identifier' => '/* testNamespaceOperatorTypeHint */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => '?namespace\Name', - 'type_token' => ($php8Names === true) ? -2 : -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => ($php8Names === true) ? -2 : -4, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'php8-union-types-simple' => [ - '/* testPHP8UnionTypesSimple */', - [ + 'identifier' => '/* testPHP8UnionTypesSimple */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'int|float', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-union-types-two-classes' => [ - '/* testPHP8UnionTypesTwoClasses */', - [ + 'identifier' => '/* testPHP8UnionTypesTwoClasses */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'MyClassA|\Package\MyClassB', - 'type_token' => ($php8Names === true) ? -4 : -7, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => ($php8Names === true) ? -4 : -7, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-union-types-all-base-types' => [ - '/* testPHP8UnionTypesAllBaseTypes */', - [ + 'identifier' => '/* testPHP8UnionTypesAllBaseTypes */', + 'expected' => [ 'scope' => 'protected', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'array|bool|int|float|NULL|object|string', - 'type_token' => -14, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -14, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-union-types-all-pseudo-types' => [ - '/* testPHP8UnionTypesAllPseudoTypes */', - [ + 'identifier' => '/* testPHP8UnionTypesAllPseudoTypes */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => false, 'is_static' => false, 'is_readonly' => false, 'type' => 'false|mixed|self|parent|iterable|Resource', - 'type_token' => -12, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -12, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-union-types-illegal-types' => [ - '/* testPHP8UnionTypesIllegalTypes */', - [ + 'identifier' => '/* testPHP8UnionTypesIllegalTypes */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, // Missing static, but that's OK as not an allowed syntax. - 'type' => 'callable||void', - 'type_token' => -6, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type' => 'callable|void', + 'type_token' => -6, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-union-types-nullable' => [ - '/* testPHP8UnionTypesNullable */', - [ + 'identifier' => '/* testPHP8UnionTypesNullable */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => '?int|float', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'php8-union-types-pseudo-type-null' => [ - '/* testPHP8PseudoTypeNull */', - [ + 'identifier' => '/* testPHP8PseudoTypeNull */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'null', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-union-types-pseudo-type-false' => [ - '/* testPHP8PseudoTypeFalse */', - [ + 'identifier' => '/* testPHP8PseudoTypeFalse */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'false', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-union-types-pseudo-type-false-and-bool' => [ - '/* testPHP8PseudoTypeFalseAndBool */', - [ + 'identifier' => '/* testPHP8PseudoTypeFalseAndBool */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'bool|FALSE', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-union-types-object-and-class' => [ - '/* testPHP8ObjectAndClass */', - [ + 'identifier' => '/* testPHP8ObjectAndClass */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'object|ClassName', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-union-types-pseudo-type-iterable-and-array' => [ - '/* testPHP8PseudoTypeIterableAndArray */', - [ + 'identifier' => '/* testPHP8PseudoTypeIterableAndArray */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'iterable|array|Traversable', - 'type_token' => -6, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -6, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-union-types-duplicate-type-with-whitespace-and-comments' => [ - '/* testPHP8DuplicateTypeInUnionWhitespaceAndComment */', - [ + 'identifier' => '/* testPHP8DuplicateTypeInUnionWhitespaceAndComment */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'int|string|INT', - 'type_token' => -10, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -10, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8.1-readonly-property' => [ - '/* testPHP81Readonly */', - [ + 'identifier' => '/* testPHP81Readonly */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => true, 'type' => 'int', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8.1-readonly-property-with-nullable-type' => [ - '/* testPHP81ReadonlyWithNullableType */', - [ + 'identifier' => '/* testPHP81ReadonlyWithNullableType */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => true, 'type' => '?array', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'php8.1-readonly-property-with-union-type' => [ - '/* testPHP81ReadonlyWithUnionType */', - [ + 'identifier' => '/* testPHP81ReadonlyWithUnionType */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => true, 'type' => 'string|int', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8.1-readonly-property-with-union-type-with-null' => [ - '/* testPHP81ReadonlyWithUnionTypeWithNull */', - [ + 'identifier' => '/* testPHP81ReadonlyWithUnionTypeWithNull */', + 'expected' => [ 'scope' => 'protected', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => true, 'type' => 'string|null', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8.1-readonly-property-with-union-type-no-visibility' => [ - '/* testPHP81OnlyReadonlyWithUnionType */', - [ + 'identifier' => '/* testPHP81OnlyReadonlyWithUnionType */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => false, 'is_static' => false, 'is_readonly' => true, 'type' => 'string|int', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8.1-readonly-property-with-multi-union-type-no-visibility' => [ - '/* testPHP81OnlyReadonlyWithUnionTypeMultiple */', - [ + 'identifier' => '/* testPHP81OnlyReadonlyWithUnionTypeMultiple */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => false, 'is_static' => false, 'is_readonly' => true, 'type' => '\InterfaceA|\Sub\InterfaceB|false', - 'type_token' => ($php8Names === true) ? -7 : -11, // Offset from the T_VARIABLE token. - 'type_end_token' => -3, // Offset from the T_VARIABLE token. + 'type_token' => ($php8Names === true) ? -7 : -11, + 'type_end_token' => -3, 'nullable_type' => false, ], ], 'php8.1-readonly-and-static-property' => [ - '/* testPHP81ReadonlyAndStatic */', - [ + 'identifier' => '/* testPHP81ReadonlyAndStatic */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => true, 'is_readonly' => true, 'type' => '?string', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'php8.1-readonly-mixed-case-keyword' => [ - '/* testPHP81ReadonlyMixedCase */', - [ + 'identifier' => '/* testPHP81ReadonlyMixedCase */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => true, @@ -923,127 +928,232 @@ public function dataGetMemberProperties() ], ], 'php8-property-with-single-attribute' => [ - '/* testPHP8PropertySingleAttribute */', - [ + 'identifier' => '/* testPHP8PropertySingleAttribute */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'string', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8-property-with-multiple-attributes' => [ - '/* testPHP8PropertyMultipleAttributes */', - [ + 'identifier' => '/* testPHP8PropertyMultipleAttributes */', + 'expected' => [ 'scope' => 'protected', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => '?int|float', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'php8-property-with-multiline-attribute' => [ - '/* testPHP8PropertyMultilineAttribute */', - [ + 'identifier' => '/* testPHP8PropertyMultilineAttribute */', + 'expected' => [ 'scope' => 'private', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'mixed', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -2, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'invalid-property-in-enum' => [ - '/* testEnumProperty */', - [], + 'identifier' => '/* testEnumProperty */', + 'expected' => [], ], 'php8.1-single-intersection-type' => [ - '/* testPHP81IntersectionTypes */', - [ + 'identifier' => '/* testPHP81IntersectionTypes */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'Foo&Bar', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8.1-multi-intersection-type' => [ - '/* testPHP81MoreIntersectionTypes */', - [ + 'identifier' => '/* testPHP81MoreIntersectionTypes */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'Foo&Bar&Baz', - 'type_token' => -6, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -6, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8.1-illegal-intersection-type' => [ - '/* testPHP81IllegalIntersectionTypes */', - [ + 'identifier' => '/* testPHP81IllegalIntersectionTypes */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'int&string', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8.1-nullable-intersection-type' => [ - '/* testPHP81NullableIntersectionType */', - [ + 'identifier' => '/* testPHP81NullableIntersectionType */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => '?Foo&Bar', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => true, ], ], 'php8.0-union-type-with-whitespace-and-comment' => [ - '/* testUnionTypeWithWhitespaceAndComment */', - [ + 'identifier' => '/* testUnionTypeWithWhitespaceAndComment */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => 'int|string', - 'type_token' => -8, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => -8, + 'type_end_token' => -2, 'nullable_type' => false, ], ], 'php8.1-intersection-type-with-whitespace-and-comment' => [ - '/* testIntersectionTypeWithWhitespaceAndComment */', - [ + 'identifier' => '/* testIntersectionTypeWithWhitespaceAndComment */', + 'expected' => [ 'scope' => 'public', 'scope_specified' => true, 'is_static' => false, 'is_readonly' => false, 'type' => '\Foo&Bar', - 'type_token' => ($php8Names === true) ? -8 : -9, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. + 'type_token' => ($php8Names === true) ? -8 : -9, + 'type_end_token' => -2, + 'nullable_type' => false, + ], + ], + 'php8.2-pseudo-type-true' => [ + 'identifier' => '/* testPHP82PseudoTypeTrue */', + 'expected' => [ + 'scope' => 'public', + 'scope_specified' => true, + 'is_static' => false, + 'is_readonly' => false, + 'type' => 'true', + 'type_token' => -2, + 'type_end_token' => -2, + 'nullable_type' => false, + ], + ], + 'php8.2-pseudo-type-true-nullable' => [ + 'identifier' => '/* testPHP82NullablePseudoTypeTrue */', + 'expected' => [ + 'scope' => 'protected', + 'scope_specified' => true, + 'is_static' => true, + 'is_readonly' => false, + 'type' => '?true', + 'type_token' => -2, + 'type_end_token' => -2, + 'nullable_type' => true, + ], + ], + 'php8.2-pseudo-type-true-in-union' => [ + 'identifier' => '/* testPHP82PseudoTypeTrueInUnion */', + 'expected' => [ + 'scope' => 'private', + 'scope_specified' => true, + 'is_static' => false, + 'is_readonly' => false, + 'type' => 'int|string|true', + 'type_token' => -6, + 'type_end_token' => -2, + 'nullable_type' => false, + ], + ], + 'php8.2-pseudo-type-invalid-true-false-union' => [ + 'identifier' => '/* testPHP82PseudoTypeFalseAndTrue */', + 'expected' => [ + 'scope' => 'public', + 'scope_specified' => false, + 'is_static' => false, + 'is_readonly' => true, + 'type' => 'true|FALSE', + 'type_token' => -4, + 'type_end_token' => -2, 'nullable_type' => false, ], ], + + 'php8.2-dnf-with-static' => [ + 'identifier' => '/* testPHP82DNFTypeStatic */', + 'expected' => [ + 'scope' => 'public', + 'scope_specified' => true, + 'is_static' => true, + 'is_readonly' => false, + 'type' => '(Foo&\Bar)|bool', + 'type_token' => ($php8Names === true) ? -8 : -9, + 'type_end_token' => -2, + 'nullable_type' => false, + ], + ], + 'php8.2-dnf-with-readonly-1' => [ + 'identifier' => '/* testPHP82DNFTypeReadonlyA */', + 'expected' => [ + 'scope' => 'protected', + 'scope_specified' => true, + 'is_static' => false, + 'is_readonly' => true, + 'type' => 'float|(Partially\Qualified&Traversable)', + 'type_token' => ($php8Names === true) ? -8 : -10, + 'type_end_token' => -2, + 'nullable_type' => false, + ], + ], + 'php8.2-dnf-with-readonly-2' => [ + 'identifier' => '/* testPHP82DNFTypeReadonlyB */', + 'expected' => [ + 'scope' => 'private', + 'scope_specified' => true, + 'is_static' => false, + 'is_readonly' => true, + 'type' => '(namespace\Foo&Bar)|string', + 'type_token' => ($php8Names === true) ? -8 : -10, + 'type_end_token' => -2, + 'nullable_type' => false, + ], + ], + 'php8.2-dnf-with-illegal-nullable' => [ + 'identifier' => '/* testPHP82DNFTypeIllegalNullable */', + 'expected' => [ + 'scope' => 'public', + 'scope_specified' => false, + 'is_static' => false, + 'is_readonly' => false, + 'type' => '?(A&\Pck\B)|bool', + 'type_token' => ($php8Names === true) ? -8 : -11, + 'type_end_token' => -2, + 'nullable_type' => true, + ], + ], ]; } @@ -1071,18 +1181,18 @@ public function testNotClassPropertyException($identifier) * * @see testNotClassPropertyException() * - * @return array + * @return array> */ - public function dataNotClassProperty() + public static function dataNotClassProperty() { return [ - ['/* testMethodParam */'], - ['/* testImportedGlobal */'], - ['/* testLocalVariable */'], - ['/* testGlobalVariable */'], - ['/* testNestedMethodParam 1 */'], - ['/* testNestedMethodParam 2 */'], - ['/* testEnumMethodParamNotProperty */'], + 'method parameter' => ['/* testMethodParam */'], + 'variable import using global keyword' => ['/* testImportedGlobal */'], + 'function local variable' => ['/* testLocalVariable */'], + 'global variable' => ['/* testGlobalVariable */'], + 'method parameter in anon class nested in ternary' => ['/* testNestedMethodParam 1 */'], + 'method parameter in anon class nested in function call' => ['/* testNestedMethodParam 2 */'], + 'method parameter in enum' => ['/* testEnumMethodParamNotProperty */'], ]; } diff --git a/Tests/BackCompat/BCFile/GetMethodParametersTest.inc b/Tests/BackCompat/BCFile/GetMethodParametersTest.inc index 17ba4a98..b504f928 100644 --- a/Tests/BackCompat/BCFile/GetMethodParametersTest.inc +++ b/Tests/BackCompat/BCFile/GetMethodParametersTest.inc @@ -159,11 +159,11 @@ function unionTypesAllPseudoTypes(false|mixed|self|parent|iterable|Resource $var $closure = function (?int|float $number) {}; /* testPHP8PseudoTypeNull */ -// Intentional fatal error - null pseudotype is only allowed in union types, but that's not the concern of the method. +// PHP 8.0 - 8.1: Intentional fatal error - null pseudotype is only allowed in union types, but that's not the concern of the method. function pseudoTypeNull(null $var = null) {} /* testPHP8PseudoTypeFalse */ -// Intentional fatal error - false pseudotype is only allowed in union types, but that's not the concern of the method. +// PHP 8.0 - 8.1: Intentional fatal error - false pseudotype is only allowed in union types, but that's not the concern of the method. function pseudoTypeFalse(false $var = false) {} /* testPHP8PseudoTypeFalseAndBool */ @@ -267,12 +267,36 @@ $closure = function (string&int $numeric_string) {}; // Intentional fatal error - nullability is not allowed with intersection types, but that's not the concern of the method. $closure = function (?Foo&Bar $object) {}; +/* testPHP82PseudoTypeTrue */ +function pseudoTypeTrue(?true $var = true) {} + +/* testPHP82PseudoTypeFalseAndTrue */ +// Intentional fatal error - Type contains both true and false, bool should be used instead, but that's not the concern of the method. +function pseudoTypeFalseAndTrue(true|false $var = true) {} + /* testPHP81NewInInitializers */ function newInInitializers( TypeA $new = new TypeA(self::CONST_VALUE), \Package\TypeB $newToo = new \Package\TypeB(10, 'string'), ) {} +/* testPHP82DNFTypes */ +function dnfTypes( + #[MyAttribute] + false|(Foo&Bar)|true $obj1, + (\Boo&\Pck\Bar)|(Boo&Baz) $obj2 = new Boo() +) {} + +/* testPHP82DNFTypesWithSpreadOperatorAndReference */ +function dnfInGlobalFunctionWithSpreadAndReference((Countable&MeMe)|iterable &$paramA, true|(Foo&Bar) ...$paramB) {} + +/* testPHP82DNFTypesIllegalNullable */ +// Intentional fatal error - nullable operator cannot be combined with DNF. +$dnf_closure = function (? ( MyClassA & /*comment*/ \Package\MyClassB & \Package\MyClassC ) $var): void {}; + +/* testPHP82DNFTypesInArrow */ +$dnf_arrow = fn((Hi&Ho)|FALSE &...$range): string => $a; + /* testFunctionCallFnPHPCS353-354 */ $value = $obj->fn(true); diff --git a/Tests/BackCompat/BCFile/GetMethodParametersTest.php b/Tests/BackCompat/BCFile/GetMethodParametersTest.php index 9ea1faa3..d473653d 100644 --- a/Tests/BackCompat/BCFile/GetMethodParametersTest.php +++ b/Tests/BackCompat/BCFile/GetMethodParametersTest.php @@ -18,7 +18,7 @@ * @author George Mponos * * @copyright 2010-2019 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */ namespace PHPCSUtils\Tests\BackCompat\BCFile; @@ -43,8 +43,8 @@ class GetMethodParametersTest extends UtilityMethodTestCase * * @dataProvider dataUnexpectedTokenException * - * @param string $commentString The comment which preceeds the test. - * @param array $targetTokenType The token type to search for after $commentString. + * @param string $commentString The comment which preceeds the test. + * @param int|string|array $targetTokenType The token type to search for after $commentString. * * @return void */ @@ -61,22 +61,22 @@ public function testUnexpectedTokenException($commentString, $targetTokenType) * * @see testUnexpectedTokenException() For the array format. * - * @return array + * @return array>> */ - public function dataUnexpectedTokenException() + public static function dataUnexpectedTokenException() { return [ 'interface' => [ - '/* testNotAFunction */', - T_INTERFACE, + 'commentString' => '/* testNotAFunction */', + 'targetTokenType' => T_INTERFACE, ], 'function-call-fn-phpcs-3.5.3-3.5.4' => [ - '/* testFunctionCallFnPHPCS353-354 */', - [T_FN, T_STRING], + 'commentString' => '/* testFunctionCallFnPHPCS353-354 */', + 'targetTokenType' => [T_FN, T_STRING], ], 'fn-live-coding' => [ - '/* testArrowFunctionLiveCoding */', - [T_FN, T_STRING], + 'commentString' => '/* testArrowFunctionLiveCoding */', + 'targetTokenType' => [T_FN, T_STRING], ], ]; } @@ -103,9 +103,9 @@ public function testInvalidUse($identifier) * * @see testInvalidUse() For the array format. * - * @return array + * @return array> */ - public function dataInvalidUse() + public static function dataInvalidUse() { return [ 'ImportUse' => ['/* testImportUse */'], @@ -120,13 +120,13 @@ public function dataInvalidUse() * * @dataProvider dataNoParams * - * @param string $commentString The comment which preceeds the test. - * @param array $targetTokenType Optional. The token type to search for after $commentString. - * Defaults to the function/closure/arrow tokens. + * @param string $commentString The comment which preceeds the test. + * @param int|string|array $targetTokenType Optional. The token type to search for after $commentString. + * Defaults to the function/closure/arrow tokens. * * @return void */ - public function testNoParams($commentString, $targetTokenType = [T_FUNCTION, T_CLOSURE, \T_FN]) + public function testNoParams($commentString, $targetTokenType = [T_FUNCTION, T_CLOSURE, T_FN]) { $target = $this->getTargetToken($commentString, $targetTokenType); $result = BCFile::getMethodParameters(self::$phpcsFile, $target); @@ -139,9 +139,9 @@ public function testNoParams($commentString, $targetTokenType = [T_FUNCTION, T_C * * @see testNoParams() For the array format. * - * @return array + * @return array>> */ - public function dataNoParams() + public static function dataNoParams() { return [ 'FunctionNoParams' => ['/* testFunctionNoParams */'], @@ -157,14 +157,15 @@ public function dataNoParams() */ public function testPassByReference() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 5, // Offset from the T_FUNCTION token. + 'token' => 5, 'name' => '$var', 'content' => '&$var', 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 4, // Offset from the T_FUNCTION token. + 'reference_token' => 4, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '', @@ -184,9 +185,10 @@ public function testPassByReference() */ public function testArrayHint() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 6, // Offset from the T_FUNCTION token. + 'token' => 6, 'name' => '$var', 'content' => 'array $var', 'has_attributes' => false, @@ -195,8 +197,8 @@ public function testArrayHint() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'array', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 4, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 4, 'nullable_type' => false, 'comma_token' => false, ]; @@ -211,9 +213,10 @@ public function testArrayHint() */ public function testVariable() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 4, // Offset from the T_FUNCTION token. + 'token' => 4, 'name' => '$var', 'content' => '$var', 'has_attributes' => false, @@ -238,14 +241,15 @@ public function testVariable() */ public function testSingleDefaultValue() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 4, // Offset from the T_FUNCTION token. + 'token' => 4, 'name' => '$var1', 'content' => '$var1=self::CONSTANT', 'default' => 'self::CONSTANT', - 'default_token' => 6, // Offset from the T_FUNCTION token. - 'default_equal_token' => 5, // Offset from the T_FUNCTION token. + 'default_token' => 6, + 'default_equal_token' => 5, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -268,14 +272,15 @@ public function testSingleDefaultValue() */ public function testDefaultValues() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 4, // Offset from the T_FUNCTION token. + 'token' => 4, 'name' => '$var1', 'content' => '$var1=1', 'default' => '1', - 'default_token' => 6, // Offset from the T_FUNCTION token. - 'default_equal_token' => 5, // Offset from the T_FUNCTION token. + 'default_token' => 6, + 'default_equal_token' => 5, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -285,15 +290,15 @@ public function testDefaultValues() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 7, // Offset from the T_FUNCTION token. + 'comma_token' => 7, ]; $expected[1] = [ - 'token' => 9, // Offset from the T_FUNCTION token. + 'token' => 9, 'name' => '$var2', 'content' => "\$var2='value'", 'default' => "'value'", - 'default_token' => 11, // Offset from the T_FUNCTION token. - 'default_equal_token' => 10, // Offset from the T_FUNCTION token. + 'default_token' => 11, + 'default_equal_token' => 10, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -316,9 +321,10 @@ public function testDefaultValues() */ public function testTypeHint() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 6, // Offset from the T_FUNCTION token. + 'token' => 6, 'name' => '$var1', 'content' => 'foo $var1', 'has_attributes' => false, @@ -327,14 +333,14 @@ public function testTypeHint() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'foo', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 4, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 4, 'nullable_type' => false, - 'comma_token' => 7, // Offset from the T_FUNCTION token. + 'comma_token' => 7, ]; $expected[1] = [ - 'token' => 11, // Offset from the T_FUNCTION token. + 'token' => 11, 'name' => '$var2', 'content' => 'bar $var2', 'has_attributes' => false, @@ -343,8 +349,8 @@ public function testTypeHint() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'bar', - 'type_hint_token' => 9, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 9, // Offset from the T_FUNCTION token. + 'type_hint_token' => 9, + 'type_hint_end_token' => 9, 'nullable_type' => false, 'comma_token' => false, ]; @@ -359,9 +365,10 @@ public function testTypeHint() */ public function testSelfTypeHint() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 6, // Offset from the T_FUNCTION token. + 'token' => 6, 'name' => '$var', 'content' => 'self $var', 'has_attributes' => false, @@ -370,8 +377,8 @@ public function testSelfTypeHint() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'self', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 4, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 4, 'nullable_type' => false, 'comma_token' => false, ]; @@ -388,9 +395,10 @@ public function testNullableTypeHint() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 7, // Offset from the T_FUNCTION token. + 'token' => 7, 'name' => '$var1', 'content' => '?int $var1', 'has_attributes' => false, @@ -399,14 +407,14 @@ public function testNullableTypeHint() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?int', - 'type_hint_token' => 5, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 5, // Offset from the T_FUNCTION token. + 'type_hint_token' => 5, + 'type_hint_end_token' => 5, 'nullable_type' => true, - 'comma_token' => 8, // Offset from the T_FUNCTION token. + 'comma_token' => 8, ]; $expected[1] = [ - 'token' => ($php8Names === true) ? 13 : 14, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 13 : 14, 'name' => '$var2', 'content' => '?\bar $var2', 'has_attributes' => false, @@ -415,8 +423,8 @@ public function testNullableTypeHint() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?\bar', - 'type_hint_token' => 11, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => ($php8Names === true) ? 11 : 12, // Offset from the T_FUNCTION token. + 'type_hint_token' => 11, + 'type_hint_end_token' => ($php8Names === true) ? 11 : 12, 'nullable_type' => true, 'comma_token' => false, ]; @@ -431,14 +439,15 @@ public function testNullableTypeHint() */ public function testBitwiseAndConstantExpressionDefaultValue() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 4, // Offset from the T_FUNCTION token. + 'token' => 4, 'name' => '$a', 'content' => '$a = 10 & 20', 'default' => '10 & 20', - 'default_token' => 8, // Offset from the T_FUNCTION token. - 'default_equal_token' => 6, // Offset from the T_FUNCTION token. + 'default_token' => 8, + 'default_equal_token' => 6, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -461,9 +470,10 @@ public function testBitwiseAndConstantExpressionDefaultValue() */ public function testArrowFunction() { + // Offsets are relative to the T_FN token. $expected = []; $expected[0] = [ - 'token' => 4, // Offset from the T_FN token. + 'token' => 4, 'name' => '$a', 'content' => 'int $a', 'has_attributes' => false, @@ -472,21 +482,21 @@ public function testArrowFunction() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'int', - 'type_hint_token' => 2, // Offset from the T_FN token. - 'type_hint_end_token' => 2, // Offset from the T_FN token. + 'type_hint_token' => 2, + 'type_hint_end_token' => 2, 'nullable_type' => false, - 'comma_token' => 5, // Offset from the T_FN token. + 'comma_token' => 5, ]; $expected[1] = [ - 'token' => 8, // Offset from the T_FN token. + 'token' => 8, 'name' => '$b', 'content' => '...$b', 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => true, - 'variadic_token' => 7, // Offset from the T_FN token. + 'variadic_token' => 7, 'type_hint' => '', 'type_hint_token' => false, 'type_hint_end_token' => false, @@ -504,9 +514,10 @@ public function testArrowFunction() */ public function testArrowFunctionReturnByRef() { + // Offsets are relative to the T_FN token. $expected = []; $expected[0] = [ - 'token' => 6, // Offset from the T_FN token. + 'token' => 6, 'name' => '$a', 'content' => '?string $a', 'has_attributes' => false, @@ -515,8 +526,8 @@ public function testArrowFunctionReturnByRef() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?string', - 'type_hint_token' => 4, // Offset from the T_FN token. - 'type_hint_end_token' => 4, // Offset from the T_FN token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 4, 'nullable_type' => true, 'comma_token' => false, ]; @@ -531,14 +542,15 @@ public function testArrowFunctionReturnByRef() */ public function testArrayDefaultValues() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 4, // Offset from the T_FUNCTION token. + 'token' => 4, 'name' => '$var1', 'content' => '$var1 = []', 'default' => '[]', - 'default_token' => 8, // Offset from the T_FUNCTION token. - 'default_equal_token' => 6, // Offset from the T_FUNCTION token. + 'default_token' => 8, + 'default_equal_token' => 6, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -548,15 +560,15 @@ public function testArrayDefaultValues() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 10, // Offset from the T_FUNCTION token. + 'comma_token' => 10, ]; $expected[1] = [ - 'token' => 12, // Offset from the T_FUNCTION token. + 'token' => 12, 'name' => '$var2', 'content' => '$var2 = array(1, 2, 3)', 'default' => 'array(1, 2, 3)', - 'default_token' => 16, // Offset from the T_FUNCTION token. - 'default_equal_token' => 14, // Offset from the T_FUNCTION token. + 'default_token' => 16, + 'default_equal_token' => 14, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -579,9 +591,10 @@ public function testArrayDefaultValues() */ public function testConstantDefaultValueSecondParam() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 4, // Offset from the T_FUNCTION token. + 'token' => 4, 'name' => '$var1', 'content' => '$var1', 'has_attributes' => false, @@ -593,15 +606,15 @@ public function testConstantDefaultValueSecondParam() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 5, // Offset from the T_FUNCTION token. + 'comma_token' => 5, ]; $expected[1] = [ - 'token' => 7, // Offset from the T_FUNCTION token. + 'token' => 7, 'name' => '$var2', 'content' => '$var2 = M_PI', 'default' => 'M_PI', - 'default_token' => 11, // Offset from the T_FUNCTION token. - 'default_equal_token' => 9, // Offset from the T_FUNCTION token. + 'default_token' => 11, + 'default_equal_token' => 9, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -624,14 +637,15 @@ public function testConstantDefaultValueSecondParam() */ public function testScalarTernaryExpressionInDefault() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 5, // Offset from the T_FUNCTION token. + 'token' => 5, 'name' => '$a', 'content' => '$a = FOO ? \'bar\' : 10', 'default' => 'FOO ? \'bar\' : 10', - 'default_token' => 9, // Offset from the T_FUNCTION token. - 'default_equal_token' => 7, // Offset from the T_FUNCTION token. + 'default_token' => 9, + 'default_equal_token' => 7, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -641,10 +655,10 @@ public function testScalarTernaryExpressionInDefault() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 18, // Offset from the T_FUNCTION token. + 'comma_token' => 18, ]; $expected[1] = [ - 'token' => 24, // Offset from the T_FUNCTION token. + 'token' => 24, 'name' => '$b', 'content' => '? bool $b', 'has_attributes' => false, @@ -653,8 +667,8 @@ public function testScalarTernaryExpressionInDefault() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?bool', - 'type_hint_token' => 22, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 22, // Offset from the T_FUNCTION token. + 'type_hint_token' => 22, + 'type_hint_end_token' => 22, 'nullable_type' => true, 'comma_token' => false, ]; @@ -669,19 +683,20 @@ public function testScalarTernaryExpressionInDefault() */ public function testVariadicFunction() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 9, // Offset from the T_FUNCTION token. + 'token' => 9, 'name' => '$a', 'content' => 'int ... $a', 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => true, - 'variadic_token' => 7, // Offset from the T_FUNCTION token. + 'variadic_token' => 7, 'type_hint' => 'int', - 'type_hint_token' => 5, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 5, // Offset from the T_FUNCTION token. + 'type_hint_token' => 5, + 'type_hint_end_token' => 5, 'nullable_type' => false, 'comma_token' => false, ]; @@ -696,16 +711,17 @@ public function testVariadicFunction() */ public function testVariadicByRefFunction() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 7, // Offset from the T_FUNCTION token. + 'token' => 7, 'name' => '$a', 'content' => '&...$a', 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 5, // Offset from the T_FUNCTION token. + 'reference_token' => 5, 'variable_length' => true, - 'variadic_token' => 6, // Offset from the T_FUNCTION token. + 'variadic_token' => 6, 'type_hint' => '', 'type_hint_token' => false, 'type_hint_end_token' => false, @@ -723,9 +739,10 @@ public function testVariadicByRefFunction() */ public function testVariadicFunctionClassType() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 4, // Offset from the T_FUNCTION token. + 'token' => 4, 'name' => '$unit', 'content' => '$unit', 'has_attributes' => false, @@ -737,10 +754,10 @@ public function testVariadicFunctionClassType() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 5, // Offset from the T_FUNCTION token. + 'comma_token' => 5, ]; $expected[1] = [ - 'token' => 10, // Offset from the T_FUNCTION token. + 'token' => 10, 'name' => '$intervals', 'content' => 'DateInterval ...$intervals', 'has_attributes' => false, @@ -749,8 +766,8 @@ public function testVariadicFunctionClassType() 'variable_length' => true, 'variadic_token' => 9, 'type_hint' => 'DateInterval', - 'type_hint_token' => 7, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 7, // Offset from the T_FUNCTION token. + 'type_hint_token' => 7, + 'type_hint_end_token' => 7, 'nullable_type' => false, 'comma_token' => false, ]; @@ -767,9 +784,10 @@ public function testNameSpacedTypeDeclaration() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => ($php8Names === true) ? 7 : 12, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 7 : 12, 'name' => '$a', 'content' => '\Package\Sub\ClassName $a', 'has_attributes' => false, @@ -778,13 +796,13 @@ public function testNameSpacedTypeDeclaration() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '\Package\Sub\ClassName', - 'type_hint_token' => 5, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => ($php8Names === true) ? 5 : 10, // Offset from the T_FUNCTION token. + 'type_hint_token' => 5, + 'type_hint_end_token' => ($php8Names === true) ? 5 : 10, 'nullable_type' => false, - 'comma_token' => ($php8Names === true) ? 8 : 13, // Offset from the T_FUNCTION token. + 'comma_token' => ($php8Names === true) ? 8 : 13, ]; $expected[1] = [ - 'token' => ($php8Names === true) ? 13 : 20, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 13 : 20, 'name' => '$b', 'content' => '?Sub\AnotherClass $b', 'has_attributes' => false, @@ -793,8 +811,8 @@ public function testNameSpacedTypeDeclaration() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?Sub\AnotherClass', - 'type_hint_token' => ($php8Names === true) ? 11 : 16, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => ($php8Names === true) ? 11 : 18, // Offset from the T_FUNCTION token. + 'type_hint_token' => ($php8Names === true) ? 11 : 16, + 'type_hint_end_token' => ($php8Names === true) ? 11 : 18, 'nullable_type' => true, 'comma_token' => false, ]; @@ -809,9 +827,10 @@ public function testNameSpacedTypeDeclaration() */ public function testWithAllTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 9, // Offset from the T_FUNCTION token. + 'token' => 9, 'name' => '$a', 'content' => '?ClassName $a', 'has_attributes' => false, @@ -820,13 +839,13 @@ public function testWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?ClassName', - 'type_hint_token' => 7, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 7, // Offset from the T_FUNCTION token. + 'type_hint_token' => 7, + 'type_hint_end_token' => 7, 'nullable_type' => true, - 'comma_token' => 10, // Offset from the T_FUNCTION token. + 'comma_token' => 10, ]; $expected[1] = [ - 'token' => 15, // Offset from the T_FUNCTION token. + 'token' => 15, 'name' => '$b', 'content' => 'self $b', 'has_attributes' => false, @@ -835,13 +854,13 @@ public function testWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'self', - 'type_hint_token' => 13, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 13, // Offset from the T_FUNCTION token. + 'type_hint_token' => 13, + 'type_hint_end_token' => 13, 'nullable_type' => false, - 'comma_token' => 16, // Offset from the T_FUNCTION token. + 'comma_token' => 16, ]; $expected[2] = [ - 'token' => 21, // Offset from the T_FUNCTION token. + 'token' => 21, 'name' => '$c', 'content' => 'parent $c', 'has_attributes' => false, @@ -850,13 +869,13 @@ public function testWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'parent', - 'type_hint_token' => 19, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 19, // Offset from the T_FUNCTION token. + 'type_hint_token' => 19, + 'type_hint_end_token' => 19, 'nullable_type' => false, - 'comma_token' => 22, // Offset from the T_FUNCTION token. + 'comma_token' => 22, ]; $expected[3] = [ - 'token' => 27, // Offset from the T_FUNCTION token. + 'token' => 27, 'name' => '$d', 'content' => 'object $d', 'has_attributes' => false, @@ -865,13 +884,13 @@ public function testWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'object', - 'type_hint_token' => 25, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 25, // Offset from the T_FUNCTION token. + 'type_hint_token' => 25, + 'type_hint_end_token' => 25, 'nullable_type' => false, - 'comma_token' => 28, // Offset from the T_FUNCTION token. + 'comma_token' => 28, ]; $expected[4] = [ - 'token' => 34, // Offset from the T_FUNCTION token. + 'token' => 34, 'name' => '$e', 'content' => '?int $e', 'has_attributes' => false, @@ -880,28 +899,28 @@ public function testWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?int', - 'type_hint_token' => 32, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 32, // Offset from the T_FUNCTION token. + 'type_hint_token' => 32, + 'type_hint_end_token' => 32, 'nullable_type' => true, - 'comma_token' => 35, // Offset from the T_FUNCTION token. + 'comma_token' => 35, ]; $expected[5] = [ - 'token' => 41, // Offset from the T_FUNCTION token. + 'token' => 41, 'name' => '$f', 'content' => 'string &$f', 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 40, // Offset from the T_FUNCTION token. + 'reference_token' => 40, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'string', - 'type_hint_token' => 38, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 38, // Offset from the T_FUNCTION token. + 'type_hint_token' => 38, + 'type_hint_end_token' => 38, 'nullable_type' => false, - 'comma_token' => 42, // Offset from the T_FUNCTION token. + 'comma_token' => 42, ]; $expected[6] = [ - 'token' => 47, // Offset from the T_FUNCTION token. + 'token' => 47, 'name' => '$g', 'content' => 'iterable $g', 'has_attributes' => false, @@ -910,77 +929,77 @@ public function testWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'iterable', - 'type_hint_token' => 45, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 45, // Offset from the T_FUNCTION token. + 'type_hint_token' => 45, + 'type_hint_end_token' => 45, 'nullable_type' => false, - 'comma_token' => 48, // Offset from the T_FUNCTION token. + 'comma_token' => 48, ]; $expected[7] = [ - 'token' => 53, // Offset from the T_FUNCTION token. + 'token' => 53, 'name' => '$h', 'content' => 'bool $h = true', 'default' => 'true', - 'default_token' => 57, // Offset from the T_FUNCTION token. - 'default_equal_token' => 55, // Offset from the T_FUNCTION token. + 'default_token' => 57, + 'default_equal_token' => 55, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'bool', - 'type_hint_token' => 51, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 51, // Offset from the T_FUNCTION token. + 'type_hint_token' => 51, + 'type_hint_end_token' => 51, 'nullable_type' => false, - 'comma_token' => 58, // Offset from the T_FUNCTION token. + 'comma_token' => 58, ]; $expected[8] = [ - 'token' => 63, // Offset from the T_FUNCTION token. + 'token' => 63, 'name' => '$i', 'content' => 'callable $i = \'is_null\'', 'default' => "'is_null'", - 'default_token' => 67, // Offset from the T_FUNCTION token. - 'default_equal_token' => 65, // Offset from the T_FUNCTION token. + 'default_token' => 67, + 'default_equal_token' => 65, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'callable', - 'type_hint_token' => 61, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 61, // Offset from the T_FUNCTION token. + 'type_hint_token' => 61, + 'type_hint_end_token' => 61, 'nullable_type' => false, - 'comma_token' => 68, // Offset from the T_FUNCTION token. + 'comma_token' => 68, ]; $expected[9] = [ - 'token' => 73, // Offset from the T_FUNCTION token. + 'token' => 73, 'name' => '$j', 'content' => 'float $j = 1.1', 'default' => '1.1', - 'default_token' => 77, // Offset from the T_FUNCTION token. - 'default_equal_token' => 75, // Offset from the T_FUNCTION token. + 'default_token' => 77, + 'default_equal_token' => 75, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'float', - 'type_hint_token' => 71, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 71, // Offset from the T_FUNCTION token. + 'type_hint_token' => 71, + 'type_hint_end_token' => 71, 'nullable_type' => false, - 'comma_token' => 78, // Offset from the T_FUNCTION token. + 'comma_token' => 78, ]; $expected[10] = [ - 'token' => 84, // Offset from the T_FUNCTION token. + 'token' => 84, 'name' => '$k', 'content' => 'array ...$k', 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => true, - 'variadic_token' => 83, // Offset from the T_FUNCTION token. + 'variadic_token' => 83, 'type_hint' => 'array', - 'type_hint_token' => 81, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 81, // Offset from the T_FUNCTION token. + 'type_hint_token' => 81, + 'type_hint_end_token' => 81, 'nullable_type' => false, 'comma_token' => false, ]; @@ -995,9 +1014,10 @@ public function testWithAllTypes() */ public function testArrowFunctionWithAllTypes() { + // Offsets are relative to the T_FN token. $expected = []; $expected[0] = [ - 'token' => 7, // Offset from the T_FN token. + 'token' => 7, 'name' => '$a', 'content' => '?ClassName $a', 'has_attributes' => false, @@ -1006,13 +1026,13 @@ public function testArrowFunctionWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?ClassName', - 'type_hint_token' => 5, // Offset from the T_FN token. - 'type_hint_end_token' => 5, // Offset from the T_FN token. + 'type_hint_token' => 5, + 'type_hint_end_token' => 5, 'nullable_type' => true, - 'comma_token' => 8, // Offset from the T_FN token. + 'comma_token' => 8, ]; $expected[1] = [ - 'token' => 13, // Offset from the T_FN token. + 'token' => 13, 'name' => '$b', 'content' => 'self $b', 'has_attributes' => false, @@ -1021,13 +1041,13 @@ public function testArrowFunctionWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'self', - 'type_hint_token' => 11, // Offset from the T_FN token. - 'type_hint_end_token' => 11, // Offset from the T_FN token. + 'type_hint_token' => 11, + 'type_hint_end_token' => 11, 'nullable_type' => false, - 'comma_token' => 14, // Offset from the T_FN token. + 'comma_token' => 14, ]; $expected[2] = [ - 'token' => 19, // Offset from the T_FN token. + 'token' => 19, 'name' => '$c', 'content' => 'parent $c', 'has_attributes' => false, @@ -1036,13 +1056,13 @@ public function testArrowFunctionWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'parent', - 'type_hint_token' => 17, // Offset from the T_FN token. - 'type_hint_end_token' => 17, // Offset from the T_FN token. + 'type_hint_token' => 17, + 'type_hint_end_token' => 17, 'nullable_type' => false, - 'comma_token' => 20, // Offset from the T_FN token. + 'comma_token' => 20, ]; $expected[3] = [ - 'token' => 25, // Offset from the T_FN token. + 'token' => 25, 'name' => '$d', 'content' => 'object $d', 'has_attributes' => false, @@ -1051,13 +1071,13 @@ public function testArrowFunctionWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'object', - 'type_hint_token' => 23, // Offset from the T_FN token. - 'type_hint_end_token' => 23, // Offset from the T_FN token. + 'type_hint_token' => 23, + 'type_hint_end_token' => 23, 'nullable_type' => false, - 'comma_token' => 26, // Offset from the T_FN token. + 'comma_token' => 26, ]; $expected[4] = [ - 'token' => 32, // Offset from the T_FN token. + 'token' => 32, 'name' => '$e', 'content' => '?int $e', 'has_attributes' => false, @@ -1066,28 +1086,28 @@ public function testArrowFunctionWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?int', - 'type_hint_token' => 30, // Offset from the T_FN token. - 'type_hint_end_token' => 30, // Offset from the T_FN token. + 'type_hint_token' => 30, + 'type_hint_end_token' => 30, 'nullable_type' => true, - 'comma_token' => 33, // Offset from the T_FN token. + 'comma_token' => 33, ]; $expected[5] = [ - 'token' => 39, // Offset from the T_FN token. + 'token' => 39, 'name' => '$f', 'content' => 'string &$f', 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 38, // Offset from the T_FN token. + 'reference_token' => 38, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'string', - 'type_hint_token' => 36, // Offset from the T_FN token. - 'type_hint_end_token' => 36, // Offset from the T_FN token. + 'type_hint_token' => 36, + 'type_hint_end_token' => 36, 'nullable_type' => false, - 'comma_token' => 40, // Offset from the T_FN token. + 'comma_token' => 40, ]; $expected[6] = [ - 'token' => 45, // Offset from the T_FN token. + 'token' => 45, 'name' => '$g', 'content' => 'iterable $g', 'has_attributes' => false, @@ -1096,77 +1116,77 @@ public function testArrowFunctionWithAllTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'iterable', - 'type_hint_token' => 43, // Offset from the T_FN token. - 'type_hint_end_token' => 43, // Offset from the T_FN token. + 'type_hint_token' => 43, + 'type_hint_end_token' => 43, 'nullable_type' => false, - 'comma_token' => 46, // Offset from the T_FN token. + 'comma_token' => 46, ]; $expected[7] = [ - 'token' => 51, // Offset from the T_FN token. + 'token' => 51, 'name' => '$h', 'content' => 'bool $h = true', 'default' => 'true', - 'default_token' => 55, // Offset from the T_FN token. - 'default_equal_token' => 53, // Offset from the T_FN token. + 'default_token' => 55, + 'default_equal_token' => 53, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'bool', - 'type_hint_token' => 49, // Offset from the T_FN token. - 'type_hint_end_token' => 49, // Offset from the T_FN token. + 'type_hint_token' => 49, + 'type_hint_end_token' => 49, 'nullable_type' => false, - 'comma_token' => 56, // Offset from the T_FN token. + 'comma_token' => 56, ]; $expected[8] = [ - 'token' => 61, // Offset from the T_FN token. + 'token' => 61, 'name' => '$i', 'content' => 'callable $i = \'is_null\'', 'default' => "'is_null'", - 'default_token' => 65, // Offset from the T_FN token. - 'default_equal_token' => 63, // Offset from the T_FN token. + 'default_token' => 65, + 'default_equal_token' => 63, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'callable', - 'type_hint_token' => 59, // Offset from the T_FN token. - 'type_hint_end_token' => 59, // Offset from the T_FN token. + 'type_hint_token' => 59, + 'type_hint_end_token' => 59, 'nullable_type' => false, - 'comma_token' => 66, // Offset from the T_FN token. + 'comma_token' => 66, ]; $expected[9] = [ - 'token' => 71, // Offset from the T_FN token. + 'token' => 71, 'name' => '$j', 'content' => 'float $j = 1.1', 'default' => '1.1', - 'default_token' => 75, // Offset from the T_FN token. - 'default_equal_token' => 73, // Offset from the T_FN token. + 'default_token' => 75, + 'default_equal_token' => 73, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'float', - 'type_hint_token' => 69, // Offset from the T_FN token. - 'type_hint_end_token' => 69, // Offset from the T_FN token. + 'type_hint_token' => 69, + 'type_hint_end_token' => 69, 'nullable_type' => false, - 'comma_token' => 76, // Offset from the T_FN token. + 'comma_token' => 76, ]; $expected[10] = [ - 'token' => 82, // Offset from the T_FN token. + 'token' => 82, 'name' => '$k', 'content' => 'array ...$k', 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => true, - 'variadic_token' => 81, // Offset from the T_FN token. + 'variadic_token' => 81, 'type_hint' => 'array', - 'type_hint_token' => 79, // Offset from the T_FN token. - 'type_hint_end_token' => 79, // Offset from the T_FN token. + 'type_hint_token' => 79, + 'type_hint_end_token' => 79, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1183,9 +1203,10 @@ public function testMessyDeclaration() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => ($php8Names === true) ? 24 : 25, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 24 : 25, 'name' => '$a', 'content' => '// comment ?\MyNS /* comment */ @@ -1200,15 +1221,15 @@ public function testMessyDeclaration() 'type_hint_token' => 9, 'type_hint_end_token' => ($php8Names === true) ? 22 : 23, 'nullable_type' => true, - 'comma_token' => ($php8Names === true) ? 25 : 26, // Offset from the T_FUNCTION token. + 'comma_token' => ($php8Names === true) ? 25 : 26, ]; $expected[1] = [ - 'token' => ($php8Names === true) ? 28 : 29, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 28 : 29, 'name' => '$b', 'content' => "\$b /* test */ = /* test */ 'default' /* test*/", 'default' => "'default' /* test*/", - 'default_token' => ($php8Names === true) ? 36 : 37, // Offset from the T_FUNCTION token. - 'default_equal_token' => ($php8Names === true) ? 32 : 33, // Offset from the T_FUNCTION token. + 'default_token' => ($php8Names === true) ? 36 : 37, + 'default_equal_token' => ($php8Names === true) ? 32 : 33, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -1218,10 +1239,10 @@ public function testMessyDeclaration() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => ($php8Names === true) ? 39 : 40, // Offset from the T_FUNCTION token. + 'comma_token' => ($php8Names === true) ? 39 : 40, ]; $expected[2] = [ - 'token' => ($php8Names === true) ? 61 : 62, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 61 : 62, 'name' => '$c', 'content' => '// phpcs:ignore Stnd.Cat.Sniff -- For reasons. ? /*comment*/ @@ -1229,12 +1250,12 @@ public function testMessyDeclaration() & /*test*/ ... /* phpcs:ignore */ $c', 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => ($php8Names === true) ? 53 : 54, // Offset from the T_FUNCTION token. + 'reference_token' => ($php8Names === true) ? 53 : 54, 'variable_length' => true, - 'variadic_token' => ($php8Names === true) ? 57 : 58, // Offset from the T_FUNCTION token. + 'variadic_token' => ($php8Names === true) ? 57 : 58, 'type_hint' => '?bool', - 'type_hint_token' => ($php8Names === true) ? 49 : 50, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => ($php8Names === true) ? 49 : 50, // Offset from the T_FUNCTION token. + 'type_hint_token' => ($php8Names === true) ? 49 : 50, + 'type_hint_end_token' => ($php8Names === true) ? 49 : 50, 'nullable_type' => true, 'comma_token' => false, ]; @@ -1249,19 +1270,20 @@ public function testMessyDeclaration() */ public function testPHP8MixedTypeHint() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$var1', 'content' => 'mixed &...$var1', 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 6, // Offset from the T_FUNCTION token. + 'reference_token' => 6, 'variable_length' => true, - 'variadic_token' => 7, // Offset from the T_FUNCTION token. + 'variadic_token' => 7, 'type_hint' => 'mixed', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 4, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 4, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1276,9 +1298,10 @@ public function testPHP8MixedTypeHint() */ public function testPHP8MixedTypeHintNullable() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 7, // Offset from the T_FUNCTION token. + 'token' => 7, 'name' => '$var1', 'content' => '?Mixed $var1', 'has_attributes' => false, @@ -1287,8 +1310,8 @@ public function testPHP8MixedTypeHintNullable() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?Mixed', - 'type_hint_token' => 5, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 5, // Offset from the T_FUNCTION token. + 'type_hint_token' => 5, + 'type_hint_end_token' => 5, 'nullable_type' => true, 'comma_token' => false, ]; @@ -1305,9 +1328,10 @@ public function testNamespaceOperatorTypeHint() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => ($php8Names === true) ? 7 : 9, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 7 : 9, 'name' => '$var1', 'content' => '?namespace\Name $var1', 'has_attributes' => false, @@ -1316,8 +1340,8 @@ public function testNamespaceOperatorTypeHint() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?namespace\Name', - 'type_hint_token' => 5, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => ($php8Names === true) ? 5 : 7, // Offset from the T_FUNCTION token. + 'type_hint_token' => 5, + 'type_hint_end_token' => ($php8Names === true) ? 5 : 7, 'nullable_type' => true, 'comma_token' => false, ]; @@ -1332,9 +1356,10 @@ public function testNamespaceOperatorTypeHint() */ public function testPHP8UnionTypesSimple() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$number', 'content' => 'int|float $number', 'has_attributes' => false, @@ -1343,23 +1368,23 @@ public function testPHP8UnionTypesSimple() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'int|float', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 6, 'nullable_type' => false, 'comma_token' => 9, ]; $expected[1] = [ - 'token' => 17, // Offset from the T_FUNCTION token. + 'token' => 17, 'name' => '$obj', 'content' => 'self|parent &...$obj', 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 15, // Offset from the T_FUNCTION token. + 'reference_token' => 15, 'variable_length' => true, 'variadic_token' => 16, 'type_hint' => 'self|parent', - 'type_hint_token' => 11, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 13, // Offset from the T_FUNCTION token. + 'type_hint_token' => 11, + 'type_hint_end_token' => 13, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1374,34 +1399,35 @@ public function testPHP8UnionTypesSimple() */ public function testPHP8UnionTypesWithSpreadOperatorAndReference() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 9, // Offset from the T_FUNCTION token. + 'token' => 9, 'name' => '$paramA', 'content' => 'float|null &$paramA', 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 8, // Offset from the T_FUNCTION token. + 'reference_token' => 8, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'float|null', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 6, 'nullable_type' => false, 'comma_token' => 10, ]; $expected[1] = [ - 'token' => 17, // Offset from the T_FUNCTION token. + 'token' => 17, 'name' => '$paramB', 'content' => 'string|int ...$paramB', 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => true, - 'variadic_token' => 16, // Offset from the T_FUNCTION token. + 'variadic_token' => 16, 'type_hint' => 'string|int', - 'type_hint_token' => 12, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 14, // Offset from the T_FUNCTION token. + 'type_hint_token' => 12, + 'type_hint_end_token' => 14, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1416,22 +1442,23 @@ public function testPHP8UnionTypesWithSpreadOperatorAndReference() */ public function testPHP8UnionTypesSimpleWithBitwiseOrInDefault() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 6, // Offset from the T_FUNCTION token. + 'token' => 6, 'name' => '$var', 'content' => 'int|float $var = CONSTANT_A | CONSTANT_B', 'default' => 'CONSTANT_A | CONSTANT_B', - 'default_token' => 10, // Offset from the T_FUNCTION token. - 'default_equal_token' => 8, // Offset from the T_FUNCTION token. + 'default_token' => 10, + 'default_equal_token' => 8, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'int|float', - 'type_hint_token' => 2, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 4, // Offset from the T_FUNCTION token. + 'type_hint_token' => 2, + 'type_hint_end_token' => 4, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1448,9 +1475,10 @@ public function testPHP8UnionTypesTwoClasses() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => ($php8Names === true) ? 8 : 11, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 8 : 11, 'name' => '$var', 'content' => 'MyClassA|\Package\MyClassB $var', 'has_attributes' => false, @@ -1459,8 +1487,8 @@ public function testPHP8UnionTypesTwoClasses() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'MyClassA|\Package\MyClassB', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => ($php8Names === true) ? 6 : 9, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => ($php8Names === true) ? 6 : 9, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1475,9 +1503,10 @@ public function testPHP8UnionTypesTwoClasses() */ public function testPHP8UnionTypesAllBaseTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 20, // Offset from the T_FUNCTION token. + 'token' => 20, 'name' => '$var', 'content' => 'array|bool|callable|int|float|null|object|string $var', 'has_attributes' => false, @@ -1486,8 +1515,8 @@ public function testPHP8UnionTypesAllBaseTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'array|bool|callable|int|float|null|object|string', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 18, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 18, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1504,9 +1533,10 @@ public function testPHP8UnionTypesAllBaseTypes() */ public function testPHP8UnionTypesAllPseudoTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 16, // Offset from the T_FUNCTION token. + 'token' => 16, 'name' => '$var', 'content' => 'false|mixed|self|parent|iterable|Resource $var', 'has_attributes' => false, @@ -1515,8 +1545,8 @@ public function testPHP8UnionTypesAllPseudoTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'false|mixed|self|parent|iterable|Resource', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 14, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 14, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1531,9 +1561,10 @@ public function testPHP8UnionTypesAllPseudoTypes() */ public function testPHP8UnionTypesNullable() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$number', 'content' => '?int|float $number', 'has_attributes' => false, @@ -1542,8 +1573,8 @@ public function testPHP8UnionTypesNullable() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?int|float', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 6, 'nullable_type' => true, 'comma_token' => false, ]; @@ -1558,22 +1589,23 @@ public function testPHP8UnionTypesNullable() */ public function testPHP8PseudoTypeNull() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 6, // Offset from the T_FUNCTION token. + 'token' => 6, 'name' => '$var', 'content' => 'null $var = null', 'default' => 'null', - 'default_token' => 10, // Offset from the T_FUNCTION token. - 'default_equal_token' => 8, // Offset from the T_FUNCTION token. + 'default_token' => 10, + 'default_equal_token' => 8, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'null', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 4, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 4, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1588,22 +1620,23 @@ public function testPHP8PseudoTypeNull() */ public function testPHP8PseudoTypeFalse() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 6, // Offset from the T_FUNCTION token. + 'token' => 6, 'name' => '$var', 'content' => 'false $var = false', 'default' => 'false', - 'default_token' => 10, // Offset from the T_FUNCTION token. - 'default_equal_token' => 8, // Offset from the T_FUNCTION token. + 'default_token' => 10, + 'default_equal_token' => 8, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'false', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 4, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 4, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1618,22 +1651,23 @@ public function testPHP8PseudoTypeFalse() */ public function testPHP8PseudoTypeFalseAndBool() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$var', 'content' => 'bool|false $var = false', 'default' => 'false', - 'default_token' => 12, // Offset from the T_FUNCTION token. - 'default_equal_token' => 10, // Offset from the T_FUNCTION token. + 'default_token' => 12, + 'default_equal_token' => 10, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'bool|false', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 6, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1648,9 +1682,10 @@ public function testPHP8PseudoTypeFalseAndBool() */ public function testPHP8ObjectAndClass() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$var', 'content' => 'object|ClassName $var', 'has_attributes' => false, @@ -1659,8 +1694,8 @@ public function testPHP8ObjectAndClass() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'object|ClassName', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 6, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1675,9 +1710,10 @@ public function testPHP8ObjectAndClass() */ public function testPHP8PseudoTypeIterableAndArray() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 10, // Offset from the T_FUNCTION token. + 'token' => 10, 'name' => '$var', 'content' => 'iterable|array|Traversable $var', 'has_attributes' => false, @@ -1686,8 +1722,8 @@ public function testPHP8PseudoTypeIterableAndArray() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'iterable|array|Traversable', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 8, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 8, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1702,9 +1738,10 @@ public function testPHP8PseudoTypeIterableAndArray() */ public function testPHP8DuplicateTypeInUnionWhitespaceAndComment() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 17, // Offset from the T_FUNCTION token. + 'token' => 17, 'name' => '$var', 'content' => 'int | string /*comment*/ | INT $var', 'has_attributes' => false, @@ -1713,8 +1750,8 @@ public function testPHP8DuplicateTypeInUnionWhitespaceAndComment() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'int|string|INT', - 'type_hint_token' => 5, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 15, // Offset from the T_FUNCTION token. + 'type_hint_token' => 5, + 'type_hint_end_token' => 15, 'nullable_type' => false, 'comma_token' => false, ]; @@ -1729,14 +1766,15 @@ public function testPHP8DuplicateTypeInUnionWhitespaceAndComment() */ public function testPHP8ConstructorPropertyPromotionNoTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$x', 'content' => 'public $x = 0.0', 'default' => '0.0', - 'default_token' => 12, // Offset from the T_FUNCTION token. - 'default_equal_token' => 10, // Offset from the T_FUNCTION token. + 'default_token' => 12, + 'default_equal_token' => 10, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -1747,17 +1785,17 @@ public function testPHP8ConstructorPropertyPromotionNoTypes() 'type_hint_end_token' => false, 'nullable_type' => false, 'property_visibility' => 'public', - 'visibility_token' => 6, // Offset from the T_FUNCTION token. + 'visibility_token' => 6, 'property_readonly' => false, 'comma_token' => 13, ]; $expected[1] = [ - 'token' => 18, // Offset from the T_FUNCTION token. + 'token' => 18, 'name' => '$y', 'content' => 'protected $y = \'\'', 'default' => "''", - 'default_token' => 22, // Offset from the T_FUNCTION token. - 'default_equal_token' => 20, // Offset from the T_FUNCTION token. + 'default_token' => 22, + 'default_equal_token' => 20, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -1768,17 +1806,17 @@ public function testPHP8ConstructorPropertyPromotionNoTypes() 'type_hint_end_token' => false, 'nullable_type' => false, 'property_visibility' => 'protected', - 'visibility_token' => 16, // Offset from the T_FUNCTION token. + 'visibility_token' => 16, 'property_readonly' => false, 'comma_token' => 23, ]; $expected[2] = [ - 'token' => 28, // Offset from the T_FUNCTION token. + 'token' => 28, 'name' => '$z', 'content' => 'private $z = null', 'default' => 'null', - 'default_token' => 32, // Offset from the T_FUNCTION token. - 'default_equal_token' => 30, // Offset from the T_FUNCTION token. + 'default_token' => 32, + 'default_equal_token' => 30, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -1789,7 +1827,7 @@ public function testPHP8ConstructorPropertyPromotionNoTypes() 'type_hint_end_token' => false, 'nullable_type' => false, 'property_visibility' => 'private', - 'visibility_token' => 26, // Offset from the T_FUNCTION token. + 'visibility_token' => 26, 'property_readonly' => false, 'comma_token' => 33, ]; @@ -1804,9 +1842,10 @@ public function testPHP8ConstructorPropertyPromotionNoTypes() */ public function testPHP8ConstructorPropertyPromotionWithTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 10, // Offset from the T_FUNCTION token. + 'token' => 10, 'name' => '$x', 'content' => 'protected float|int $x', 'has_attributes' => false, @@ -1815,37 +1854,37 @@ public function testPHP8ConstructorPropertyPromotionWithTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'float|int', - 'type_hint_token' => 6, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 8, // Offset from the T_FUNCTION token. + 'type_hint_token' => 6, + 'type_hint_end_token' => 8, 'nullable_type' => false, 'property_visibility' => 'protected', - 'visibility_token' => 4, // Offset from the T_FUNCTION token. + 'visibility_token' => 4, 'property_readonly' => false, 'comma_token' => 11, ]; $expected[1] = [ - 'token' => 19, // Offset from the T_FUNCTION token. + 'token' => 19, 'name' => '$y', 'content' => 'public ?string &$y = \'test\'', 'default' => "'test'", - 'default_token' => 23, // Offset from the T_FUNCTION token. - 'default_equal_token' => 21, // Offset from the T_FUNCTION token. + 'default_token' => 23, + 'default_equal_token' => 21, 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 18, // Offset from the T_FUNCTION token. + 'reference_token' => 18, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?string', - 'type_hint_token' => 16, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 16, // Offset from the T_FUNCTION token. + 'type_hint_token' => 16, + 'type_hint_end_token' => 16, 'nullable_type' => true, 'property_visibility' => 'public', - 'visibility_token' => 13, // Offset from the T_FUNCTION token. + 'visibility_token' => 13, 'property_readonly' => false, 'comma_token' => 24, ]; $expected[2] = [ - 'token' => 30, // Offset from the T_FUNCTION token. + 'token' => 30, 'name' => '$z', 'content' => 'private mixed $z', 'has_attributes' => false, @@ -1854,11 +1893,11 @@ public function testPHP8ConstructorPropertyPromotionWithTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'mixed', - 'type_hint_token' => 28, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 28, // Offset from the T_FUNCTION token. + 'type_hint_token' => 28, + 'type_hint_end_token' => 28, 'nullable_type' => false, 'property_visibility' => 'private', - 'visibility_token' => 26, // Offset from the T_FUNCTION token. + 'visibility_token' => 26, 'property_readonly' => false, 'comma_token' => false, ]; @@ -1873,9 +1912,10 @@ public function testPHP8ConstructorPropertyPromotionWithTypes() */ public function testPHP8ConstructorPropertyPromotionAndNormalParam() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$promotedProp', 'content' => 'public int $promotedProp', 'has_attributes' => false, @@ -1884,16 +1924,16 @@ public function testPHP8ConstructorPropertyPromotionAndNormalParam() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'int', - 'type_hint_token' => 6, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. + 'type_hint_token' => 6, + 'type_hint_end_token' => 6, 'nullable_type' => false, 'property_visibility' => 'public', - 'visibility_token' => 4, // Offset from the T_FUNCTION token. + 'visibility_token' => 4, 'property_readonly' => false, 'comma_token' => 9, ]; $expected[1] = [ - 'token' => 14, // Offset from the T_FUNCTION token. + 'token' => 14, 'name' => '$normalArg', 'content' => '?int $normalArg', 'has_attributes' => false, @@ -1902,8 +1942,8 @@ public function testPHP8ConstructorPropertyPromotionAndNormalParam() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?int', - 'type_hint_token' => 12, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 12, // Offset from the T_FUNCTION token. + 'type_hint_token' => 12, + 'type_hint_end_token' => 12, 'nullable_type' => true, 'comma_token' => false, ]; @@ -1918,9 +1958,10 @@ public function testPHP8ConstructorPropertyPromotionAndNormalParam() */ public function testPHP81ConstructorPropertyPromotionWithReadOnly() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 11, // Offset from the T_FUNCTION token. + 'token' => 11, 'name' => '$promotedProp', 'content' => 'public readonly ?int $promotedProp', 'has_attributes' => false, @@ -1929,32 +1970,32 @@ public function testPHP81ConstructorPropertyPromotionWithReadOnly() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?int', - 'type_hint_token' => 9, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 9, // Offset from the T_FUNCTION token. + 'type_hint_token' => 9, + 'type_hint_end_token' => 9, 'nullable_type' => true, 'property_visibility' => 'public', - 'visibility_token' => 4, // Offset from the T_FUNCTION token. + 'visibility_token' => 4, 'property_readonly' => true, - 'readonly_token' => 6, // Offset from the T_FUNCTION token. + 'readonly_token' => 6, 'comma_token' => 12, ]; $expected[1] = [ - 'token' => 23, // Offset from the T_FUNCTION token. + 'token' => 23, 'name' => '$promotedToo', 'content' => 'ReadOnly private string|bool &$promotedToo', 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 22, // Offset from the T_FUNCTION token. + 'reference_token' => 22, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'string|bool', - 'type_hint_token' => 18, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 20, // Offset from the T_FUNCTION token. + 'type_hint_token' => 18, + 'type_hint_end_token' => 20, 'nullable_type' => false, 'property_visibility' => 'private', - 'visibility_token' => 16, // Offset from the T_FUNCTION token. + 'visibility_token' => 16, 'property_readonly' => true, - 'readonly_token' => 14, // Offset from the T_FUNCTION token. + 'readonly_token' => 14, 'comma_token' => false, ]; @@ -1969,9 +2010,10 @@ public function testPHP81ConstructorPropertyPromotionWithReadOnly() */ public function testPHP81ConstructorPropertyPromotionWithReadOnlyNoTypeDeclaration() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$promotedProp', 'content' => 'public readonly $promotedProp', 'has_attributes' => false, @@ -1984,18 +2026,18 @@ public function testPHP81ConstructorPropertyPromotionWithReadOnlyNoTypeDeclarati 'type_hint_end_token' => false, 'nullable_type' => false, 'property_visibility' => 'public', - 'visibility_token' => 4, // Offset from the T_FUNCTION token. + 'visibility_token' => 4, 'property_readonly' => true, - 'readonly_token' => 6, // Offset from the T_FUNCTION token. + 'readonly_token' => 6, 'comma_token' => 9, ]; $expected[1] = [ - 'token' => 16, // Offset from the T_FUNCTION token. + 'token' => 16, 'name' => '$promotedToo', 'content' => 'ReadOnly private &$promotedToo', 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 15, // Offset from the T_FUNCTION token. + 'reference_token' => 15, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '', @@ -2003,9 +2045,9 @@ public function testPHP81ConstructorPropertyPromotionWithReadOnlyNoTypeDeclarati 'type_hint_end_token' => false, 'nullable_type' => false, 'property_visibility' => 'private', - 'visibility_token' => 13, // Offset from the T_FUNCTION token. + 'visibility_token' => 13, 'property_readonly' => true, - 'readonly_token' => 11, // Offset from the T_FUNCTION token. + 'readonly_token' => 11, 'comma_token' => false, ]; @@ -2020,9 +2062,10 @@ public function testPHP81ConstructorPropertyPromotionWithReadOnlyNoTypeDeclarati */ public function testPHP81ConstructorPropertyPromotionWithOnlyReadOnly() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 10, // Offset from the T_FUNCTION token. + 'token' => 10, 'name' => '$promotedProp', 'content' => 'readonly Foo&Bar $promotedProp', 'has_attributes' => false, @@ -2031,17 +2074,17 @@ public function testPHP81ConstructorPropertyPromotionWithOnlyReadOnly() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'Foo&Bar', - 'type_hint_token' => 6, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 8, // Offset from the T_FUNCTION token. + 'type_hint_token' => 6, + 'type_hint_end_token' => 8, 'nullable_type' => false, 'property_visibility' => 'public', 'visibility_token' => false, 'property_readonly' => true, - 'readonly_token' => 4, // Offset from the T_FUNCTION token. + 'readonly_token' => 4, 'comma_token' => 11, ]; $expected[1] = [ - 'token' => 18, // Offset from the T_FUNCTION token. + 'token' => 18, 'name' => '$promotedToo', 'content' => 'readonly ?bool $promotedToo', 'has_attributes' => false, @@ -2050,13 +2093,13 @@ public function testPHP81ConstructorPropertyPromotionWithOnlyReadOnly() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?bool', - 'type_hint_token' => 16, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 16, // Offset from the T_FUNCTION token. + 'type_hint_token' => 16, + 'type_hint_end_token' => 16, 'nullable_type' => true, 'property_visibility' => 'public', 'visibility_token' => false, 'property_readonly' => true, - 'readonly_token' => 13, // Offset from the T_FUNCTION token. + 'readonly_token' => 13, 'comma_token' => 19, ]; @@ -2070,9 +2113,10 @@ public function testPHP81ConstructorPropertyPromotionWithOnlyReadOnly() */ public function testPHP8ConstructorPropertyPromotionGlobalFunction() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 6, // Offset from the T_FUNCTION token. + 'token' => 6, 'name' => '$x', 'content' => 'private $x', 'has_attributes' => false, @@ -2085,7 +2129,7 @@ public function testPHP8ConstructorPropertyPromotionGlobalFunction() 'type_hint_end_token' => false, 'nullable_type' => false, 'property_visibility' => 'private', - 'visibility_token' => 4, // Offset from the T_FUNCTION token. + 'visibility_token' => 4, 'property_readonly' => false, 'comma_token' => false, ]; @@ -2100,9 +2144,10 @@ public function testPHP8ConstructorPropertyPromotionGlobalFunction() */ public function testPHP8ConstructorPropertyPromotionAbstractMethod() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$y', 'content' => 'public callable $y', 'has_attributes' => false, @@ -2111,29 +2156,29 @@ public function testPHP8ConstructorPropertyPromotionAbstractMethod() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'callable', - 'type_hint_token' => 6, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. + 'type_hint_token' => 6, + 'type_hint_end_token' => 6, 'nullable_type' => false, 'property_visibility' => 'public', - 'visibility_token' => 4, // Offset from the T_FUNCTION token. + 'visibility_token' => 4, 'property_readonly' => false, 'comma_token' => 9, ]; $expected[1] = [ - 'token' => 14, // Offset from the T_FUNCTION token. + 'token' => 14, 'name' => '$x', 'content' => 'private ...$x', 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => true, - 'variadic_token' => 13, // Offset from the T_FUNCTION token. + 'variadic_token' => 13, 'type_hint' => '', 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, 'property_visibility' => 'private', - 'visibility_token' => 11, // Offset from the T_FUNCTION token. + 'visibility_token' => 11, 'property_readonly' => false, 'comma_token' => false, ]; @@ -2148,23 +2193,24 @@ public function testPHP8ConstructorPropertyPromotionAbstractMethod() */ public function testCommentsInParameter() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 19, // Offset from the T_FUNCTION token. + 'token' => 19, 'name' => '$param', 'content' => '// Leading comment. ?MyClass /*-*/ & /*-*/.../*-*/ $param /*-*/ = /*-*/ \'default value\' . /*-*/ \'second part\' // Trailing comment.', 'default' => '\'default value\' . /*-*/ \'second part\' // Trailing comment.', - 'default_token' => 27, // Offset from the T_FUNCTION token. - 'default_equal_token' => 23, // Offset from the T_FUNCTION token. + 'default_token' => 27, + 'default_equal_token' => 23, 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 13, // Offset from the T_FUNCTION token. + 'reference_token' => 13, 'variable_length' => true, - 'variadic_token' => 16, // Offset from the T_FUNCTION token. + 'variadic_token' => 16, 'type_hint' => '?MyClass', - 'type_hint_token' => 9, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 9, // Offset from the T_FUNCTION token. + 'type_hint_token' => 9, + 'type_hint_end_token' => 9, 'nullable_type' => true, 'comma_token' => false, ]; @@ -2181,9 +2227,10 @@ public function testParameterAttributesInFunctionDeclaration() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => ($php8Names === true) ? 14 : 17, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 14 : 17, 'name' => '$constructorPropPromTypedParamSingleAttribute', 'content' => '#[\MyExample\MyAttribute] private string' . ' $constructorPropPromTypedParamSingleAttribute', @@ -2193,16 +2240,16 @@ public function testParameterAttributesInFunctionDeclaration() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'string', - 'type_hint_token' => ($php8Names === true) ? 12 : 15, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => ($php8Names === true) ? 12 : 15, // Offset from the T_FUNCTION token. + 'type_hint_token' => ($php8Names === true) ? 12 : 15, + 'type_hint_end_token' => ($php8Names === true) ? 12 : 15, 'nullable_type' => false, 'property_visibility' => 'private', - 'visibility_token' => ($php8Names === true) ? 10 : 13, // Offset from the T_FUNCTION token. + 'visibility_token' => ($php8Names === true) ? 10 : 13, 'property_readonly' => false, - 'comma_token' => ($php8Names === true) ? 15 : 18, // Offset from the T_FUNCTION token. + 'comma_token' => ($php8Names === true) ? 15 : 18, ]; $expected[1] = [ - 'token' => ($php8Names === true) ? 36 : 39, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 36 : 39, 'name' => '$typedParamSingleAttribute', 'content' => '#[MyAttr([1, 2])] Type|false @@ -2213,13 +2260,13 @@ public function testParameterAttributesInFunctionDeclaration() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'Type|false', - 'type_hint_token' => ($php8Names === true) ? 31 : 34, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => ($php8Names === true) ? 33 : 36, // Offset from the T_FUNCTION token. + 'type_hint_token' => ($php8Names === true) ? 31 : 34, + 'type_hint_end_token' => ($php8Names === true) ? 33 : 36, 'nullable_type' => false, - 'comma_token' => ($php8Names === true) ? 37 : 40, // Offset from the T_FUNCTION token. + 'comma_token' => ($php8Names === true) ? 37 : 40, ]; $expected[2] = [ - 'token' => ($php8Names === true) ? 56 : 59, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 56 : 59, 'name' => '$nullableTypedParamMultiAttribute', 'content' => '#[MyAttribute(1234), MyAttribute(5678)] ?int $nullableTypedParamMultiAttribute', 'has_attributes' => true, @@ -2228,13 +2275,13 @@ public function testParameterAttributesInFunctionDeclaration() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?int', - 'type_hint_token' => ($php8Names === true) ? 54 : 57, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => ($php8Names === true) ? 54 : 57, // Offset from the T_FUNCTION token. + 'type_hint_token' => ($php8Names === true) ? 54 : 57, + 'type_hint_end_token' => ($php8Names === true) ? 54 : 57, 'nullable_type' => true, - 'comma_token' => ($php8Names === true) ? 57 : 60, // Offset from the T_FUNCTION token. + 'comma_token' => ($php8Names === true) ? 57 : 60, ]; $expected[3] = [ - 'token' => ($php8Names === true) ? 71 : 74, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 71 : 74, 'name' => '$nonTypedParamTwoAttributes', 'content' => '#[WithoutArgument] #[SingleArgument(0)] $nonTypedParamTwoAttributes', 'has_attributes' => true, @@ -2246,23 +2293,23 @@ public function testParameterAttributesInFunctionDeclaration() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => ($php8Names === true) ? 72 : 75, // Offset from the T_FUNCTION token. + 'comma_token' => ($php8Names === true) ? 72 : 75, ]; $expected[4] = [ - 'token' => ($php8Names === true) ? 92 : 95, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 92 : 95, 'name' => '$otherParam', 'content' => '#[MyAttribute(array("key" => "value"))] &...$otherParam', 'has_attributes' => true, 'pass_by_reference' => true, - 'reference_token' => ($php8Names === true) ? 90 : 93, // Offset from the T_FUNCTION token. + 'reference_token' => ($php8Names === true) ? 90 : 93, 'variable_length' => true, - 'variadic_token' => ($php8Names === true) ? 91 : 94, // Offset from the T_FUNCTION token. + 'variadic_token' => ($php8Names === true) ? 91 : 94, 'type_hint' => '', 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => ($php8Names === true) ? 93 : 96, // Offset from the T_FUNCTION token. + 'comma_token' => ($php8Names === true) ? 93 : 96, ]; $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); @@ -2275,9 +2322,10 @@ public function testParameterAttributesInFunctionDeclaration() */ public function testPHP8IntersectionTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$obj1', 'content' => 'Foo&Bar $obj1', 'has_attributes' => false, @@ -2286,13 +2334,13 @@ public function testPHP8IntersectionTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'Foo&Bar', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 6, 'nullable_type' => false, 'comma_token' => 9, ]; $expected[1] = [ - 'token' => 15, // Offset from the T_FUNCTION token. + 'token' => 15, 'name' => '$obj2', 'content' => 'Boo&Bar $obj2', 'has_attributes' => false, @@ -2301,8 +2349,8 @@ public function testPHP8IntersectionTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'Boo&Bar', - 'type_hint_token' => 11, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 13, // Offset from the T_FUNCTION token. + 'type_hint_token' => 11, + 'type_hint_end_token' => 13, 'nullable_type' => false, 'comma_token' => false, ]; @@ -2318,34 +2366,35 @@ public function testPHP8IntersectionTypes() */ public function testPHP81IntersectionTypesWithSpreadOperatorAndReference() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 9, // Offset from the T_FUNCTION token. + 'token' => 9, 'name' => '$paramA', 'content' => 'Boo&Bar &$paramA', 'has_attributes' => false, 'pass_by_reference' => true, - 'reference_token' => 8, // Offset from the T_FUNCTION token. + 'reference_token' => 8, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'Boo&Bar', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 6, 'nullable_type' => false, 'comma_token' => 10, ]; $expected[1] = [ - 'token' => 17, // Offset from the T_FUNCTION token. + 'token' => 17, 'name' => '$paramB', 'content' => 'Foo&Bar ...$paramB', 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => true, - 'variadic_token' => 16, // Offset from the T_FUNCTION token. + 'variadic_token' => 16, 'type_hint' => 'Foo&Bar', - 'type_hint_token' => 12, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 14, // Offset from the T_FUNCTION token. + 'type_hint_token' => 12, + 'type_hint_end_token' => 14, 'nullable_type' => false, 'comma_token' => false, ]; @@ -2362,9 +2411,10 @@ public function testPHP81MoreIntersectionTypes() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => ($php8Names === true) ? 10 : 16, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 10 : 16, 'name' => '$var', 'content' => 'MyClassA&\Package\MyClassB&\Package\MyClassC $var', 'has_attributes' => false, @@ -2373,8 +2423,8 @@ public function testPHP81MoreIntersectionTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'MyClassA&\Package\MyClassB&\Package\MyClassC', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => ($php8Names === true) ? 8 : 14, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => ($php8Names === true) ? 8 : 14, 'nullable_type' => false, 'comma_token' => false, ]; @@ -2389,9 +2439,10 @@ public function testPHP81MoreIntersectionTypes() */ public function testPHP81IllegalIntersectionTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 7, // Offset from the T_FUNCTION token. + 'token' => 7, 'name' => '$numeric_string', 'content' => 'string&int $numeric_string', 'has_attributes' => false, @@ -2400,8 +2451,8 @@ public function testPHP81IllegalIntersectionTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'string&int', - 'type_hint_token' => 3, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 5, // Offset from the T_FUNCTION token. + 'type_hint_token' => 3, + 'type_hint_end_token' => 5, 'nullable_type' => false, 'comma_token' => false, ]; @@ -2416,9 +2467,10 @@ public function testPHP81IllegalIntersectionTypes() */ public function testPHP81NullableIntersectionTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$object', 'content' => '?Foo&Bar $object', 'has_attributes' => false, @@ -2427,8 +2479,8 @@ public function testPHP81NullableIntersectionTypes() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?Foo&Bar', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 6, 'nullable_type' => true, 'comma_token' => false, ]; @@ -2436,6 +2488,68 @@ public function testPHP81NullableIntersectionTypes() $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } + /** + * Verify recognition of PHP 8.2 stand-alone `true` type. + * + * @return void + */ + public function testPHP82PseudoTypeTrue() + { + // Offsets are relative to the T_FUNCTION token. + $expected = []; + $expected[0] = [ + 'token' => 7, + 'name' => '$var', + 'content' => '?true $var = true', + 'default' => 'true', + 'default_token' => 11, + 'default_equal_token' => 9, + 'has_attributes' => false, + 'pass_by_reference' => false, + 'reference_token' => false, + 'variable_length' => false, + 'variadic_token' => false, + 'type_hint' => '?true', + 'type_hint_token' => 5, + 'type_hint_end_token' => 5, + 'nullable_type' => true, + 'comma_token' => false, + ]; + + $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Verify recognition of PHP 8.2 type declaration with (illegal) type false combined with type true. + * + * @return void + */ + public function testPHP82PseudoTypeFalseAndTrue() + { + // Offsets are relative to the T_FUNCTION token. + $expected = []; + $expected[0] = [ + 'token' => 8, + 'name' => '$var', + 'content' => 'true|false $var = true', + 'default' => 'true', + 'default_token' => 12, + 'default_equal_token' => 10, + 'has_attributes' => false, + 'pass_by_reference' => false, + 'reference_token' => false, + 'variable_length' => false, + 'variadic_token' => false, + 'type_hint' => 'true|false', + 'type_hint_token' => 4, + 'type_hint_end_token' => 6, + 'nullable_type' => false, + 'comma_token' => false, + ]; + + $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + /** * Verify behaviour when the default value uses the "new" keyword, as is allowed per PHP 8.1. * @@ -2445,40 +2559,41 @@ public function testPHP81NewInInitializers() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$new', 'content' => 'TypeA $new = new TypeA(self::CONST_VALUE)', 'default' => 'new TypeA(self::CONST_VALUE)', - 'default_token' => 12, // Offset from the T_FUNCTION token. - 'default_equal_token' => 10, // Offset from the T_FUNCTION token. + 'default_token' => 12, + 'default_equal_token' => 10, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => 'TypeA', - 'type_hint_token' => 6, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. + 'type_hint_token' => 6, + 'type_hint_end_token' => 6, 'nullable_type' => false, 'comma_token' => 20, ]; $expected[1] = [ - 'token' => ($php8Names === true) ? 25 : 28, // Offset from the T_FUNCTION token. + 'token' => ($php8Names === true) ? 25 : 28, 'name' => '$newToo', 'content' => '\Package\TypeB $newToo = new \Package\TypeB(10, \'string\')', 'default' => "new \Package\TypeB(10, 'string')", - 'default_token' => ($php8Names === true) ? 29 : 32, // Offset from the T_FUNCTION token. - 'default_equal_token' => ($php8Names === true) ? 27 : 30, // Offset from the T_FUNCTION token. + 'default_token' => ($php8Names === true) ? 29 : 32, + 'default_equal_token' => ($php8Names === true) ? 27 : 30, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '\Package\TypeB', - 'type_hint_token' => 23, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => ($php8Names === true) ? 23 : 26, // Offset from the T_FUNCTION token. + 'type_hint_token' => 23, + 'type_hint_end_token' => ($php8Names === true) ? 23 : 26, 'nullable_type' => false, 'comma_token' => ($php8Names === true) ? 38 : 44, ]; @@ -2486,6 +2601,157 @@ public function testPHP81NewInInitializers() $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } + /** + * Verify recognition of 8.2 DNF parameter type declarations. + * + * @return void + */ + public function testPHP82DNFTypes() + { + $php8Names = parent::usesPhp8NameTokens(); + + // Offsets are relative to the T_FUNCTION token. + $expected = []; + $expected[0] = [ + 'token' => 21, + 'name' => '$obj1', + 'content' => '#[MyAttribute] + false|(Foo&Bar)|true $obj1', + 'has_attributes' => true, + 'pass_by_reference' => false, + 'reference_token' => false, + 'variable_length' => false, + 'variadic_token' => false, + 'type_hint' => 'false|(Foo&Bar)|true', + 'type_hint_token' => 11, + 'type_hint_end_token' => 19, + 'nullable_type' => false, + 'comma_token' => 22, + ]; + $expected[1] = [ + 'token' => ($php8Names === true) ? 37 : 41, + 'name' => '$obj2', + 'content' => '(\Boo&\Pck\Bar)|(Boo&Baz) $obj2 = new Boo()', + 'default' => 'new Boo()', + 'default_token' => ($php8Names === true) ? 41 : 45, + 'default_equal_token' => ($php8Names === true) ? 39 : 43, + 'has_attributes' => false, + 'pass_by_reference' => false, + 'reference_token' => false, + 'variable_length' => false, + 'variadic_token' => false, + 'type_hint' => '(\Boo&\Pck\Bar)|(Boo&Baz)', + 'type_hint_token' => 25, + 'type_hint_end_token' => ($php8Names === true) ? 35 : 39, + 'nullable_type' => false, + 'comma_token' => false, + ]; + + $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Verify recognition of PHP 8.2 DNF parameter type declarations when the variable + * has either a spread operator or a reference. + * + * @return void + */ + public function testPHP82DNFTypesWithSpreadOperatorAndReference() + { + // Offsets are relative to the T_FUNCTION token. + $expected = []; + $expected[0] = [ + 'token' => 13, + 'name' => '$paramA', + 'content' => '(Countable&MeMe)|iterable &$paramA', + 'has_attributes' => false, + 'pass_by_reference' => true, + 'reference_token' => 12, + 'variable_length' => false, + 'variadic_token' => false, + 'type_hint' => '(Countable&MeMe)|iterable', + 'type_hint_token' => 4, + 'type_hint_end_token' => 10, + 'nullable_type' => false, + 'comma_token' => 14, + ]; + $expected[1] = [ + 'token' => 25, + 'name' => '$paramB', + 'content' => 'true|(Foo&Bar) ...$paramB', + 'has_attributes' => false, + 'pass_by_reference' => false, + 'reference_token' => false, + 'variable_length' => true, + 'variadic_token' => 24, + 'type_hint' => 'true|(Foo&Bar)', + 'type_hint_token' => 16, + 'type_hint_end_token' => 22, + 'nullable_type' => false, + 'comma_token' => false, + ]; + + $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Verify recognition of PHP 8.2 DNF parameter type declarations using the nullability operator (not allowed). + * + * @return void + */ + public function testPHP82DNFTypesIllegalNullable() + { + $php8Names = parent::usesPhp8NameTokens(); + + // Offsets are relative to the T_FUNCTION token. + $expected = []; + $expected[0] = [ + 'token' => ($php8Names === true) ? 21 : 27, + 'name' => '$var', + 'content' => '? ( MyClassA & /*comment*/ \Package\MyClassB & \Package\MyClassC ) $var', + 'has_attributes' => false, + 'pass_by_reference' => false, + 'reference_token' => false, + 'variable_length' => false, + 'variadic_token' => false, + 'type_hint' => '?(MyClassA&\Package\MyClassB&\Package\MyClassC)', + 'type_hint_token' => 5, + 'type_hint_end_token' => ($php8Names === true) ? 19 : 25, + 'nullable_type' => true, + 'comma_token' => false, + ]; + + $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Verify recognition of PHP 8.2 DNF parameter type declarations in an arrow function. + * + * @return void + */ + public function testPHP82DNFTypesInArrow() + { + // Offsets are relative to the T_FUNCTION token. + $expected = []; + $expected[0] = [ + 'token' => 12, + 'name' => '$range', + 'content' => '(Hi&Ho)|FALSE &...$range', + 'has_attributes' => false, + 'pass_by_reference' => true, + 'reference_token' => 10, + 'variable_length' => true, + 'variadic_token' => 11, + 'type_hint' => '(Hi&Ho)|FALSE', + 'type_hint_token' => 2, + 'type_hint_end_token' => 8, + 'nullable_type' => false, + 'comma_token' => false, + ]; + + $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + /** * Verify handling of a closure. * @@ -2493,14 +2759,15 @@ public function testPHP81NewInInitializers() */ public function testClosure() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 3, // Offset from the T_FUNCTION token. + 'token' => 3, 'name' => '$a', 'content' => '$a = \'test\'', 'default' => "'test'", - 'default_token' => 7, // Offset from the T_FUNCTION token. - 'default_equal_token' => 5, // Offset from the T_FUNCTION token. + 'default_token' => 7, + 'default_equal_token' => 5, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -2523,9 +2790,10 @@ public function testClosure() */ public function testClosureUse() { + // Offsets are relative to the T_USE token. $expected = []; $expected[0] = [ - 'token' => 3, // Offset from the T_USE token. + 'token' => 3, 'name' => '$foo', 'content' => '$foo', 'has_attributes' => false, @@ -2537,10 +2805,10 @@ public function testClosureUse() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 4, // Offset from the T_USE token. + 'comma_token' => 4, ]; $expected[1] = [ - 'token' => 6, // Offset from the T_USE token. + 'token' => 6, 'name' => '$bar', 'content' => '$bar', 'has_attributes' => false, @@ -2565,9 +2833,10 @@ public function testClosureUse() */ public function testFunctionParamListWithTrailingComma() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 9, // Offset from the T_FUNCTION token. + 'token' => 9, 'name' => '$foo', 'content' => '?string $foo /*comment*/', 'has_attributes' => false, @@ -2576,18 +2845,18 @@ public function testFunctionParamListWithTrailingComma() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?string', - 'type_hint_token' => 7, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 7, // Offset from the T_FUNCTION token. + 'type_hint_token' => 7, + 'type_hint_end_token' => 7, 'nullable_type' => true, - 'comma_token' => 13, // Offset from the T_FUNCTION token. + 'comma_token' => 13, ]; $expected[1] = [ - 'token' => 16, // Offset from the T_FUNCTION token. + 'token' => 16, 'name' => '$bar', 'content' => '$bar = 0', 'default' => '0', - 'default_token' => 20, // Offset from the T_FUNCTION token. - 'default_equal_token' => 18, // Offset from the T_FUNCTION token. + 'default_token' => 20, + 'default_equal_token' => 18, 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, @@ -2597,7 +2866,7 @@ public function testFunctionParamListWithTrailingComma() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 21, // Offset from the T_FUNCTION token. + 'comma_token' => 21, ]; $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); @@ -2610,9 +2879,10 @@ public function testFunctionParamListWithTrailingComma() */ public function testClosureParamListWithTrailingComma() { + // Offsets are relative to the T_FUNCTION token. $expected = []; $expected[0] = [ - 'token' => 4, // Offset from the T_FUNCTION token. + 'token' => 4, 'name' => '$foo', 'content' => '$foo', 'has_attributes' => false, @@ -2624,10 +2894,10 @@ public function testClosureParamListWithTrailingComma() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 5, // Offset from the T_FUNCTION token. + 'comma_token' => 5, ]; $expected[1] = [ - 'token' => 8, // Offset from the T_FUNCTION token. + 'token' => 8, 'name' => '$bar', 'content' => '$bar', 'has_attributes' => false, @@ -2639,7 +2909,7 @@ public function testClosureParamListWithTrailingComma() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 9, // Offset from the T_FUNCTION token. + 'comma_token' => 9, ]; $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); @@ -2652,9 +2922,10 @@ public function testClosureParamListWithTrailingComma() */ public function testArrowFunctionParamListWithTrailingComma() { + // Offsets are relative to the T_FN token. $expected = []; $expected[0] = [ - 'token' => 6, // Offset from the T_FN token. + 'token' => 6, 'name' => '$a', 'content' => '?int $a', 'has_attributes' => false, @@ -2663,25 +2934,25 @@ public function testArrowFunctionParamListWithTrailingComma() 'variable_length' => false, 'variadic_token' => false, 'type_hint' => '?int', - 'type_hint_token' => 4, // Offset from the T_FN token. - 'type_hint_end_token' => 4, // Offset from the T_FN token. + 'type_hint_token' => 4, + 'type_hint_end_token' => 4, 'nullable_type' => true, - 'comma_token' => 8, // Offset from the T_FN token. + 'comma_token' => 8, ]; $expected[1] = [ - 'token' => 11, // Offset from the T_FN token. + 'token' => 11, 'name' => '$b', 'content' => '...$b', 'has_attributes' => false, 'pass_by_reference' => false, 'reference_token' => false, 'variable_length' => true, - 'variadic_token' => 10, // Offset from the T_FN token. + 'variadic_token' => 10, 'type_hint' => '', 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 12, // Offset from the T_FN token. + 'comma_token' => 12, ]; $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); @@ -2694,9 +2965,10 @@ public function testArrowFunctionParamListWithTrailingComma() */ public function testClosureUseWithTrailingComma() { + // Offsets are relative to the T_USE token. $expected = []; $expected[0] = [ - 'token' => 4, // Offset from the T_USE token. + 'token' => 4, 'name' => '$foo', 'content' => '$foo /*comment*/', 'has_attributes' => false, @@ -2708,10 +2980,10 @@ public function testClosureUseWithTrailingComma() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 8, // Offset from the T_USE token. + 'comma_token' => 8, ]; $expected[1] = [ - 'token' => 11, // Offset from the T_USE token. + 'token' => 11, 'name' => '$bar', 'content' => '$bar', 'has_attributes' => false, @@ -2723,7 +2995,7 @@ public function testClosureUseWithTrailingComma() 'type_hint_token' => false, 'type_hint_end_token' => false, 'nullable_type' => false, - 'comma_token' => 12, // Offset from the T_USE token. + 'comma_token' => 12, ]; $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected, [T_USE]); @@ -2732,10 +3004,10 @@ public function testClosureUseWithTrailingComma() /** * Test helper. * - * @param string $marker The comment which preceeds the test. - * @param array $expected The expected function output. - * @param array $targetType Optional. The token type to search for after $marker. - * Defaults to the function/closure/arrow tokens. + * @param string $marker The comment which preceeds the test. + * @param array> $expected The expected function output. + * @param int|string|array $targetType Optional. The token type to search for after $marker. + * Defaults to the function/closure/arrow tokens. * * @return void */ @@ -2744,22 +3016,23 @@ protected function getMethodParametersTestHelper($marker, $expected, $targetType $target = $this->getTargetToken($marker, $targetType); $found = BCFile::getMethodParameters(self::$phpcsFile, $target); + // Convert offsets to absolute positions in the token stream. foreach ($expected as $key => $param) { $expected[$key]['token'] += $target; - if ($param['reference_token'] !== false) { + if (\is_int($param['reference_token']) === true) { $expected[$key]['reference_token'] += $target; } - if ($param['variadic_token'] !== false) { + if (\is_int($param['variadic_token']) === true) { $expected[$key]['variadic_token'] += $target; } - if ($param['type_hint_token'] !== false) { + if (\is_int($param['type_hint_token']) === true) { $expected[$key]['type_hint_token'] += $target; } - if ($param['type_hint_end_token'] !== false) { + if (\is_int($param['type_hint_end_token']) === true) { $expected[$key]['type_hint_end_token'] += $target; } - if ($param['comma_token'] !== false) { + if (\is_int($param['comma_token']) === true) { $expected[$key]['comma_token'] += $target; } if (isset($param['default_token'])) { @@ -2768,7 +3041,7 @@ protected function getMethodParametersTestHelper($marker, $expected, $targetType if (isset($param['default_equal_token'])) { $expected[$key]['default_equal_token'] += $target; } - if (isset($param['visibility_token']) && $param['visibility_token'] !== false) { + if (isset($param['visibility_token']) && \is_int($param['visibility_token']) === true) { $expected[$key]['visibility_token'] += $target; } if (isset($param['readonly_token'])) { diff --git a/Tests/BackCompat/BCFile/GetMethodPropertiesParseError1Test.inc b/Tests/BackCompat/BCFile/GetMethodPropertiesParseError1Test.inc new file mode 100644 index 00000000..6a2f3065 --- /dev/null +++ b/Tests/BackCompat/BCFile/GetMethodPropertiesParseError1Test.inc @@ -0,0 +1,5 @@ +getTargetToken('/* testParseError */', Collections::functionDeclarationTokens()); + $result = BCFile::getMethodProperties(self::$phpcsFile, $target); + + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => '', + 'return_type_token' => false, + 'return_type_end_token' => false, + 'nullable_return_type' => false, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => false, + ]; + + $this->assertSame($expected, $result); + } +} diff --git a/Tests/BackCompat/BCFile/GetMethodPropertiesTest.inc b/Tests/BackCompat/BCFile/GetMethodPropertiesTest.inc index 3d149e83..cc0322f2 100644 --- a/Tests/BackCompat/BCFile/GetMethodPropertiesTest.inc +++ b/Tests/BackCompat/BCFile/GetMethodPropertiesTest.inc @@ -109,11 +109,11 @@ function unionTypesAllPseudoTypes($var) : false|MIXED|self|parent|static|iterabl $closure = function () use($a) :?int|float {}; /* testPHP8PseudoTypeNull */ -// Intentional fatal error - null pseudotype is only allowed in union types, but that's not the concern of the method. +// PHP 8.0 - 8.1: Intentional fatal error - null pseudotype is only allowed in union types, but that's not the concern of the method. function pseudoTypeNull(): null {} /* testPHP8PseudoTypeFalse */ -// Intentional fatal error - false pseudotype is only allowed in union types, but that's not the concern of the method. +// PHP 8.0 - 8.1: Intentional fatal error - false pseudotype is only allowed in union types, but that's not the concern of the method. function pseudoTypeFalse(): false {} /* testPHP8PseudoTypeFalseAndBool */ @@ -158,6 +158,32 @@ $closure = function (): string&int {}; // Intentional fatal error - nullability is not allowed with intersection types, but that's not the concern of the method. $closure = function (): ?Foo&Bar {}; +/* testPHP82PseudoTypeTrue */ +function pseudoTypeTrue(): ?true {} + +/* testPHP82PseudoTypeFalseAndTrue */ +// Intentional fatal error - Type contains both true and false, bool should be used instead, but that's not the concern of the method. +function pseudoTypeFalseAndTrue(): true|false {} + +/* testPHP82DNFType */ +function hasDNFType() : bool|(Foo&Bar)|string {} + +abstract class AbstractClass { + /* testPHP82DNFTypeAbstractMethod */ + abstract protected function abstractMethodDNFType() : float|(Foo&Bar); +} + +/* testPHP82DNFTypeIllegalNullable */ +// Intentional fatal error - nullable operator cannot be combined with DNF. +function illegalNullableDNF(): ?(A&\Pck\B)|bool {} + +/* testPHP82DNFTypeClosure */ +$closure = function() : object|(namespace\Foo&Countable) {}; + +/* testPHP82DNFTypeFn */ +// Intentional fatal error - void type cannot be combined with DNF. +$arrow = fn() : null|(Partially\Qualified&Traversable)|void => do_something(); + /* testNotAFunction */ return true; @@ -178,6 +204,18 @@ $value = $obj->fn(true); /* testFunctionDeclarationNestedInTernaryPHPCS2975 */ return (!$a ? [ new class { public function b(): c {} } ] : []); +/* testClosureWithUseNoReturnType */ +$closure = function () use($a) /*comment*/ {}; + +/* testClosureWithUseNoReturnTypeIllegalUseProp */ +$closure = function () use ($this->prop){}; + +/* testClosureWithUseWithReturnType */ +$closure = function () use /*comment*/ ($a): Type {}; + +/* testClosureWithUseMultiParamWithReturnType */ +$closure = function () use ($a, &$b, $c, $d, $e, $f, $g): ?array {}; + /* testArrowFunctionLiveCoding */ // Intentional parse error. This has to be the last test in the file. $fn = fn diff --git a/Tests/BackCompat/BCFile/GetMethodPropertiesTest.php b/Tests/BackCompat/BCFile/GetMethodPropertiesTest.php index ee20479d..6d698243 100644 --- a/Tests/BackCompat/BCFile/GetMethodPropertiesTest.php +++ b/Tests/BackCompat/BCFile/GetMethodPropertiesTest.php @@ -15,7 +15,7 @@ * @author Juliette Reinders Folmer * * @copyright 2018-2019 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */ namespace PHPCSUtils\Tests\BackCompat\BCFile; @@ -40,8 +40,8 @@ class GetMethodPropertiesTest extends UtilityMethodTestCase * * @dataProvider dataNotAFunctionException * - * @param string $commentString The comment which preceeds the test. - * @param array $targetTokenType The token type to search for after $commentString. + * @param string $commentString The comment which preceeds the test. + * @param int|string|array $targetTokenType The token type to search for after $commentString. * * @return void */ @@ -58,22 +58,22 @@ public function testNotAFunctionException($commentString, $targetTokenType) * * @see testNotAFunctionException() For the array format. * - * @return array + * @return array>> */ - public function dataNotAFunctionException() + public static function dataNotAFunctionException() { return [ 'return' => [ - '/* testNotAFunction */', - T_RETURN, + 'commentString' => '/* testNotAFunction */', + 'targetTokenType' => T_RETURN, ], 'function-call-fn-phpcs-3.5.3-3.5.4' => [ - '/* testFunctionCallFnPHPCS353-354 */', - [T_FN, T_STRING], + 'commentString' => '/* testFunctionCallFnPHPCS353-354 */', + 'targetTokenType' => [T_FN, T_STRING], ], 'fn-live-coding' => [ - '/* testArrowFunctionLiveCoding */', - [T_FN, T_STRING], + 'commentString' => '/* testArrowFunctionLiveCoding */', + 'targetTokenType' => [T_FN, T_STRING], ], ]; } @@ -108,12 +108,13 @@ public function testBasicFunction() */ public function testReturnFunction() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'array', - 'return_type_token' => 11, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 11, // Offset from the T_FUNCTION token. + 'return_type_token' => 11, + 'return_type_end_token' => 11, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -131,12 +132,13 @@ public function testReturnFunction() */ public function testNestedClosure() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'int', - 'return_type_token' => 8, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 8, // Offset from the T_FUNCTION token. + 'return_type_token' => 8, + 'return_type_end_token' => 8, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -223,12 +225,13 @@ public function testFinalMethod() */ public function testProtectedReturnMethod() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'protected', 'scope_specified' => true, 'return_type' => 'int', - 'return_type_token' => 8, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 8, // Offset from the T_FUNCTION token. + 'return_type_token' => 8, + 'return_type_end_token' => 8, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -246,12 +249,13 @@ public function testProtectedReturnMethod() */ public function testPublicReturnMethod() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => true, 'return_type' => 'array', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 7, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 7, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -269,12 +273,13 @@ public function testPublicReturnMethod() */ public function testNullableReturnMethod() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => true, 'return_type' => '?array', - 'return_type_token' => 8, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 8, // Offset from the T_FUNCTION token. + 'return_type_token' => 8, + 'return_type_end_token' => 8, 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, @@ -292,12 +297,13 @@ public function testNullableReturnMethod() */ public function testMessyNullableReturnMethod() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => true, 'return_type' => '?array', - 'return_type_token' => 18, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 18, // Offset from the T_FUNCTION token. + 'return_type_token' => 18, + 'return_type_end_token' => 18, 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, @@ -317,12 +323,13 @@ public function testReturnNamespace() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '\MyNamespace\MyClass', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => ($php8Names === true) ? 7 : 10, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => ($php8Names === true) ? 7 : 10, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -342,12 +349,13 @@ public function testReturnMultilineNamespace() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '\MyNamespace\MyClass\Foo', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => ($php8Names === true) ? 20 : 23, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => ($php8Names === true) ? 20 : 23, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -365,12 +373,13 @@ public function testReturnMultilineNamespace() */ public function testReturnUnqualifiedName() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'private', 'scope_specified' => true, 'return_type' => '?MyClass', - 'return_type_token' => 8, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 8, // Offset from the T_FUNCTION token. + 'return_type_token' => 8, + 'return_type_end_token' => 8, 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, @@ -390,12 +399,13 @@ public function testReturnPartiallyQualifiedName() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'Sub\Level\MyClass', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => ($php8Names === true) ? 7 : 11, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => ($php8Names === true) ? 7 : 11, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -436,12 +446,13 @@ public function testAbstractMethod() */ public function testAbstractReturnMethod() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'protected', 'scope_specified' => true, 'return_type' => 'bool', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 7, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 7, 'nullable_return_type' => false, 'is_abstract' => true, 'is_final' => false, @@ -482,12 +493,13 @@ public function testInterfaceMethod() */ public function testArrowFunction() { + // Offsets are relative to the T_FN token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'int', - 'return_type_token' => 9, // Offset from the T_FN token. - 'return_type_end_token' => 9, // Offset from the T_FN token. + 'return_type_token' => 9, + 'return_type_end_token' => 9, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -505,12 +517,13 @@ public function testArrowFunction() */ public function testReturnTypeStatic() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'private', 'scope_specified' => true, 'return_type' => 'static', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 7, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 7, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -528,12 +541,13 @@ public function testReturnTypeStatic() */ public function testPHP8MixedTypeHint() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'mixed', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 7, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 7, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -551,12 +565,13 @@ public function testPHP8MixedTypeHint() */ public function testPHP8MixedTypeHintNullable() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '?mixed', - 'return_type_token' => 8, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 8, // Offset from the T_FUNCTION token. + 'return_type_token' => 8, + 'return_type_end_token' => 8, 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, @@ -576,12 +591,13 @@ public function testNamespaceOperatorTypeHint() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '?namespace\Name', - 'return_type_token' => 9, // Offset from the T_FUNCTION token. - 'return_type_end_token' => ($php8Names === true) ? 9 : 11, // Offset from the T_FUNCTION token. + 'return_type_token' => 9, + 'return_type_end_token' => ($php8Names === true) ? 9 : 11, 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, @@ -599,12 +615,13 @@ public function testNamespaceOperatorTypeHint() */ public function testPHP8UnionTypesSimple() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'int|float', - 'return_type_token' => 9, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 11, // Offset from the T_FUNCTION token. + 'return_type_token' => 9, + 'return_type_end_token' => 11, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -624,12 +641,13 @@ public function testPHP8UnionTypesTwoClasses() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'MyClassA|\Package\MyClassB', - 'return_type_token' => 6, // Offset from the T_FUNCTION token. - 'return_type_end_token' => ($php8Names === true) ? 8 : 11, // Offset from the T_FUNCTION token. + 'return_type_token' => 6, + 'return_type_end_token' => ($php8Names === true) ? 8 : 11, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -647,12 +665,13 @@ public function testPHP8UnionTypesTwoClasses() */ public function testPHP8UnionTypesAllBaseTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'array|bool|callable|int|float|null|Object|string', - 'return_type_token' => 8, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 22, // Offset from the T_FUNCTION token. + 'return_type_token' => 8, + 'return_type_end_token' => 22, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -672,12 +691,13 @@ public function testPHP8UnionTypesAllBaseTypes() */ public function testPHP8UnionTypesAllPseudoTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'false|MIXED|self|parent|static|iterable|Resource|void', - 'return_type_token' => 9, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 23, // Offset from the T_FUNCTION token. + 'return_type_token' => 9, + 'return_type_end_token' => 23, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -695,12 +715,13 @@ public function testPHP8UnionTypesAllPseudoTypes() */ public function testPHP8UnionTypesNullable() { + // Offsets are relative to the T_CLOSURE token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '?int|float', - 'return_type_token' => 12, // Offset from the T_CLOSURE token. - 'return_type_end_token' => 14, // Offset from the T_CLOSURE token. + 'return_type_token' => 12, + 'return_type_end_token' => 14, 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, @@ -718,12 +739,13 @@ public function testPHP8UnionTypesNullable() */ public function testPHP8PseudoTypeNull() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'null', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 7, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 7, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -741,12 +763,13 @@ public function testPHP8PseudoTypeNull() */ public function testPHP8PseudoTypeFalse() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'false', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 7, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 7, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -764,12 +787,13 @@ public function testPHP8PseudoTypeFalse() */ public function testPHP8PseudoTypeFalseAndBool() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'bool|false', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 9, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 9, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -787,12 +811,13 @@ public function testPHP8PseudoTypeFalseAndBool() */ public function testPHP8ObjectAndClass() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'object|ClassName', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 9, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 9, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -810,12 +835,13 @@ public function testPHP8ObjectAndClass() */ public function testPHP8PseudoTypeIterableAndArray() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => true, 'return_type' => 'iterable|array|Traversable', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 11, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 11, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -833,12 +859,13 @@ public function testPHP8PseudoTypeIterableAndArray() */ public function testPHP8DuplicateTypeInUnionWhitespaceAndComment() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'int|string|INT', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 17, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 17, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -856,12 +883,13 @@ public function testPHP8DuplicateTypeInUnionWhitespaceAndComment() */ public function testPHP81NeverType() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'never', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 7, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 7, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -879,12 +907,13 @@ public function testPHP81NeverType() */ public function testPHP81NullableNeverType() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '?never', - 'return_type_token' => 8, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 8, // Offset from the T_FUNCTION token. + 'return_type_token' => 8, + 'return_type_end_token' => 8, 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, @@ -902,12 +931,13 @@ public function testPHP81NullableNeverType() */ public function testPHP8IntersectionTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'Foo&Bar', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 9, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 9, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -927,12 +957,13 @@ public function testPHP81MoreIntersectionTypes() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'MyClassA&\Package\MyClassB&\Package\MyClassC', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => ($php8Names === true) ? 11 : 17, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => ($php8Names === true) ? 11 : 17, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -952,12 +983,13 @@ public function testPHP81IntersectionArrowFunction() { $php8Names = parent::usesPhp8NameTokens(); + // Offsets are relative to the T_FN token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'MyClassA&\Package\MyClassB', - 'return_type_token' => 6, // Offset from the T_FN token. - 'return_type_end_token' => ($php8Names === true) ? 8 : 11, // Offset from the T_FN token. + 'return_type_token' => 6, + 'return_type_end_token' => ($php8Names === true) ? 8 : 11, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -975,12 +1007,13 @@ public function testPHP81IntersectionArrowFunction() */ public function testPHP81IllegalIntersectionTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'string&int', - 'return_type_token' => 6, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 8, // Offset from the T_FUNCTION token. + 'return_type_token' => 6, + 'return_type_end_token' => 8, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -998,12 +1031,13 @@ public function testPHP81IllegalIntersectionTypes() */ public function testPHP81NullableIntersectionTypes() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '?Foo&Bar', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 9, // Offset from the T_FUNCTION token. + 'return_type_token' => 7, + 'return_type_end_token' => 9, 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, @@ -1014,6 +1048,180 @@ public function testPHP81NullableIntersectionTypes() $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } + /** + * Verify recognition of PHP 8.2 stand-alone `true` type. + * + * @return void + */ + public function testPHP82PseudoTypeTrue() + { + // Offsets are relative to the T_FUNCTION token. + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => '?true', + 'return_type_token' => 8, + 'return_type_end_token' => 8, + 'nullable_return_type' => true, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => true, + ]; + + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Verify recognition of PHP 8.2 type declaration with (illegal) type false combined with type true. + * + * @return void + */ + public function testPHP82PseudoTypeFalseAndTrue() + { + // Offsets are relative to the T_FUNCTION token. + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => 'true|false', + 'return_type_token' => 7, + 'return_type_end_token' => 9, + 'nullable_return_type' => false, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => true, + ]; + + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Verify recognition of PHP 8.2 DNF return type declaration. + * + * @return void + */ + public function testPHP82DNFType() + { + // Offsets are relative to the T_FUNCTION token. + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => 'bool|(Foo&Bar)|string', + 'return_type_token' => 8, + 'return_type_end_token' => 16, + 'nullable_return_type' => false, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => true, + ]; + + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Verify recognition of PHP 8.2 DNF return type declaration on an abstract method. + * + * @return void + */ + public function testPHP82DNFTypeAbstractMethod() + { + // Offsets are relative to the T_FUNCTION token. + $expected = [ + 'scope' => 'protected', + 'scope_specified' => true, + 'return_type' => 'float|(Foo&Bar)', + 'return_type_token' => 8, + 'return_type_end_token' => 14, + 'nullable_return_type' => false, + 'is_abstract' => true, + 'is_final' => false, + 'is_static' => false, + 'has_body' => false, + ]; + + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Verify recognition of PHP 8.2 DNF return type declaration with illegal nullability. + * + * @return void + */ + public function testPHP82DNFTypeIllegalNullable() + { + $php8Names = parent::usesPhp8NameTokens(); + + // Offsets are relative to the T_FUNCTION token. + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => '?(A&\Pck\B)|bool', + 'return_type_token' => 8, + 'return_type_end_token' => ($php8Names === true) ? 14 : 17, + 'nullable_return_type' => true, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => true, + ]; + + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Verify recognition of PHP 8.2 DNF return type declaration on a closure. + * + * @return void + */ + public function testPHP82DNFTypeClosure() + { + $php8Names = parent::usesPhp8NameTokens(); + + // Offsets are relative to the T_CLOSURE token. + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => 'object|(namespace\Foo&Countable)', + 'return_type_token' => 6, + 'return_type_end_token' => ($php8Names === true) ? 12 : 14, + 'nullable_return_type' => false, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => true, + ]; + + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Verify recognition of PHP 8.2 DNF return type declaration on an arrow function. + * + * @return void + */ + public function testPHP82DNFTypeFn() + { + $php8Names = parent::usesPhp8NameTokens(); + + // Offsets are relative to the T_FN token. + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => 'null|(Partially\Qualified&Traversable)|void', + 'return_type_token' => 6, + 'return_type_end_token' => ($php8Names === true) ? 14 : 16, + 'nullable_return_type' => false, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => true, + ]; + + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + /** * Test for incorrect tokenization of array return type declarations in PHPCS < 2.8.0. * @@ -1023,12 +1231,13 @@ public function testPHP81NullableIntersectionTypes() */ public function testPhpcsIssue1264() { + // Offsets are relative to the T_FUNCTION token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'array', - 'return_type_token' => 8, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 8, // Offset from the T_FUNCTION token. + 'return_type_token' => 8, + 'return_type_end_token' => 8, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -1049,12 +1258,13 @@ public function testPhpcsIssue1264() */ public function testArrowFunctionArrayReturnValue() { + // Offsets are relative to the T_FN token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'array', - 'return_type_token' => 5, // Offset from the T_FN token. - 'return_type_end_token' => 5, // Offset from the T_FN token. + 'return_type_token' => 5, + 'return_type_end_token' => 5, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -1072,12 +1282,13 @@ public function testArrowFunctionArrayReturnValue() */ public function testArrowFunctionReturnByRef() { + // Offsets are relative to the T_FN token. $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '?string', - 'return_type_token' => 12, // Offset from the T_FN token. - 'return_type_end_token' => 12, // Offset from the T_FN token. + 'return_type_token' => 12, + 'return_type_end_token' => 12, 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, @@ -1096,12 +1307,13 @@ public function testArrowFunctionReturnByRef() */ public function testFunctionDeclarationNestedInTernaryPHPCS2975() { + // Offsets are relative to the T_FN token. $expected = [ 'scope' => 'public', 'scope_specified' => true, 'return_type' => 'c', - 'return_type_token' => 7, // Offset from the T_FN token. - 'return_type_end_token' => 7, // Offset from the T_FN token. + 'return_type_token' => 7, + 'return_type_end_token' => 7, 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, @@ -1112,13 +1324,110 @@ public function testFunctionDeclarationNestedInTernaryPHPCS2975() $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } + /** + * Test handling of closure declarations with a use variable import without a return type declaration. + * + * @return void + */ + public function testClosureWithUseNoReturnType() + { + // Offsets are relative to the T_CLOSURE token. + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => '', + 'return_type_token' => false, + 'return_type_end_token' => false, + 'nullable_return_type' => false, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => true, + ]; + + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Test handling of closure declarations with an illegal use variable for a property import (not allowed in PHP) + * without a return type declaration. + * + * @return void + */ + public function testClosureWithUseNoReturnTypeIllegalUseProp() + { + // Offsets are relative to the T_CLOSURE token. + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => '', + 'return_type_token' => false, + 'return_type_end_token' => false, + 'nullable_return_type' => false, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => true, + ]; + + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Test handling of closure declarations with a use variable import with a return type declaration. + * + * @return void + */ + public function testClosureWithUseWithReturnType() + { + // Offsets are relative to the T_CLOSURE token. + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => 'Type', + 'return_type_token' => 14, + 'return_type_end_token' => 14, + 'nullable_return_type' => false, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => true, + ]; + + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + + /** + * Test handling of closure declarations with a use variable import with a return type declaration. + * + * @return void + */ + public function testClosureWithUseMultiParamWithReturnType() + { + // Offsets are relative to the T_CLOSURE token. + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => '?array', + 'return_type_token' => 32, + 'return_type_end_token' => 32, + 'nullable_return_type' => true, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => true, + ]; + + $this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); + } + /** * Test helper. * - * @param string $commentString The comment which preceeds the test. - * @param array $expected The expected function output. - * @param array $targetType Optional. The token type to search for after $commentString. - * Defaults to the function/closure tokens. + * @param string $commentString The comment which preceeds the test. + * @param array $expected The expected function output. + * @param int|string|array $targetType Optional. The token type to search for after $commentString. + * Defaults to the function/closure tokens. * * @return void */ @@ -1130,10 +1439,11 @@ protected function getMethodPropertiesTestHelper( $function = $this->getTargetToken($commentString, $targetType); $found = BCFile::getMethodProperties(self::$phpcsFile, $function); - if ($expected['return_type_token'] !== false) { + // Convert offsets to absolute positions in the token stream. + if (\is_int($expected['return_type_token']) === true) { $expected['return_type_token'] += $function; } - if ($expected['return_type_end_token'] !== false) { + if (\is_int($expected['return_type_end_token']) === true) { $expected['return_type_end_token'] += $function; } diff --git a/Tests/BackCompat/BCFile/GetTokensAsStringTest.php b/Tests/BackCompat/BCFile/GetTokensAsStringTest.php index b3df5437..d0196fb5 100644 --- a/Tests/BackCompat/BCFile/GetTokensAsStringTest.php +++ b/Tests/BackCompat/BCFile/GetTokensAsStringTest.php @@ -93,12 +93,12 @@ public function testLengthBeyondEndOfFile() /** * Test getting a token set as a string. * - * @dataProvider dataGetTokensAsString() + * @dataProvider dataGetTokensAsString * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $startTokenType The type of token(s) to look for for the start of the string. - * @param int $length Token length to get. - * @param string $expected The expected function return value. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $startTokenType The type of token(s) to look for for the start of the string. + * @param int $length Token length to get. + * @param string $expected The expected function return value. * * @return void */ @@ -114,151 +114,151 @@ public function testGetTokensAsString($testMarker, $startTokenType, $length, $ex * * @see testGetTokensAsString() For the array format. * - * @return array + * @return array> */ - public function dataGetTokensAsString() + public static function dataGetTokensAsString() { $php8Names = parent::usesPhp8NameTokens(); return [ 'length-0' => [ - '/* testCalculation */', - \T_LNUMBER, - 0, - '', + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 0, + 'expected' => '', ], 'length-1' => [ - '/* testCalculation */', - \T_LNUMBER, - 1, - '1', + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 1, + 'expected' => '1', ], 'length-2' => [ - '/* testCalculation */', - \T_LNUMBER, - 2, - '1 ', + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 2, + 'expected' => '1 ', ], 'length-3' => [ - '/* testCalculation */', - \T_LNUMBER, - 3, - '1 +', + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 3, + 'expected' => '1 +', ], 'length-4' => [ - '/* testCalculation */', - \T_LNUMBER, - 4, - '1 + ', + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 4, + 'expected' => '1 + ', ], 'length-5' => [ - '/* testCalculation */', - \T_LNUMBER, - 5, - '1 + 2', + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 5, + 'expected' => '1 + 2', ], 'length-6' => [ - '/* testCalculation */', - \T_LNUMBER, - 6, - '1 + 2 ', + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 6, + 'expected' => '1 + 2 ', ], 'length-7' => [ - '/* testCalculation */', - \T_LNUMBER, - 7, - '1 + 2 +', + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 7, + 'expected' => '1 + 2 +', ], 'length-8' => [ - '/* testCalculation */', - \T_LNUMBER, - 8, - '1 + 2 + + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 8, + 'expected' => '1 + 2 + ', ], 'length-9' => [ - '/* testCalculation */', - \T_LNUMBER, - 9, - '1 + 2 + + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 9, + 'expected' => '1 + 2 + ', ], 'length-10' => [ - '/* testCalculation */', - \T_LNUMBER, - 10, - '1 + 2 + + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 10, + 'expected' => '1 + 2 + // Comment. ', ], 'length-11' => [ - '/* testCalculation */', - \T_LNUMBER, - 11, - '1 + 2 + + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 11, + 'expected' => '1 + 2 + // Comment. ', ], 'length-12' => [ - '/* testCalculation */', - \T_LNUMBER, - 12, - '1 + 2 + + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 12, + 'expected' => '1 + 2 + // Comment. 3', ], 'length-13' => [ - '/* testCalculation */', - \T_LNUMBER, - 13, - '1 + 2 + + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 13, + 'expected' => '1 + 2 + // Comment. 3 ', ], 'length-14' => [ - '/* testCalculation */', - \T_LNUMBER, - 14, - '1 + 2 + + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 14, + 'expected' => '1 + 2 + // Comment. 3 +', ], 'length-34' => [ - '/* testCalculation */', - \T_LNUMBER, - 34, - '1 + 2 + + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'length' => 34, + 'expected' => '1 + 2 + // Comment. 3 + 4 + 5 + 6 + 7 > 20;', ], 'namespace' => [ - '/* testNamespace */', - \T_NAMESPACE, - ($php8Names === true) ? 4 : 8, - 'namespace Foo\Bar\Baz;', + 'testMarker' => '/* testNamespace */', + 'startTokenType' => \T_NAMESPACE, + 'length' => ($php8Names === true) ? 4 : 8, + 'expected' => 'namespace Foo\Bar\Baz;', ], 'use-with-comments' => [ - '/* testUseWithComments */', - \T_USE, - 17, - 'use Foo /*comment*/ \ Bar + 'testMarker' => '/* testUseWithComments */', + 'startTokenType' => \T_USE, + 'length' => 17, + 'expected' => 'use Foo /*comment*/ \ Bar // phpcs:ignore Stnd.Cat.Sniff -- For reasons. \ Bah;', ], 'echo-with-tabs' => [ - '/* testEchoWithTabs */', - \T_ECHO, - 13, - 'echo \'foo\', + 'testMarker' => '/* testEchoWithTabs */', + 'startTokenType' => \T_ECHO, + 'length' => 13, + 'expected' => 'echo \'foo\', \'bar\' , \'baz\';', ], 'end-of-file' => [ - '/* testEndOfFile */', - \T_ECHO, - 4, - 'echo $foo;', + 'testMarker' => '/* testEndOfFile */', + 'startTokenType' => \T_ECHO, + 'length' => 4, + 'expected' => 'echo $foo;', ], ]; } @@ -266,12 +266,12 @@ public function dataGetTokensAsString() /** * Test getting a token set as a string with the original, non tab-replaced content. * - * @dataProvider dataGetOrigContent() + * @dataProvider dataGetOrigContent * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $startTokenType The type of token(s) to look for for the start of the string. - * @param int $length Token length to get. - * @param string $expected The expected function return value. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $startTokenType The type of token(s) to look for for the start of the string. + * @param int $length Token length to get. + * @param string $expected The expected function return value. * * @return void */ @@ -287,32 +287,32 @@ public function testGetOrigContent($testMarker, $startTokenType, $length, $expec * * @see testGetOrigContent() For the array format. * - * @return array + * @return array> */ - public function dataGetOrigContent() + public static function dataGetOrigContent() { return [ 'use-with-comments' => [ - '/* testUseWithComments */', - \T_USE, - 17, - 'use Foo /*comment*/ \ Bar + 'testMarker' => '/* testUseWithComments */', + 'startTokenType' => \T_USE, + 'length' => 17, + 'expected' => 'use Foo /*comment*/ \ Bar // phpcs:ignore Stnd.Cat.Sniff -- For reasons. \ Bah;', ], 'echo-with-tabs' => [ - '/* testEchoWithTabs */', - \T_ECHO, - 13, - 'echo \'foo\', + 'testMarker' => '/* testEchoWithTabs */', + 'startTokenType' => \T_ECHO, + 'length' => 13, + 'expected' => 'echo \'foo\', \'bar\' , \'baz\';', ], 'end-of-file' => [ - '/* testEndOfFile */', - \T_ECHO, - 4, - 'echo $foo;', + 'testMarker' => '/* testEndOfFile */', + 'startTokenType' => \T_ECHO, + 'length' => 4, + 'expected' => 'echo $foo;', ], ]; } diff --git a/Tests/BackCompat/BCFile/IsReferenceTest.inc b/Tests/BackCompat/BCFile/IsReferenceTest.inc index 93c7acc6..05af8390 100644 --- a/Tests/BackCompat/BCFile/IsReferenceTest.inc +++ b/Tests/BackCompat/BCFile/IsReferenceTest.inc @@ -169,7 +169,7 @@ functionCall( $something , &new Foobar() ); $closure = function() use (&$var){}; /* testUseByReferenceWithCommentFirstParam */ -$closure = function() use /*comment*/ (&$this->value){}; +$closure = function() use /*comment*/ (&$value){}; /* testUseByReferenceWithCommentSecondParam */ $closure = function() use /*comment*/ ($varA, &$varB){}; @@ -201,6 +201,12 @@ $closure = function &($param) use ($value) {}; /* testBitwiseAndArrowFunctionInDefault */ $fn = fn( $one = E_NOTICE & E_STRICT) => 1; +/* testIntersectionIsNotReference */ +function intersect(Foo&Bar $param) {} + +/* testDNFTypeIsNotReference */ +$fn = fn((Foo&\Bar)|null /* testParamPassByReference */ &$param) => $param; + /* testTokenizerIssue1284PHPCSlt280A */ if ($foo) {} [&$a, /* testTokenizerIssue1284PHPCSlt280B */ &$b] = $c; diff --git a/Tests/BackCompat/BCFile/IsReferenceTest.php b/Tests/BackCompat/BCFile/IsReferenceTest.php index 2bb169df..ef92b927 100644 --- a/Tests/BackCompat/BCFile/IsReferenceTest.php +++ b/Tests/BackCompat/BCFile/IsReferenceTest.php @@ -17,7 +17,7 @@ * @author Phil Davis * * @copyright 2017-2019 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */ namespace PHPCSUtils\Tests\BackCompat\BCFile; @@ -49,31 +49,62 @@ class IsReferenceTest extends UtilityMethodTestCase /** * Test that false is returned when a non-"bitwise and" token is passed. * + * @param string $testMarker Comment which precedes the test case. + * @param array $targetTokens Type of tokens to look for. + * + * @dataProvider dataNotBitwiseAndToken + * * @return void */ - public function testNotBitwiseAndToken() + public function testNotBitwiseAndToken($testMarker, $targetTokens) { - $testClass = static::TEST_CLASS; + $testClass = static::TEST_CLASS; + $targetTokens[] = T_BITWISE_AND; - $target = $this->getTargetToken('/* testBitwiseAndA */', T_STRING); + $target = $this->getTargetToken($testMarker, $targetTokens); $this->assertFalse($testClass::isReference(self::$phpcsFile, $target)); } /** - * Test correctly identifying that whether a "bitwise and" token is a reference or not. + * Data provider. + * + * @see testNotBitwiseAndToken() + * + * @return array>> + */ + public static function dataNotBitwiseAndToken() + { + return [ + 'Not ampersand token at all' => [ + 'testMarker' => '/* testBitwiseAndA */', + 'targetTokens' => [T_STRING], + ], + 'ampersand in intersection type' => [ + 'testMarker' => '/* testIntersectionIsNotReference */', + 'targetTokens' => [T_TYPE_INTERSECTION], + ], + 'ampersand in DNF type' => [ + 'testMarker' => '/* testDNFTypeIsNotReference */', + 'targetTokens' => [T_TYPE_INTERSECTION], + ], + ]; + } + + /** + * Test correctly identifying whether a "bitwise and" token is a reference or not. * * @dataProvider dataIsReference * - * @param string $identifier Comment which precedes the test case. + * @param string $testMarker Comment which precedes the test case. * @param bool $expected Expected function output. * * @return void */ - public function testIsReference($identifier, $expected) + public function testIsReference($testMarker, $expected) { $testClass = static::TEST_CLASS; - $bitwiseAnd = $this->getTargetToken($identifier, T_BITWISE_AND); + $bitwiseAnd = $this->getTargetToken($testMarker, T_BITWISE_AND); $result = $testClass::isReference(self::$phpcsFile, $bitwiseAnd); $this->assertSame($expected, $result); } @@ -83,9 +114,9 @@ public function testIsReference($identifier, $expected) * * @see testIsReference() * - * @return array + * @return array> */ - public function dataIsReference() + public static function dataIsReference() { return [ 'issue-1971-list-first-in-file' => [ @@ -97,272 +128,276 @@ public function dataIsReference() 'expected' => true, ], 'bitwise and: param in function call' => [ - '/* testBitwiseAndA */', - false, + 'testMarker' => '/* testBitwiseAndA */', + 'expected' => false, ], 'bitwise and: in unkeyed short array, first value' => [ - '/* testBitwiseAndB */', - false, + 'testMarker' => '/* testBitwiseAndB */', + 'expected' => false, ], 'bitwise and: in unkeyed short array, last value' => [ - '/* testBitwiseAndC */', - false, + 'testMarker' => '/* testBitwiseAndC */', + 'expected' => false, ], 'bitwise and: in unkeyed long array, last value' => [ - '/* testBitwiseAndD */', - false, + 'testMarker' => '/* testBitwiseAndD */', + 'expected' => false, ], 'bitwise and: in keyed short array, last value' => [ - '/* testBitwiseAndE */', - false, + 'testMarker' => '/* testBitwiseAndE */', + 'expected' => false, ], 'bitwise and: in keyed long array, last value' => [ - '/* testBitwiseAndF */', - false, + 'testMarker' => '/* testBitwiseAndF */', + 'expected' => false, ], 'bitwise and: in assignment' => [ - '/* testBitwiseAndG */', - false, + 'testMarker' => '/* testBitwiseAndG */', + 'expected' => false, ], 'bitwise and: in param default value in function declaration' => [ - '/* testBitwiseAndH */', - false, + 'testMarker' => '/* testBitwiseAndH */', + 'expected' => false, ], 'bitwise and: in param default value in closure declaration' => [ - '/* testBitwiseAndI */', - false, + 'testMarker' => '/* testBitwiseAndI */', + 'expected' => false, ], 'reference: function declared to return by reference' => [ - '/* testFunctionReturnByReference */', - true, + 'testMarker' => '/* testFunctionReturnByReference */', + 'expected' => true, ], 'reference: only param in function declaration, pass by reference' => [ - '/* testFunctionPassByReferenceA */', - true, + 'testMarker' => '/* testFunctionPassByReferenceA */', + 'expected' => true, ], 'reference: last param in function declaration, pass by reference' => [ - '/* testFunctionPassByReferenceB */', - true, + 'testMarker' => '/* testFunctionPassByReferenceB */', + 'expected' => true, ], 'reference: only param in closure declaration, pass by reference' => [ - '/* testFunctionPassByReferenceC */', - true, + 'testMarker' => '/* testFunctionPassByReferenceC */', + 'expected' => true, ], 'reference: last param in closure declaration, pass by reference' => [ - '/* testFunctionPassByReferenceD */', - true, + 'testMarker' => '/* testFunctionPassByReferenceD */', + 'expected' => true, ], 'reference: typed param in function declaration, pass by reference' => [ - '/* testFunctionPassByReferenceE */', - true, + 'testMarker' => '/* testFunctionPassByReferenceE */', + 'expected' => true, ], 'reference: typed param in closure declaration, pass by reference' => [ - '/* testFunctionPassByReferenceF */', - true, + 'testMarker' => '/* testFunctionPassByReferenceF */', + 'expected' => true, ], 'reference: variadic param in function declaration, pass by reference' => [ - '/* testFunctionPassByReferenceG */', - true, + 'testMarker' => '/* testFunctionPassByReferenceG */', + 'expected' => true, ], 'reference: foreach value' => [ - '/* testForeachValueByReference */', - true, + 'testMarker' => '/* testForeachValueByReference */', + 'expected' => true, ], 'reference: foreach key' => [ - '/* testForeachKeyByReference */', - true, + 'testMarker' => '/* testForeachKeyByReference */', + 'expected' => true, ], 'reference: keyed short array, first value, value by reference' => [ - '/* testArrayValueByReferenceA */', - true, + 'testMarker' => '/* testArrayValueByReferenceA */', + 'expected' => true, ], 'reference: keyed short array, last value, value by reference' => [ - '/* testArrayValueByReferenceB */', - true, + 'testMarker' => '/* testArrayValueByReferenceB */', + 'expected' => true, ], 'reference: unkeyed short array, only value, value by reference' => [ - '/* testArrayValueByReferenceC */', - true, + 'testMarker' => '/* testArrayValueByReferenceC */', + 'expected' => true, ], 'reference: unkeyed short array, last value, value by reference' => [ - '/* testArrayValueByReferenceD */', - true, + 'testMarker' => '/* testArrayValueByReferenceD */', + 'expected' => true, ], 'reference: keyed long array, first value, value by reference' => [ - '/* testArrayValueByReferenceE */', - true, + 'testMarker' => '/* testArrayValueByReferenceE */', + 'expected' => true, ], 'reference: keyed long array, last value, value by reference' => [ - '/* testArrayValueByReferenceF */', - true, + 'testMarker' => '/* testArrayValueByReferenceF */', + 'expected' => true, ], 'reference: unkeyed long array, only value, value by reference' => [ - '/* testArrayValueByReferenceG */', - true, + 'testMarker' => '/* testArrayValueByReferenceG */', + 'expected' => true, ], 'reference: unkeyed long array, last value, value by reference' => [ - '/* testArrayValueByReferenceH */', - true, + 'testMarker' => '/* testArrayValueByReferenceH */', + 'expected' => true, ], 'reference: variable, assign by reference' => [ - '/* testAssignByReferenceA */', - true, + 'testMarker' => '/* testAssignByReferenceA */', + 'expected' => true, ], 'reference: variable, assign by reference, spacing variation' => [ - '/* testAssignByReferenceB */', - true, + 'testMarker' => '/* testAssignByReferenceB */', + 'expected' => true, ], 'reference: variable, assign by reference, concat assign' => [ - '/* testAssignByReferenceC */', - true, + 'testMarker' => '/* testAssignByReferenceC */', + 'expected' => true, ], 'reference: property, assign by reference' => [ - '/* testAssignByReferenceD */', - true, + 'testMarker' => '/* testAssignByReferenceD */', + 'expected' => true, ], 'reference: function return value, assign by reference' => [ - '/* testAssignByReferenceE */', - true, + 'testMarker' => '/* testAssignByReferenceE */', + 'expected' => true, ], 'reference: function return value, assign by reference, null coalesce assign' => [ - '/* testAssignByReferenceF */', - true, + 'testMarker' => '/* testAssignByReferenceF */', + 'expected' => true, ], 'reference: unkeyed short list, first var, assign by reference' => [ - '/* testShortListAssignByReferenceNoKeyA */', - true, + 'testMarker' => '/* testShortListAssignByReferenceNoKeyA */', + 'expected' => true, ], 'reference: unkeyed short list, second var, assign by reference' => [ - '/* testShortListAssignByReferenceNoKeyB */', - true, + 'testMarker' => '/* testShortListAssignByReferenceNoKeyB */', + 'expected' => true, ], 'reference: unkeyed short list, nested var, assign by reference' => [ - '/* testNestedShortListAssignByReferenceNoKey */', - true, + 'testMarker' => '/* testNestedShortListAssignByReferenceNoKey */', + 'expected' => true, ], 'reference: unkeyed long list, second var, assign by reference' => [ - '/* testLongListAssignByReferenceNoKeyA */', - true, + 'testMarker' => '/* testLongListAssignByReferenceNoKeyA */', + 'expected' => true, ], 'reference: unkeyed long list, first nested var, assign by reference' => [ - '/* testLongListAssignByReferenceNoKeyB */', - true, + 'testMarker' => '/* testLongListAssignByReferenceNoKeyB */', + 'expected' => true, ], 'reference: unkeyed long list, last nested var, assign by reference' => [ - '/* testLongListAssignByReferenceNoKeyC */', - true, + 'testMarker' => '/* testLongListAssignByReferenceNoKeyC */', + 'expected' => true, ], 'reference: keyed short list, first nested var, assign by reference' => [ - '/* testNestedShortListAssignByReferenceWithKeyA */', - true, + 'testMarker' => '/* testNestedShortListAssignByReferenceWithKeyA */', + 'expected' => true, ], 'reference: keyed short list, last nested var, assign by reference' => [ - '/* testNestedShortListAssignByReferenceWithKeyB */', - true, + 'testMarker' => '/* testNestedShortListAssignByReferenceWithKeyB */', + 'expected' => true, ], 'reference: keyed long list, only var, assign by reference' => [ - '/* testLongListAssignByReferenceWithKeyA */', - true, + 'testMarker' => '/* testLongListAssignByReferenceWithKeyA */', + 'expected' => true, ], 'reference: first param in function call, pass by reference' => [ - '/* testPassByReferenceA */', - true, + 'testMarker' => '/* testPassByReferenceA */', + 'expected' => true, ], 'reference: last param in function call, pass by reference' => [ - '/* testPassByReferenceB */', - true, + 'testMarker' => '/* testPassByReferenceB */', + 'expected' => true, ], 'reference: property in function call, pass by reference' => [ - '/* testPassByReferenceC */', - true, + 'testMarker' => '/* testPassByReferenceC */', + 'expected' => true, ], 'reference: hierarchical self property in function call, pass by reference' => [ - '/* testPassByReferenceD */', - true, + 'testMarker' => '/* testPassByReferenceD */', + 'expected' => true, ], 'reference: hierarchical parent property in function call, pass by reference' => [ - '/* testPassByReferenceE */', - true, + 'testMarker' => '/* testPassByReferenceE */', + 'expected' => true, ], 'reference: hierarchical static property in function call, pass by reference' => [ - '/* testPassByReferenceF */', - true, + 'testMarker' => '/* testPassByReferenceF */', + 'expected' => true, ], 'reference: static property in function call, pass by reference' => [ - '/* testPassByReferenceG */', - true, + 'testMarker' => '/* testPassByReferenceG */', + 'expected' => true, ], 'reference: static property in function call, first with FQN, pass by reference' => [ - '/* testPassByReferenceH */', - true, + 'testMarker' => '/* testPassByReferenceH */', + 'expected' => true, ], 'reference: static property in function call, last with FQN, pass by reference' => [ - '/* testPassByReferenceI */', - true, + 'testMarker' => '/* testPassByReferenceI */', + 'expected' => true, ], 'reference: static property in function call, last with namespace relative name, pass by reference' => [ - '/* testPassByReferenceJ */', - true, + 'testMarker' => '/* testPassByReferenceJ */', + 'expected' => true, ], 'reference: static property in function call, last with PQN, pass by reference' => [ - '/* testPassByReferencePartiallyQualifiedName */', - true, + 'testMarker' => '/* testPassByReferencePartiallyQualifiedName */', + 'expected' => true, ], 'reference: new by reference' => [ - '/* testNewByReferenceA */', - true, + 'testMarker' => '/* testNewByReferenceA */', + 'expected' => true, ], 'reference: new by reference as function call param' => [ - '/* testNewByReferenceB */', - true, + 'testMarker' => '/* testNewByReferenceB */', + 'expected' => true, ], 'reference: closure use by reference' => [ - '/* testUseByReference */', - true, + 'testMarker' => '/* testUseByReference */', + 'expected' => true, ], 'reference: closure use by reference, first param, with comment' => [ - '/* testUseByReferenceWithCommentFirstParam */', - true, + 'testMarker' => '/* testUseByReferenceWithCommentFirstParam */', + 'expected' => true, ], 'reference: closure use by reference, last param, with comment' => [ - '/* testUseByReferenceWithCommentSecondParam */', - true, + 'testMarker' => '/* testUseByReferenceWithCommentSecondParam */', + 'expected' => true, ], 'reference: arrow fn declared to return by reference' => [ - '/* testArrowFunctionReturnByReference */', - true, + 'testMarker' => '/* testArrowFunctionReturnByReference */', + 'expected' => true, ], 'bitwise and: first param default value in closure declaration' => [ - '/* testBitwiseAndExactParameterA */', - false, + 'testMarker' => '/* testBitwiseAndExactParameterA */', + 'expected' => false, ], 'reference: param in closure declaration, pass by reference' => [ - '/* testPassByReferenceExactParameterB */', - true, + 'testMarker' => '/* testPassByReferenceExactParameterB */', + 'expected' => true, ], 'reference: variadic param in closure declaration, pass by reference' => [ - '/* testPassByReferenceExactParameterC */', - true, + 'testMarker' => '/* testPassByReferenceExactParameterC */', + 'expected' => true, ], 'bitwise and: last param default value in closure declaration' => [ - '/* testBitwiseAndExactParameterD */', - false, + 'testMarker' => '/* testBitwiseAndExactParameterD */', + 'expected' => false, ], 'reference: typed param in arrow fn declaration, pass by reference' => [ - '/* testArrowFunctionPassByReferenceA */', - true, + 'testMarker' => '/* testArrowFunctionPassByReferenceA */', + 'expected' => true, ], 'reference: variadic param in arrow fn declaration, pass by reference' => [ - '/* testArrowFunctionPassByReferenceB */', - true, + 'testMarker' => '/* testArrowFunctionPassByReferenceB */', + 'expected' => true, ], 'reference: closure declared to return by reference' => [ - '/* testClosureReturnByReference */', - true, + 'testMarker' => '/* testClosureReturnByReference */', + 'expected' => true, ], 'bitwise and: param default value in arrow fn declaration' => [ - '/* testBitwiseAndArrowFunctionInDefault */', - false, + 'testMarker' => '/* testBitwiseAndArrowFunctionInDefault */', + 'expected' => false, + ], + 'reference: param pass by ref in arrow function' => [ + 'testMarker' => '/* testParamPassByReference */', + 'expected' => true, ], 'issue-1284-short-list-directly-after-close-curly-control-structure' => [ 'testMarker' => '/* testTokenizerIssue1284PHPCSlt280A */', diff --git a/Tests/BackCompat/BCTokens/UnchangedTokenArraysTest.php b/Tests/BackCompat/BCTokens/UnchangedTokenArraysTest.php index d7199a74..992c126f 100644 --- a/Tests/BackCompat/BCTokens/UnchangedTokenArraysTest.php +++ b/Tests/BackCompat/BCTokens/UnchangedTokenArraysTest.php @@ -53,7 +53,7 @@ final class UnchangedTokenArraysTest extends TestCase /** * Tokens that represent equality comparisons. * - * @var array => + * @var array */ private $equalityTokens = [ \T_IS_EQUAL => \T_IS_EQUAL, @@ -120,7 +120,7 @@ final class UnchangedTokenArraysTest extends TestCase /** * Tokens that perform boolean operations. * - * @var array => + * @var array */ private $booleanOperators = [ \T_BOOLEAN_AND => \T_BOOLEAN_AND, @@ -133,7 +133,7 @@ final class UnchangedTokenArraysTest extends TestCase /** * Tokens that represent casting. * - * @var array => + * @var array */ private $castTokens = [ \T_INT_CAST => \T_INT_CAST, @@ -183,7 +183,7 @@ final class UnchangedTokenArraysTest extends TestCase /** * Tokens that represent scope modifiers. * - * @var array => + * @var array */ private $scopeModifiers = [ \T_PRIVATE => \T_PRIVATE, @@ -194,7 +194,7 @@ final class UnchangedTokenArraysTest extends TestCase /** * Tokens that can prefix a method name * - * @var array => + * @var array */ private $methodPrefixes = [ \T_PRIVATE => \T_PRIVATE, @@ -208,7 +208,7 @@ final class UnchangedTokenArraysTest extends TestCase /** * Tokens that open code blocks. * - * @var array => + * @var array */ private $blockOpeners = [ \T_OPEN_CURLY_BRACKET => \T_OPEN_CURLY_BRACKET, @@ -276,7 +276,7 @@ final class UnchangedTokenArraysTest extends TestCase /** * Tokens that represent strings. * - * @var array => + * @var array */ private $stringTokens = [ \T_CONSTANT_ENCAPSED_STRING => \T_CONSTANT_ENCAPSED_STRING, @@ -299,7 +299,7 @@ final class UnchangedTokenArraysTest extends TestCase /** * Tokens that represent brackets and parenthesis. * - * @var array => + * @var array */ private $bracketTokens = [ \T_OPEN_CURLY_BRACKET => \T_OPEN_CURLY_BRACKET, @@ -313,7 +313,7 @@ final class UnchangedTokenArraysTest extends TestCase /** * Tokens that include files. * - * @var array => + * @var array */ private $includeTokens = [ \T_REQUIRE_ONCE => \T_REQUIRE_ONCE, @@ -325,7 +325,7 @@ final class UnchangedTokenArraysTest extends TestCase /** * Tokens that make up a heredoc string. * - * @var array => + * @var array */ private $heredocTokens = [ \T_START_HEREDOC => \T_START_HEREDOC, @@ -352,7 +352,7 @@ final class UnchangedTokenArraysTest extends TestCase /** * Tokens representing PHP magic constants. * - * @var array => + * @var array * * @link https://www.php.net/language.constants.predefined PHP Manual on magic constants */ @@ -452,8 +452,8 @@ final class UnchangedTokenArraysTest extends TestCase * * @dataProvider dataUnchangedTokenArrays * - * @param string $name The token array name. - * @param array $expected The token array content. + * @param string $name The token array name. + * @param array $expected The token array content. * * @return void */ @@ -467,9 +467,9 @@ public function testUnchangedTokenArrays($name, $expected) * * @see testUnchangedTokenArrays() For the array format. * - * @return array + * @return array> */ - public function dataUnchangedTokenArrays() + public static function dataUnchangedTokenArrays() { $phpunitProp = [ 'backupGlobals' => true, @@ -484,7 +484,7 @@ public function dataUnchangedTokenArrays() ]; $data = []; - $tokenArrays = \get_object_vars($this); + $tokenArrays = \get_class_vars(__CLASS__); foreach ($tokenArrays as $name => $expected) { if (isset($phpunitProp[$name])) { continue; diff --git a/Tests/BackCompat/Helper/ConfigDataTest.php b/Tests/BackCompat/Helper/ConfigDataTest.php index 9c3b1fcd..022aa105 100644 --- a/Tests/BackCompat/Helper/ConfigDataTest.php +++ b/Tests/BackCompat/Helper/ConfigDataTest.php @@ -12,8 +12,7 @@ use PHP_CodeSniffer\Config; use PHPCSUtils\BackCompat\Helper; -use PHPUnit\Framework\TestCase; -use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; +use Yoast\PHPUnitPolyfills\TestCases\TestCase; /** * Test class. @@ -21,13 +20,10 @@ * @covers \PHPCSUtils\BackCompat\Helper::setConfigData * @covers \PHPCSUtils\BackCompat\Helper::getConfigData * - * @group helper - * * @since 1.0.0 */ final class ConfigDataTest extends TestCase { - use ExpectException; /** * Test the getConfigData() and setConfigData() method when used in a cross-version compatible manner. diff --git a/Tests/BackCompat/Helper/GetCommandLineDataTest.php b/Tests/BackCompat/Helper/GetCommandLineDataTest.php index 35b2c6ac..c8f06e6f 100644 --- a/Tests/BackCompat/Helper/GetCommandLineDataTest.php +++ b/Tests/BackCompat/Helper/GetCommandLineDataTest.php @@ -12,14 +12,13 @@ use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use stdClass; /** * Test class. * * @coversDefaultClass \PHPCSUtils\BackCompat\Helper * - * @group helper - * * @since 1.0.0 */ final class GetCommandLineDataTest extends UtilityMethodTestCase @@ -202,4 +201,28 @@ public function testIgnoreAnnotationsSetViaProperty() $this->assertTrue($result); } + + /** + * Test the ignoreAnnotations() method. + * + * @covers ::ignoreAnnotations + * + * @return void + */ + public function testIgnoreAnnotationsUsesGetConfigDataWhenInvalidFileParamPassed() + { + $config = null; + if (isset(self::$phpcsFile->config) === true) { + $config = self::$phpcsFile->config; + } + + Helper::setConfigData('annotations', false, true, $config); + + $result = Helper::ignoreAnnotations(new stdClass()); + + // Restore defaults before moving to the next test. + Helper::setConfigData('annotations', true, true, $config); + + $this->assertTrue($result); + } } diff --git a/Tests/BackCompat/Helper/GetVersionTest.php b/Tests/BackCompat/Helper/GetVersionTest.php index 162b6070..3e21a0d3 100644 --- a/Tests/BackCompat/Helper/GetVersionTest.php +++ b/Tests/BackCompat/Helper/GetVersionTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\BackCompat\Helper::getVersion * - * @group helper - * * @since 1.0.0 */ final class GetVersionTest extends TestCase @@ -32,7 +30,7 @@ final class GetVersionTest extends TestCase * * @var string */ - const DEVMASTER = '3.7.2'; + const DEVMASTER = '3.9.2'; /** * Test the method. @@ -46,12 +44,10 @@ public function testGetVersion() $this->markTestSkipped('The test for the Helper::getVersion() method will only run' . ' if the PHPCS_VERSION environment variable is set, such as during a CI build' . ' or when this variable has been set in the PHPUnit configuration file.'); - - return; } if ($expected === 'lowest') { - $expected = '3.7.1'; + $expected = '3.10.0'; } $result = Helper::getVersion(); diff --git a/Tests/ExpectWithConsecutiveArgs.php b/Tests/ExpectWithConsecutiveArgs.php new file mode 100644 index 00000000..b2844d93 --- /dev/null +++ b/Tests/ExpectWithConsecutiveArgs.php @@ -0,0 +1,82 @@ +withConsecutive()` method could be used to test + * this, but that method was removed in PHPUnit 10.0. + * + * @since 1.0.7 + */ +trait ExpectWithConsecutiveArgs +{ + + /** + * PHPUnit cross-version helper method to test the arguments passed to a method in a mocked object. + * + * @param object $mockObject The object mock. + * @param object $countMatcher Matcher for number of time the method is expected to be called. + * @param string $methodName The name of the method on which to set the expectations. + * @param array> $expectedArgs Multi-dimentional array of arguments expected to be passed in + * consecutive calls. + * + * @return object Expectation object. + */ + final public function setExpectationWithConsecutiveArgs($mockObject, $countMatcher, $methodName, $expectedArgs) + { + $methodExpectation = $mockObject->expects($countMatcher) + ->method($methodName); + + if (\method_exists($methodExpectation, 'withConsecutive')) { + // PHPUnit 4.x - 9.x. + + $expectationsArray = []; + foreach ($expectedArgs as $key => $series) { + foreach ($series as $arg) { + $expectationsArray[$key][] = $this->identicalTo($arg); + } + } + + return \call_user_func_array([$methodExpectation, 'withConsecutive'], $expectationsArray); + } + + // PHPUnit 10+. + return $methodExpectation->willReturnCallback( + function () use (&$expectedArgs, $countMatcher, $methodName) { + $actualArgs = \func_get_args(); + $expected = \array_shift($expectedArgs); + + $this->assertCount( + \count($expected), + $actualArgs, + \sprintf( + 'Actual number of arguments received does not match expected for call %d to method %s', + $countMatcher->numberOfInvocations(), + $methodName + ) + ); + + $this->assertSame( + $expected, + $actualArgs, + \sprintf( + 'Arguments received do not match expected arguments for call %d to method %s', + $countMatcher->numberOfInvocations(), + $methodName + ) + ); + } + ); + } +} diff --git a/Tests/Fixers/SpacesFixer/SpacesFixerAtEOFTest.inc b/Tests/Fixers/SpacesFixer/SpacesFixerAtEOFTest.inc new file mode 100644 index 00000000..4cad7aa2 --- /dev/null +++ b/Tests/Fixers/SpacesFixer/SpacesFixerAtEOFTest.inc @@ -0,0 +1,4 @@ + + */ + protected static $selectedSniff = ['PHPCSUtils.SpacesFixer.Test']; + + /** + * Test that violations are correctly reported when there is no non-empty token after the second stack pointer. + * + * @return void + */ + public function testCheckAndFix() + { + $stackPtr = $this->getTargetToken(self::TESTMARKER, \T_SEMICOLON); + $secondPtr = $this->getTargetToken(self::TESTMARKER, \T_COMMENT); + + SpacesFixer::checkAndFix( + self::$phpcsFile, + $stackPtr, + $secondPtr, + self::SPACES, + self::MSG, + self::CODE + ); + + $result = self::$phpcsFile->getErrors(); + $tokens = self::$phpcsFile->getTokens(); + + if (isset($result[$tokens[$stackPtr]['line']][$tokens[$stackPtr]['column']]) === false) { + $this->fail('Expected 1 violation. None found.'); + } + + $messages = $result[$tokens[$stackPtr]['line']][$tokens[$stackPtr]['column']]; + + // Expect one violation. + $this->assertCount(1, $messages, 'Expected 1 violation, found: ' . \count($messages)); + + /* + * Test the violation details. + */ + $this->assertSame(self::CODE, $messages[0]['source'], 'Error code comparison failed'); + + $this->assertSame(true, $messages[0]['fixable'], 'Fixability comparison failed'); + } + + /** + * Test that the fixes are correctly made when there is no non-empty token after the second stack pointer. + * + * @return void + */ + public function testFixesMade() + { + self::$phpcsFile->fixer->startFile(self::$phpcsFile); + self::$phpcsFile->fixer->enabled = true; + + $stackPtr = $this->getTargetToken(self::TESTMARKER, \T_SEMICOLON); + $secondPtr = $this->getTargetToken(self::TESTMARKER, \T_COMMENT); + + SpacesFixer::checkAndFix( + self::$phpcsFile, + $stackPtr, + $secondPtr, + self::SPACES, + self::MSG, + self::CODE + ); + + $fixedFile = self::$phpcsFile->getFilename() . '.fixed'; + $result = self::$phpcsFile->fixer->getContents(); + + $this->assertStringEqualsFile( + $fixedFile, + $result, + \sprintf( + 'Fixed version of %s does not match expected version in %s', + \basename(self::$caseFile), + \basename($fixedFile) + ) + ); + } +} diff --git a/Tests/Fixers/SpacesFixer/SpacesFixerExceptionsTest.php b/Tests/Fixers/SpacesFixer/SpacesFixerExceptionsTest.php index 3ff2ef0e..a244369f 100644 --- a/Tests/Fixers/SpacesFixer/SpacesFixerExceptionsTest.php +++ b/Tests/Fixers/SpacesFixer/SpacesFixerExceptionsTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Fixers\SpacesFixer::checkAndFix * - * @group fixers - * * @since 1.0.0 */ final class SpacesFixerExceptionsTest extends UtilityMethodTestCase diff --git a/Tests/Fixers/SpacesFixer/SpacesFixerNewlineTest.php b/Tests/Fixers/SpacesFixer/SpacesFixerNewlineTest.php index 9e426aad..60455f90 100644 --- a/Tests/Fixers/SpacesFixer/SpacesFixerNewlineTest.php +++ b/Tests/Fixers/SpacesFixer/SpacesFixerNewlineTest.php @@ -17,8 +17,6 @@ * * @covers \PHPCSUtils\Fixers\SpacesFixer::checkAndFix * - * @group fixers - * * @since 1.0.0 */ final class SpacesFixerNewlineTest extends SpacesFixerTestCase @@ -48,9 +46,9 @@ final class SpacesFixerNewlineTest extends SpacesFixerTestCase /** * The names of the test case(s) in compliance. * - * @var array + * @var array */ - protected $compliantCases = [ + protected static $compliantCases = [ 'newline-and-trailing-spaces', 'multiple-newlines-and-spaces', 'comment-and-new line', diff --git a/Tests/Fixers/SpacesFixer/SpacesFixerNoSpaceTest.php b/Tests/Fixers/SpacesFixer/SpacesFixerNoSpaceTest.php index 366706ef..da40d2d4 100644 --- a/Tests/Fixers/SpacesFixer/SpacesFixerNoSpaceTest.php +++ b/Tests/Fixers/SpacesFixer/SpacesFixerNoSpaceTest.php @@ -17,8 +17,6 @@ * * @covers \PHPCSUtils\Fixers\SpacesFixer::checkAndFix * - * @group fixers - * * @since 1.0.0 */ final class SpacesFixerNoSpaceTest extends SpacesFixerTestCase @@ -48,9 +46,9 @@ final class SpacesFixerNoSpaceTest extends SpacesFixerTestCase /** * The names of the test case(s) in compliance. * - * @var array + * @var array */ - protected $compliantCases = ['no-space']; + protected static $compliantCases = ['no-space']; /** * Full path to the fixed version of the test case file associated with this test class. diff --git a/Tests/Fixers/SpacesFixer/SpacesFixerOneSpaceTest.php b/Tests/Fixers/SpacesFixer/SpacesFixerOneSpaceTest.php index 2fe33692..10578cc5 100644 --- a/Tests/Fixers/SpacesFixer/SpacesFixerOneSpaceTest.php +++ b/Tests/Fixers/SpacesFixer/SpacesFixerOneSpaceTest.php @@ -17,8 +17,6 @@ * * @covers \PHPCSUtils\Fixers\SpacesFixer::checkAndFix * - * @group fixers - * * @since 1.0.0 */ final class SpacesFixerOneSpaceTest extends SpacesFixerTestCase @@ -48,9 +46,9 @@ final class SpacesFixerOneSpaceTest extends SpacesFixerTestCase /** * The names of the test case(s) in compliance. * - * @var array + * @var array */ - protected $compliantCases = [ + protected static $compliantCases = [ 'one-space', 'comment-and-space', ]; diff --git a/Tests/Fixers/SpacesFixer/SpacesFixerTestCase.php b/Tests/Fixers/SpacesFixer/SpacesFixerTestCase.php index 57988e94..efc39a4f 100644 --- a/Tests/Fixers/SpacesFixer/SpacesFixerTestCase.php +++ b/Tests/Fixers/SpacesFixer/SpacesFixerTestCase.php @@ -26,7 +26,7 @@ abstract class SpacesFixerTestCase extends UtilityMethodTestCase * * Important: this MUST be set in the concrete test class! * - * @var int|string + * @var int|string|null Note: `null` is not an acceptable value for the overloaded constant! */ const SPACES = null; @@ -69,9 +69,9 @@ abstract class SpacesFixerTestCase extends UtilityMethodTestCase * * Important: this MUST be set in the concrete test class! * - * @var array + * @var array */ - protected $compliantCases = []; + protected static $compliantCases = []; /** * Full path to the fixed version of the test case file associated with this test class. @@ -85,7 +85,7 @@ abstract class SpacesFixerTestCase extends UtilityMethodTestCase /** * Set the name of a sniff to pass to PHPCS to limit the run (and force it to record errors). * - * @var array + * @var array */ protected static $selectedSniff = ['PHPCSUtils.SpacesFixer.Test']; @@ -109,8 +109,8 @@ public static function setUpTestFile() * * @dataProvider dataCheckAndFixNoError * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected Expected error details (for the metric input). + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected Expected error details (for the metric input). * * @return void */ @@ -154,16 +154,17 @@ public function testCheckAndFixNoError($testMarker, $expected) * * @see testCheckAndFixNoError() For the array format. * - * @return array + * @return array>> */ - public function dataCheckAndFixNoError() + public static function dataCheckAndFixNoError() { $data = []; - $baseData = $this->getAllData(); + $baseData = self::getAllData(); - foreach ($this->compliantCases as $caseName) { + foreach (static::$compliantCases as $caseName) { if (isset($baseData[$caseName])) { $data[$caseName] = $baseData[$caseName]; + unset($data[$caseName]['type']); } } @@ -177,9 +178,9 @@ public function dataCheckAndFixNoError() * * @dataProvider dataCheckAndFix * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected Expected error details. - * @param string $type The message type to test: 'error' or 'warning'. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected Expected error details. + * @param string $type The message type to test: 'error' or 'warning'. * * @return void */ @@ -242,13 +243,13 @@ public function testCheckAndFix($testMarker, $expected, $type) * * @see testCheckAndFix() For the array format. * - * @return array + * @return array>> */ - public function dataCheckAndFix() + public static function dataCheckAndFix() { - $data = $this->getAllData(); + $data = self::getAllData(); - foreach ($this->compliantCases as $caseName) { + foreach (static::$compliantCases as $caseName) { unset($data[$caseName]); } @@ -301,9 +302,9 @@ public function testFixesMade() /** * Helper function holding the base data for the data providers. * - * @return array + * @return array>> */ - protected function getAllData() + protected static function getAllData() { return [ 'no-space' => [ diff --git a/Tests/Fixers/SpacesFixer/SpacesFixerTwoSpaceTest.php b/Tests/Fixers/SpacesFixer/SpacesFixerTwoSpaceTest.php index 9c31d17b..6a9aa604 100644 --- a/Tests/Fixers/SpacesFixer/SpacesFixerTwoSpaceTest.php +++ b/Tests/Fixers/SpacesFixer/SpacesFixerTwoSpaceTest.php @@ -17,8 +17,6 @@ * * @covers \PHPCSUtils\Fixers\SpacesFixer::checkAndFix * - * @group fixers - * * @since 1.0.0 */ final class SpacesFixerTwoSpaceTest extends SpacesFixerTestCase @@ -50,9 +48,9 @@ final class SpacesFixerTwoSpaceTest extends SpacesFixerTestCase /** * The names of the test case(s) in compliance. * - * @var array + * @var array */ - protected $compliantCases = ['two-spaces']; + protected static $compliantCases = ['two-spaces']; /** * Full path to the fixed version of the test case file associated with this test class. diff --git a/Tests/Fixers/SpacesFixer/TrailingCommentHandlingNewlineTest.php b/Tests/Fixers/SpacesFixer/TrailingCommentHandlingNewlineTest.php index 5bf75275..576350c3 100644 --- a/Tests/Fixers/SpacesFixer/TrailingCommentHandlingNewlineTest.php +++ b/Tests/Fixers/SpacesFixer/TrailingCommentHandlingNewlineTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Fixers\SpacesFixer::checkAndFix * - * @group fixers - * * @since 1.0.0 */ final class TrailingCommentHandlingNewlineTest extends UtilityMethodTestCase @@ -65,7 +63,7 @@ final class TrailingCommentHandlingNewlineTest extends UtilityMethodTestCase /** * Set the name of a sniff to pass to PHPCS to limit the run (and force it to record errors). * - * @var array + * @var array */ protected static $selectedSniff = ['PHPCSUtils.SpacesFixer.Test']; @@ -154,9 +152,9 @@ public function testNoFixesMade() * * @see testCheckAndFixNoError() For the array format. * - * @return array + * @return array> */ - public function dataCheckAndFixNoError() + public static function dataCheckAndFixNoError() { return [ 'correct-newline-before' => [ diff --git a/Tests/Fixers/SpacesFixer/TrailingCommentHandlingTest.php b/Tests/Fixers/SpacesFixer/TrailingCommentHandlingTest.php index 5c771d57..74dab315 100644 --- a/Tests/Fixers/SpacesFixer/TrailingCommentHandlingTest.php +++ b/Tests/Fixers/SpacesFixer/TrailingCommentHandlingTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Fixers\SpacesFixer::checkAndFix * - * @group fixers - * * @since 1.0.0 */ final class TrailingCommentHandlingTest extends UtilityMethodTestCase @@ -65,7 +63,7 @@ final class TrailingCommentHandlingTest extends UtilityMethodTestCase /** * Set the name of a sniff to pass to PHPCS to limit the run (and force it to record errors). * - * @var array + * @var array */ protected static $selectedSniff = ['PHPCSUtils.SpacesFixer.Test']; @@ -74,9 +72,9 @@ final class TrailingCommentHandlingTest extends UtilityMethodTestCase * * @dataProvider dataCheckAndFix * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected Expected error details. - * @param string $type The message type to test: 'error' or 'warning'. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected Expected error details. + * @param string $type The message type to test: 'error' or 'warning'. * * @return void */ @@ -180,9 +178,9 @@ public function testFixesMade() * * @see testCheckAndFix() For the array format. * - * @return array + * @return array>> */ - public function dataCheckAndFix() + public static function dataCheckAndFix() { return [ 'trailing-comment-not-fixable' => [ diff --git a/Tests/Internal/Cache/GetClearTest.php b/Tests/Internal/Cache/GetClearTest.php index 420394a1..e329af4a 100644 --- a/Tests/Internal/Cache/GetClearTest.php +++ b/Tests/Internal/Cache/GetClearTest.php @@ -280,9 +280,9 @@ public function testGetWillRetrievedPreviouslySetValue($id, $expected) /** * Data provider. * - * @return array + * @return array> */ - public function dataEveryTypeOfInput() + public static function dataEveryTypeOfInput() { $allTypes = TypeProviderHelper::getAll(); $data = []; @@ -401,7 +401,7 @@ public function testGetForFileWillNotConfuseDataFromDifferentLoops() /** * Test that previously cached data is no longer available when the cache has been cleared. * - * @dataProvider dataEveryTypeOfInput + * @dataProvider dataClearCache * * @covers ::clear * @@ -416,4 +416,22 @@ public function testClearCache($id) $this->assertFalse(Cache::isCached(self::$phpcsFile, 'Utility1', $id)); $this->assertFalse(Cache::isCached(self::$phpcsFile, 'Utility2', $id)); } + + /** + * Data provider. + * + * @see testClearCache() For the array format. + * + * @return array> + */ + public static function dataClearCache() + { + $data = self::dataEveryTypeOfInput(); + + foreach ($data as $name => $dataset) { + unset($data[$name]['expected']); + } + + return $data; + } } diff --git a/Tests/Internal/Cache/SetTest.php b/Tests/Internal/Cache/SetTest.php index b82e67ec..77bb3362 100644 --- a/Tests/Internal/Cache/SetTest.php +++ b/Tests/Internal/Cache/SetTest.php @@ -95,7 +95,7 @@ public static function resetCachingStatus() */ public function testSetAcceptsEveryTypeOfInput($input) { - $id = $this->getName(); + $id = \base_convert((string) \rand((int) 10e16, (int) 10e20), 10, 36); Cache::set(self::$phpcsFile, __METHOD__, $id, $input); $this->assertTrue( @@ -113,9 +113,9 @@ public function testSetAcceptsEveryTypeOfInput($input) /** * Data provider. * - * @return array + * @return array> */ - public function dataEveryTypeOfInput() + public static function dataEveryTypeOfInput() { return TypeProviderHelper::getAll(); } @@ -155,9 +155,9 @@ public function testSetAcceptsIntAndStringIdKeys($id) /** * Data provider. * - * @return array + * @return array> */ - public function dataSetAcceptsIntAndStringIdKeys() + public static function dataSetAcceptsIntAndStringIdKeys() { return [ 'ID: int zero' => [ diff --git a/Tests/Internal/IsShortArrayOrList/ConstructorTest.php b/Tests/Internal/IsShortArrayOrList/ConstructorTest.php index 612f88f8..ad97db03 100644 --- a/Tests/Internal/IsShortArrayOrList/ConstructorTest.php +++ b/Tests/Internal/IsShortArrayOrList/ConstructorTest.php @@ -42,8 +42,8 @@ public function testNonExistentToken() * * @dataProvider dataNotOpenBracket * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetType The token type(s) to look for. * * @return void */ @@ -62,9 +62,9 @@ public function testNotOpenBracket($testMarker, $targetType) * * @see testNotBracket() For the array format. * - * @return array + * @return array> */ - public function dataNotOpenBracket() + public static function dataNotOpenBracket() { return [ 'long-array' => [ @@ -95,8 +95,8 @@ public function dataNotOpenBracket() * * @dataProvider dataSupportedBrackets * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetType The token type(s) to look for. * * @return void */ @@ -113,9 +113,9 @@ public function testSupportedBrackets($testMarker, $targetType) * * @see testSupportedBrackets() For the array format. * - * @return array + * @return array> */ - public function dataSupportedBrackets() + public static function dataSupportedBrackets() { return [ 'short-array-open-bracket' => [ diff --git a/Tests/Internal/IsShortArrayOrList/IsInForeachTest.php b/Tests/Internal/IsShortArrayOrList/IsInForeachTest.php index d28e9117..fb5078d7 100644 --- a/Tests/Internal/IsShortArrayOrList/IsInForeachTest.php +++ b/Tests/Internal/IsShortArrayOrList/IsInForeachTest.php @@ -67,9 +67,9 @@ public function testIsInForeach($testMarker, $expected) * * @see testIsInForeach() For the array format. * - * @return array + * @return array> */ - public function dataIsInForeachResolved() + public static function dataIsInForeachResolved() { return [ 'resolved: short array in foreach' => [ @@ -112,9 +112,9 @@ public function dataIsInForeachResolved() * * @see testIsInForeach() For the array format. * - * @return array + * @return array> */ - public function dataIsInForeachNestedResolvedViaOuter() + public static function dataIsInForeachNestedResolvedViaOuter() { return [ 'resolved-on-outer: short array in foreach nested at start' => [ @@ -157,9 +157,9 @@ public function dataIsInForeachNestedResolvedViaOuter() * * @see testIsInForeach() For the array format. * - * @return array + * @return array> */ - public function dataIsInForeachUndetermined() + public static function dataIsInForeachUndetermined() { return [ 'undetermined: short array in function call in foreach' => [ diff --git a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC1Test.php b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC1Test.php index 48856cf0..302b7e37 100644 --- a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC1Test.php +++ b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC1Test.php @@ -50,9 +50,9 @@ public function testIsShortArrayBracket($testMarker, $expected) * * @see testIsShortArrayBracket() For the array format. * - * @return array + * @return array> */ - public function dataIsShortArrayBracket() + public static function dataIsShortArrayBracket() { return [ 'issue-1971-list-first-in-file' => [ diff --git a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC2Test.php b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC2Test.php index 2c999392..7580784f 100644 --- a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC2Test.php +++ b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC2Test.php @@ -50,9 +50,9 @@ public function testIsShortArrayBracket($testMarker, $expected) * * @see testIsShortArrayBracket() For the array format. * - * @return array + * @return array> */ - public function dataIsShortArrayBracket() + public static function dataIsShortArrayBracket() { return [ // Make sure the utility method does not throw false positives for a short array at the start of a file. diff --git a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC3Test.php b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC3Test.php index 342e296c..026d5ca1 100644 --- a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC3Test.php +++ b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC3Test.php @@ -50,9 +50,9 @@ public function testIsShortArrayBracket($testMarker, $expected) * * @see testIsShortArrayBracket() For the array format. * - * @return array + * @return array> */ - public function dataIsShortArrayBracket() + public static function dataIsShortArrayBracket() { return [ 'issue-1971-short-array-first-in-file' => [ diff --git a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC4Test.php b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC4Test.php index 20ca21e8..0b4eaabf 100644 --- a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC4Test.php +++ b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC4Test.php @@ -50,9 +50,9 @@ public function testIsShortArrayBracket($testMarker, $expected) * * @see testIsShortArrayBracket() For the array format. * - * @return array + * @return array> */ - public function dataIsShortArrayBracket() + public static function dataIsShortArrayBracket() { return [ 'issue-1971-short-list-first-in-file' => [ diff --git a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC5Test.php b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC5Test.php index 01a164e0..79edb170 100644 --- a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC5Test.php +++ b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC5Test.php @@ -50,9 +50,9 @@ public function testIsShortArrayBracket($testMarker, $expected) * * @see testIsShortArrayBracket() For the array format. * - * @return array + * @return array> */ - public function dataIsShortArrayBracket() + public static function dataIsShortArrayBracket() { return [ 'issue-1971-short-list-first-in-file' => [ diff --git a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC6Test.php b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC6Test.php index d703fbf8..e23f987e 100644 --- a/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC6Test.php +++ b/Tests/Internal/IsShortArrayOrList/IsShortArrayBracketBC6Test.php @@ -50,9 +50,9 @@ public function testIsShortArrayBracket($testMarker, $expected) * * @see testIsShortArrayBracket() For the array format. * - * @return array + * @return array> */ - public function dataIsShortArrayBracket() + public static function dataIsShortArrayBracket() { return [ 'issue-1971-short-list-first-in-file' => [ diff --git a/Tests/Internal/IsShortArrayOrList/IsShortArrayOrListTest.php b/Tests/Internal/IsShortArrayOrList/IsShortArrayOrListTest.php index f7cc7019..c3379825 100644 --- a/Tests/Internal/IsShortArrayOrList/IsShortArrayOrListTest.php +++ b/Tests/Internal/IsShortArrayOrList/IsShortArrayOrListTest.php @@ -52,9 +52,9 @@ public function testIsShortArrayOrList($testMarker, $expected) * * @see testIsShortArrayOrList() For the array format. * - * @return array + * @return array> */ - public function dataIsShortArrayOrList() + public static function dataIsShortArrayOrList() { return [ 'short-array-comparison-no-assignment' => [ diff --git a/Tests/Internal/IsShortArrayOrList/IsSquareBracketTest.php b/Tests/Internal/IsShortArrayOrList/IsSquareBracketTest.php index cd10578d..6ad49d42 100644 --- a/Tests/Internal/IsShortArrayOrList/IsSquareBracketTest.php +++ b/Tests/Internal/IsShortArrayOrList/IsSquareBracketTest.php @@ -61,9 +61,9 @@ public function testSquareBrackets($testMarker) * * @see testSquareBrackets() For the array format. * - * @return array + * @return array> */ - public function dataSquareBrackets() + public static function dataSquareBrackets() { return [ 'array-assignment-no-key' => [ diff --git a/Tests/Internal/IsShortArrayOrList/SolveTest.php b/Tests/Internal/IsShortArrayOrList/SolveTest.php index b51f8d4a..8328a6c0 100644 --- a/Tests/Internal/IsShortArrayOrList/SolveTest.php +++ b/Tests/Internal/IsShortArrayOrList/SolveTest.php @@ -37,7 +37,7 @@ final class SolveTest extends UtilityMethodTestCase public function testSolve($testMarker, $expected) { $stackPtr = $this->getTargetToken($testMarker, StableCollections::$shortArrayListOpenTokensBC); - $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr, []); + $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr); $type = $solver->solve(); $this->assertSame($expected, $type); @@ -48,9 +48,9 @@ public function testSolve($testMarker, $expected) * * @see testSolve() For the array format. * - * @return array + * @return array> */ - public function dataSolve() + public static function dataSolve() { return [ 'real square brackets' => [ diff --git a/Tests/Internal/IsShortArrayOrList/WalkInsideTest.php b/Tests/Internal/IsShortArrayOrList/WalkInsideTest.php index d034bc6d..3dda6e8d 100644 --- a/Tests/Internal/IsShortArrayOrList/WalkInsideTest.php +++ b/Tests/Internal/IsShortArrayOrList/WalkInsideTest.php @@ -36,7 +36,7 @@ final class WalkInsideTest extends UtilityMethodTestCase public function testWalkInsideUndetermined($testMarker, $expected) { $stackPtr = $this->getTargetToken($testMarker, [\T_OPEN_SHORT_ARRAY]); - $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr, []); + $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr); $type = $solver->solve(); $this->assertSame($expected, $type); @@ -47,9 +47,9 @@ public function testWalkInsideUndetermined($testMarker, $expected) * * @see testWalkInsideUndetermined() For the array format. * - * @return array + * @return array> */ - public function dataWalkInsideUndetermined() + public static function dataWalkInsideUndetermined() { return [ 'nested-short-array-empty' => [ @@ -121,7 +121,7 @@ public function dataWalkInsideUndetermined() public function testWalkInsideResolved($testMarker, $expected) { $stackPtr = $this->getTargetToken($testMarker, [\T_OPEN_SHORT_ARRAY]); - $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr, []); + $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr); $type = $solver->solve(); $this->assertSame($expected, $type); @@ -132,9 +132,9 @@ public function testWalkInsideResolved($testMarker, $expected) * * @see testWalkInsideResolved() For the array format. * - * @return array + * @return array> */ - public function dataWalkInsideResolved() + public static function dataWalkInsideResolved() { return [ 'nested-short-array-no-vars-or-nested-null' => [ @@ -244,7 +244,7 @@ public function dataWalkInsideResolved() public function testSampleTooSmall() { $stackPtr = $this->getTargetToken('/* testNestedShortArraySampleTooSmall */', \T_OPEN_SHORT_ARRAY); - $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr, []); + $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr); $type = $solver->solve(); $this->assertSame(IsShortArrayOrList::SHORT_ARRAY, $type); @@ -263,7 +263,7 @@ public function testSampleTooSmall() public function testRecursionLimit($testMarker, $expected) { $stackPtr = $this->getTargetToken($testMarker, [\T_OPEN_SHORT_ARRAY]); - $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr, []); + $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr); $type = $solver->solve(); $this->assertSame($expected, $type); @@ -274,9 +274,9 @@ public function testRecursionLimit($testMarker, $expected) * * @see testRecursionLimit() For the array format. * - * @return array + * @return array> */ - public function dataRecursionLimit() + public static function dataRecursionLimit() { return [ 'nested-short-array-with-nested-short-array-recursion-4' => [ diff --git a/Tests/Internal/IsShortArrayOrList/WalkOutsideTest.php b/Tests/Internal/IsShortArrayOrList/WalkOutsideTest.php index 984a2bea..e7e41b1a 100644 --- a/Tests/Internal/IsShortArrayOrList/WalkOutsideTest.php +++ b/Tests/Internal/IsShortArrayOrList/WalkOutsideTest.php @@ -39,7 +39,7 @@ final class WalkOutsideTest extends UtilityMethodTestCase public function testWalkOutside($testMarker, $expected) { $stackPtr = $this->getTargetToken($testMarker, [\T_OPEN_SHORT_ARRAY]); - $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr, []); + $solver = new IsShortArrayOrList(self::$phpcsFile, $stackPtr); $type = $solver->solve(); $this->assertSame($expected, $type); @@ -50,9 +50,9 @@ public function testWalkOutside($testMarker, $expected) * * @see testWalkOutside() For the array format. * - * @return array + * @return array> */ - public function dataWalkOutside() + public static function dataWalkOutside() { return [ 'nested-short-array-start-of-file' => [ @@ -186,9 +186,9 @@ public function testReuseCacheFromAdjacent($testMarker, $adjacent1, $adjacent2, * * @see testReuseCacheFromAdjacent() For the array format. * - * @return array + * @return array> */ - public function dataReuseCacheFromAdjacent() + public static function dataReuseCacheFromAdjacent() { return [ 'nested-short-array' => [ diff --git a/Tests/Internal/IsShortArrayOrListWithCache/CachingTest.php b/Tests/Internal/IsShortArrayOrListWithCache/CachingTest.php index 3fd0f45c..63918ee9 100644 --- a/Tests/Internal/IsShortArrayOrListWithCache/CachingTest.php +++ b/Tests/Internal/IsShortArrayOrListWithCache/CachingTest.php @@ -67,9 +67,9 @@ public function testResultIsCached($testMarker, $expected) /** * Data provider. * - * @return array + * @return array> */ - public function dataResultIsCached() + public static function dataResultIsCached() { return [ 'short array' => [ diff --git a/Tests/Internal/IsShortArrayOrListWithCache/EntryPointsTest.php b/Tests/Internal/IsShortArrayOrListWithCache/EntryPointsTest.php index 0bbee83f..057f6b29 100644 --- a/Tests/Internal/IsShortArrayOrListWithCache/EntryPointsTest.php +++ b/Tests/Internal/IsShortArrayOrListWithCache/EntryPointsTest.php @@ -29,7 +29,7 @@ final class EntryPointsTest extends IsShortArrayOrListWithCacheTestCase /** * Return values in use for the IsShortArrayOrListWithCache::solve() method. * - * @var string[] + * @var array */ private $validValues = [ IsShortArrayOrList::SHORT_ARRAY, @@ -45,8 +45,8 @@ final class EntryPointsTest extends IsShortArrayOrListWithCacheTestCase * * @covers \PHPCSUtils\Utils\Arrays::isShortArray * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the file. + * @param int|string|array $targetType The token type(s) to look for. * * @return void */ @@ -63,8 +63,8 @@ public function testIsShortArrayApi($testMarker, $targetType) * * @covers \PHPCSUtils\Utils\Lists::isShortList * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the file. + * @param int|string|array $targetType The token type(s) to look for. * * @return void */ @@ -82,8 +82,8 @@ public function testIsShortListApi($testMarker, $targetType) * * @covers \PHPCSUtils\Internal\IsShortArrayOrListWithCache::isShortArray * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the file. + * @param int|string|array $targetType The token type(s) to look for. * * @return void */ @@ -101,8 +101,8 @@ public function testIsShortArrayInternal($testMarker, $targetType) * * @covers \PHPCSUtils\Internal\IsShortArrayOrListWithCache::isShortList * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the file. + * @param int|string|array $targetType The token type(s) to look for. * * @return void */ @@ -120,8 +120,8 @@ public function testIsShortListInternal($testMarker, $targetType) * * @covers \PHPCSUtils\Internal\IsShortArrayOrListWithCache::getType * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the file. + * @param int|string|array $targetType The token type(s) to look for. * * @return void */ @@ -134,9 +134,9 @@ public function testGetTypeInternal($testMarker, $targetType) /** * Data provider. * - * @return array + * @return array>> */ - public function dataEntryPoints() + public static function dataEntryPoints() { return [ 'not a square bracket' => [ diff --git a/Tests/Internal/IsShortArrayOrListWithCache/IsValidStackPtrTest.php b/Tests/Internal/IsShortArrayOrListWithCache/IsValidStackPtrTest.php index eadbbdd2..62d620c1 100644 --- a/Tests/Internal/IsShortArrayOrListWithCache/IsValidStackPtrTest.php +++ b/Tests/Internal/IsShortArrayOrListWithCache/IsValidStackPtrTest.php @@ -27,7 +27,7 @@ final class IsValidStackPtrTest extends IsShortArrayOrListWithCacheTestCase /** * Return values in use for square brackets. * - * @var string[] + * @var array */ private $validValues = [ IsShortArrayOrList::SHORT_ARRAY, @@ -50,8 +50,8 @@ public function testNonExistentToken() * * @dataProvider dataNotBracket * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetType The token type(s) to look for. * * @return void */ @@ -66,9 +66,9 @@ public function testNotBracket($testMarker, $targetType) * * @see testNotBracket() For the array format. * - * @return array + * @return array> */ - public function dataNotBracket() + public static function dataNotBracket() { return [ 'long-array' => [ @@ -89,8 +89,8 @@ public function dataNotBracket() * * @dataProvider dataValidBracket * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetType The token type(s) to look for. * * @return void */ @@ -107,9 +107,9 @@ public function testValidBracket($testMarker, $targetType) * * @see testNotBracket() For the array format. * - * @return array + * @return array> */ - public function dataValidBracket() + public static function dataValidBracket() { return [ 'open square bracket' => [ diff --git a/Tests/Internal/IsShortArrayOrListWithCache/ProcessTest.php b/Tests/Internal/IsShortArrayOrListWithCache/ProcessTest.php index 7a651867..83472c68 100644 --- a/Tests/Internal/IsShortArrayOrListWithCache/ProcessTest.php +++ b/Tests/Internal/IsShortArrayOrListWithCache/ProcessTest.php @@ -42,9 +42,9 @@ public function testInvalidStackPtr() * * @dataProvider dataSupportedBrackets * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. - * @param string|false $expected The expected function return value. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetType The token type(s) to look for. + * @param string $expected The expected function return value. * * @return void */ @@ -59,9 +59,9 @@ public function testSupportedBrackets($testMarker, $targetType, $expected) * * @see testSupportedBrackets() For the array format. * - * @return array + * @return array> */ - public function dataSupportedBrackets() + public static function dataSupportedBrackets() { return [ 'short array open bracket' => [ diff --git a/Tests/Internal/NoFileCache/GetClearTest.php b/Tests/Internal/NoFileCache/GetClearTest.php index e00ca447..840bb9d4 100644 --- a/Tests/Internal/NoFileCache/GetClearTest.php +++ b/Tests/Internal/NoFileCache/GetClearTest.php @@ -232,9 +232,9 @@ public function testGetWillRetrievedPreviouslySetValue($id, $expected) /** * Data provider. * - * @return array + * @return array> */ - public function dataEveryTypeOfInput() + public static function dataEveryTypeOfInput() { $allTypes = TypeProviderHelper::getAll(); $data = []; @@ -265,7 +265,7 @@ public function testGetForKey() /** * Test that previously cached data is no longer available when the cache has been cleared. * - * @dataProvider dataEveryTypeOfInput + * @dataProvider dataClearCache * * @covers ::clear * @@ -280,4 +280,22 @@ public function testClearCache($id) $this->assertFalse(NoFileCache::isCached('Utility1', $id)); $this->assertFalse(NoFileCache::isCached('Utility2', $id)); } + + /** + * Data provider. + * + * @see testClearCache() For the array format. + * + * @return array> + */ + public static function dataClearCache() + { + $data = self::dataEveryTypeOfInput(); + + foreach ($data as $name => $dataset) { + unset($data[$name]['expected']); + } + + return $data; + } } diff --git a/Tests/Internal/NoFileCache/SetTest.php b/Tests/Internal/NoFileCache/SetTest.php index 916f53f0..b672f047 100644 --- a/Tests/Internal/NoFileCache/SetTest.php +++ b/Tests/Internal/NoFileCache/SetTest.php @@ -89,7 +89,7 @@ public static function resetCachingStatus() */ public function testSetAcceptsEveryTypeOfInput($input) { - $id = $this->getName(); + $id = \base_convert((string) \rand((int) 10e16, (int) 10e20), 10, 36); NoFileCache::set(__METHOD__, $id, $input); $this->assertTrue( @@ -107,9 +107,9 @@ public function testSetAcceptsEveryTypeOfInput($input) /** * Data provider. * - * @return array + * @return array> */ - public function dataEveryTypeOfInput() + public static function dataEveryTypeOfInput() { return TypeProviderHelper::getAll(); } @@ -149,9 +149,9 @@ public function testSetAcceptsIntAndStringIdKeys($id) /** * Data provider. * - * @return array + * @return array> */ - public function dataSetAcceptsIntAndStringIdKeys() + public static function dataSetAcceptsIntAndStringIdKeys() { return [ 'ID: int zero' => [ diff --git a/Tests/PolyfilledTestCase.php b/Tests/PolyfilledTestCase.php index 58af5e3d..7bb6b70a 100644 --- a/Tests/PolyfilledTestCase.php +++ b/Tests/PolyfilledTestCase.php @@ -6,20 +6,28 @@ * @copyright 2019-2020 PHPCSUtils Contributors * @license https://opensource.org/licenses/LGPL-3.0 LGPL3 * @link https://github.com/PHPCSStandards/PHPCSUtils + * + * @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses + * @phpcs:disable Generic.Files.OneObjectStructurePerFile.MultipleFound */ namespace PHPCSUtils\Tests; -use PHPCSUtils\Tests\AssertAttributeSame; +use PHPCSUtils\Tests\AssertPropertySame; +use PHPCSUtils\Tests\ExpectWithConsecutiveArgs; use PHPCSUtils\TestUtils\UtilityMethodTestCase; +use Yoast\PHPUnitPolyfills\Autoload; 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; @@ -27,39 +35,80 @@ use Yoast\PHPUnitPolyfills\Polyfills\ExpectExceptionObject; use Yoast\PHPUnitPolyfills\Polyfills\ExpectPHPException; -/** - * Abstract utilty method base test case which includes all available polyfills. - * - * This test case includes all polyfills from the PHPUnit Polyfill library to make them - * available to the tests. - * - * Generally speaking, this testcase only needs to be used when the concrete test class will - * use functionality which has changed in PHPUnit cross-version. - * In all other cases, the `UtilityMethodTestCase` can be extended directly. - * - * {@internal The list of included polyfill traits should be reviewed after each new - * release of the PHPUnit Polyfill library.} - * - * @since 1.0.0 - */ -abstract class PolyfilledTestCase extends UtilityMethodTestCase -{ - // PHPCSUtils native helper. - use AssertAttributeSame; +if (\version_compare(Autoload::VERSION, '2.0.0', '>=')) { + /** + * Abstract utility method base test case which includes all available polyfills (PHPUnit Polyfills 2.x compaible). + * + * This test case includes all polyfills from the PHPUnit Polyfill library to make them + * available to the tests. + * + * Generally speaking, this testcase only needs to be used when the concrete test class will + * use functionality which has changed in PHPUnit cross-version. + * In all other cases, the `UtilityMethodTestCase` can be extended directly. + * + * {@internal The list of included polyfill traits should be reviewed after each new + * release of the PHPUnit Polyfill library.} + * + * @since 1.0.0 + */ + abstract class PolyfilledTestCase extends UtilityMethodTestCase + { + // PHPCSUtils native helpers. + use AssertPropertySame; + use ExpectWithConsecutiveArgs; + + // PHPUnit Polyfills. + use AssertClosedResource; + use AssertEqualsSpecializations; + use AssertFileEqualsSpecializations; + use AssertIgnoringLineEndings; + use AssertionRenames; + use AssertIsList; + use AssertIsType; + use AssertObjectEquals; + use AssertObjectProperty; + use AssertStringContains; + use EqualToSpecializations; + use ExpectExceptionMessageMatches; + use ExpectExceptionObject; + } +} else { + /** + * Abstract utility method base test case which includes all available polyfills (PHPUnit Polyfills 1.x compaible). + * + * This test case includes all polyfills from the PHPUnit Polyfill library to make them + * available to the tests. + * + * Generally speaking, this testcase only needs to be used when the concrete test class will + * use functionality which has changed in PHPUnit cross-version. + * In all other cases, the `UtilityMethodTestCase` can be extended directly. + * + * {@internal The list of included polyfill traits should be reviewed after each new + * release of the PHPUnit Polyfill library.} + * + * @since 1.0.0 + */ + abstract class PolyfilledTestCase extends UtilityMethodTestCase + { + // PHPCSUtils native helper. + use AssertPropertySame; + use ExpectWithConsecutiveArgs; - // PHPUnit Polyfills. - use AssertClosedResource; - use AssertEqualsSpecializations; - use AssertFileDirectory; - use AssertFileEqualsSpecializations; - use AssertionRenames; - use AssertIsType; - use AssertNumericType; - use AssertObjectEquals; - use AssertStringContains; - use EqualToSpecializations; - use ExpectException; - use ExpectExceptionMessageMatches; - use ExpectExceptionObject; - use ExpectPHPException; + // PHPUnit Polyfills. + use AssertClosedResource; + use AssertEqualsSpecializations; + use AssertFileDirectory; + use AssertFileEqualsSpecializations; + use AssertionRenames; + use AssertIsType; + use AssertNumericType; + use AssertObjectEquals; + use AssertObjectProperty; + use AssertStringContains; + use EqualToSpecializations; + use ExpectException; + use ExpectExceptionMessageMatches; + use ExpectExceptionObject; + use ExpectPHPException; + } } diff --git a/Tests/TestUtils/UtilityMethodTestCase/ExpectPhpcsExceptionTest.php b/Tests/TestUtils/UtilityMethodTestCase/ExpectPhpcsExceptionTest.php index 5b31884a..542911b2 100644 --- a/Tests/TestUtils/UtilityMethodTestCase/ExpectPhpcsExceptionTest.php +++ b/Tests/TestUtils/UtilityMethodTestCase/ExpectPhpcsExceptionTest.php @@ -19,8 +19,6 @@ * * @covers \PHPCSUtils\TestUtils\UtilityMethodTestCase::expectPhpcsException * - * @group testutils - * * @since 1.0.0 */ final class ExpectPhpcsExceptionTest extends UtilityMethodTestCase diff --git a/Tests/TestUtils/UtilityMethodTestCase/FailedToTokenizeTest.php b/Tests/TestUtils/UtilityMethodTestCase/FailedToTokenizeTest.php index 988d89b3..f6356f73 100644 --- a/Tests/TestUtils/UtilityMethodTestCase/FailedToTokenizeTest.php +++ b/Tests/TestUtils/UtilityMethodTestCase/FailedToTokenizeTest.php @@ -17,8 +17,6 @@ * * @covers \PHPCSUtils\TestUtils\UtilityMethodTestCase::setUpTestFile * - * @group testutils - * * @since 1.0.0 */ final class FailedToTokenizeTest extends PolyfilledTestCase diff --git a/Tests/TestUtils/UtilityMethodTestCase/GetTargetTokenFileNotFoundTest.php b/Tests/TestUtils/UtilityMethodTestCase/GetTargetTokenFileNotFoundTest.php index 1990b7b6..01e112c7 100644 --- a/Tests/TestUtils/UtilityMethodTestCase/GetTargetTokenFileNotFoundTest.php +++ b/Tests/TestUtils/UtilityMethodTestCase/GetTargetTokenFileNotFoundTest.php @@ -17,8 +17,6 @@ * * @covers \PHPCSUtils\TestUtils\UtilityMethodTestCase::getTargetToken * - * @group testutils - * * @since 1.0.0 */ final class GetTargetTokenFileNotFoundTest extends PolyfilledTestCase diff --git a/Tests/TestUtils/UtilityMethodTestCase/GetTargetTokenTest.php b/Tests/TestUtils/UtilityMethodTestCase/GetTargetTokenTest.php index 162da8f5..c4dcb7f7 100644 --- a/Tests/TestUtils/UtilityMethodTestCase/GetTargetTokenTest.php +++ b/Tests/TestUtils/UtilityMethodTestCase/GetTargetTokenTest.php @@ -17,8 +17,6 @@ * * @covers \PHPCSUtils\TestUtils\UtilityMethodTestCase::getTargetToken * - * @group testutils - * * @since 1.0.0 */ final class GetTargetTokenTest extends PolyfilledTestCase @@ -42,10 +40,10 @@ public static function setUpTestFile() * * @dataProvider dataGetTargetToken * - * @param int|false $expected Expected function output. - * @param string $commentString The delimiter comment to look for. - * @param int|string|array $tokenType The type of token(s) to look for. - * @param string $tokenContent Optional. The token content for the target token. + * @param int $expected Expected function output. + * @param string $commentString The delimiter comment to look for. + * @param int|string|array $tokenType The type of token(s) to look for. + * @param string $tokenContent Optional. The token content for the target token. * * @return void */ @@ -65,9 +63,9 @@ public function testGetTargetToken($expected, $commentString, $tokenType, $token * * @see testGetTargetToken() For the array format. * - * @return array + * @return array>> */ - public function dataGetTargetToken() + public static function dataGetTargetToken() { return [ 'single-token-type' => [ diff --git a/Tests/TestUtils/UtilityMethodTestCase/MissingCaseFileTest.php b/Tests/TestUtils/UtilityMethodTestCase/MissingCaseFileTest.php index ead82dfa..58b8cea1 100644 --- a/Tests/TestUtils/UtilityMethodTestCase/MissingCaseFileTest.php +++ b/Tests/TestUtils/UtilityMethodTestCase/MissingCaseFileTest.php @@ -17,8 +17,6 @@ * * @covers \PHPCSUtils\TestUtils\UtilityMethodTestCase::setUpTestFile * - * @group testutils - * * @since 1.0.0 */ final class MissingCaseFileTest extends PolyfilledTestCase diff --git a/Tests/TestUtils/UtilityMethodTestCase/SkipJSCSSTestsOnPHPCS4Test.php b/Tests/TestUtils/UtilityMethodTestCase/SkipJSCSSTestsOnPHPCS4Test.php index 76064d2c..6d71e6b4 100644 --- a/Tests/TestUtils/UtilityMethodTestCase/SkipJSCSSTestsOnPHPCS4Test.php +++ b/Tests/TestUtils/UtilityMethodTestCase/SkipJSCSSTestsOnPHPCS4Test.php @@ -17,8 +17,6 @@ * * @covers \PHPCSUtils\TestUtils\UtilityMethodTestCase::skipJSCSSTestsOnPHPCS4 * - * @group testutils - * * @since 1.0.0 */ final class SkipJSCSSTestsOnPHPCS4Test extends PolyfilledTestCase @@ -53,7 +51,11 @@ public function testSkipJsCss() if (\version_compare(parent::$phpcsVersion, '3.99.99', '>') === true) { $msg = 'JS and CSS support has been removed in PHPCS 4.'; $exception = 'PHPUnit\Framework\SkippedTestError'; - if (\class_exists('PHPUnit_Framework_SkippedTestError')) { + + if (\class_exists('PHPUnit\Framework\SkippedWithMessageException')) { + // PHPUnit 10+. + $exception = 'PHPUnit\Framework\SkippedWithMessageException'; + } elseif (\class_exists('PHPUnit_Framework_SkippedTestError')) { // PHPUnit < 6. $exception = 'PHPUnit_Framework_SkippedTestError'; } diff --git a/Tests/TestUtils/UtilityMethodTestCase/UtilityMethodTestCaseTest.php b/Tests/TestUtils/UtilityMethodTestCase/UtilityMethodTestCaseTest.php index 6247c17f..137f440b 100644 --- a/Tests/TestUtils/UtilityMethodTestCase/UtilityMethodTestCaseTest.php +++ b/Tests/TestUtils/UtilityMethodTestCase/UtilityMethodTestCaseTest.php @@ -17,8 +17,6 @@ * * @covers \PHPCSUtils\TestUtils\UtilityMethodTestCase * - * @group testutils - * * @since 1.0.0 */ final class UtilityMethodTestCaseTest extends PolyfilledTestCase diff --git a/Tests/Tokens/Collections/ArrayOpenTokensBCTest.php b/Tests/Tokens/Collections/ArrayOpenTokensBCTest.php index 12568b4e..60f90060 100644 --- a/Tests/Tokens/Collections/ArrayOpenTokensBCTest.php +++ b/Tests/Tokens/Collections/ArrayOpenTokensBCTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -19,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::arrayOpenTokensBC * - * @group collections - * * @since 1.0.2 */ final class ArrayOpenTokensBCTest extends TestCase @@ -38,10 +35,6 @@ public function testArrayOpenTokensBC() \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, ]; - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $expected[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - } - $this->assertSame($expected, Collections::arrayOpenTokensBC()); } } diff --git a/Tests/Tokens/Collections/ArrayTokensBCTest.php b/Tests/Tokens/Collections/ArrayTokensBCTest.php index 009b825e..c3f2a9c8 100644 --- a/Tests/Tokens/Collections/ArrayTokensBCTest.php +++ b/Tests/Tokens/Collections/ArrayTokensBCTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -19,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::arrayTokensBC * - * @group collections - * * @since 1.0.2 */ final class ArrayTokensBCTest extends TestCase @@ -39,11 +36,6 @@ public function testArrayTokensBC() \T_CLOSE_SHORT_ARRAY => \T_CLOSE_SHORT_ARRAY, ]; - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $expected[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - $expected[\T_CLOSE_SQUARE_BRACKET] = \T_CLOSE_SQUARE_BRACKET; - } - $this->assertSame($expected, Collections::arrayTokensBC()); } } diff --git a/Tests/Tokens/Collections/FunctionCallTokensTest.php b/Tests/Tokens/Collections/FunctionCallTokensTest.php index 2c7b0fb3..ce3a6ad4 100644 --- a/Tests/Tokens/Collections/FunctionCallTokensTest.php +++ b/Tests/Tokens/Collections/FunctionCallTokensTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::functionCallTokens * - * @group collections - * * @since 1.0.0 */ final class FunctionCallTokensTest extends TestCase diff --git a/Tests/Tokens/Collections/ListOpenTokensBCTest.php b/Tests/Tokens/Collections/ListOpenTokensBCTest.php index 487d8942..571eef2d 100644 --- a/Tests/Tokens/Collections/ListOpenTokensBCTest.php +++ b/Tests/Tokens/Collections/ListOpenTokensBCTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -19,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::listOpenTokensBC * - * @group collections - * * @since 1.0.2 */ final class ListOpenTokensBCTest extends TestCase @@ -38,10 +35,6 @@ public function testListOpenTokensBC() \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, ]; - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $expected[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - } - $this->assertSame($expected, Collections::listOpenTokensBC()); } } diff --git a/Tests/Tokens/Collections/ListTokensBCTest.php b/Tests/Tokens/Collections/ListTokensBCTest.php index fd94860b..8936c863 100644 --- a/Tests/Tokens/Collections/ListTokensBCTest.php +++ b/Tests/Tokens/Collections/ListTokensBCTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -19,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::listTokensBC * - * @group collections - * * @since 1.0.2 */ final class ListTokensBCTest extends TestCase @@ -39,11 +36,6 @@ public function testListTokensBC() \T_CLOSE_SHORT_ARRAY => \T_CLOSE_SHORT_ARRAY, ]; - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $expected[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - $expected[\T_CLOSE_SQUARE_BRACKET] = \T_CLOSE_SQUARE_BRACKET; - } - $this->assertSame($expected, Collections::listTokensBC()); } } diff --git a/Tests/Tokens/Collections/NamespacedNameTokensTest.php b/Tests/Tokens/Collections/NamespacedNameTokensTest.php index 9fb3d4c1..9c081b8e 100644 --- a/Tests/Tokens/Collections/NamespacedNameTokensTest.php +++ b/Tests/Tokens/Collections/NamespacedNameTokensTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::namespacedNameTokens * - * @group collections - * * @since 1.0.0 */ final class NamespacedNameTokensTest extends TestCase diff --git a/Tests/Tokens/Collections/ParameterPassingTokensTest.php b/Tests/Tokens/Collections/ParameterPassingTokensTest.php index 9638edd6..e26255cb 100644 --- a/Tests/Tokens/Collections/ParameterPassingTokensTest.php +++ b/Tests/Tokens/Collections/ParameterPassingTokensTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -19,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::parameterPassingTokens * - * @group collections - * * @since 1.0.0 */ final class ParameterPassingTokensTest extends TestCase @@ -49,10 +46,6 @@ public function testParameterPassingTokens() \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, ]; - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $expected[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - } - $this->assertSame($expected, Collections::parameterPassingTokens()); } } diff --git a/Tests/Tokens/Collections/ParameterTypeTokensTest.php b/Tests/Tokens/Collections/ParameterTypeTokensTest.php index 417741cb..d5a31389 100644 --- a/Tests/Tokens/Collections/ParameterTypeTokensTest.php +++ b/Tests/Tokens/Collections/ParameterTypeTokensTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::parameterTypeTokens * - * @group collections - * * @since 1.0.0 */ final class ParameterTypeTokensTest extends TestCase @@ -33,20 +31,22 @@ final class ParameterTypeTokensTest extends TestCase public function testParameterTypeTokens() { $expected = [ - \T_CALLABLE => \T_CALLABLE, - \T_SELF => \T_SELF, - \T_PARENT => \T_PARENT, - \T_FALSE => \T_FALSE, - \T_TRUE => \T_TRUE, - \T_NULL => \T_NULL, - \T_TYPE_UNION => \T_TYPE_UNION, - \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, - \T_NS_SEPARATOR => \T_NS_SEPARATOR, - \T_NAMESPACE => \T_NAMESPACE, - \T_STRING => \T_STRING, - \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, - \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, - \T_NAME_RELATIVE => \T_NAME_RELATIVE, + \T_CALLABLE => \T_CALLABLE, + \T_SELF => \T_SELF, + \T_PARENT => \T_PARENT, + \T_FALSE => \T_FALSE, + \T_TRUE => \T_TRUE, + \T_NULL => \T_NULL, + \T_TYPE_UNION => \T_TYPE_UNION, + \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, + \T_TYPE_OPEN_PARENTHESIS => \T_TYPE_OPEN_PARENTHESIS, + \T_TYPE_CLOSE_PARENTHESIS => \T_TYPE_CLOSE_PARENTHESIS, + \T_NS_SEPARATOR => \T_NS_SEPARATOR, + \T_NAMESPACE => \T_NAMESPACE, + \T_STRING => \T_STRING, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, ]; $this->assertSame($expected, Collections::parameterTypeTokens()); diff --git a/Tests/Tokens/Collections/PropertyBasedTokenArraysTest.php b/Tests/Tokens/Collections/PropertyBasedTokenArraysTest.php index b2113575..e9b40f68 100644 --- a/Tests/Tokens/Collections/PropertyBasedTokenArraysTest.php +++ b/Tests/Tokens/Collections/PropertyBasedTokenArraysTest.php @@ -19,8 +19,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::__callStatic * - * @group collections - * * @since 1.0.0 */ final class PropertyBasedTokenArraysTest extends TestCase @@ -50,9 +48,9 @@ public function testPropertyBasedTokenArrays($name) * * @see testPropertyBasedTokenArrays() For the array format. * - * @return array + * @return array> */ - public function dataPropertyBasedTokenArrays() + public static function dataPropertyBasedTokenArrays() { $names = [ 'alternativeControlStructureSyntaxes', diff --git a/Tests/Tokens/Collections/PropertyTypeTokensTest.php b/Tests/Tokens/Collections/PropertyTypeTokensTest.php index d2c3aeae..bb6eb396 100644 --- a/Tests/Tokens/Collections/PropertyTypeTokensTest.php +++ b/Tests/Tokens/Collections/PropertyTypeTokensTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::propertyTypeTokens * - * @group collections - * * @since 1.0.0 */ final class PropertyTypeTokensTest extends TestCase @@ -33,20 +31,22 @@ final class PropertyTypeTokensTest extends TestCase public function testPropertyTypeTokens() { $expected = [ - \T_CALLABLE => \T_CALLABLE, - \T_SELF => \T_SELF, - \T_PARENT => \T_PARENT, - \T_FALSE => \T_FALSE, - \T_TRUE => \T_TRUE, - \T_NULL => \T_NULL, - \T_TYPE_UNION => \T_TYPE_UNION, - \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, - \T_NS_SEPARATOR => \T_NS_SEPARATOR, - \T_NAMESPACE => \T_NAMESPACE, - \T_STRING => \T_STRING, - \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, - \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, - \T_NAME_RELATIVE => \T_NAME_RELATIVE, + \T_CALLABLE => \T_CALLABLE, + \T_SELF => \T_SELF, + \T_PARENT => \T_PARENT, + \T_FALSE => \T_FALSE, + \T_TRUE => \T_TRUE, + \T_NULL => \T_NULL, + \T_TYPE_UNION => \T_TYPE_UNION, + \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, + \T_TYPE_OPEN_PARENTHESIS => \T_TYPE_OPEN_PARENTHESIS, + \T_TYPE_CLOSE_PARENTHESIS => \T_TYPE_CLOSE_PARENTHESIS, + \T_NS_SEPARATOR => \T_NS_SEPARATOR, + \T_NAMESPACE => \T_NAMESPACE, + \T_STRING => \T_STRING, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, ]; $this->assertSame($expected, Collections::propertyTypeTokens()); diff --git a/Tests/Tokens/Collections/ReturnTypeTokensTest.php b/Tests/Tokens/Collections/ReturnTypeTokensTest.php index 085061c7..9357ac1c 100644 --- a/Tests/Tokens/Collections/ReturnTypeTokensTest.php +++ b/Tests/Tokens/Collections/ReturnTypeTokensTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::returnTypeTokens * - * @group collections - * * @since 1.0.0 */ final class ReturnTypeTokensTest extends TestCase @@ -33,21 +31,23 @@ final class ReturnTypeTokensTest extends TestCase public function testReturnTypeTokens() { $expected = [ - \T_CALLABLE => \T_CALLABLE, - \T_FALSE => \T_FALSE, - \T_TRUE => \T_TRUE, - \T_NULL => \T_NULL, - \T_TYPE_UNION => \T_TYPE_UNION, - \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, - \T_PARENT => \T_PARENT, - \T_SELF => \T_SELF, - \T_STATIC => \T_STATIC, - \T_NS_SEPARATOR => \T_NS_SEPARATOR, - \T_NAMESPACE => \T_NAMESPACE, - \T_STRING => \T_STRING, - \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, - \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, - \T_NAME_RELATIVE => \T_NAME_RELATIVE, + \T_CALLABLE => \T_CALLABLE, + \T_FALSE => \T_FALSE, + \T_TRUE => \T_TRUE, + \T_NULL => \T_NULL, + \T_TYPE_UNION => \T_TYPE_UNION, + \T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION, + \T_TYPE_OPEN_PARENTHESIS => \T_TYPE_OPEN_PARENTHESIS, + \T_TYPE_CLOSE_PARENTHESIS => \T_TYPE_CLOSE_PARENTHESIS, + \T_PARENT => \T_PARENT, + \T_SELF => \T_SELF, + \T_STATIC => \T_STATIC, + \T_NS_SEPARATOR => \T_NS_SEPARATOR, + \T_NAMESPACE => \T_NAMESPACE, + \T_STRING => \T_STRING, + \T_NAME_QUALIFIED => \T_NAME_QUALIFIED, + \T_NAME_FULLY_QUALIFIED => \T_NAME_FULLY_QUALIFIED, + \T_NAME_RELATIVE => \T_NAME_RELATIVE, ]; $this->assertSame($expected, Collections::returnTypeTokens()); diff --git a/Tests/Tokens/Collections/ShortArrayListOpenTokensBCTest.php b/Tests/Tokens/Collections/ShortArrayListOpenTokensBCTest.php index 81526b2e..55bff891 100644 --- a/Tests/Tokens/Collections/ShortArrayListOpenTokensBCTest.php +++ b/Tests/Tokens/Collections/ShortArrayListOpenTokensBCTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -19,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::shortArrayListOpenTokensBC * - * @group collections - * * @since 1.0.2 */ final class ShortArrayListOpenTokensBCTest extends TestCase @@ -37,10 +34,6 @@ public function testShortArrayListOpenTokensBC() \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY, ]; - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $expected[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - } - $this->assertSame($expected, Collections::shortArrayListOpenTokensBC()); } } diff --git a/Tests/Tokens/Collections/ShortArrayTokensBCTest.php b/Tests/Tokens/Collections/ShortArrayTokensBCTest.php index 4c023e26..07f36c3a 100644 --- a/Tests/Tokens/Collections/ShortArrayTokensBCTest.php +++ b/Tests/Tokens/Collections/ShortArrayTokensBCTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -19,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::shortArrayTokensBC * - * @group collections - * * @since 1.0.2 */ final class ShortArrayTokensBCTest extends TestCase @@ -38,11 +35,6 @@ public function testShortArrayTokensBC() \T_CLOSE_SHORT_ARRAY => \T_CLOSE_SHORT_ARRAY, ]; - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $expected[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - $expected[\T_CLOSE_SQUARE_BRACKET] = \T_CLOSE_SQUARE_BRACKET; - } - $this->assertSame($expected, Collections::shortArrayTokensBC()); } } diff --git a/Tests/Tokens/Collections/ShortListTokensBCTest.php b/Tests/Tokens/Collections/ShortListTokensBCTest.php index e2775f0a..10a36c61 100644 --- a/Tests/Tokens/Collections/ShortListTokensBCTest.php +++ b/Tests/Tokens/Collections/ShortListTokensBCTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Tokens\Collections; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tokens\Collections; use PHPUnit\Framework\TestCase; @@ -19,8 +18,6 @@ * * @covers \PHPCSUtils\Tokens\Collections::shortListTokensBC * - * @group collections - * * @since 1.0.2 */ final class ShortListTokensBCTest extends TestCase @@ -38,11 +35,6 @@ public function testShortListTokensBC() \T_CLOSE_SHORT_ARRAY => \T_CLOSE_SHORT_ARRAY, ]; - if (\version_compare(Helper::getVersion(), '3.7.1', '<=')) { - $expected[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET; - $expected[\T_CLOSE_SQUARE_BRACKET] = \T_CLOSE_SQUARE_BRACKET; - } - $this->assertSame($expected, Collections::shortListTokensBC()); } } diff --git a/Tests/Tokens/TokenHelper/TokenExistsTest.php b/Tests/Tokens/TokenHelper/TokenExistsTest.php index 96f23266..718737ef 100644 --- a/Tests/Tokens/TokenHelper/TokenExistsTest.php +++ b/Tests/Tokens/TokenHelper/TokenExistsTest.php @@ -58,11 +58,11 @@ public function testTokenExists($name, $expected) * {@internal This dataprovider does not currently contain any tests for * PHP native tokens which may not exist (depending on the PHPCS version). * These tests are not relevant at this time with the current minimum - * PHPCS version of 3.7.1, but this may change again in the future.} + * PHPCS version, but this may change again in the future.} * - * @return array + * @return array> */ - public function dataTokenExists() + public static function dataTokenExists() { return [ 'Token which doesn\'t exist either way' => [ diff --git a/Tests/Utils/Arrays/GetDoubleArrowPtrTest.inc b/Tests/Utils/Arrays/GetDoubleArrowPtrTest.inc index c0e6a866..ce5a865b 100644 --- a/Tests/Utils/Arrays/GetDoubleArrowPtrTest.inc +++ b/Tests/Utils/Arrays/GetDoubleArrowPtrTest.inc @@ -104,6 +104,12 @@ $array = [ FOO => BAR, default => [0 => 10], } => 'value', + + /* testNoArrowKeyedLongListInValue */ + list( 'key1' => $a, 'key2' => $b ) = $array, + + /* testNoArrowKeyedShortListInValue */ + [ 'key1' => $a, 'key2' => $b ] = $array, /* testNoArrowValueClosureWithAttribute */ #[MyAttribute([0 => 'value'])] function() { /* do something */ }(), diff --git a/Tests/Utils/Arrays/GetDoubleArrowPtrTest.php b/Tests/Utils/Arrays/GetDoubleArrowPtrTest.php index 8ff7fa75..cb072944 100644 --- a/Tests/Utils/Arrays/GetDoubleArrowPtrTest.php +++ b/Tests/Utils/Arrays/GetDoubleArrowPtrTest.php @@ -20,8 +20,6 @@ * * @covers \PHPCSUtils\Utils\Arrays::getDoubleArrowPtr * - * @group arrays - * * @since 1.0.0 */ final class GetDoubleArrowPtrTest extends UtilityMethodTestCase @@ -30,7 +28,7 @@ final class GetDoubleArrowPtrTest extends UtilityMethodTestCase /** * Cache for the parsed parameters array. * - * @var array => + * @var array> */ private static $parameters = []; @@ -106,8 +104,8 @@ public function testInvalidStartEndPositionException() * * @dataProvider dataGetDoubleArrowPtr * - * @param string $testMarker The comment which is part of the target array item in the test file. - * @param array $expected The expected function call result. + * @param string $testMarker The comment which is part of the target array item in the test file. + * @param int|bool $expected The expected function call result. * * @return void */ @@ -136,9 +134,9 @@ public function testGetDoubleArrowPtr($testMarker, $expected) * * @see testGetDoubleArrowPtr() * - * @return array + * @return array> */ - public function dataGetDoubleArrowPtr() + public static function dataGetDoubleArrowPtr() { return [ 'test-no-arrow' => [ @@ -210,7 +208,8 @@ public function dataGetDoubleArrowPtr() 'expected' => 8, ], // Test specifically for PHPCS 3.5.3 and 3.5.4 in which all "fn" tokens were tokenized as T_FN. - // While PHPCS < 3.7.1 is no longer supported, the test remains to safeguard against tokenizer regressions. + // While these PHPCS versions are no longer supported, the test remains to safeguard against + // tokenizer regressions. 'test-arrow-access-to-property-named-fn-as-key-phpcs-3.5.3-3.5.4' => [ 'testMarker' => '/* testKeyPropertyAccessFnPHPCS353-354 */', 'expected' => 12, @@ -234,6 +233,16 @@ public function dataGetDoubleArrowPtr() 'expected' => 38, ], + // Safeguard that PHP 7.2 keyed lists in values are handled correctly. + 'test-no-arrow-value-keyed-long-list' => [ + 'testMarker' => '/* testNoArrowKeyedLongListInValue */', + 'expected' => false, + ], + 'test-no-arrow-value-keyed-short-list' => [ + 'testMarker' => '/* testNoArrowKeyedShortListInValue */', + 'expected' => false, + ], + // Safeguard that double arrows in PHP 8.0 attributes are disregarded. 'test-no-arrow-value-closure-with-attached-attribute-containing-arrow' => [ 'testMarker' => '/* testNoArrowValueClosureWithAttribute */', diff --git a/Tests/Utils/Arrays/GetOpenCloseTest.php b/Tests/Utils/Arrays/GetOpenCloseTest.php index 98a4dea9..bdcccb63 100644 --- a/Tests/Utils/Arrays/GetOpenCloseTest.php +++ b/Tests/Utils/Arrays/GetOpenCloseTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Arrays::getOpenClose * - * @group arrays - * * @since 1.0.0 */ final class GetOpenCloseTest extends UtilityMethodTestCase @@ -40,8 +38,8 @@ public function testNonExistentToken() * * @dataProvider dataNotArrayOpenToken * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetToken The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetToken The token type(s) to look for. * * @return void */ @@ -56,9 +54,9 @@ public function testNotArrayOpenToken($testMarker, $targetToken) * * @see testNotArrayOpenToken() For the array format. * - * @return array + * @return array> */ - public function dataNotArrayOpenToken() + public static function dataNotArrayOpenToken() { return [ 'short-list' => [ @@ -89,9 +87,9 @@ public function dataNotArrayOpenToken() * * @dataProvider dataGetOpenClose * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetToken The token type(s) to look for. - * @param array|false $expected The expected function return value. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetToken The token type(s) to look for. + * @param array|false $expected The expected function return value. * * @return void */ @@ -116,9 +114,9 @@ public function testGetOpenClose($testMarker, $targetToken, $expected) * * @see testGetOpenClose() For the array format. * - * @return array + * @return array|false>> */ - public function dataGetOpenClose() + public static function dataGetOpenClose() { return [ 'long-array' => [ diff --git a/Tests/Utils/Conditions/GetConditionTest.php b/Tests/Utils/Conditions/GetConditionTest.php index e2dcc63c..52d40116 100644 --- a/Tests/Utils/Conditions/GetConditionTest.php +++ b/Tests/Utils/Conditions/GetConditionTest.php @@ -148,9 +148,9 @@ public function testGetFirstCondition($testMarker) * * @see testGetFirstCondition() For the array format. * - * @return array + * @return array> */ - public function dataGetFirstCondition() + public static function dataGetFirstCondition() { $data = []; foreach (self::$testTargets as $marker) { @@ -165,9 +165,9 @@ public function dataGetFirstCondition() * * @dataProvider dataGetLastCondition * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The marker for the pointers to the expected condition - * results for the pre-set tests. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The marker for the pointers to the expected condition + * results for the pre-set tests. * * @return void */ @@ -193,9 +193,9 @@ public function testGetLastCondition($testMarker, $expected) * * @see testGetLastCondition() For the array format. * - * @return array + * @return array>> */ - public function dataGetLastCondition() + public static function dataGetLastCondition() { return [ 'testSeriouslyNestedMethod' => [ diff --git a/Tests/Utils/Context/InAttributeTest.php b/Tests/Utils/Context/InAttributeTest.php index 95333014..3cb9b8cb 100644 --- a/Tests/Utils/Context/InAttributeTest.php +++ b/Tests/Utils/Context/InAttributeTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Context::inAttribute * - * @group context - * * @since 1.0.0 */ final class InAttributeTest extends UtilityMethodTestCase @@ -40,8 +38,8 @@ public function testNonExistentToken() * * @dataProvider dataNotInAttribute * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetType The token type(s) to look for. * * @return void */ @@ -56,9 +54,9 @@ public function testNotInAttribute($testMarker, $targetType) * * @see testInAttribute() * - * @return array + * @return array> */ - public function dataNotInAttribute() + public static function dataNotInAttribute() { return [ 'code nowhere near an attribute [1]' => [ @@ -104,8 +102,8 @@ public function dataNotInAttribute() * * @dataProvider dataInAttribute * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetType The token type(s) to look for. * * @return void */ @@ -120,9 +118,9 @@ public function testInAttribute($testMarker, $targetType) * * @see testInAttribute() * - * @return array + * @return array> */ - public function dataInAttribute() + public static function dataInAttribute() { return [ 'single line attribute - attribute name' => [ diff --git a/Tests/Utils/Context/InEmptyTest.php b/Tests/Utils/Context/InEmptyTest.php index 0a49654a..f9b40f6c 100644 --- a/Tests/Utils/Context/InEmptyTest.php +++ b/Tests/Utils/Context/InEmptyTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Context::inEmpty * - * @group context - * * @since 1.0.0 */ final class InEmptyTest extends UtilityMethodTestCase @@ -56,9 +54,9 @@ public function testInEmpty($testMarker, $expected) * * @see testInEmpty() * - * @return array + * @return array> */ - public function dataInEmpty() + public static function dataInEmpty() { return [ 'method-called-empty' => [ diff --git a/Tests/Utils/Context/InForConditionTest.php b/Tests/Utils/Context/InForConditionTest.php index 57531278..b1897aee 100644 --- a/Tests/Utils/Context/InForConditionTest.php +++ b/Tests/Utils/Context/InForConditionTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Context::inForCondition * - * @group context - * * @since 1.0.0 */ final class InForConditionTest extends UtilityMethodTestCase @@ -55,9 +53,9 @@ public function testNotInFor($testMarker) * * @see testNotInFor() * - * @return array + * @return array> */ - public function dataNotInFor() + public static function dataNotInFor() { return [ 'no-parenthesis' => ['/* testNoParentheses */'], @@ -76,12 +74,12 @@ public function dataNotInFor() * * @dataProvider dataInForCondition * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param string $expected The expected function return value. - * @param int|string|array $targetType Optional. The token type of the target token. - * Defaults to T_VARIABLE. - * @param string $targetContent Optional. The token content of the target token. - * Defaults to `$target` for `T_VARIABLE`. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param string $expected The expected function return value. + * @param int|string $targetType Optional. The token type of the target token. + * Defaults to T_VARIABLE. + * @param string $targetContent Optional. The token content of the target token. + * Defaults to `$target` for `T_VARIABLE`. * * @return void */ @@ -101,9 +99,9 @@ public function testInForCondition($testMarker, $expected, $targetType = \T_VARI * * @see testInForCondition() * - * @return array + * @return array> */ - public function dataInForCondition() + public static function dataInForCondition() { return [ 'expr1' => [ diff --git a/Tests/Utils/Context/InForeachConditionTest.php b/Tests/Utils/Context/InForeachConditionTest.php index 4ce9f86c..0c66287f 100644 --- a/Tests/Utils/Context/InForeachConditionTest.php +++ b/Tests/Utils/Context/InForeachConditionTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Context::inForeachCondition * - * @group context - * * @since 1.0.0 */ final class InForeachConditionTest extends UtilityMethodTestCase @@ -55,9 +53,9 @@ public function testNotInForeach($testMarker) * * @see testNotInForeach() * - * @return array + * @return array> */ - public function dataNotInForeach() + public static function dataNotInForeach() { return [ 'no-parenthesis' => ['/* testNoParentheses */'], @@ -75,12 +73,12 @@ public function dataNotInForeach() * * @dataProvider dataInForeachCondition * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param string $expected The expected function return value. - * @param int|string|array $targetType Optional. The token type of the target token. - * Defaults to T_VARIABLE. - * @param string $targetContent Optional. The token content of the target token. - * Defaults to `$target` for `T_VARIABLE`. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param string $expected The expected function return value. + * @param int|string $targetType Optional. The token type of the target token. + * Defaults to T_VARIABLE. + * @param string $targetContent Optional. The token content of the target token. + * Defaults to `$target` for `T_VARIABLE`. * * @return void */ @@ -100,9 +98,9 @@ public function testInForeachCondition($testMarker, $expected, $targetType = \T_ * * @see testInForeachCondition() * - * @return array + * @return array> */ - public function dataInForeachCondition() + public static function dataInForeachCondition() { return [ 'before' => [ diff --git a/Tests/Utils/Context/InIssetTest.php b/Tests/Utils/Context/InIssetTest.php index e332e75b..6952e95b 100644 --- a/Tests/Utils/Context/InIssetTest.php +++ b/Tests/Utils/Context/InIssetTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Context::inIsset * - * @group context - * * @since 1.0.0 */ final class InIssetTest extends UtilityMethodTestCase @@ -56,9 +54,9 @@ public function testInIsset($testMarker, $expected) * * @see testInIsset() * - * @return array + * @return array> */ - public function dataInIsset() + public static function dataInIsset() { return [ 'method-called-isset' => [ diff --git a/Tests/Utils/Context/InUnsetTest.php b/Tests/Utils/Context/InUnsetTest.php index b0b65cae..4209ff65 100644 --- a/Tests/Utils/Context/InUnsetTest.php +++ b/Tests/Utils/Context/InUnsetTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Context::inUnset * - * @group context - * * @since 1.0.0 */ final class InUnsetTest extends UtilityMethodTestCase @@ -56,9 +54,9 @@ public function testInUnset($testMarker, $expected) * * @see testInUnset() * - * @return array + * @return array> */ - public function dataInUnset() + public static function dataInUnset() { return [ 'method-called-unset' => [ diff --git a/Tests/Utils/ControlStructures/GetCaughtExceptionsTest.php b/Tests/Utils/ControlStructures/GetCaughtExceptionsTest.php index 32d4dcba..0377450f 100644 --- a/Tests/Utils/ControlStructures/GetCaughtExceptionsTest.php +++ b/Tests/Utils/ControlStructures/GetCaughtExceptionsTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\ControlStructures::getCaughtExceptions * - * @group controlstructures - * * @since 1.0.0 */ final class GetCaughtExceptionsTest extends UtilityMethodTestCase @@ -49,26 +47,13 @@ public function testNotCatch() ControlStructures::getCaughtExceptions(self::$phpcsFile, $target); } - /** - * Test receiving an expected exception when a parse error is encountered. - * - * @return void - */ - public function testParseError() - { - $this->expectPhpcsException('Parentheses opener/closer of the T_CATCH could not be determined'); - - $target = $this->getTargetToken('/* testLiveCoding */', \T_CATCH); - ControlStructures::getCaughtExceptions(self::$phpcsFile, $target); - } - /** * Test retrieving the exceptions caught in a `catch` condition. * * @dataProvider dataGetCaughtExceptions * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected return value. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array> $expected The expected return value. * * @return void */ @@ -91,9 +76,9 @@ public function testGetCaughtExceptions($testMarker, $expected) * * @see testGetCaughtExceptions() For the array format. * - * @return array + * @return array>>> */ - public function dataGetCaughtExceptions() + public static function dataGetCaughtExceptions() { $php8Names = parent::usesPhp8NameTokens(); @@ -222,6 +207,10 @@ public function dataGetCaughtExceptions() 'testMarker' => '/* testMultiMissingExceptionNames */', 'expected' => [], ], + 'live coding / parse error' => [ + 'testMarker' => '/* testLiveCoding */', + 'expected' => [], + ], ]; } } diff --git a/Tests/Utils/ControlStructures/HasBodyParseError1Test.php b/Tests/Utils/ControlStructures/HasBodyParseError1Test.php index 3869f40a..1997a0e1 100644 --- a/Tests/Utils/ControlStructures/HasBodyParseError1Test.php +++ b/Tests/Utils/ControlStructures/HasBodyParseError1Test.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\ControlStructures::hasBody * - * @group controlstructures - * * @since 1.0.0 */ final class HasBodyParseError1Test extends UtilityMethodTestCase diff --git a/Tests/Utils/ControlStructures/HasBodyParseError2Test.php b/Tests/Utils/ControlStructures/HasBodyParseError2Test.php index 83072b75..781e3ab3 100644 --- a/Tests/Utils/ControlStructures/HasBodyParseError2Test.php +++ b/Tests/Utils/ControlStructures/HasBodyParseError2Test.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\ControlStructures::hasBody * - * @group controlstructures - * * @since 1.0.0 */ final class HasBodyParseError2Test extends UtilityMethodTestCase diff --git a/Tests/Utils/ControlStructures/HasBodyTest.php b/Tests/Utils/ControlStructures/HasBodyTest.php index 456115f7..6045b290 100644 --- a/Tests/Utils/ControlStructures/HasBodyTest.php +++ b/Tests/Utils/ControlStructures/HasBodyTest.php @@ -19,8 +19,6 @@ * * @covers \PHPCSUtils\Utils\ControlStructures::hasBody * - * @group controlstructures - * * @since 1.0.0 */ final class HasBodyTest extends UtilityMethodTestCase @@ -76,9 +74,9 @@ public function testHasBody($testMarker, $hasBody, $hasNonEmptyBody) * * @see testHasBody() For the array format. * - * @return array + * @return array> */ - public function dataHasBody() + public static function dataHasBody() { return [ 'if-without-body' => [ diff --git a/Tests/Utils/ControlStructures/IsElseIfTest.php b/Tests/Utils/ControlStructures/IsElseIfTest.php index cc63b327..9e1869ed 100644 --- a/Tests/Utils/ControlStructures/IsElseIfTest.php +++ b/Tests/Utils/ControlStructures/IsElseIfTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\ControlStructures::isElseIf * - * @group controlstructures - * * @since 1.0.0 */ final class IsElseIfTest extends UtilityMethodTestCase @@ -68,9 +66,9 @@ public function testIsElseIf($testMarker, $expected) * * @see testIsElseIf() For the array format. * - * @return array + * @return array> */ - public function dataIsElseIf() + public static function dataIsElseIf() { return [ 'if' => [ diff --git a/Tests/Utils/FunctionDeclarations/GetParametersDiffTest.inc b/Tests/Utils/FunctionDeclarations/GetParametersDiffTest.inc deleted file mode 100644 index d9f8c995..00000000 --- a/Tests/Utils/FunctionDeclarations/GetParametersDiffTest.inc +++ /dev/null @@ -1,8 +0,0 @@ -expectPhpcsException('$stackPtr must be of type T_FUNCTION, T_CLOSURE or T_USE or an arrow function'); - - FunctionDeclarations::getParameters(self::$phpcsFile, 10000); - } - - /** - * Verify recognition of PHP 8.2 stand-alone `true` type. - * - * @return void - */ - public function testPHP82PseudoTypeTrue() - { - $expected = []; - $expected[0] = [ - 'token' => 7, // Offset from the T_FUNCTION token. - 'name' => '$var', - 'content' => '?true $var = true', - 'default' => 'true', - 'default_token' => 11, // Offset from the T_FUNCTION token. - 'default_equal_token' => 9, // Offset from the T_FUNCTION token. - 'has_attributes' => false, - 'pass_by_reference' => false, - 'reference_token' => false, - 'variable_length' => false, - 'variadic_token' => false, - 'type_hint' => '?true', - 'type_hint_token' => 5, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 5, // Offset from the T_FUNCTION token. - 'nullable_type' => true, - 'comma_token' => false, - ]; - - $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); - } - - /** - * Verify recognition of PHP 8.2 type declaration with (illegal) type false combined with type true. - * - * @return void - */ - public function testPHP82PseudoTypeFalseAndTrue() - { - $expected = []; - $expected[0] = [ - 'token' => 8, // Offset from the T_FUNCTION token. - 'name' => '$var', - 'content' => 'true|false $var = true', - 'default' => 'true', - 'default_token' => 12, // Offset from the T_FUNCTION token. - 'default_equal_token' => 10, // Offset from the T_FUNCTION token. - 'has_attributes' => false, - 'pass_by_reference' => false, - 'reference_token' => false, - 'variable_length' => false, - 'variadic_token' => false, - 'type_hint' => 'true|false', - 'type_hint_token' => 4, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 6, // Offset from the T_FUNCTION token. - 'nullable_type' => false, - 'comma_token' => false, - ]; - - $this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected); - } - - /** - * Test helper. + * Initialize PHPCS & tokenize the test case file. * - * @param string $marker The comment which preceeds the test. - * @param array $expected The expected function output. - * @param array $targetType Optional. The token type to search for after $marker. - * Defaults to the function/closure/arrow tokens. + * @beforeClass * * @return void */ - protected function getMethodParametersTestHelper($marker, $expected, $targetType = [\T_FUNCTION, \T_CLOSURE, \T_FN]) + public static function setUpTestFile() { - $target = $this->getTargetToken($marker, $targetType); - $found = FunctionDeclarations::getParameters(self::$phpcsFile, $target); - $expected = $this->updateExpectedTokenPositions($target, $expected); - - $this->assertSame($expected, $found); + self::$caseFile = \dirname(\dirname(__DIR__)) . '/DummyFile.inc'; + parent::setUpTestFile(); } /** - * Test helper to translate token offsets to absolute positions in an "expected" array. - * - * @param string $targetPtr The token pointer to the target token from which the offset is calculated. - * @param array $expected The expected function output containing offsets. - * - * @return array - */ - private function updateExpectedTokenPositions($targetPtr, $expected) - { - foreach ($expected as $key => $param) { - $expected[$key]['token'] += $targetPtr; - - if ($param['reference_token'] !== false) { - $expected[$key]['reference_token'] += $targetPtr; - } - if ($param['variadic_token'] !== false) { - $expected[$key]['variadic_token'] += $targetPtr; - } - if ($param['type_hint_token'] !== false) { - $expected[$key]['type_hint_token'] += $targetPtr; - } - if ($param['type_hint_end_token'] !== false) { - $expected[$key]['type_hint_end_token'] += $targetPtr; - } - if ($param['comma_token'] !== false) { - $expected[$key]['comma_token'] += $targetPtr; - } - if (isset($param['default_token'])) { - $expected[$key]['default_token'] += $targetPtr; - } - if (isset($param['default_equal_token'])) { - $expected[$key]['default_equal_token'] += $targetPtr; - } - if (isset($param['visibility_token']) && $param['visibility_token'] !== false) { - $expected[$key]['visibility_token'] += $targetPtr; - } - if (isset($param['readonly_token'])) { - $expected[$key]['readonly_token'] += $targetPtr; - } - } - - return $expected; - } - - /** - * Verify that the build-in caching is used when caching is enabled. + * Test passing a non-existent token pointer. * * @return void */ - public function testResultIsCached() + public function testNonExistentToken() { - // The test case used is specifically selected to be one which will always reach the cache check. - $methodName = 'PHPCSUtils\\Utils\\FunctionDeclarations::getParameters'; - $testMarker = '/* testPHP82PseudoTypeTrue */'; - $expected = [ - 0 => [ - 'token' => 7, // Offset from the T_FUNCTION token. - 'name' => '$var', - 'content' => '?true $var = true', - 'default' => 'true', - 'default_token' => 11, // Offset from the T_FUNCTION token. - 'default_equal_token' => 9, // Offset from the T_FUNCTION token. - 'has_attributes' => false, - 'pass_by_reference' => false, - 'reference_token' => false, - 'variable_length' => false, - 'variadic_token' => false, - 'type_hint' => '?true', - 'type_hint_token' => 5, // Offset from the T_FUNCTION token. - 'type_hint_end_token' => 5, // Offset from the T_FUNCTION token. - 'nullable_type' => true, - 'comma_token' => false, - ], - ]; - - $stackPtr = $this->getTargetToken($testMarker, Collections::functionDeclarationTokens()); - $expected = $this->updateExpectedTokenPositions($stackPtr, $expected); - - // Verify the caching works. - $origStatus = Cache::$enabled; - Cache::$enabled = true; - - $resultFirstRun = FunctionDeclarations::getParameters(self::$phpcsFile, $stackPtr); - $isCached = Cache::isCached(self::$phpcsFile, $methodName, $stackPtr); - $resultSecondRun = FunctionDeclarations::getParameters(self::$phpcsFile, $stackPtr); - - if ($origStatus === false) { - Cache::clear(); - } - Cache::$enabled = $origStatus; + $this->expectPhpcsException('$stackPtr must be of type T_FUNCTION, T_CLOSURE or T_USE or an arrow function'); - $this->assertSame($expected, $resultFirstRun, 'First result did not match expectation'); - $this->assertTrue($isCached, 'Cache::isCached() could not find the cached value'); - $this->assertSame($resultFirstRun, $resultSecondRun, 'Second result did not match first'); + FunctionDeclarations::getParameters(self::$phpcsFile, 10000); } } diff --git a/Tests/Utils/FunctionDeclarations/GetParametersTest.php b/Tests/Utils/FunctionDeclarations/GetParametersTest.php index 995501a0..d5bfe22d 100644 --- a/Tests/Utils/FunctionDeclarations/GetParametersTest.php +++ b/Tests/Utils/FunctionDeclarations/GetParametersTest.php @@ -10,7 +10,9 @@ namespace PHPCSUtils\Tests\Utils\FunctionDeclarations; +use PHPCSUtils\Internal\Cache; use PHPCSUtils\Tests\BackCompat\BCFile\GetMethodParametersTest as BCFile_GetMethodParametersTest; +use PHPCSUtils\Tokens\Collections; use PHPCSUtils\Utils\FunctionDeclarations; /** @@ -52,8 +54,8 @@ public static function setUpTestFile() * * @dataProvider dataUnexpectedTokenException * - * @param string $commentString The comment which preceeds the test. - * @param array $targetTokenType The token type to search for after $commentString. + * @param string $commentString The comment which preceeds the test. + * @param int|string|array $targetTokenType The token type to search for after $commentString. * * @return void */ @@ -87,9 +89,9 @@ public function testInvalidUse($identifier) * * @dataProvider dataNoParams * - * @param string $commentString The comment which preceeds the test. - * @param array $targetTokenType Optional. The token type to search for after $commentString. - * Defaults to the function/closure/arrow tokens. + * @param string $commentString The comment which preceeds the test. + * @param int|string|array $targetTokenType Optional. The token type to search for after $commentString. + * Defaults to the function/closure/arrow tokens. * * @return void */ @@ -104,50 +106,119 @@ public function testNoParams($commentString, $targetTokenType = [\T_FUNCTION, \T /** * Test helper. * - * @param string $marker The comment which preceeds the test. - * @param array $expected The expected function output. - * @param array $targetType Optional. The token type to search for after $marker. - * Defaults to the function/closure/arrow tokens. + * @param string $marker The comment which preceeds the test. + * @param array> $expected The expected function output. + * @param int|string|array $targetType Optional. The token type to search for after $marker. + * Defaults to the function/closure/arrow tokens. * * @return void */ protected function getMethodParametersTestHelper($marker, $expected, $targetType = [\T_FUNCTION, \T_CLOSURE, \T_FN]) { - $target = $this->getTargetToken($marker, $targetType); - $found = FunctionDeclarations::getParameters(self::$phpcsFile, $target); + $target = $this->getTargetToken($marker, $targetType); + $found = FunctionDeclarations::getParameters(self::$phpcsFile, $target); + $expected = $this->updateExpectedTokenPositions($target, $expected); + $this->assertSame($expected, $found); + } + + /** + * Test helper to translate token offsets to absolute positions in an "expected" array. + * + * @param int $targetPtr The token pointer to the target token from which + * the offset is calculated. + * @param array> $expected The expected function output containing offsets. + * + * @return array> + */ + private function updateExpectedTokenPositions($targetPtr, $expected) + { foreach ($expected as $key => $param) { - $expected[$key]['token'] += $target; + $expected[$key]['token'] += $targetPtr; - if ($param['reference_token'] !== false) { - $expected[$key]['reference_token'] += $target; + if (\is_int($param['reference_token']) === true) { + $expected[$key]['reference_token'] += $targetPtr; } - if ($param['variadic_token'] !== false) { - $expected[$key]['variadic_token'] += $target; + if (\is_int($param['variadic_token']) === true) { + $expected[$key]['variadic_token'] += $targetPtr; } - if ($param['type_hint_token'] !== false) { - $expected[$key]['type_hint_token'] += $target; + if (\is_int($param['type_hint_token']) === true) { + $expected[$key]['type_hint_token'] += $targetPtr; } - if ($param['type_hint_end_token'] !== false) { - $expected[$key]['type_hint_end_token'] += $target; + if (\is_int($param['type_hint_end_token']) === true) { + $expected[$key]['type_hint_end_token'] += $targetPtr; } - if ($param['comma_token'] !== false) { - $expected[$key]['comma_token'] += $target; + if (\is_int($param['comma_token']) === true) { + $expected[$key]['comma_token'] += $targetPtr; } if (isset($param['default_token'])) { - $expected[$key]['default_token'] += $target; + $expected[$key]['default_token'] += $targetPtr; } if (isset($param['default_equal_token'])) { - $expected[$key]['default_equal_token'] += $target; + $expected[$key]['default_equal_token'] += $targetPtr; } - if (isset($param['visibility_token']) && $param['visibility_token'] !== false) { - $expected[$key]['visibility_token'] += $target; + if (isset($param['visibility_token']) && \is_int($param['visibility_token']) === true) { + $expected[$key]['visibility_token'] += $targetPtr; } if (isset($param['readonly_token'])) { - $expected[$key]['readonly_token'] += $target; + $expected[$key]['readonly_token'] += $targetPtr; } } - $this->assertSame($expected, $found); + return $expected; + } + + /** + * Verify that the build-in caching is used when caching is enabled. + * + * @return void + */ + public function testResultIsCached() + { + // The test case used is specifically selected to be one which will always reach the cache check. + $methodName = 'PHPCSUtils\\Utils\\FunctionDeclarations::getParameters'; + $testMarker = '/* testPHP82PseudoTypeTrue */'; + + // Offsets are relative to the T_FUNCTION token. + $expected = [ + 0 => [ + 'token' => 7, + 'name' => '$var', + 'content' => '?true $var = true', + 'default' => 'true', + 'default_token' => 11, + 'default_equal_token' => 9, + 'has_attributes' => false, + 'pass_by_reference' => false, + 'reference_token' => false, + 'variable_length' => false, + 'variadic_token' => false, + 'type_hint' => '?true', + 'type_hint_token' => 5, + 'type_hint_end_token' => 5, + 'nullable_type' => true, + 'comma_token' => false, + ], + ]; + + $stackPtr = $this->getTargetToken($testMarker, Collections::functionDeclarationTokens()); + $expected = $this->updateExpectedTokenPositions($stackPtr, $expected); + + // Verify the caching works. + $origStatus = Cache::$enabled; + Cache::$enabled = true; + + $resultFirstRun = FunctionDeclarations::getParameters(self::$phpcsFile, $stackPtr); + $isCached = Cache::isCached(self::$phpcsFile, $methodName, $stackPtr); + $resultSecondRun = FunctionDeclarations::getParameters(self::$phpcsFile, $stackPtr); + + if ($origStatus === false) { + Cache::clear(); + } + Cache::$enabled = $origStatus; + + $this->assertSame($expected, $resultFirstRun, 'First result did not match expectation'); + $this->assertTrue($isCached, 'Cache::isCached() could not find the cached value'); + $this->assertSame($resultFirstRun, $resultSecondRun, 'Second result did not match first'); } } diff --git a/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.inc b/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.inc index e78b70e9..391ff60f 100644 --- a/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.inc +++ b/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.inc @@ -17,10 +17,3 @@ trait FooTrait { $func(); } } - -/* testPHP82PseudoTypeTrue */ -function pseudoTypeTrue(): ?true {} - -/* testPHP82PseudoTypeFalseAndTrue */ -// Intentional fatal error - Type contains both true and false, bool should be used instead, but that's not the concern of the method. -function pseudoTypeFalseAndTrue(): true|false {} diff --git a/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.php b/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.php index 03259499..4745703f 100644 --- a/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.php +++ b/Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.php @@ -88,59 +88,13 @@ public function testMessyPhpcsAnnotationsStaticClosure() $this->getPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); } - /** - * Verify recognition of PHP 8.2 stand-alone `true` type. - * - * @return void - */ - public function testPHP82PseudoTypeTrue() - { - $expected = [ - 'scope' => 'public', - 'scope_specified' => false, - 'return_type' => '?true', - 'return_type_token' => 8, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 8, // Offset from the T_FUNCTION token. - 'nullable_return_type' => true, - 'is_abstract' => false, - 'is_final' => false, - 'is_static' => false, - 'has_body' => true, - ]; - - $this->getPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); - } - - /** - * Verify recognition of PHP 8.2 type declaration with (illegal) type false combined with type true. - * - * @return void - */ - public function testPHP82PseudoTypeFalseAndTrue() - { - $expected = [ - 'scope' => 'public', - 'scope_specified' => false, - 'return_type' => 'true|false', - 'return_type_token' => 7, // Offset from the T_FUNCTION token. - 'return_type_end_token' => 9, // Offset from the T_FUNCTION token. - 'nullable_return_type' => false, - 'is_abstract' => false, - 'is_final' => false, - 'is_static' => false, - 'has_body' => true, - ]; - - $this->getPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected); - } - /** * Test helper. * - * @param string $commentString The comment which preceeds the test. - * @param array $expected The expected function output. - * @param array $targetType Optional. The token type to search for after $commentString. - * Defaults to the function/closure tokens. + * @param string $commentString The comment which preceeds the test. + * @param array $expected The expected function output. + * @param int|string|array $targetType Optional. The token type to search for after $commentString. + * Defaults to the function/closure tokens. * * @return void */ @@ -152,10 +106,11 @@ protected function getPropertiesTestHelper( $function = $this->getTargetToken($commentString, $targetType); $found = FunctionDeclarations::getProperties(self::$phpcsFile, $function); - if ($expected['return_type_token'] !== false) { + // Convert offsets to absolute positions in the token stream. + if (\is_int($expected['return_type_token']) === true) { $expected['return_type_token'] += $function; } - if ($expected['return_type_end_token'] !== false) { + if (\is_int($expected['return_type_end_token']) === true) { $expected['return_type_end_token'] += $function; } diff --git a/Tests/Utils/FunctionDeclarations/GetPropertiesParseError1Test.php b/Tests/Utils/FunctionDeclarations/GetPropertiesParseError1Test.php new file mode 100644 index 00000000..3650a78f --- /dev/null +++ b/Tests/Utils/FunctionDeclarations/GetPropertiesParseError1Test.php @@ -0,0 +1,76 @@ +getTargetToken('/* testParseError */', Collections::functionDeclarationTokens()); + $result = FunctionDeclarations::getProperties(self::$phpcsFile, $target); + + $expected = [ + 'scope' => 'public', + 'scope_specified' => false, + 'return_type' => '', + 'return_type_token' => false, + 'return_type_end_token' => false, + 'nullable_return_type' => false, + 'is_abstract' => false, + 'is_final' => false, + 'is_static' => false, + 'has_body' => false, + ]; + + $this->assertSame($expected, $result); + } +} diff --git a/Tests/Utils/FunctionDeclarations/GetPropertiesTest.php b/Tests/Utils/FunctionDeclarations/GetPropertiesTest.php index aa0f172e..3f98fd75 100644 --- a/Tests/Utils/FunctionDeclarations/GetPropertiesTest.php +++ b/Tests/Utils/FunctionDeclarations/GetPropertiesTest.php @@ -52,8 +52,8 @@ public static function setUpTestFile() * * @dataProvider dataNotAFunctionException * - * @param string $commentString The comment which preceeds the test. - * @param array $targetTokenType The token type to search for after $commentString. + * @param string $commentString The comment which preceeds the test. + * @param int|string|array $targetTokenType The token type to search for after $commentString. * * @return void */ @@ -68,10 +68,10 @@ public function testNotAFunctionException($commentString, $targetTokenType) /** * Test helper. * - * @param string $commentString The comment which preceeds the test. - * @param array $expected The expected function output. - * @param array $targetType Optional. The token type to search for after $commentString. - * Defaults to the function/closure tokens. + * @param string $commentString The comment which preceeds the test. + * @param array $expected The expected function output. + * @param int|string|array $targetType Optional. The token type to search for after $commentString. + * Defaults to the function/closure tokens. * * @return void */ @@ -83,10 +83,11 @@ protected function getMethodPropertiesTestHelper( $function = $this->getTargetToken($commentString, $targetType); $found = FunctionDeclarations::getProperties(self::$phpcsFile, $function); - if ($expected['return_type_token'] !== false) { + // Convert offsets to absolute positions in the token stream. + if (\is_int($expected['return_type_token']) === true) { $expected['return_type_token'] += $function; } - if ($expected['return_type_end_token'] !== false) { + if (\is_int($expected['return_type_end_token']) === true) { $expected['return_type_end_token'] += $function; } diff --git a/Tests/Utils/FunctionDeclarations/IsMagicFunctionNameTest.php b/Tests/Utils/FunctionDeclarations/IsMagicFunctionNameTest.php index 0b81a56f..779336ce 100644 --- a/Tests/Utils/FunctionDeclarations/IsMagicFunctionNameTest.php +++ b/Tests/Utils/FunctionDeclarations/IsMagicFunctionNameTest.php @@ -44,9 +44,9 @@ public function testIsMagicFunctionName($name) * * @see testIsMagicFunctionName() For the array format. * - * @return array + * @return array> */ - public function dataIsMagicFunctionName() + public static function dataIsMagicFunctionName() { return [ 'lowercase' => ['__autoload'], @@ -74,9 +74,9 @@ public function testIsNotMagicFunctionName($name) * * @see testIsNotMagicFunctionName() For the array format. * - * @return array + * @return array> */ - public function dataIsNotMagicFunctionName() + public static function dataIsNotMagicFunctionName() { return [ 'no_underscore' => ['noDoubleUnderscore'], diff --git a/Tests/Utils/FunctionDeclarations/IsMagicMethodNameTest.php b/Tests/Utils/FunctionDeclarations/IsMagicMethodNameTest.php index 1ad5f01c..f1887159 100644 --- a/Tests/Utils/FunctionDeclarations/IsMagicMethodNameTest.php +++ b/Tests/Utils/FunctionDeclarations/IsMagicMethodNameTest.php @@ -61,9 +61,9 @@ public function testIsSpecialMethodName($name) * @see testIsMagicMethodName() For the array format. * @see testIsSpecialMethodName() For the array format. * - * @return array + * @return array> */ - public function dataIsMagicMethodName() + public static function dataIsMagicMethodName() { return [ // Normal case. @@ -142,9 +142,9 @@ public function testIsNotSpecialMethodName($name) * @see testIsNotMagicMethodName() For the array format. * @see testIsNotSpecialMethodName() For the array format. * - * @return array + * @return array> */ - public function dataIsNotMagicMethodName() + public static function dataIsNotMagicMethodName() { return [ 'no_underscore' => ['construct'], diff --git a/Tests/Utils/FunctionDeclarations/IsPHPDoubleUnderscoreMethodNameTest.php b/Tests/Utils/FunctionDeclarations/IsPHPDoubleUnderscoreMethodNameTest.php index f5735666..4b6fc948 100644 --- a/Tests/Utils/FunctionDeclarations/IsPHPDoubleUnderscoreMethodNameTest.php +++ b/Tests/Utils/FunctionDeclarations/IsPHPDoubleUnderscoreMethodNameTest.php @@ -62,9 +62,9 @@ public function testIsSpecialMethodName($name) * @see testIsPHPDoubleUnderscoreMethodName() For the array format. * @see testIsSpecialMethodName() For the array format. * - * @return array + * @return array> */ - public function dataIsPHPDoubleUnderscoreMethodName() + public static function dataIsPHPDoubleUnderscoreMethodName() { return [ // Normal case. @@ -133,9 +133,9 @@ public function testIsNotSpecialMethodName($name) * @see testIsNotPHPDoubleUnderscoreMethodName() For the array format. * @see testIsNotSpecialMethodName() For the array format. * - * @return array + * @return array> */ - public function dataIsNotPHPDoubleUnderscoreMethodName() + public static function dataIsNotPHPDoubleUnderscoreMethodName() { return [ 'no_underscore' => ['getLastResponseHeaders'], diff --git a/Tests/Utils/FunctionDeclarations/SpecialFunctionsTest.php b/Tests/Utils/FunctionDeclarations/SpecialFunctionsTest.php index 499c64c3..1f8cb6dd 100644 --- a/Tests/Utils/FunctionDeclarations/SpecialFunctionsTest.php +++ b/Tests/Utils/FunctionDeclarations/SpecialFunctionsTest.php @@ -86,8 +86,8 @@ public function testNotAFunctionToken() * @dataProvider dataItsAKindOfMagic * @covers ::isMagicFunction * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected return values for the various functions. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected return values for the various functions. * * @return void */ @@ -104,8 +104,8 @@ public function testIsMagicFunction($testMarker, $expected) * @dataProvider dataItsAKindOfMagic * @covers ::isMagicMethod * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected return values for the various functions. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected return values for the various functions. * * @return void */ @@ -122,8 +122,8 @@ public function testIsMagicMethod($testMarker, $expected) * @dataProvider dataItsAKindOfMagic * @covers ::isPHPDoubleUnderscoreMethod * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected return values for the various functions. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected return values for the various functions. * * @return void */ @@ -140,8 +140,8 @@ public function testIsPHPDoubleUnderscoreMethod($testMarker, $expected) * @dataProvider dataItsAKindOfMagic * @covers ::isSpecialMethod * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected return values for the various functions. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected return values for the various functions. * * @return void */ @@ -160,9 +160,9 @@ public function testIsSpecialMethod($testMarker, $expected) * @see testIsPHPDoubleUnderscoreMethod() For the array format. * @see testIsSpecialMethod() For the array format. * - * @return array + * @return array>> */ - public function dataItsAKindOfMagic() + public static function dataItsAKindOfMagic() { return [ 'MagicMethodInClass' => [ diff --git a/Tests/Utils/GetTokensAsString/GetTokensAsStringTest.php b/Tests/Utils/GetTokensAsString/GetTokensAsStringTest.php index 30f6b6fb..ff1dd8f8 100644 --- a/Tests/Utils/GetTokensAsString/GetTokensAsStringTest.php +++ b/Tests/Utils/GetTokensAsString/GetTokensAsStringTest.php @@ -112,11 +112,11 @@ public function testLengthBeyondEndOfFile() /** * Test getting a token set as a string. * - * @dataProvider dataGetTokensAsString() + * @dataProvider dataGetTokensAsString * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $startTokenType The type of token(s) to look for for the start of the string. - * @param array $expected The expected function's return values. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $startTokenType The type of token(s) to look for for the start of the string. + * @param array $expected The expected function's return values. * * @return void */ @@ -132,11 +132,11 @@ public function testNormal($testMarker, $startTokenType, $expected) /** * Test getting a token set as a string with the original content. * - * @dataProvider dataGetTokensAsString() + * @dataProvider dataGetTokensAsString * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $startTokenType The type of token(s) to look for for the start of the string. - * @param array $expected The expected function's return values. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $startTokenType The type of token(s) to look for for the start of the string. + * @param array $expected The expected function's return values. * * @return void */ @@ -152,11 +152,11 @@ public function testOrigContent($testMarker, $startTokenType, $expected) /** * Test getting a token set as a string without comments. * - * @dataProvider dataGetTokensAsString() + * @dataProvider dataGetTokensAsString * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $startTokenType The type of token(s) to look for for the start of the string. - * @param array $expected The expected function's return values. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $startTokenType The type of token(s) to look for for the start of the string. + * @param array $expected The expected function's return values. * * @return void */ @@ -172,11 +172,11 @@ public function testNoComments($testMarker, $startTokenType, $expected) /** * Test getting a token set as a string without comments or whitespace. * - * @dataProvider dataGetTokensAsString() + * @dataProvider dataGetTokensAsString * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $startTokenType The type of token(s) to look for for the start of the string. - * @param array $expected The expected function's return values. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $startTokenType The type of token(s) to look for for the start of the string. + * @param array $expected The expected function's return values. * * @return void */ @@ -192,11 +192,11 @@ public function testNoEmpties($testMarker, $startTokenType, $expected) /** * Test getting a token set as a string with compacted whitespace. * - * @dataProvider dataGetTokensAsString() + * @dataProvider dataGetTokensAsString * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $startTokenType The type of token(s) to look for for the start of the string. - * @param array $expected The expected function's return values. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $startTokenType The type of token(s) to look for for the start of the string. + * @param array $expected The expected function's return values. * * @return void */ @@ -212,11 +212,11 @@ public function testCompact($testMarker, $startTokenType, $expected) /** * Test getting a token set as a string without comments and with compacted whitespace. * - * @dataProvider dataGetTokensAsString() + * @dataProvider dataGetTokensAsString * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $startTokenType The type of token(s) to look for for the start of the string. - * @param array $expected The expected function's return values. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $startTokenType The type of token(s) to look for for the start of the string. + * @param array $expected The expected function's return values. * * @return void */ @@ -239,15 +239,15 @@ public function testCompactNoComments($testMarker, $startTokenType, $expected) * @see testCompact() For the array format. * @see testCompactNoComments() For the array format. * - * @return array + * @return array>> */ - public function dataGetTokensAsString() + public static function dataGetTokensAsString() { return [ 'namespace' => [ - 'marker' => '/* testNamespace */', - 'type' => \T_NAMESPACE, - 'expected' => [ + 'testMarker' => '/* testNamespace */', + 'startTokenType' => \T_NAMESPACE, + 'expected' => [ 'tab_replaced' => 'namespace Foo\Bar\Baz;', 'orig' => 'namespace Foo\Bar\Baz;', 'no_comments' => 'namespace Foo\Bar\Baz;', @@ -257,9 +257,9 @@ public function dataGetTokensAsString() ], ], 'use-with-comments' => [ - 'marker' => '/* testUseWithComments */', - 'type' => \T_STRING, - 'expected' => [ + 'testMarker' => '/* testUseWithComments */', + 'startTokenType' => \T_STRING, + 'expected' => [ 'tab_replaced' => 'Foo /*comment*/ \ Bar // phpcs:ignore Stnd.Cat.Sniff -- For reasons. \ Bah;', @@ -275,9 +275,9 @@ public function dataGetTokensAsString() ], ], 'calculation' => [ - 'marker' => '/* testCalculation */', - 'type' => \T_LNUMBER, - 'expected' => [ + 'testMarker' => '/* testCalculation */', + 'startTokenType' => \T_LNUMBER, + 'expected' => [ 'tab_replaced' => '1 + 2 + // Comment. 3 + 4 @@ -296,9 +296,9 @@ public function dataGetTokensAsString() ], ], 'echo-with-tabs' => [ - 'marker' => '/* testEchoWithTabs */', - 'type' => \T_ECHO, - 'expected' => [ + 'testMarker' => '/* testEchoWithTabs */', + 'startTokenType' => \T_ECHO, + 'expected' => [ 'tab_replaced' => 'echo \'foo\', \'bar\' , \'baz\';', @@ -314,9 +314,9 @@ public function dataGetTokensAsString() ], ], 'end-of-file' => [ - 'marker' => '/* testEndOfFile */', - 'type' => \T_ECHO, - 'expected' => [ + 'testMarker' => '/* testEndOfFile */', + 'startTokenType' => \T_ECHO, + 'expected' => [ 'tab_replaced' => 'echo $foo;', 'orig' => 'echo $foo;', 'no_comments' => 'echo $foo;', diff --git a/Tests/Utils/Lists/GetAssignmentsTest.php b/Tests/Utils/Lists/GetAssignmentsTest.php index 3bbf364c..51ceb068 100644 --- a/Tests/Utils/Lists/GetAssignmentsTest.php +++ b/Tests/Utils/Lists/GetAssignmentsTest.php @@ -20,8 +20,6 @@ * * @covers \PHPCSUtils\Utils\Lists::getAssignments * - * @group lists - * * @since 1.0.0 */ final class GetAssignmentsTest extends UtilityMethodTestCase @@ -44,8 +42,8 @@ public function testNonExistentToken() * * @dataProvider dataNotListToken * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetToken The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetToken The token type(s) to look for. * * @return void */ @@ -62,9 +60,9 @@ public function testNotListToken($testMarker, $targetToken) * * @see testNotListToken() For the array format. * - * @return array + * @return array> */ - public function dataNotListToken() + public static function dataNotListToken() { return [ 'not-a-list' => [ @@ -83,9 +81,10 @@ public function dataNotListToken() * * @dataProvider dataGetAssignments * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetToken The token type(s) to look for. - * @param array|false $expected The expected function return value. + * @param string $testMarker The comment which prefaces the target token + * in the test file. + * @param int|string $targetToken The token type(s) to look for. + * @param array> $expected The expected function return value. * * @return void */ @@ -126,9 +125,9 @@ public function testGetAssignments($testMarker, $targetToken, $expected) * * @see testGetAssignments() For the array format. * - * @return array + * @return array>>> */ - public function dataGetAssignments() + public static function dataGetAssignments() { return [ 'long-list-empty' => [ diff --git a/Tests/Utils/Lists/GetOpenCloseTest.php b/Tests/Utils/Lists/GetOpenCloseTest.php index 76be9d73..cfe5a440 100644 --- a/Tests/Utils/Lists/GetOpenCloseTest.php +++ b/Tests/Utils/Lists/GetOpenCloseTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Lists::getOpenClose * - * @group lists - * * @since 1.0.0 */ final class GetOpenCloseTest extends UtilityMethodTestCase @@ -40,8 +38,8 @@ public function testNonExistentToken() * * @dataProvider dataNotListOpenToken * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetToken The token type(s) to look for. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetToken The token type(s) to look for. * * @return void */ @@ -56,9 +54,9 @@ public function testNotListOpenToken($testMarker, $targetToken) * * @see testNotListOpenToken() For the array format. * - * @return array + * @return array> */ - public function dataNotListOpenToken() + public static function dataNotListOpenToken() { return [ 'short-array' => [ @@ -89,9 +87,9 @@ public function dataNotListOpenToken() * * @dataProvider dataGetOpenClose * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetToken The token type(s) to look for. - * @param array|false $expected The expected function return value. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetToken The token type(s) to look for. + * @param array|false $expected The expected function return value. * * @return void */ @@ -116,9 +114,9 @@ public function testGetOpenClose($testMarker, $targetToken, $expected) * * @see testGetOpenClose() For the array format. * - * @return array + * @return array|false>> */ - public function dataGetOpenClose() + public static function dataGetOpenClose() { return [ 'long-list' => [ diff --git a/Tests/Utils/MessageHelper/AddMessageTest.php b/Tests/Utils/MessageHelper/AddMessageTest.php index f9a1ccc7..5b2d59ac 100644 --- a/Tests/Utils/MessageHelper/AddMessageTest.php +++ b/Tests/Utils/MessageHelper/AddMessageTest.php @@ -22,8 +22,6 @@ * * @coversDefaultClass \PHPCSUtils\Utils\MessageHelper * - * @group messagehelper - * * @since 1.0.0 */ final class AddMessageTest extends UtilityMethodTestCase @@ -41,7 +39,7 @@ final class AddMessageTest extends UtilityMethodTestCase /** * Set the name of a sniff to pass to PHPCS to limit the run (and force it to record errors). * - * @var array + * @var array */ protected static $selectedSniff = ['PHPCSUtils.MessageHelper.AddMessageTest']; @@ -51,9 +49,9 @@ final class AddMessageTest extends UtilityMethodTestCase * @dataProvider dataAddMessage * @covers ::addMessage * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param bool $isError Whether to test adding an error or a warning. - * @param array $expected Expected error details. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param bool $isError Whether to test adding an error or a warning. + * @param array $expected Expected error details. * * @return void */ @@ -84,9 +82,9 @@ public function testAddMessage($testMarker, $isError, $expected) * * @see testAddMessage() For the array format. * - * @return array + * @return array>> */ - public function dataAddMessage() + public static function dataAddMessage() { return [ 'add-error' => [ @@ -116,9 +114,9 @@ public function dataAddMessage() * @dataProvider dataAddFixableMessage * @covers ::addFixableMessage * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param bool $isError Whether to test adding an error or a warning. - * @param array $expected Expected error details. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param bool $isError Whether to test adding an error or a warning. + * @param array $expected Expected error details. * * @return void */ @@ -150,9 +148,9 @@ public function testAddFixableMessage($testMarker, $isError, $expected) * * @see testAddFixableMessage() For the array format. * - * @return array + * @return array>> */ - public function dataAddFixableMessage() + public static function dataAddFixableMessage() { return [ 'add-fixable-error' => [ @@ -179,9 +177,9 @@ public function dataAddFixableMessage() /** * Helper method to verify the expected message details. * - * @param int $stackPtr The stack pointer on which the error/warning is expected. - * @param bool $isError Whether to test adding an error or a warning. - * @param array $expected Expected error details. + * @param int $stackPtr The stack pointer on which the error/warning is expected. + * @param bool $isError Whether to test adding an error or a warning. + * @param array $expected Expected error details. * * @return void */ @@ -232,9 +230,6 @@ protected function verifyRecordedMessages($stackPtr, $isError, $expected) $violation = $messages[0]; - // PHPCS 2.x places `unknownSniff.` before the actual error code for utility tests with a dummy error code. - $violation['source'] = \str_replace('unknownSniff.', '', $violation['source']); - /* * Test the violation details. */ diff --git a/Tests/Utils/MessageHelper/ShowEscapeCharsTest.php b/Tests/Utils/MessageHelper/ShowEscapeCharsTest.php index a2240cb6..e8cc8cb3 100644 --- a/Tests/Utils/MessageHelper/ShowEscapeCharsTest.php +++ b/Tests/Utils/MessageHelper/ShowEscapeCharsTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\MessageHelper::showEscapeChars * - * @group messagehelper - * * @since 1.0.0 */ final class ShowEscapeCharsTest extends TestCase @@ -45,9 +43,9 @@ public function testShowEscapeChars($input, $expected) * * @see testShowEscapeChars() For the array format. * - * @return array + * @return array> */ - public function dataShowEscapeChars() + public static function dataShowEscapeChars() { return [ 'no-escape-chars' => [ diff --git a/Tests/Utils/MessageHelper/StringToErrorcodeTest.php b/Tests/Utils/MessageHelper/StringToErrorcodeTest.php index f45f46b1..1dddabba 100644 --- a/Tests/Utils/MessageHelper/StringToErrorcodeTest.php +++ b/Tests/Utils/MessageHelper/StringToErrorcodeTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\MessageHelper::stringToErrorcode * - * @group messagehelper - * * @since 1.0.0 */ final class StringToErrorcodeTest extends TestCase @@ -45,9 +43,9 @@ public function testStringToErrorCode($input, $expected) * * @see testStringToErrorCode() For the array format. * - * @return array + * @return array> */ - public function dataStringToErrorCode() + public static function dataStringToErrorCode() { return [ 'no-special-chars' => [ @@ -97,9 +95,9 @@ public function testStringToErrorCodeWithCaseChange($input, $expected) * * @see testStringToErrorCode() For the array format. * - * @return array + * @return array> */ - public function dataStringToErrorCodeWithCaseChange() + public static function dataStringToErrorCodeWithCaseChange() { return [ 'no-special-chars' => [ diff --git a/Tests/Utils/Namespaces/DetermineNamespaceTest.php b/Tests/Utils/Namespaces/DetermineNamespaceTest.php index 3256217a..1028039e 100644 --- a/Tests/Utils/Namespaces/DetermineNamespaceTest.php +++ b/Tests/Utils/Namespaces/DetermineNamespaceTest.php @@ -21,8 +21,6 @@ * @covers \PHPCSUtils\Utils\Namespaces::findNamespacePtr * @covers \PHPCSUtils\Utils\Namespaces::determineNamespace * - * @group namespaces - * * @since 1.0.0 */ final class DetermineNamespaceTest extends UtilityMethodTestCase @@ -43,8 +41,8 @@ public function testInvalidTokenPassed() * * @dataProvider dataDetermineNamespace * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected output for the functions. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected output for the functions. * * @return void */ @@ -66,8 +64,8 @@ public function testFindNamespacePtr($testMarker, $expected) * * @dataProvider dataDetermineNamespace * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected output for the functions. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected output for the functions. * * @return void */ @@ -84,9 +82,9 @@ public function testDetermineNamespace($testMarker, $expected) * * @see testDetermineNamespace() For the array format. * - * @return array + * @return array>> */ - public function dataDetermineNamespace() + public static function dataDetermineNamespace() { return [ 'no-namespace' => [ @@ -260,7 +258,7 @@ public function testFallbackToEmptyString() $result = Namespaces::findNamespacePtr(self::$phpcsFile, $stackPtr); $this->assertSame($expected, $result, 'Failed test with findNamespacePtr'); - $result = Namespaces::determineNamespace(self::$phpcsFile, $stackPtr, false); + $result = Namespaces::determineNamespace(self::$phpcsFile, $stackPtr); $this->assertSame('', $result, 'Failed test with determineNamespace'); } } diff --git a/Tests/Utils/Namespaces/GetDeclaredNameTest.php b/Tests/Utils/Namespaces/GetDeclaredNameTest.php index bfbfc518..eafa1dfd 100644 --- a/Tests/Utils/Namespaces/GetDeclaredNameTest.php +++ b/Tests/Utils/Namespaces/GetDeclaredNameTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Namespaces::getDeclaredName * - * @group namespaces - * * @since 1.0.0 */ final class GetDeclaredNameTest extends UtilityMethodTestCase @@ -44,11 +42,11 @@ public function testInvalidTokenPassed() * * @dataProvider dataGetDeclaredName * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected output for the function. - * @param bool $skipOnPHP8 Optional. Whether the test should be skipped when the PHP 8 identifier - * name tokenization is used (as the target token won't exist). - * Defaults to `false`. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected output for the function. + * @param bool $skipOnPHP8 Optional. Whether the test should be skipped when the + * PHP 8 identifier name tokenization is used (as the target token + * won't exist). Defaults to `false`. * * @return void */ @@ -69,11 +67,11 @@ public function testGetDeclaredNameClean($testMarker, $expected, $skipOnPHP8 = f * * @dataProvider dataGetDeclaredName * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected output for the function. - * @param bool $skipOnPHP8 Optional. Whether the test should be skipped when the PHP 8 identifier - * name tokenization is used (as the target token won't exist). - * Defaults to `false`. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected output for the function. + * @param bool $skipOnPHP8 Optional. Whether the test should be skipped when the + * PHP 8 identifier name tokenization is used (as the target token + * won't exist). Defaults to `false`. * * @return void */ @@ -94,9 +92,9 @@ public function testGetDeclaredNameDirty($testMarker, $expected, $skipOnPHP8 = f * * @see testGetDeclaredName() For the array format. * - * @return array + * @return array|bool>> */ - public function dataGetDeclaredName() + public static function dataGetDeclaredName() { return [ 'global-namespace-curlies' => [ diff --git a/Tests/Utils/Namespaces/NamespaceTypeTest.php b/Tests/Utils/Namespaces/NamespaceTypeTest.php index 320eae61..4ebbfb46 100644 --- a/Tests/Utils/Namespaces/NamespaceTypeTest.php +++ b/Tests/Utils/Namespaces/NamespaceTypeTest.php @@ -22,8 +22,6 @@ * @covers \PHPCSUtils\Utils\Namespaces::isOperator * @covers \PHPCSUtils\Utils\Namespaces::getType * - * @group namespaces - * * @since 1.0.0 */ final class NamespaceTypeTest extends UtilityMethodTestCase @@ -58,11 +56,11 @@ public function testNonNamespaceToken() * * @dataProvider dataNamespaceType * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected output for the functions. - * @param bool $skipOnPHP8 Optional. Whether the test should be skipped when the PHP 8 identifier - * name tokenization is used (as the target token won't exist). - * Defaults to `false`. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected output for the functions. + * @param bool $skipOnPHP8 Optional. Whether the test should be skipped when the PHP 8 identifier + * name tokenization is used (as the target token won't exist). + * Defaults to `false`. * * @return void */ @@ -83,11 +81,11 @@ public function testIsDeclaration($testMarker, $expected, $skipOnPHP8 = false) * * @dataProvider dataNamespaceType * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected output for the functions. - * @param bool $skipOnPHP8 Optional. Whether the test should be skipped when the PHP 8 identifier - * name tokenization is used (as the target token won't exist). - * Defaults to `false`. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected output for the functions. + * @param bool $skipOnPHP8 Optional. Whether the test should be skipped when the PHP 8 identifier + * name tokenization is used (as the target token won't exist). + * Defaults to `false`. * * @return void */ @@ -109,9 +107,9 @@ public function testIsOperator($testMarker, $expected, $skipOnPHP8 = false) * @see testIsDeclaration() For the array format. * @see testIsOperator() For the array format. * - * @return array + * @return array|true>> */ - public function dataNamespaceType() + public static function dataNamespaceType() { return [ 'namespace-declaration' => [ diff --git a/Tests/Utils/NamingConventions/IsEqualTest.php b/Tests/Utils/NamingConventions/IsEqualTest.php index 85104ce9..81d9c9b6 100644 --- a/Tests/Utils/NamingConventions/IsEqualTest.php +++ b/Tests/Utils/NamingConventions/IsEqualTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\NamingConventions::isEqual * - * @group namingconventions - * * @since 1.0.0 */ final class IsEqualTest extends TestCase @@ -32,7 +30,7 @@ final class IsEqualTest extends TestCase * * @param string $inputA The first name. * @param string $inputB The second name. - * @param array $expected The expected function output. + * @param bool $expected The expected function output. * * @return void */ @@ -46,9 +44,9 @@ public function testIsEqual($inputA, $inputB, $expected) * * @see testIsEqual() For the array format. * - * @return array + * @return array> */ - public function dataIsEqual() + public static function dataIsEqual() { return [ 'a-z-0-9-only-same-case' => [ diff --git a/Tests/Utils/NamingConventions/IsValidIdentifierNameTest.php b/Tests/Utils/NamingConventions/IsValidIdentifierNameTest.php index d3b6b195..7c1e3d0c 100644 --- a/Tests/Utils/NamingConventions/IsValidIdentifierNameTest.php +++ b/Tests/Utils/NamingConventions/IsValidIdentifierNameTest.php @@ -18,20 +18,28 @@ * * @covers \PHPCSUtils\Utils\NamingConventions::isValidIdentifierName * - * @group namingconventions - * * @since 1.0.0 */ final class IsValidIdentifierNameTest extends TestCase { + /** + * Test that non-string input is rejected as invalid for a PHP identifier name. + * + * @return void + */ + public function testIsValidIdentifierNameReturnsFalseOnInvalidType() + { + $this->assertFalse(NamingConventions::isValidIdentifierName(12345)); + } + /** * Test correctly detecting whether an arbitrary string can be a valid PHP identifier name. * * @dataProvider dataIsValidIdentifierName * * @param string $input The input string. - * @param array $expected The expected function output. + * @param bool $expected The expected function output. * * @return void */ @@ -45,9 +53,9 @@ public function testIsValidIdentifierName($input, $expected) * * @see testIsValidIdentifierName() For the array format. * - * @return array + * @return array> */ - public function dataIsValidIdentifierName() + public static function dataIsValidIdentifierName() { return [ // Valid names. @@ -97,10 +105,6 @@ public function dataIsValidIdentifierName() ], // Invalid names. - 'not-a-string' => [ - 'input' => 12345, - 'expected' => false, - ], 'empty-string' => [ 'input' => '', 'expected' => false, diff --git a/Tests/Utils/Numbers/GetCompleteNumberTest.php b/Tests/Utils/Numbers/GetCompleteNumberTest.php index c65e9efc..e1e95a19 100644 --- a/Tests/Utils/Numbers/GetCompleteNumberTest.php +++ b/Tests/Utils/Numbers/GetCompleteNumberTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Numbers::getCompleteNumber * - * @group numbers - * * @since 1.0.0 */ final class GetCompleteNumberTest extends UtilityMethodTestCase @@ -43,8 +41,8 @@ public function testNotANumberException() * * @dataProvider dataGetCompleteNumber * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected Expected function return value. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected Expected function return value. * * @return void */ @@ -68,9 +66,9 @@ public function testGetCompleteNumber($testMarker, $expected) * * @see testGetCompleteNumber() For the array format. * - * @return array + * @return array>> */ - public function dataGetCompleteNumber() + public static function dataGetCompleteNumber() { /* * Disabling the hexnumeric string detection for the rest of the file. diff --git a/Tests/Utils/Numbers/GetDecimalValueTest.php b/Tests/Utils/Numbers/GetDecimalValueTest.php index 0dd2fec8..ff601f76 100644 --- a/Tests/Utils/Numbers/GetDecimalValueTest.php +++ b/Tests/Utils/Numbers/GetDecimalValueTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Numbers::getDecimalValue * - * @group numbers - * * @since 1.0.0 */ final class GetDecimalValueTest extends TestCase @@ -45,9 +43,9 @@ public function testGetDecimalValue($input, $expected) * * @see testGetDecimalValue() For the array format. * - * @return array + * @return array> */ - public function dataGetDecimalValue() + public static function dataGetDecimalValue() { return [ // Decimal integers. @@ -94,7 +92,7 @@ public function dataGetDecimalValue() * * @dataProvider dataGetDecimalValueInvalid * - * @param string $input The input string. + * @param mixed $input The input value. * * @return void */ @@ -108,9 +106,9 @@ public function testGetDecimalValueInvalid($input) * * @see testGetDecimalValueInvalid() For the array format. * - * @return array + * @return array> */ - public function dataGetDecimalValueInvalid() + public static function dataGetDecimalValueInvalid() { return [ 'not-a-string-bool' => [true], diff --git a/Tests/Utils/Numbers/NumberTypesTest.php b/Tests/Utils/Numbers/NumberTypesTest.php index 60cffb6b..21e61f8d 100644 --- a/Tests/Utils/Numbers/NumberTypesTest.php +++ b/Tests/Utils/Numbers/NumberTypesTest.php @@ -22,21 +22,117 @@ * * @coversDefaultClass \PHPCSUtils\Utils\Numbers * - * @group numbers - * * @since 1.0.0 */ final class NumberTypesTest extends TestCase { + /** + * Test correctly rejecting non-string input. + * + * @dataProvider dataNotAString + * @covers ::isDecimalInt + * + * @param mixed $input The input data. + * + * @return void + */ + public function testIsDecimalIntInvalidInput($input) + { + $this->assertFalse(Numbers::isDecimalInt($input)); + } + + /** + * Test correctly rejecting non-string input. + * + * @dataProvider dataNotAString + * @covers ::isHexidecimalInt + * + * @param mixed $input The input data. + * + * @return void + */ + public function testIsHexidecimalIntInvalidInput($input) + { + $this->assertFalse(Numbers::isHexidecimalInt($input)); + } + + /** + * Test correctly rejecting non-string input. + * + * @dataProvider dataNotAString + * @covers ::isBinaryInt + * + * @param mixed $input The input data. + * + * @return void + */ + public function testIsBinaryIntInvalidInput($input) + { + $this->assertFalse(Numbers::isBinaryInt($input)); + } + + /** + * Test correctly rejecting non-string input. + * + * @dataProvider dataNotAString + * @covers ::isOctalInt + * + * @param mixed $input The input data. + * + * @return void + */ + public function testIsOctalIntInvalidInput($input) + { + $this->assertFalse(Numbers::isOctalInt($input)); + } + + /** + * Test correctly rejecting non-string input. + * + * @dataProvider dataNotAString + * @covers ::isFloat + * + * @param mixed $input The input data. + * + * @return void + */ + public function testIsFloatInvalidInput($input) + { + $this->assertFalse(Numbers::isFloat($input)); + } + + /** + * Data Provider. + * + * @see testIsDecimalInt() For the array format. + * @see testIsHexidecimalInt() For the array format. + * @see testIsBinaryInt() For the array format. + * @see testIsOctalInt() For the array format. + * @see testIsDecimalFloat() For the array format. + * + * @return array> + */ + public static function dataNotAString() + { + return [ + 'not-a-string-bool' => [ + 'input' => true, + ], + 'not-a-string-int' => [ + 'input' => 10, + ], + ]; + } + /** * Test correctly recognizing an arbitrary string representing a decimal integer. * * @dataProvider dataNumbers * @covers ::isDecimalInt * - * @param string $input The input string. - * @param string $expected The expected output for the various functions. + * @param string $input The input string. + * @param array $expected The expected output for the various functions. * * @return void */ @@ -51,8 +147,8 @@ public function testIsDecimalInt($input, $expected) * @dataProvider dataNumbers * @covers ::isHexidecimalInt * - * @param string $input The input string. - * @param string $expected The expected output for the various functions. + * @param string $input The input string. + * @param array $expected The expected output for the various functions. * * @return void */ @@ -67,8 +163,8 @@ public function testIsHexidecimalInt($input, $expected) * @dataProvider dataNumbers * @covers ::isBinaryInt * - * @param string $input The input string. - * @param string $expected The expected output for the various functions. + * @param string $input The input string. + * @param array $expected The expected output for the various functions. * * @return void */ @@ -83,8 +179,8 @@ public function testIsBinaryInt($input, $expected) * @dataProvider dataNumbers * @covers ::isOctalInt * - * @param string $input The input string. - * @param string $expected The expected output for the various functions. + * @param string $input The input string. + * @param array $expected The expected output for the various functions. * * @return void */ @@ -99,8 +195,8 @@ public function testIsOctalInt($input, $expected) * @dataProvider dataNumbers * @covers ::isFloat * - * @param string $input The input string. - * @param string $expected The expected output for the various functions. + * @param string $input The input string. + * @param array $expected The expected output for the various functions. * * @return void */ @@ -118,33 +214,11 @@ public function testIsFloat($input, $expected) * @see testIsOctalInt() For the array format. * @see testIsDecimalFloat() For the array format. * - * @return array + * @return array>> */ public static function dataNumbers() { return [ - // Not strings. - 'not-a-string-bool' => [ - 'input' => true, - 'expected' => [ - 'decimal' => false, - 'hex' => false, - 'binary' => false, - 'octal' => false, - 'float' => false, - ], - ], - 'not-a-string-int' => [ - 'input' => 10, - 'expected' => [ - 'decimal' => false, - 'hex' => false, - 'binary' => false, - 'octal' => false, - 'float' => false, - ], - ], - // Not numeric strings. 'empty-string' => [ 'input' => '', diff --git a/Tests/Utils/ObjectDeclarations/FindExtendedClassNameDiffTest.php b/Tests/Utils/ObjectDeclarations/FindExtendedClassNameDiffTest.php index 5da5a50e..c6b0d603 100644 --- a/Tests/Utils/ObjectDeclarations/FindExtendedClassNameDiffTest.php +++ b/Tests/Utils/ObjectDeclarations/FindExtendedClassNameDiffTest.php @@ -34,8 +34,8 @@ final class FindExtendedClassNameDiffTest extends UtilityMethodTestCase * * @dataProvider dataFindExtendedClassName * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param bool $expected Expected function output. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param string|false $expected Expected function output. * * @return void */ @@ -51,9 +51,9 @@ public function testFindExtendedClassName($testMarker, $expected) * * @see testFindExtendedClassName() For the array format. * - * @return array + * @return array> */ - public function dataFindExtendedClassName() + public static function dataFindExtendedClassName() { return [ 'phpcs-annotation-and-comments' => [ diff --git a/Tests/Utils/ObjectDeclarations/FindExtendedInterfaceNamesTest.php b/Tests/Utils/ObjectDeclarations/FindExtendedInterfaceNamesTest.php index 3da86aaa..7a942dc7 100644 --- a/Tests/Utils/ObjectDeclarations/FindExtendedInterfaceNamesTest.php +++ b/Tests/Utils/ObjectDeclarations/FindExtendedInterfaceNamesTest.php @@ -54,8 +54,8 @@ public function testNotAnInterface() * * @dataProvider dataFindExtendedInterfaceNames * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array|false $expected Expected function output. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array|false $expected Expected function output. * * @return void */ @@ -71,9 +71,9 @@ public function testFindExtendedInterfaceNames($testMarker, $expected) * * @see testFindExtendedInterfaceNames() For the array format. * - * @return array + * @return array|false>> */ - public function dataFindExtendedInterfaceNames() + public static function dataFindExtendedInterfaceNames() { return [ 'not-extended' => [ diff --git a/Tests/Utils/ObjectDeclarations/FindImplementedInterfaceNamesDiffTest.php b/Tests/Utils/ObjectDeclarations/FindImplementedInterfaceNamesDiffTest.php index 34706c96..201f018d 100644 --- a/Tests/Utils/ObjectDeclarations/FindImplementedInterfaceNamesDiffTest.php +++ b/Tests/Utils/ObjectDeclarations/FindImplementedInterfaceNamesDiffTest.php @@ -34,8 +34,8 @@ final class FindImplementedInterfaceNamesDiffTest extends UtilityMethodTestCase * * @dataProvider dataFindImplementedInterfaceNames * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param bool $expected Expected function output. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array|false $expected Expected function output. * * @return void */ @@ -51,9 +51,9 @@ public function testFindImplementedInterfaceNames($testMarker, $expected) * * @see testFindImplementedInterfaceNames() For the array format. * - * @return array + * @return array|false>> */ - public function dataFindImplementedInterfaceNames() + public static function dataFindImplementedInterfaceNames() { return [ 'phpcs-annotation-and-comments' => [ diff --git a/Tests/Utils/ObjectDeclarations/GetClassPropertiesDiffTest.php b/Tests/Utils/ObjectDeclarations/GetClassPropertiesDiffTest.php index 8a2b8a48..0cdf2569 100644 --- a/Tests/Utils/ObjectDeclarations/GetClassPropertiesDiffTest.php +++ b/Tests/Utils/ObjectDeclarations/GetClassPropertiesDiffTest.php @@ -45,8 +45,8 @@ public function testNonExistentToken() * * @dataProvider dataGetClassProperties * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected Expected function output. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected Expected function output. * * @return void */ @@ -55,13 +55,13 @@ public function testGetClassProperties($testMarker, $expected) $class = $this->getTargetToken($testMarker, \T_CLASS); // Translate offsets to absolute token positions. - if ($expected['abstract_token'] !== false) { + if (\is_int($expected['abstract_token']) === true) { $expected['abstract_token'] += $class; } - if ($expected['final_token'] !== false) { + if (\is_int($expected['final_token']) === true) { $expected['final_token'] += $class; } - if ($expected['readonly_token'] !== false) { + if (\is_int($expected['readonly_token']) === true) { $expected['readonly_token'] += $class; } @@ -74,9 +74,9 @@ public function testGetClassProperties($testMarker, $expected) * * @see testGetClassProperties() For the array format. * - * @return array + * @return array>> */ - public function dataGetClassProperties() + public static function dataGetClassProperties() { return [ 'phpcs-annotation' => [ diff --git a/Tests/Utils/ObjectDeclarations/GetClassPropertiesTest.php b/Tests/Utils/ObjectDeclarations/GetClassPropertiesTest.php index 4d502378..978a909f 100644 --- a/Tests/Utils/ObjectDeclarations/GetClassPropertiesTest.php +++ b/Tests/Utils/ObjectDeclarations/GetClassPropertiesTest.php @@ -62,8 +62,8 @@ public static function setUpTestFile() * * @dataProvider dataGetClassProperties * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected Expected function output. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected Expected function output. * * @return void */ @@ -72,13 +72,13 @@ public function testGetClassProperties($testMarker, $expected) $class = $this->getTargetToken($testMarker, \T_CLASS); // Translate offsets to absolute token positions. - if ($expected['abstract_token'] !== false) { + if (\is_int($expected['abstract_token']) === true) { $expected['abstract_token'] += $class; } - if ($expected['final_token'] !== false) { + if (\is_int($expected['final_token']) === true) { $expected['final_token'] += $class; } - if ($expected['readonly_token'] !== false) { + if (\is_int($expected['readonly_token']) === true) { $expected['readonly_token'] += $class; } diff --git a/Tests/Utils/ObjectDeclarations/GetNameDiffTest.inc b/Tests/Utils/ObjectDeclarations/GetNameDiffTest.inc index 3e54ed11..7a7ae4e5 100644 --- a/Tests/Utils/ObjectDeclarations/GetNameDiffTest.inc +++ b/Tests/Utils/ObjectDeclarations/GetNameDiffTest.inc @@ -12,15 +12,6 @@ interface switch{ // Intentional parse error. public function someFunction(); } -/* testFunctionReturnByRefWithReservedKeywordParent */ -function &parent() {} - -/* testFunctionReturnByRefWithReservedKeywordSelf */ -function &self() {} - -/* testFunctionReturnByRefWithReservedKeywordStatic */ -function &static() {} - /* testLiveCoding */ // Intentional parse error. Redundancy testing. abstract class diff --git a/Tests/Utils/ObjectDeclarations/GetNameDiffTest.php b/Tests/Utils/ObjectDeclarations/GetNameDiffTest.php index b09173a8..de4f67ee 100644 --- a/Tests/Utils/ObjectDeclarations/GetNameDiffTest.php +++ b/Tests/Utils/ObjectDeclarations/GetNameDiffTest.php @@ -61,9 +61,9 @@ public function testGetNameNull($testMarker, $targetType) * * @see testGetNameNull() For the array format. * - * @return array + * @return array> */ - public function dataGetNameNull() + public static function dataGetNameNull() { return [ 'live-coding' => [ @@ -78,9 +78,9 @@ public function dataGetNameNull() * * @dataProvider dataGetName * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param string $expected Expected function output. - * @param int|string $targetType Token type of the token to get as stackPtr. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param string $expected Expected function output. + * @param int|string|null $targetType Token type of the token to get as stackPtr. * * @return void */ @@ -100,9 +100,9 @@ public function testGetName($testMarker, $expected, $targetType = null) * * @see testGetName() For the array format. * - * @return array + * @return array> */ - public function dataGetName() + public static function dataGetName() { return [ 'trait-name-starts-with-number' => [ @@ -117,18 +117,6 @@ public function dataGetName() 'testMarker' => '/* testInvalidInterfaceName */', 'expected' => 'switch', ], - 'function-return-by-reference-with-reserved-keyword-parent' => [ - '/* testFunctionReturnByRefWithReservedKeywordParent */', - 'parent', - ], - 'function-return-by-reference-with-reserved-keyword-self' => [ - '/* testFunctionReturnByRefWithReservedKeywordSelf */', - 'self', - ], - 'function-return-by-reference-with-reserved-keyword-static' => [ - '/* testFunctionReturnByRefWithReservedKeywordStatic */', - 'static', - ], ]; } } diff --git a/Tests/Utils/ObjectDeclarations/GetNameJSTest.php b/Tests/Utils/ObjectDeclarations/GetNameJSTest.php index 875761bd..155f9189 100644 --- a/Tests/Utils/ObjectDeclarations/GetNameJSTest.php +++ b/Tests/Utils/ObjectDeclarations/GetNameJSTest.php @@ -86,9 +86,9 @@ public function testGetDeclarationNameNull($testMarker, $targetType) * * @dataProvider dataGetDeclarationName * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param string $expected Expected function output. - * @param int|string $targetType Token type of the token to get as stackPtr. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param string $expected Expected function output. + * @param array|null $targetType Token type of the token to get as stackPtr. * * @return void */ diff --git a/Tests/Utils/ObjectDeclarations/GetNameTest.php b/Tests/Utils/ObjectDeclarations/GetNameTest.php index eb1e1509..074cdf7c 100644 --- a/Tests/Utils/ObjectDeclarations/GetNameTest.php +++ b/Tests/Utils/ObjectDeclarations/GetNameTest.php @@ -86,9 +86,9 @@ public function testGetDeclarationNameNull($testMarker, $targetType) * * @dataProvider dataGetDeclarationName * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param string $expected Expected function output. - * @param int|string $targetType Token type of the token to get as stackPtr. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param string $expected Expected function output. + * @param int|string|null $targetType Token type of the token to get as stackPtr. * * @return void */ diff --git a/Tests/Utils/Operators/IsShortTernaryTest.php b/Tests/Utils/Operators/IsShortTernaryTest.php index 9539f3b6..22674560 100644 --- a/Tests/Utils/Operators/IsShortTernaryTest.php +++ b/Tests/Utils/Operators/IsShortTernaryTest.php @@ -72,9 +72,9 @@ public function testIsShortTernary($testMarker, $expected) * * @see testIsShortTernary() For the array format. * - * @return array + * @return array> */ - public function dataIsShortTernary() + public static function dataIsShortTernary() { return [ 'long-ternary' => [ diff --git a/Tests/Utils/Operators/IsUnaryPlusMinusJSTest.php b/Tests/Utils/Operators/IsUnaryPlusMinusJSTest.php index ef47170d..5df83917 100644 --- a/Tests/Utils/Operators/IsUnaryPlusMinusJSTest.php +++ b/Tests/Utils/Operators/IsUnaryPlusMinusJSTest.php @@ -36,9 +36,9 @@ final class IsUnaryPlusMinusJSTest extends IsUnaryPlusMinusTestCase * * @see IsUnaryPlusMinusTest::testIsUnaryPlusMinus() For the array format. * - * @return array + * @return array> */ - public function dataIsUnaryPlusMinus() + public static function dataIsUnaryPlusMinus() { return [ 'non-unary-plus' => [ diff --git a/Tests/Utils/Operators/IsUnaryPlusMinusTest.php b/Tests/Utils/Operators/IsUnaryPlusMinusTest.php index 93514299..3c8d7ef0 100644 --- a/Tests/Utils/Operators/IsUnaryPlusMinusTest.php +++ b/Tests/Utils/Operators/IsUnaryPlusMinusTest.php @@ -29,9 +29,9 @@ final class IsUnaryPlusMinusTest extends IsUnaryPlusMinusTestCase * * @see testIsUnaryPlusMinus() For the array format. * - * @return array + * @return array> */ - public function dataIsUnaryPlusMinus() + public static function dataIsUnaryPlusMinus() { return [ 'non-unary-plus' => [ diff --git a/Tests/Utils/Operators/IsUnaryPlusMinusTestCase.php b/Tests/Utils/Operators/IsUnaryPlusMinusTestCase.php index cb441f01..00bacf61 100644 --- a/Tests/Utils/Operators/IsUnaryPlusMinusTestCase.php +++ b/Tests/Utils/Operators/IsUnaryPlusMinusTestCase.php @@ -71,7 +71,7 @@ public function testIsUnaryPlusMinus($testMarker, $expected) * * @see testIsUnaryPlusMinus() For the array format. * - * @return array + * @return array> */ - abstract public function dataIsUnaryPlusMinus(); + abstract public static function dataIsUnaryPlusMinus(); } diff --git a/Tests/Utils/Orthography/FirstCharTest.php b/Tests/Utils/Orthography/FirstCharTest.php index b474ac4e..06405e24 100644 --- a/Tests/Utils/Orthography/FirstCharTest.php +++ b/Tests/Utils/Orthography/FirstCharTest.php @@ -20,8 +20,6 @@ * @covers \PHPCSUtils\Utils\Orthography::isFirstCharCapitalized * @covers \PHPCSUtils\Utils\Orthography::isFirstCharLowercase * - * @group orthography - * * @since 1.0.0 */ final class FirstCharTest extends TestCase @@ -32,8 +30,8 @@ final class FirstCharTest extends TestCase * * @dataProvider dataFirstChar * - * @param string $input The input string. - * @param array $expected The expected function output for the respective functions. + * @param string $input The input string. + * @param array $expected The expected function output for the respective functions. * * @return void */ @@ -47,8 +45,8 @@ public function testIsFirstCharCapitalized($input, $expected) * * @dataProvider dataFirstChar * - * @param string $input The input string. - * @param array $expected The expected function output for the respective functions. + * @param string $input The input string. + * @param array $expected The expected function output for the respective functions. * * @return void */ @@ -63,9 +61,9 @@ public function testIsFirstCharLowercase($input, $expected) * @see testIsFirstCharCapitalized() For the array format. * @see testIsFirstCharLowercase() For the array format. * - * @return array + * @return array>> */ - public function dataFirstChar() + public static function dataFirstChar() { $data = [ // Quotes should be stripped before passing the string. diff --git a/Tests/Utils/Orthography/IsLastCharPunctuationTest.php b/Tests/Utils/Orthography/IsLastCharPunctuationTest.php index d177e252..b148fde1 100644 --- a/Tests/Utils/Orthography/IsLastCharPunctuationTest.php +++ b/Tests/Utils/Orthography/IsLastCharPunctuationTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\Orthography::isLastCharPunctuation * - * @group orthography - * * @since 1.0.0 */ final class IsLastCharPunctuationTest extends TestCase @@ -52,9 +50,9 @@ public function testIsLastCharPunctuation($input, $expected, $allowedChars = nul * * @see testIsLastCharPunctuation() For the array format. * - * @return array + * @return array> */ - public function dataIsLastCharPunctuation() + public static function dataIsLastCharPunctuation() { return [ // Quotes should be stripped before passing the string. diff --git a/Tests/Utils/Parentheses/ParenthesesTest.php b/Tests/Utils/Parentheses/ParenthesesTest.php index 76b365a3..57e85a69 100644 --- a/Tests/Utils/Parentheses/ParenthesesTest.php +++ b/Tests/Utils/Parentheses/ParenthesesTest.php @@ -19,8 +19,6 @@ * * @covers \PHPCSUtils\Utils\Parentheses * - * @group parentheses - * * @since 1.0.0 */ final class ParenthesesTest extends UtilityMethodTestCase @@ -29,7 +27,7 @@ final class ParenthesesTest extends UtilityMethodTestCase /** * List of all the test markers with their target token info in the test case file. * - * @var array + * @var array> */ public static $testTargets = [ 'testIfWithArray-$a' => [ @@ -194,7 +192,7 @@ final class ParenthesesTest extends UtilityMethodTestCase /** * Cache for the test token stack pointers. * - * @var array => + * @var array */ private static $testTokens = []; @@ -210,7 +208,7 @@ final class ParenthesesTest extends UtilityMethodTestCase * This array isn't auto-generated based on the array in Tokens as for these * tests we want to have access to the token constant names, not just their values. * - * @var array => + * @var array */ private $ownerDefaults = [ 'T_ARRAY' => false, @@ -427,8 +425,8 @@ public function testFunctionNamedFnKeywordNotParenthesesOwner() * * @dataProvider dataWalkParentheses * - * @param string $testName The name of this test as set in the cached $testTokens array. - * @param array $expectedResults Expected function output for the various functions. + * @param string $testName The name of this test as set in the cached $testTokens array. + * @param array $expectedResults Expected function output for the various functions. * * @return void */ @@ -458,8 +456,8 @@ public function testGetFirstOpener($testName, $expectedResults) * * @dataProvider dataWalkParentheses * - * @param string $testName The name of this test as set in the cached $testTokens array. - * @param array $expectedResults Expected function output for the various functions. + * @param string $testName The name of this test as set in the cached $testTokens array. + * @param array $expectedResults Expected function output for the various functions. * * @return void */ @@ -489,8 +487,8 @@ public function testGetFirstCloser($testName, $expectedResults) * * @dataProvider dataWalkParentheses * - * @param string $testName The name of this test as set in the cached $testTokens array. - * @param array $expectedResults Expected function output for the various functions. + * @param string $testName The name of this test as set in the cached $testTokens array. + * @param array $expectedResults Expected function output for the various functions. * * @return void */ @@ -520,8 +518,8 @@ public function testGetFirstOwner($testName, $expectedResults) * * @dataProvider dataWalkParentheses * - * @param string $testName The name of this test as set in the cached $testTokens array. - * @param array $expectedResults Expected function output for the various functions. + * @param string $testName The name of this test as set in the cached $testTokens array. + * @param array $expectedResults Expected function output for the various functions. * * @return void */ @@ -551,8 +549,8 @@ public function testGetLastOpener($testName, $expectedResults) * * @dataProvider dataWalkParentheses * - * @param string $testName The name of this test as set in the cached $testTokens array. - * @param array $expectedResults Expected function output for the various functions. + * @param string $testName The name of this test as set in the cached $testTokens array. + * @param array $expectedResults Expected function output for the various functions. * * @return void */ @@ -582,8 +580,8 @@ public function testGetLastCloser($testName, $expectedResults) * * @dataProvider dataWalkParentheses * - * @param string $testName The name of this test as set in the cached $testTokens array. - * @param array $expectedResults Expected function output for the various functions. + * @param string $testName The name of this test as set in the cached $testTokens array. + * @param array $expectedResults Expected function output for the various functions. * * @return void */ @@ -618,9 +616,9 @@ public function testGetLastOwner($testName, $expectedResults) * @see testGetLastCloser() For the array format. * @see testGetLastOwner() For the array format. * - * @return array + * @return array>> */ - public function dataWalkParentheses() + public static function dataWalkParentheses() { $data = [ 'testIfWithArray-$a' => [ @@ -939,9 +937,9 @@ public function dataWalkParentheses() * * @dataProvider dataHasOwner * - * @param string $testName The name of this test as set in the cached $testTokens array. - * @param array $expectedResults Array with the owner token type to search for as key - * and the expected result as a value. + * @param string $testName The name of this test as set in the cached $testTokens array. + * @param array $expectedResults Array with the owner token type to search for as key + * and the expected result as a value. * * @return void */ @@ -971,9 +969,9 @@ public function testHasOwner($testName, $expectedResults) * * @see testHasOwner() For the array format. * - * @return array + * @return array>> */ - public function dataHasOwner() + public static function dataHasOwner() { return [ 'testIfWithArray-$a' => [ @@ -1193,9 +1191,9 @@ public function testHasOwnerMultipleTypes() * * @dataProvider dataFirstOwnerIn * - * @param string $testName The name of this test as set in the cached $testTokens array. - * @param array $validOwners Valid owners to test against. - * @param int|false $expected Expected function output + * @param string $testName The name of this test as set in the cached $testTokens array. + * @param array $validOwners Valid owners to test against. + * @param int|false $expected Expected function output * * @return void */ @@ -1215,9 +1213,9 @@ public function testFirstOwnerIn($testName, $validOwners, $expected) * * @see testFirstOwnerIn() For the array format. * - * @return array + * @return array|false>> */ - public function dataFirstOwnerIn() + public static function dataFirstOwnerIn() { return [ 'testElseIfWithClosure-$a-elseif' => [ @@ -1284,9 +1282,9 @@ public function dataFirstOwnerIn() * * @dataProvider dataLastOwnerIn * - * @param string $testName The name of this test as set in the cached $testTokens array. - * @param array $validOwners Valid owners to test against. - * @param int|false $expected Expected function output + * @param string $testName The name of this test as set in the cached $testTokens array. + * @param array $validOwners Valid owners to test against. + * @param int|false $expected Expected function output * * @return void */ @@ -1306,9 +1304,9 @@ public function testLastOwnerIn($testName, $validOwners, $expected) * * @see testLastOwnerIn() For the array format. * - * @return array + * @return array|false>> */ - public function dataLastOwnerIn() + public static function dataLastOwnerIn() { return [ 'testElseIfWithClosure-$a-closure' => [ diff --git a/Tests/Utils/PassedParameters/GetParameterCountTest.inc b/Tests/Utils/PassedParameters/GetParameterCountTest.inc index 490a579e..f69def98 100644 --- a/Tests/Utils/PassedParameters/GetParameterCountTest.inc +++ b/Tests/Utils/PassedParameters/GetParameterCountTest.inc @@ -219,6 +219,14 @@ $anon = new class( $param1, $param2 ) { public function __construct($param1, $param2) {} }; +/* testPHP80ClassInstantiationInAttribute */ +#[MyAttribute(1, self::Foo, 'string')] +function foo() {} + +/* testPHP80ClassInstantiationInMultiAttribute */ +#[AttributeOne, \AttributeTwo(1, self::Foo)] +function bar() {} + /* testArrayWithEmptyItem */ // Intentional parse error. $bar = [0 => $a,, 2 => $b]; diff --git a/Tests/Utils/PassedParameters/GetParameterCountTest.php b/Tests/Utils/PassedParameters/GetParameterCountTest.php index 49d85db4..5ee5e8db 100644 --- a/Tests/Utils/PassedParameters/GetParameterCountTest.php +++ b/Tests/Utils/PassedParameters/GetParameterCountTest.php @@ -21,8 +21,6 @@ * @covers \PHPCSUtils\Utils\PassedParameters::getParameters * @covers \PHPCSUtils\Utils\PassedParameters::hasParameters * - * @group passedparameters - * * @since 1.0.0 */ final class GetParameterCountTest extends UtilityMethodTestCase @@ -33,10 +31,10 @@ final class GetParameterCountTest extends UtilityMethodTestCase * * @dataProvider dataGetParameterCount * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int $expected The expected parameter count. - * @param string $targetContent Optional. The content of the target token to find. - * Defaults to null (ignore content). + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int $expected The expected parameter count. + * @param string|null $targetContent Optional. The content of the target token to find. + * Defaults to null (ignore content). * * @return void */ @@ -58,9 +56,9 @@ public function testGetParameterCount($testMarker, $expected, $targetContent = n * * @see testGetParameterCount() For the array format. * - * @return array + * @return array> */ - public function dataGetParameterCount() + public static function dataGetParameterCount() { $php8Names = parent::usesPhp8NameTokens(); @@ -355,6 +353,21 @@ public function dataGetParameterCount() 'expected' => 2, ], + 'class-instantiation-in-attribute' => [ + 'testMarker' => '/* testPHP80ClassInstantiationInAttribute */', + 'expected' => 3, + ], + 'class-instantiation-in-attribute-no-params' => [ + 'testMarker' => '/* testPHP80ClassInstantiationInMultiAttribute */', + 'expected' => 0, + 'targetContent' => 'AttributeOne', + ], + 'class-instantiation-in-attribute-with-params' => [ + 'testMarker' => '/* testPHP80ClassInstantiationInMultiAttribute */', + 'expected' => 2, + 'targetContent' => ($php8Names === true) ? '\AttributeTwo' : 'AttributeTwo', + ], + 'array-with-empty-item' => [ 'testMarker' => '/* testArrayWithEmptyItem */', 'expected' => 3, diff --git a/Tests/Utils/PassedParameters/GetParameterFromStackTest.php b/Tests/Utils/PassedParameters/GetParameterFromStackTest.php index b600f753..8b8e50da 100644 --- a/Tests/Utils/PassedParameters/GetParameterFromStackTest.php +++ b/Tests/Utils/PassedParameters/GetParameterFromStackTest.php @@ -21,8 +21,6 @@ * @covers \PHPCSUtils\Utils\PassedParameters::getParameter * @covers \PHPCSUtils\Utils\PassedParameters::getParameterFromStack * - * @group passedparameters - * * @since 1.0.0 */ final class GetParameterFromStackTest extends UtilityMethodTestCase @@ -71,9 +69,9 @@ public function testGetParameterNonFunctionCallNoParamName($testMarker, $targetT * * @see testGetParameterNonFunctionCallNoParamName() For the array format. * - * @return array + * @return array> */ - public function dataGetParameterNonFunctionCallNoParamName() + public static function dataGetParameterNonFunctionCallNoParamName() { return [ 'isset' => [ @@ -148,8 +146,8 @@ public function testGetParameterFunctionCallPositionalMissingParamNameNonExisten * * @dataProvider dataGetParameterFunctionCallWithParamName * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected function output. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected function output. * * @return void */ @@ -173,9 +171,9 @@ public function testGetParameterFunctionCallWithParamName($testMarker, $expected * * @see testGetParameterFunctionCallWithParamName() For the array format. * - * @return array + * @return array>> */ - public function dataGetParameterFunctionCallWithParamName() + public static function dataGetParameterFunctionCallWithParamName() { return [ 'all-named-non-standard-order' => [ @@ -204,10 +202,11 @@ public function dataGetParameterFunctionCallWithParamName() * * @dataProvider dataGetParameterFromStack * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expectedName The expected result array for the $name parameter. - * @param array|false $expectedExpires The expected result array for the $expires_or_options parameter. - * @param array|false $expectedHttpOnly The expected result array for the $httponly parameter. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array|false $expectedName The expected result array for the $name parameter. + * @param array|false $expectedExpires The expected result array for the $expires_or_options + * parameter. + * @param array|false $expectedHttpOnly The expected result array for the $httponly parameter. * * @return void */ @@ -282,9 +281,9 @@ public function testGetParameterFromStack($testMarker, $expectedName, $expectedE * * @see testGetParameterFromStack() For the array format. * - * @return array + * @return array|false>> */ - public function dataGetParameterFromStack() + public static function dataGetParameterFromStack() { return [ 'all-params-all-positional' => [ @@ -415,9 +414,9 @@ public function dataGetParameterFromStack() * * @dataProvider dataGetParameterFromStackNamedAfterVariadic * - * @param string $offset The positional offfset to pass. - * @param array $names The parameter names to pass. - * @param array|false $expected The expected result array for the parameter. + * @param int $offset The positional offfset to pass. + * @param array $names The parameter names to pass. + * @param array|false $expected The expected result array for the parameter. * * @return void */ @@ -448,9 +447,9 @@ public function testGetParameterFromStackNamedAfterVariadic($offset, $names, $ex * * @see testGetParameterFromStackNamedAfterVariadic() For the array format. * - * @return array + * @return array|array|false>> */ - public function dataGetParameterFromStackNamedAfterVariadic() + public static function dataGetParameterFromStackNamedAfterVariadic() { return [ 'first param, positional' => [ diff --git a/Tests/Utils/PassedParameters/GetParametersNamedTest.php b/Tests/Utils/PassedParameters/GetParametersNamedTest.php index 75c446dc..78916dd8 100644 --- a/Tests/Utils/PassedParameters/GetParametersNamedTest.php +++ b/Tests/Utils/PassedParameters/GetParametersNamedTest.php @@ -23,8 +23,6 @@ * @covers \PHPCSUtils\Utils\PassedParameters::getParameterFromStack * @covers \PHPCSUtils\Utils\PassedParameters::hasParameters * - * @group passedparameters - * * @since 1.0.0 */ final class GetParametersNamedTest extends UtilityMethodTestCase @@ -35,10 +33,11 @@ final class GetParametersNamedTest extends UtilityMethodTestCase * * @dataProvider dataGetParameters * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string $targetType The type of token to look for. - * @param array $expected The expected parameter array. - * @param mixed $targetContent Optional. The token content to look for. + * @param string $testMarker The comment which prefaces the target token + * in the test file. + * @param int|string $targetType The type of token to look for. + * @param array> $expected The expected parameter array. + * @param string|null $targetContent Optional. The token content to look for. * * @return void */ @@ -75,9 +74,9 @@ public function testGetParameters($testMarker, $targetType, $expected, $targetCo * * @see testGetParameters() For the array format. * - * @return array + * @return array>|null>> */ - public function dataGetParameters() + public static function dataGetParameters() { $php8Names = parent::usesPhp8NameTokens(); diff --git a/Tests/Utils/PassedParameters/GetParametersSkipShortArrayCheckTest.php b/Tests/Utils/PassedParameters/GetParametersSkipShortArrayCheckTest.php index fdb7a4b9..39ab014e 100644 --- a/Tests/Utils/PassedParameters/GetParametersSkipShortArrayCheckTest.php +++ b/Tests/Utils/PassedParameters/GetParametersSkipShortArrayCheckTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Utils\PassedParameters; -use PHPCSUtils\BackCompat\Helper; use PHPCSUtils\Tests\PolyfilledTestCase; use PHPCSUtils\Utils\PassedParameters; @@ -22,8 +21,6 @@ * @covers \PHPCSUtils\Utils\PassedParameters::hasParameters * @covers \PHPCSUtils\Utils\PassedParameters::getParameters * - * @group passedparameters - * * @since 1.0.0 */ final class GetParametersSkipShortArrayCheckTest extends PolyfilledTestCase @@ -35,7 +32,7 @@ final class GetParametersSkipShortArrayCheckTest extends PolyfilledTestCase * * Also verify that for valid constructs, the method still behaves like normal. * - * @dataProvider dataTestCases + * @dataProvider dataHasParametersDontSkipShortArrayCheck * * @param string $testMarker The comment which prefaces the target token in the test file. * @param int|string $targetType The type of token to look for. @@ -58,27 +55,44 @@ public function testHasParametersDontSkipShortArrayCheck($testMarker, $targetTyp $this->assertIsBool($hasParams); } + /** + * Data provider. + * + * @see testHasParametersDontSkipShortArrayCheck() For the array format. + * + * @return array>>> + */ + public static function dataHasParametersDontSkipShortArrayCheck() + { + $data = self::dataTestCases(); + + foreach ($data as $name => $dataset) { + unset($data[$name]['expected']); + } + + return $data; + } + /** * Test retrieving the parameter details for valid and invalid constructs when the * `$isShortArray` parameter is set to TRUE. * - * @dataProvider dataTestCases + * @dataProvider dataGetParametersSkipShortArrayCheck * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string $targetType The type of token to look for. - * @param bool $ignore Not used in this test. - * @param array $expected The expected return value. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetType The type of token to look for. + * @param array> $expected The expected return value. * * @return void */ - public function testGetParametersSkipShortArrayCheck($testMarker, $targetType, $ignore, $expected) + public function testGetParametersSkipShortArrayCheck($testMarker, $targetType, $expected) { /* * Expect an exception on PHPCS versions when square brackets will never be a short array. * Note: this also means that the "$expected" value will not be tested as the exception * will be received before the code reaches that point. */ - if ($targetType === \T_OPEN_SQUARE_BRACKET && \version_compare(Helper::getVersion(), '3.7.1', '>')) { + if ($targetType === \T_OPEN_SQUARE_BRACKET) { $this->expectPhpcsException( 'The hasParameters() method expects a function call, array, isset or unset token to be passed.' ); @@ -105,28 +119,46 @@ public function testGetParametersSkipShortArrayCheck($testMarker, $targetType, $ $this->assertSame($expected, $result); } + /** + * Data provider. + * + * @see testGetParametersSkipShortArrayCheck() For the array format. + * + * @return array>>> + */ + public static function dataGetParametersSkipShortArrayCheck() + { + $data = self::dataTestCases(); + + foreach ($data as $name => $dataset) { + unset($data[$name]['expectException']); + } + + return $data; + } + /** * Data provider. * * @see testGetParametersSkipShortArrayCheck() For the array format. * @see testHasParametersDontSkipShortArrayCheck() For the array format. * - * @return array + * @return array>>> */ - public function dataTestCases() + public static function dataTestCases() { return [ 'no-params' => [ - 'testMarker' => '/* testNoParams */', - 'targetType' => \T_OPEN_SHORT_ARRAY, - 'ignore' => false, - 'expected' => [], + 'testMarker' => '/* testNoParams */', + 'targetType' => \T_OPEN_SHORT_ARRAY, + 'expectException' => false, + 'expected' => [], ], 'long-array' => [ - 'testMarker' => '/* testLongArray */', - 'targetType' => \T_ARRAY, - 'ignore' => false, - 'expected' => [ + 'testMarker' => '/* testLongArray */', + 'targetType' => \T_ARRAY, + 'expectException' => false, + 'expected' => [ 1 => [ 'start' => 2, 'end' => 3, @@ -140,10 +172,10 @@ public function dataTestCases() ], ], 'short-array' => [ - 'testMarker' => '/* testShortArray */', - 'targetType' => \T_OPEN_SHORT_ARRAY, - 'ignore' => false, - 'expected' => [ + 'testMarker' => '/* testShortArray */', + 'targetType' => \T_OPEN_SHORT_ARRAY, + 'expectException' => false, + 'expected' => [ 1 => [ 'start' => 1, 'end' => 6, @@ -157,10 +189,10 @@ public function dataTestCases() ], ], 'short-list' => [ - 'testMarker' => '/* testShortList */', - 'targetType' => \T_OPEN_SHORT_ARRAY, - 'ignore' => true, - 'expected' => [ + 'testMarker' => '/* testShortList */', + 'targetType' => \T_OPEN_SHORT_ARRAY, + 'expectException' => true, + 'expected' => [ 1 => [ 'start' => 1, 'end' => 6, @@ -180,10 +212,10 @@ public function dataTestCases() * class for those PHPCS versions. */ 'array-assign' => [ - 'testMarker' => '/* testArrayAssign */', - 'targetType' => \T_OPEN_SQUARE_BRACKET, - 'ignore' => true, - 'expected' => [], + 'testMarker' => '/* testArrayAssign */', + 'targetType' => \T_OPEN_SQUARE_BRACKET, + 'expectException' => true, + 'expected' => [], ], /* * This test will result in an (expected) Exception when run on PHPCS versions which @@ -192,10 +224,10 @@ public function dataTestCases() * class for those PHPCS versions. */ 'array-access' => [ - 'testMarker' => '/* testArrayAccess */', - 'targetType' => \T_OPEN_SQUARE_BRACKET, - 'ignore' => true, - 'expected' => [ + 'testMarker' => '/* testArrayAccess */', + 'targetType' => \T_OPEN_SQUARE_BRACKET, + 'expectException' => true, + 'expected' => [ 1 => [ 'start' => 1, 'end' => 4, @@ -204,10 +236,10 @@ public function dataTestCases() ], ], 'short-list-with-empties-before' => [ - 'testMarker' => '/* testShortListWithEmptyItemsBefore */', - 'targetType' => \T_OPEN_SHORT_ARRAY, - 'ignore' => true, - 'expected' => [ + 'testMarker' => '/* testShortListWithEmptyItemsBefore */', + 'targetType' => \T_OPEN_SHORT_ARRAY, + 'expectException' => true, + 'expected' => [ 1 => [ 'start' => 1, 'end' => 0, @@ -226,10 +258,10 @@ public function dataTestCases() ], ], 'short-list-with-empties-after' => [ - 'testMarker' => '/* testShortListWithEmptyItemsAfter */', - 'targetType' => \T_OPEN_SHORT_ARRAY, - 'ignore' => true, - 'expected' => [ + 'testMarker' => '/* testShortListWithEmptyItemsAfter */', + 'targetType' => \T_OPEN_SHORT_ARRAY, + 'expectException' => true, + 'expected' => [ 1 => [ 'start' => 1, 'end' => 1, @@ -243,10 +275,10 @@ public function dataTestCases() ], ], 'short-list-with-all-empties' => [ - 'testMarker' => '/* testShortListWithAllEmptyItems */', - 'targetType' => \T_OPEN_SHORT_ARRAY, - 'ignore' => true, - 'expected' => [ + 'testMarker' => '/* testShortListWithAllEmptyItems */', + 'targetType' => \T_OPEN_SHORT_ARRAY, + 'expectException' => true, + 'expected' => [ 1 => [ 'start' => 1, 'end' => 0, diff --git a/Tests/Utils/PassedParameters/GetParametersTest.inc b/Tests/Utils/PassedParameters/GetParametersTest.inc index 6e291206..3295cf8b 100644 --- a/Tests/Utils/PassedParameters/GetParametersTest.inc +++ b/Tests/Utils/PassedParameters/GetParametersTest.inc @@ -132,10 +132,17 @@ $arr4 = array(...$arr1, ...arrGen(), ...new ArrayIterator(['a', 'b', 'c'])); // Also includes code sample for PHP 8.1 unpacking with string keys. $fruits = ['banana', ...$parts, 'watermelon', ...["a" => 2],]; -/* testPHP80FunctionCallInAttribute */ +/* testPHP80ClassInstantiationInAttribute1 */ #[AttributeAttachedToClosure([1, 2, 3])] $closure = function() {}; +/* testPHP80ClassInstantiationInAttribute2 */ +#[MyAttribute(1, self::Foo, 'string')] +function foo() {} + +#[AttributeOne, /* testPHP80ClassInstantiationInMultiAttribute */ \AttributeTwo(1, self::Foo)] +function bar() {} + /* testPHP80SkippingOverAttributes */ $result = function_call( $value, diff --git a/Tests/Utils/PassedParameters/GetParametersTest.php b/Tests/Utils/PassedParameters/GetParametersTest.php index ccc8433c..8e435ead 100644 --- a/Tests/Utils/PassedParameters/GetParametersTest.php +++ b/Tests/Utils/PassedParameters/GetParametersTest.php @@ -23,8 +23,6 @@ * @covers \PHPCSUtils\Utils\PassedParameters::getParameterFromStack * @covers \PHPCSUtils\Utils\PassedParameters::hasParameters * - * @group passedparameters - * * @since 1.0.0 */ final class GetParametersTest extends UtilityMethodTestCase @@ -51,9 +49,10 @@ public function testGetParametersNoParams() * * @dataProvider dataGetParameters * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string $targetType The type of token to look for. - * @param array $expected The expected parameter array. + * @param string $testMarker The comment which prefaces the target token in + * the test file. + * @param int|string $targetType The type of token to look for. + * @param array> $expected The expected parameter array. * * @return void */ @@ -86,10 +85,12 @@ public function testGetParameters($testMarker, $targetType, $expected) * * @see testGetParameters() For the array format. * - * @return array + * @return array>>> */ - public function dataGetParameters() + public static function dataGetParameters() { + $php8Names = parent::usesPhp8NameTokens(); + return [ 'function-call' => [ 'testMarker' => '/* testFunctionCall */', @@ -588,9 +589,9 @@ public function test( $foo, $bar ) { ], ], - // PHP 8.0: function calls in attributes. - 'function-call-within-an-attribute' => [ - 'testMarker' => '/* testPHP80FunctionCallInAttribute */', + // PHP 8.0: class instantiation in attributes. + 'class-instantiation-within-an-attribute-1' => [ + 'testMarker' => '/* testPHP80ClassInstantiationInAttribute1 */', 'targetType' => \T_STRING, 'expected' => [ 1 => [ @@ -600,6 +601,43 @@ public function test( $foo, $bar ) { ], ], ], + 'class-instantiation-within-an-attribute-2' => [ + 'testMarker' => '/* testPHP80ClassInstantiationInAttribute2 */', + 'targetType' => \T_STRING, + 'expected' => [ + 1 => [ + 'start' => 2, + 'end' => 2, + 'raw' => '1', + ], + 2 => [ + 'start' => 4, + 'end' => 7, + 'raw' => 'self::Foo', + ], + 3 => [ + 'start' => 9, + 'end' => 10, + 'raw' => "'string'", + ], + ], + ], + 'class-instantiation-within-a-multi-attribute' => [ + 'testMarker' => '/* testPHP80ClassInstantiationInMultiAttribute */', + 'targetType' => ($php8Names === true) ? \T_NAME_FULLY_QUALIFIED : \T_STRING, + 'expected' => [ + 1 => [ + 'start' => 2, + 'end' => 2, + 'raw' => '1', + ], + 2 => [ + 'start' => 4, + 'end' => 7, + 'raw' => 'self::Foo', + ], + ], + ], // PHP 8.0: skipping over attributes. 'function-call-with-attributes-attached-to-passed-closure' => [ @@ -691,10 +729,10 @@ public function testGetParametersResultIsCached() * * @dataProvider dataGetParameter * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string $targetType The type of token to look for. - * @param int $paramPosition The position of the parameter we want to retrieve the details for. - * @param array $expected The expected array for the specific parameter. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetType The type of token to look for. + * @param int $paramPosition The position of the parameter we want to retrieve the details for. + * @param array $expected The expected array for the specific parameter. * * @return void */ @@ -723,9 +761,9 @@ public function testGetParameter($testMarker, $targetType, $paramPosition, $expe * * @see testGetParameter() For the array format. * - * @return array + * @return array>> */ - public function dataGetParameter() + public static function dataGetParameter() { return [ 'function-call-param-4' => [ diff --git a/Tests/Utils/PassedParameters/GetParametersWithLimitTest.php b/Tests/Utils/PassedParameters/GetParametersWithLimitTest.php index bfcb271b..0edd22b3 100644 --- a/Tests/Utils/PassedParameters/GetParametersWithLimitTest.php +++ b/Tests/Utils/PassedParameters/GetParametersWithLimitTest.php @@ -20,8 +20,6 @@ * * @covers \PHPCSUtils\Utils\PassedParameters::getParameters * - * @group passedparameters - * * @since 1.0.0 */ final class GetParametersWithLimitTest extends UtilityMethodTestCase @@ -71,9 +69,9 @@ public function testGetParametersWithIneffectiveLimit($limit) * * @see testGetParametersWithIneffectiveLimit() For the array format. * - * @return array + * @return array> */ - public function dataGetParametersWithIneffectiveLimit() + public static function dataGetParametersWithIneffectiveLimit() { return [ 'invalid-limit-wrong-type-null' => [null], @@ -90,11 +88,12 @@ public function dataGetParametersWithIneffectiveLimit() * * @dataProvider dataGetParametersWithLimit * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string $targetType The type of token to look for. - * @param array $limit The number of parameters to limit this call to. - * Should match the expected count. - * @param array $expected Optional. The expected return value. Only tested when not empty. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string $targetType The type of token to look for. + * @param int $limit The number of parameters to limit this call to. + * Should match the expected count. + * @param array> $expected Optional. The expected return value. Only tested when + * not empty. * * @return void */ @@ -131,9 +130,9 @@ public function testGetParametersWithLimit($testMarker, $targetType, $limit, $ex * * @see testGetParametersWithLimit() For the array format. * - * @return array + * @return array>>> */ - public function dataGetParametersWithLimit() + public static function dataGetParametersWithLimit() { return [ 'function-call' => [ diff --git a/Tests/Utils/PassedParameters/HasParametersTest.inc b/Tests/Utils/PassedParameters/HasParametersTest.inc index 5eca6c33..f02a6ab5 100644 --- a/Tests/Utils/PassedParameters/HasParametersTest.inc +++ b/Tests/Utils/PassedParameters/HasParametersTest.inc @@ -172,6 +172,14 @@ $anon = new class() {}; /* testHasParamsAnonClass */ $anon = new class( $param1, $param2 ) {}; +/* testHasParamsPHP80ClassInstantiationInAttribute */ +#[MyAttribute(1, self::Foo, 'string')] +function foo() {} + +/* testHasParamsPHP80ClassInstantiationInMultiAttribute */ +#[AttributeOne, \AttributeTwo(1, self::Foo)] +function bar() {} + /* testPHP81FirstClassCallableNotFunctionCallGlobalFunction */ $fn = strlen(...); diff --git a/Tests/Utils/PassedParameters/HasParametersTest.php b/Tests/Utils/PassedParameters/HasParametersTest.php index 71d6d1fd..350cd81c 100644 --- a/Tests/Utils/PassedParameters/HasParametersTest.php +++ b/Tests/Utils/PassedParameters/HasParametersTest.php @@ -19,8 +19,6 @@ * * @covers \PHPCSUtils\Utils\PassedParameters::hasParameters * - * @group passedparameters - * * @since 1.0.0 */ final class HasParametersTest extends UtilityMethodTestCase @@ -57,7 +55,7 @@ public function testNotAnAcceptedTokenException() } /** - * Test receiving an expected exception when T_SELF is passed not preceeded by `new`. + * Test receiving an expected exception when a hierarchy keyword is passed not preceeded by `new`. * * @dataProvider dataNotACallToConstructor * @@ -81,9 +79,9 @@ public function testNotACallToConstructor($testMarker, $targetType) * * @see testNotACallToConstructor() For the array format. * - * @return array + * @return array> */ - public function dataNotACallToConstructor() + public static function dataNotACallToConstructor() { return [ 'parent' => [ @@ -124,11 +122,11 @@ public function testNotAShortArray() * * @dataProvider dataHasParameters * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param int|string|array $targetType The type(s) of token to look for. - * @param bool $expected Whether or not the function/array has parameters/values. - * @param string $targetContent Optional. The content of the target token to find. - * Defaults to null (ignore content). + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param int|string|array $targetType The type(s) of token to look for. + * @param bool $expected Whether or not the function/array has parameters/values. + * @param string|null $targetContent Optional. The content of the target token to find. + * Defaults to null (ignore content). * * @return void */ @@ -144,9 +142,9 @@ public function testHasParameters($testMarker, $targetType, $expected, $targetCo * * @see testHasParameters() For the array format. * - * @return array + * @return array|null>> */ - public function dataHasParameters() + public static function dataHasParameters() { $php8Names = parent::usesPhp8NameTokens(); @@ -389,6 +387,25 @@ public function dataHasParameters() 'expected' => true, ], + // Class instantiations in attribute. + 'has-params-class-instantiation-in-attribute' => [ + 'testMarker' => '/* testHasParamsPHP80ClassInstantiationInAttribute */', + 'targetType' => \T_STRING, + 'expected' => true, + ], + 'no-params-class-instantiation-in-multi-attribute' => [ + 'testMarker' => '/* testHasParamsPHP80ClassInstantiationInMultiAttribute */', + 'targetType' => \T_STRING, + 'expected' => false, + 'targetContent' => 'AttributeOne', + ], + 'has-params-class-instantiation-in-multi-attribute' => [ + 'testMarker' => '/* testHasParamsPHP80ClassInstantiationInMultiAttribute */', + 'targetType' => ($php8Names === true) ? \T_NAME_FULLY_QUALIFIED : \T_STRING, + 'expected' => true, + 'targetContent' => ($php8Names === true) ? '\AttributeTwo' : 'AttributeTwo', + ], + // PHP 8.1 first class callables are callbacks, not function calls. 'no-params-php81-first-class-callable-global-function' => [ 'testMarker' => '/* testPHP81FirstClassCallableNotFunctionCallGlobalFunction */', diff --git a/Tests/Utils/Scopes/IsOOConstantTest.php b/Tests/Utils/Scopes/IsOOConstantTest.php index 911514d0..80c66c05 100644 --- a/Tests/Utils/Scopes/IsOOConstantTest.php +++ b/Tests/Utils/Scopes/IsOOConstantTest.php @@ -18,8 +18,6 @@ * * @coversDefaultClass \PHPCSUtils\Utils\Scopes * - * @group scopes - * * @since 1.0.0 */ final class IsOOConstantTest extends UtilityMethodTestCase @@ -76,9 +74,9 @@ public function testIsOOConstant($testMarker, $expected) * * @see testIsOOConstant() For the array format. * - * @return array + * @return array> */ - public function dataIsOOConstant() + public static function dataIsOOConstant() { return [ 'global-const' => [ diff --git a/Tests/Utils/Scopes/IsOOMethodTest.php b/Tests/Utils/Scopes/IsOOMethodTest.php index 540cdb93..9ca5983f 100644 --- a/Tests/Utils/Scopes/IsOOMethodTest.php +++ b/Tests/Utils/Scopes/IsOOMethodTest.php @@ -18,8 +18,6 @@ * * @coversDefaultClass \PHPCSUtils\Utils\Scopes * - * @group scopes - * * @since 1.0.0 */ final class IsOOMethodTest extends UtilityMethodTestCase @@ -76,9 +74,9 @@ public function testIsOOMethod($testMarker, $expected) * * @see testIsOOMethod() For the array format. * - * @return array + * @return array> */ - public function dataIsOOMethod() + public static function dataIsOOMethod() { return [ 'global-function' => [ diff --git a/Tests/Utils/Scopes/IsOOPropertyTest.php b/Tests/Utils/Scopes/IsOOPropertyTest.php index 5e3f9c04..0bdbe6d3 100644 --- a/Tests/Utils/Scopes/IsOOPropertyTest.php +++ b/Tests/Utils/Scopes/IsOOPropertyTest.php @@ -18,8 +18,6 @@ * * @coversDefaultClass \PHPCSUtils\Utils\Scopes * - * @group scopes - * * @since 1.0.0 */ final class IsOOPropertyTest extends UtilityMethodTestCase @@ -76,9 +74,9 @@ public function testIsOOProperty($testMarker, $expected) * * @see testIsOOProperty() For the array format. * - * @return array + * @return array> */ - public function dataIsOOProperty() + public static function dataIsOOProperty() { return [ 'global-var' => [ diff --git a/Tests/Utils/TextStrings/GetCompleteTextStringTest.php b/Tests/Utils/TextStrings/GetCompleteTextStringTest.php index 5a80ee38..1caa1d5f 100644 --- a/Tests/Utils/TextStrings/GetCompleteTextStringTest.php +++ b/Tests/Utils/TextStrings/GetCompleteTextStringTest.php @@ -21,8 +21,6 @@ * @covers \PHPCSUtils\Utils\TextStrings::getCompleteTextString * @covers \PHPCSUtils\Utils\TextStrings::getEndOfCompleteTextString * - * @group textstrings - * * @since 1.0.0 */ final class GetCompleteTextStringTest extends UtilityMethodTestCase @@ -31,7 +29,7 @@ final class GetCompleteTextStringTest extends UtilityMethodTestCase /** * Token types to target for these tests. * - * @var array + * @var array */ private $targets = [ \T_START_HEREDOC, @@ -105,9 +103,9 @@ public function testNotFirstTextStringException($method) /** * Data provider. * - * @return array + * @return array> */ - public function dataExceptions() + public static function dataExceptions() { return [ 'getCompleteTextString' => ['getCompleteTextString'], @@ -142,9 +140,9 @@ public function testGetCompleteTextString($testMarker, $expected, $expectedWithQ * * @see testGetCompleteTextString() For the array format. * - * @return array + * @return array> */ - public function dataGetCompleteTextString() + public static function dataGetCompleteTextString() { return [ 'single-line-constant-encapsed-string' => [ diff --git a/Tests/Utils/TextStrings/GetEndOfCompleteTextStringTest.php b/Tests/Utils/TextStrings/GetEndOfCompleteTextStringTest.php index f16d3053..0821427d 100644 --- a/Tests/Utils/TextStrings/GetEndOfCompleteTextStringTest.php +++ b/Tests/Utils/TextStrings/GetEndOfCompleteTextStringTest.php @@ -22,8 +22,6 @@ * * @covers \PHPCSUtils\Utils\TextStrings::getEndOfCompleteTextString * - * @group textstrings - * * @since 1.0.0 */ final class GetEndOfCompleteTextStringTest extends UtilityMethodTestCase @@ -53,9 +51,9 @@ public function testGetEndOfDoubleQuotedString($testMarker, $expectedContent) * * @see testGetEndOfDoubleQuotedString() For the array format. * - * @return array + * @return array> */ - public function dataGetEndOfDoubleQuotedString() + public static function dataGetEndOfDoubleQuotedString() { return [ 'Simple embedded variable 1' => [ diff --git a/Tests/Utils/TextStrings/InterpolatedVariablesTest.php b/Tests/Utils/TextStrings/InterpolatedVariablesTest.php index 5e590f62..dad4e49b 100644 --- a/Tests/Utils/TextStrings/InterpolatedVariablesTest.php +++ b/Tests/Utils/TextStrings/InterpolatedVariablesTest.php @@ -21,8 +21,6 @@ * @covers \PHPCSUtils\Utils\TextStrings::stripEmbeds * @covers \PHPCSUtils\Utils\TextStrings::getStripEmbeds * - * @group textstrings - * * @since 1.0.0 */ final class InterpolatedVariablesTest extends TestCase @@ -33,7 +31,7 @@ final class InterpolatedVariablesTest extends TestCase * * @var array */ - private $embeds = [ + private static $embeds = [ // Simple. '$foo', '{$foo}', @@ -125,7 +123,7 @@ final class InterpolatedVariablesTest extends TestCase * * @var array */ - private $phrases = [ + private static $phrases = [ 'single line' => "%s this is nonsense %s\tbut that's not the point %s", 'single line, embed followed by non-space 1' => '%s- dash %s+ plus %s', 'single line, embed followed by non-space 2' => '%s. dash %s= plus %s', @@ -145,8 +143,8 @@ final class InterpolatedVariablesTest extends TestCase * * @dataProvider dataEmbedsInPhrases * - * @param string $input The input string. - * @param array $expected The expected function output of the respective functions. + * @param string $input The input string. + * @param array> $expected The expected function output of the respective functions. * * @return void */ @@ -162,8 +160,8 @@ public function testGetEmbeds($input, $expected) * @dataProvider dataEscaping * @dataProvider dataSpecificCases * - * @param string $input The input string. - * @param array $expected The expected function output of the respective functions. + * @param string $input The input string. + * @param array> $expected The expected function output of the respective functions. * * @return void */ @@ -179,8 +177,8 @@ public function testGetEmbedsAndCheckOffset($input, $expected) * @dataProvider dataEscaping * @dataProvider dataSpecificCases * - * @param string $input The input string. - * @param array $expected The expected function output of the respective functions. + * @param string $input The input string. + * @param array> $expected The expected function output of the respective functions. * * @return void */ @@ -195,12 +193,12 @@ public function testStripEmbeds($input, $expected) * @see testGetEmbeds() For the array format. * @see testStripEmbeds() For the array format. * - * @return array + * @return array>>> */ - public function dataEmbedsInPhrases() + public static function dataEmbedsInPhrases() { $data = []; - foreach ($this->embeds as $embed) { + foreach (self::$embeds as $embed) { $data[$embed . '| Plain embed (heredoc)'] = [ 'input' => $embed, 'expected' => [ @@ -217,64 +215,64 @@ public function dataEmbedsInPhrases() ]; // Plain, no double quotes (heredoc). - $phraseKey = \array_rand($this->phrases); + $phraseKey = \array_rand(self::$phrases); $dataKey = $embed . '| Embed at start of plain phrase in: ' . $phraseKey; $data[$dataKey] = [ - 'input' => \sprintf($this->phrases[$phraseKey], $embed, '', ''), + 'input' => \sprintf(self::$phrases[$phraseKey], $embed, '', ''), 'expected' => [ 'get' => [$embed], - 'stripped' => \sprintf($this->phrases[$phraseKey], '', '', ''), + 'stripped' => \sprintf(self::$phrases[$phraseKey], '', '', ''), ], ]; - $phraseKey = \array_rand($this->phrases); + $phraseKey = \array_rand(self::$phrases); $dataKey = $embed . '| Embed in middle of plain phrase in: ' . $phraseKey; $data[$dataKey] = [ - 'input' => \sprintf($this->phrases[$phraseKey], '', $embed, ''), + 'input' => \sprintf(self::$phrases[$phraseKey], '', $embed, ''), 'expected' => [ 'get' => [$embed], - 'stripped' => \sprintf($this->phrases[$phraseKey], '', '', ''), + 'stripped' => \sprintf(self::$phrases[$phraseKey], '', '', ''), ], ]; - $phraseKey = \array_rand($this->phrases); + $phraseKey = \array_rand(self::$phrases); $dataKey = $embed . '| Embed at end of plain phrase in: ' . $phraseKey; $data[$dataKey] = [ - 'input' => \sprintf($this->phrases[$phraseKey], '', '', $embed), + 'input' => \sprintf(self::$phrases[$phraseKey], '', '', $embed), 'expected' => [ 'get' => [$embed], - 'stripped' => \sprintf($this->phrases[$phraseKey], '', '', ''), + 'stripped' => \sprintf(self::$phrases[$phraseKey], '', '', ''), ], ]; // Phrase in double quotes. - $phraseKey = \array_rand($this->phrases); + $phraseKey = \array_rand(self::$phrases); $dataKey = $embed . '| Embed at start of quoted phrase in: ' . $phraseKey; $data[$dataKey] = [ - 'input' => '"' . \sprintf($this->phrases[$phraseKey], $embed, '', '') . '"', + 'input' => '"' . \sprintf(self::$phrases[$phraseKey], $embed, '', '') . '"', 'expected' => [ 'get' => [$embed], - 'stripped' => '"' . \sprintf($this->phrases[$phraseKey], '', '', '') . '"', + 'stripped' => '"' . \sprintf(self::$phrases[$phraseKey], '', '', '') . '"', ], ]; - $phraseKey = \array_rand($this->phrases); + $phraseKey = \array_rand(self::$phrases); $dataKey = $embed . '| Embed in middle of quoted phrase in: ' . $phraseKey; $data[$dataKey] = [ - 'input' => '"' . \sprintf($this->phrases[$phraseKey], '', $embed, '') . '"', + 'input' => '"' . \sprintf(self::$phrases[$phraseKey], '', $embed, '') . '"', 'expected' => [ 'get' => [$embed], - 'stripped' => '"' . \sprintf($this->phrases[$phraseKey], '', '', '') . '"', + 'stripped' => '"' . \sprintf(self::$phrases[$phraseKey], '', '', '') . '"', ], ]; - $phraseKey = \array_rand($this->phrases); + $phraseKey = \array_rand(self::$phrases); $dataKey = $embed . '| Embed at end of quoted phrase in: ' . $phraseKey; $data[$dataKey] = [ - 'input' => '"' . \sprintf($this->phrases[$phraseKey], '', '', $embed) . '"', + 'input' => '"' . \sprintf(self::$phrases[$phraseKey], '', '', $embed) . '"', 'expected' => [ 'get' => [$embed], - 'stripped' => '"' . \sprintf($this->phrases[$phraseKey], '', '', '') . '"', + 'stripped' => '"' . \sprintf(self::$phrases[$phraseKey], '', '', '') . '"', ], ]; } @@ -288,9 +286,9 @@ public function dataEmbedsInPhrases() * @see testGetEmbedsAndCheckOffset() For the array format. * @see testStripEmbeds() For the array format. * - * @return array + * @return array>>> */ - public function dataEscaping() + public static function dataEscaping() { $embedAtEnd = '"Foo: %s%s"'; $embedAtStart = '%s%s Foo'; // Not, no double quotes! @@ -359,9 +357,9 @@ public function dataEscaping() * @see testGetEmbedsAndCheckOffset() For the array format. * @see testStripEmbeds() For the array format. * - * @return array + * @return array>>> */ - public function dataSpecificCases() + public static function dataSpecificCases() { return [ // No embeds. diff --git a/Tests/Utils/TextStrings/StripQuotesTest.php b/Tests/Utils/TextStrings/StripQuotesTest.php index 56faac11..5616874a 100644 --- a/Tests/Utils/TextStrings/StripQuotesTest.php +++ b/Tests/Utils/TextStrings/StripQuotesTest.php @@ -18,8 +18,6 @@ * * @covers \PHPCSUtils\Utils\TextStrings::stripQuotes * - * @group textstrings - * * @since 1.0.0 */ final class StripQuotesTest extends TestCase @@ -45,9 +43,9 @@ public function testStripQuotes($input, $expected) * * @see testStripQuotes() For the array format. * - * @return array + * @return array> */ - public function dataStripQuotes() + public static function dataStripQuotes() { return [ 'simple-string-double-quotes' => [ diff --git a/Tests/Utils/UseStatements/SplitAndMergeImportUseStatementTest.php b/Tests/Utils/UseStatements/SplitAndMergeImportUseStatementTest.php index b550bce2..caa3d36f 100644 --- a/Tests/Utils/UseStatements/SplitAndMergeImportUseStatementTest.php +++ b/Tests/Utils/UseStatements/SplitAndMergeImportUseStatementTest.php @@ -20,8 +20,6 @@ * @covers \PHPCSUtils\Utils\UseStatements::splitAndMergeImportUseStatement * @covers \PHPCSUtils\Utils\UseStatements::mergeImportUseStatements * - * @group usestatements - * * @since 1.0.0 */ final class SplitAndMergeImportUseStatementTest extends UtilityMethodTestCase @@ -32,9 +30,9 @@ final class SplitAndMergeImportUseStatementTest extends UtilityMethodTestCase * * @dataProvider dataSplitAndMergeImportUseStatement * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected return value of the function. - * @param array $previousUse Previous use statement parameter to pass to the method. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array> $expected The expected return value of the function. + * @param array> $previousUse Previous use statement parameter to pass to the method. * * @return void */ @@ -50,9 +48,9 @@ public function testSplitAndMergeImportUseStatement($testMarker, $expected, $pre * * @see testSplitAndMergeImportUseStatement() For the array format. * - * @return array + * @return array>>> */ - public function dataSplitAndMergeImportUseStatement() + public static function dataSplitAndMergeImportUseStatement() { $data = [ 'name-plain' => [ diff --git a/Tests/Utils/UseStatements/SplitImportUseStatementTest.inc b/Tests/Utils/UseStatements/SplitImportUseStatementTest.inc index e9daecf2..9f5af864 100644 --- a/Tests/Utils/UseStatements/SplitImportUseStatementTest.inc +++ b/Tests/Utils/UseStatements/SplitImportUseStatementTest.inc @@ -14,6 +14,9 @@ use MyNamespace\MyClass; /* testUsePlainAliased */ use MyNamespace \ YourClass as ClassAlias; +/* testUsePlainLeadingBackslash */ +use \MyNamespace\TheirClass; + /* testUseMultipleWithComments */ use Vendor\Foo\ClassA as ClassABC, Vendor \ /*comment*/ Bar \ /*another comment */ InterfaceB, @@ -38,7 +41,7 @@ use CONST MyNamespace\MY_CONST; use const MyNamespace\YOUR_CONST as CONST_ALIAS; /* testUseConstMultiple */ -use const foo\math\PI, foo\math\GOLDEN_RATIO as MATH_GOLDEN; +use const foo\math\PI, \foo\math\GOLDEN_RATIO as MATH_GOLDEN; /* testGroupUse */ use some\namespacing\{ @@ -47,6 +50,12 @@ use some\namespacing\{ another\level\SomeClassC as C }; +/* testGroupUseLeadingBackslash */ +use \world\namespacing\{ + SomeClassA, + deeper\level\SomeClassB +}; + /* testGroupUseFunctionTrailingComma */ use function bar\math\{ Msin, @@ -70,15 +79,15 @@ use Some\NS\ { }; /* testUsePlainReservedKeyword */ -// Intentional parse error - use of reserved keyword in namespace. +// Intentional parse error for PHP < 8.0 - use of reserved keyword in namespace. use Vendor\break\ClassName; /* testUseFunctionPlainReservedKeyword */ -// Intentional parse error - use of reserved keyword in namespace. +// Intentional parse error for PHP < 8.0 - use of reserved keyword in namespace. use function Vendor\YourNamespace\switch\yourFunction; /* testUseConstPlainReservedKeyword */ -// Intentional parse error - use of reserved keyword in namespace. +// Intentional parse error for PHP < 8.0 - use of reserved keyword in namespace. use const Vendor\YourNamespace\function\yourConst; /* testUsePlainAliasReservedKeyword */ @@ -88,7 +97,7 @@ use Vendor\YourNamespace\ClassName as class; /* testUsePlainAliasReservedKeywordFunction */ // Intentional parse error - use of reserved keyword as alias. use Vendor\{ - YourNamespace\ClassName as function + YourNamespace\ClassName as function }; /* testUsePlainAliasReservedKeywordConst */ diff --git a/Tests/Utils/UseStatements/SplitImportUseStatementTest.php b/Tests/Utils/UseStatements/SplitImportUseStatementTest.php index 83b40647..5bc3c34a 100644 --- a/Tests/Utils/UseStatements/SplitImportUseStatementTest.php +++ b/Tests/Utils/UseStatements/SplitImportUseStatementTest.php @@ -19,8 +19,6 @@ * * @covers \PHPCSUtils\Utils\UseStatements::splitImportUseStatement * - * @group usestatements - * * @since 1.0.0 */ final class SplitImportUseStatementTest extends UtilityMethodTestCase @@ -73,9 +71,9 @@ public function testNonImportUseTokenPassed($testMarker) * * @see testSplitImportUseStatement() For the array format. * - * @return array + * @return array> */ - public function dataNonImportUseTokenPassed() + public static function dataNonImportUseTokenPassed() { return [ 'closure-use' => ['/* testClosureUse */'], @@ -88,8 +86,8 @@ public function dataNonImportUseTokenPassed() * * @dataProvider dataSplitImportUseStatement * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected return value of the function. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array> $expected The expected return value of the function. * * @return void */ @@ -105,9 +103,9 @@ public function testSplitImportUseStatement($testMarker, $expected) * * @see testSplitImportUseStatement() For the array format. * - * @return array + * @return array>>> */ - public function dataSplitImportUseStatement() + public static function dataSplitImportUseStatement() { return [ 'plain' => [ @@ -126,6 +124,15 @@ public function dataSplitImportUseStatement() 'const' => [], ], ], + 'plain-with-leading-backslash' => [ + 'testMarker' => '/* testUsePlainLeadingBackslash */', + 'expected' => [ + 'name' => ['TheirClass' => 'MyNamespace\TheirClass'], + 'function' => [], + 'const' => [], + ], + ], + 'multiple-with-comments' => [ 'testMarker' => '/* testUseMultipleWithComments */', 'expected' => [ @@ -205,6 +212,17 @@ public function dataSplitImportUseStatement() 'const' => [], ], ], + 'group-with-leading-backslash' => [ + 'testMarker' => '/* testGroupUseLeadingBackslash */', + 'expected' => [ + 'name' => [ + 'SomeClassA' => 'world\namespacing\SomeClassA', + 'SomeClassB' => 'world\namespacing\deeper\level\SomeClassB', + ], + 'function' => [], + 'const' => [], + ], + ], 'group-function-trailing-comma' => [ 'testMarker' => '/* testGroupUseFunctionTrailingComma */', 'expected' => [ diff --git a/Tests/Utils/UseStatements/UseTypeTest.php b/Tests/Utils/UseStatements/UseTypeTest.php index 81faabb9..49ded75b 100644 --- a/Tests/Utils/UseStatements/UseTypeTest.php +++ b/Tests/Utils/UseStatements/UseTypeTest.php @@ -24,8 +24,6 @@ * @covers \PHPCSUtils\Utils\UseStatements::isClosureUse * @covers \PHPCSUtils\Utils\UseStatements::getType * - * @group usestatements - * * @since 1.0.0 */ final class UseTypeTest extends UtilityMethodTestCase @@ -60,8 +58,8 @@ public function testNonUseToken() * * @dataProvider dataUseType * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected return values for the various functions. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected return values for the various functions. * * @return void */ @@ -78,8 +76,8 @@ public function testIsClosureUse($testMarker, $expected) * * @dataProvider dataUseType * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected return values for the various functions. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected return values for the various functions. * * @return void */ @@ -96,8 +94,8 @@ public function testIsImportUse($testMarker, $expected) * * @dataProvider dataUseType * - * @param string $testMarker The comment which prefaces the target token in the test file. - * @param array $expected The expected return values for the various functions. + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array $expected The expected return values for the various functions. * * @return void */ @@ -116,9 +114,9 @@ public function testIsTraitUse($testMarker, $expected) * @see testIsImportUse() For the array format. * @see testIsTraitUse() For the array format. * - * @return array + * @return array>> */ - public function dataUseType() + public static function dataUseType() { return [ 'import-1' => [ diff --git a/Tests/Utils/Variables/GetMemberPropertiesDiffTest.inc b/Tests/Utils/Variables/GetMemberPropertiesDiffTest.inc index affc1f2e..055ad9c6 100644 --- a/Tests/Utils/Variables/GetMemberPropertiesDiffTest.inc +++ b/Tests/Utils/Variables/GetMemberPropertiesDiffTest.inc @@ -11,18 +11,3 @@ enum Suit /* testEnumProperty */ protected $anonymous; } - -$anon = class() { - /* testPHP82PseudoTypeTrue */ - public true $pseudoTypeTrue; - - /* testPHP82NullablePseudoTypeTrue */ - static protected ?true $pseudoTypeNullableTrue; - - /* testPHP82PseudoTypeTrueInUnion */ - private int|string|true $pseudoTypeTrueInUnion; - - /* testPHP82PseudoTypeFalseAndTrue */ - // Intentional fatal error - Type contains both true and false, bool should be used instead, but that's not the concern of the method. - readonly true|FALSE $pseudoTypeFalseAndTrue; -}; diff --git a/Tests/Utils/Variables/GetMemberPropertiesDiffTest.php b/Tests/Utils/Variables/GetMemberPropertiesDiffTest.php index 3e5c189d..5b6b6ebc 100644 --- a/Tests/Utils/Variables/GetMemberPropertiesDiffTest.php +++ b/Tests/Utils/Variables/GetMemberPropertiesDiffTest.php @@ -10,7 +10,6 @@ namespace PHPCSUtils\Tests\Utils\Variables; -use PHPCSUtils\Internal\Cache; use PHPCSUtils\TestUtils\UtilityMethodTestCase; use PHPCSUtils\Utils\Variables; @@ -63,142 +62,13 @@ public function testNotClassPropertyException($testMarker) * * @see testNotClassPropertyException() * - * @return array + * @return array> */ - public function dataNotClassPropertyException() + public static function dataNotClassPropertyException() { return [ 'interface property' => ['/* testInterfaceProperty */'], 'enum property' => ['/* testEnumProperty */'], ]; } - - /** - * Test the getMemberProperties() method. - * - * @dataProvider dataGetMemberProperties - * - * @param string $identifier Comment which precedes the test case. - * @param bool $expected Expected function output. - * - * @return void - */ - public function testGetMemberProperties($identifier, $expected) - { - $variable = $this->getTargetToken($identifier, \T_VARIABLE); - $result = Variables::getMemberProperties(self::$phpcsFile, $variable); - - if (isset($expected['type_token']) && $expected['type_token'] !== false) { - $expected['type_token'] += $variable; - } - if (isset($expected['type_end_token']) && $expected['type_end_token'] !== false) { - $expected['type_end_token'] += $variable; - } - - $this->assertSame($expected, $result); - } - - /** - * Data provider. - * - * @see testGetMemberProperties() - * - * @return array - */ - public function dataGetMemberProperties() - { - return [ - 'php8.2-pseudo-type-true' => [ - 'identifier' => '/* testPHP82PseudoTypeTrue */', - 'expected' => [ - 'scope' => 'public', - 'scope_specified' => true, - 'is_static' => false, - 'is_readonly' => false, - 'type' => 'true', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. - 'nullable_type' => false, - ], - ], - 'php8.2-pseudo-type-true-nullable' => [ - 'identifier' => '/* testPHP82NullablePseudoTypeTrue */', - 'expected' => [ - 'scope' => 'protected', - 'scope_specified' => true, - 'is_static' => true, - 'is_readonly' => false, - 'type' => '?true', - 'type_token' => -2, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. - 'nullable_type' => true, - ], - ], - 'php8.2-pseudo-type-true-in-union' => [ - 'identifier' => '/* testPHP82PseudoTypeTrueInUnion */', - 'expected' => [ - 'scope' => 'private', - 'scope_specified' => true, - 'is_static' => false, - 'is_readonly' => false, - 'type' => 'int|string|true', - 'type_token' => -6, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. - 'nullable_type' => false, - ], - ], - 'php8.2-pseudo-type-invalid-true-false-union' => [ - 'identifier' => '/* testPHP82PseudoTypeFalseAndTrue */', - 'expected' => [ - 'scope' => 'public', - 'scope_specified' => false, - 'is_static' => false, - 'is_readonly' => true, - 'type' => 'true|FALSE', - 'type_token' => -4, // Offset from the T_VARIABLE token. - 'type_end_token' => -2, // Offset from the T_VARIABLE token. - 'nullable_type' => false, - ], - ], - ]; - } - - /** - * Verify that the build-in caching is used when caching is enabled. - * - * @return void - */ - public function testResultIsCached() - { - $methodName = 'PHPCSUtils\\Utils\\Variables::getMemberProperties'; - $cases = $this->dataGetMemberProperties(); - $identifier = $cases['php8.2-pseudo-type-true-in-union']['identifier']; - $expected = $cases['php8.2-pseudo-type-true-in-union']['expected']; - - $variable = $this->getTargetToken($identifier, \T_VARIABLE); - - if (isset($expected['type_token']) && $expected['type_token'] !== false) { - $expected['type_token'] += $variable; - } - if (isset($expected['type_end_token']) && $expected['type_end_token'] !== false) { - $expected['type_end_token'] += $variable; - } - - // Verify the caching works. - $origStatus = Cache::$enabled; - Cache::$enabled = true; - - $resultFirstRun = Variables::getMemberProperties(self::$phpcsFile, $variable); - $isCached = Cache::isCached(self::$phpcsFile, $methodName, $variable); - $resultSecondRun = Variables::getMemberProperties(self::$phpcsFile, $variable); - - if ($origStatus === false) { - Cache::clear(); - } - Cache::$enabled = $origStatus; - - $this->assertSame($expected, $resultFirstRun, 'First result did not match expectation'); - $this->assertTrue($isCached, 'Cache::isCached() could not find the cached value'); - $this->assertSame($resultFirstRun, $resultSecondRun, 'Second result did not match first'); - } } diff --git a/Tests/Utils/Variables/GetMemberPropertiesTest.php b/Tests/Utils/Variables/GetMemberPropertiesTest.php index 619f7a2f..07e08235 100644 --- a/Tests/Utils/Variables/GetMemberPropertiesTest.php +++ b/Tests/Utils/Variables/GetMemberPropertiesTest.php @@ -10,7 +10,9 @@ namespace PHPCSUtils\Tests\Utils\Variables; +use PHPCSUtils\Internal\Cache; use PHPCSUtils\Tests\BackCompat\BCFile\GetMemberPropertiesTest as BCFile_GetMemberPropertiesTest; +use PHPCSUtils\Utils\Variables; /** * Tests for the \PHPCSUtils\Utils\Variables::getMemberProperties method. @@ -61,22 +63,57 @@ public static function setUpTestFile() * * @see testGetMemberProperties() * - * @return array + * @return array>> */ - public function dataGetMemberProperties() + public static function dataGetMemberProperties() { $data = parent::dataGetMemberProperties(); /* - * Remove the data set related to the invalid interface/enum properties. + * Remove the data sets related to the invalid interface/enum properties. * These will now throw an exception instead. */ - foreach ($data as $key => $value) { - if ($value[0] === '/* testInterfaceProperty */' || $value[0] === '/* testEnumProperty */') { - unset($data[$key]); - } - } + unset($data['invalid-property-in-interface'], $data['invalid-property-in-enum']); return $data; } + + /** + * Verify that the build-in caching is used when caching is enabled. + * + * @return void + */ + public function testResultIsCached() + { + $methodName = 'PHPCSUtils\\Utils\\Variables::getMemberProperties'; + $cases = self::dataGetMemberProperties(); + $identifier = $cases['php8.2-pseudo-type-true-in-union']['identifier']; + $expected = $cases['php8.2-pseudo-type-true-in-union']['expected']; + + $variable = $this->getTargetToken($identifier, \T_VARIABLE); + + if (isset($expected['type_token']) && \is_int($expected['type_token']) === true) { + $expected['type_token'] += $variable; + } + if (isset($expected['type_end_token']) && \is_int($expected['type_end_token']) === true) { + $expected['type_end_token'] += $variable; + } + + // Verify the caching works. + $origStatus = Cache::$enabled; + Cache::$enabled = true; + + $resultFirstRun = Variables::getMemberProperties(self::$phpcsFile, $variable); + $isCached = Cache::isCached(self::$phpcsFile, $methodName, $variable); + $resultSecondRun = Variables::getMemberProperties(self::$phpcsFile, $variable); + + if ($origStatus === false) { + Cache::clear(); + } + Cache::$enabled = $origStatus; + + $this->assertSame($expected, $resultFirstRun, 'First result did not match expectation'); + $this->assertTrue($isCached, 'Cache::isCached() could not find the cached value'); + $this->assertSame($resultFirstRun, $resultSecondRun, 'Second result did not match first'); + } } diff --git a/Tests/Utils/Variables/IsPHPReservedVarNameTest.php b/Tests/Utils/Variables/IsPHPReservedVarNameTest.php index acc7adaa..4808f8e6 100644 --- a/Tests/Utils/Variables/IsPHPReservedVarNameTest.php +++ b/Tests/Utils/Variables/IsPHPReservedVarNameTest.php @@ -44,9 +44,9 @@ public function testIsPHPReservedVarName($name) * * @see testIsPHPReservedVarName() For the array format. * - * @return array + * @return array> */ - public function dataIsPHPReservedVarName() + public static function dataIsPHPReservedVarName() { return [ // With dollar sign. @@ -116,9 +116,9 @@ public function testIsPHPReservedVarNameFalse($name) * * @see testIsPHPReservedVarNameFalse() For the array format. * - * @return array + * @return array> */ - public function dataIsPHPReservedVarNameFalse() + public static function dataIsPHPReservedVarNameFalse() { return [ // Different case. diff --git a/Tests/Utils/Variables/IsSuperglobalTest.php b/Tests/Utils/Variables/IsSuperglobalTest.php index 57019d49..d7205af2 100644 --- a/Tests/Utils/Variables/IsSuperglobalTest.php +++ b/Tests/Utils/Variables/IsSuperglobalTest.php @@ -62,9 +62,9 @@ public function testIsSuperglobal($testMarker, $expected, $targetType = \T_VARIA * * @see testIsSuperglobal() For the array format. * - * @return array + * @return array> */ - public function dataIsSuperglobal() + public static function dataIsSuperglobal() { return [ 'not-a-variable' => [ @@ -155,9 +155,9 @@ public function testIsSuperglobalName($name) * * @see testIsSuperglobalName() For the array format. * - * @return array + * @return array> */ - public function dataIsSuperglobalName() + public static function dataIsSuperglobalName() { return [ '$_SERVER' => ['$_SERVER'], @@ -191,9 +191,9 @@ public function testIsSuperglobalNameFalse($name) * * @see testIsSuperglobalNameFalse() For the array format. * - * @return array + * @return array> */ - public function dataIsSuperglobalNameFalse() + public static function dataIsSuperglobalNameFalse() { return [ 'non-reserved-var' => ['$not_a_superglobal'], diff --git a/Tests/Xtra/Messages/HasNewLineSupportTest.php b/Tests/Xtra/Messages/HasNewLineSupportTest.php index 6943c078..c1778654 100644 --- a/Tests/Xtra/Messages/HasNewLineSupportTest.php +++ b/Tests/Xtra/Messages/HasNewLineSupportTest.php @@ -41,7 +41,7 @@ final class HasNewLineSupportTest extends PolyfilledTestCase /** * Set the name of a sniff to pass to PHPCS to limit the run (and force it to record errors). * - * @var array + * @var array */ protected static $selectedSniff = ['PHPCSUtils.Xtra.HasNewLineSupportTest']; @@ -77,9 +77,6 @@ public function testHasNewLineSupport() // Make sure space on empty line is included (often removed by file editor). $expected = \str_replace("|\n", "| \n", $expected); - $this->expectOutputString($expected); - $this->setOutputCallback([$this, 'normalizeOutput']); - /* * Create the error. */ @@ -102,12 +99,17 @@ public function testHasNewLineSupport() $reportClass = new Full(); $reportData = $reporter->prepareFileReport(self::$phpcsFile); + \ob_start(); $reportClass->generateFileReport( $reportData, self::$phpcsFile, self::$phpcsFile->config->showSources, $config->reportWidth ); + $output = \ob_get_contents(); + \ob_end_clean(); + + $this->assertSame($expected, $this->normalizeOutput($output)); } /** diff --git a/Tests/Xtra/Tokens/TokenNameTest.php b/Tests/Xtra/Tokens/TokenNameTest.php index b72c9a85..75bd2227 100644 --- a/Tests/Xtra/Tokens/TokenNameTest.php +++ b/Tests/Xtra/Tokens/TokenNameTest.php @@ -48,9 +48,9 @@ public function testTokenName($tokenCode, $expected) * * @see testTokenName() For the array format. * - * @return array + * @return array> */ - public function dataTokenName() + public static function dataTokenName() { return [ 'PHP native token: T_ECHO' => [ diff --git a/composer.json b/composer.json index 0a7a3d4f..80167bcb 100644 --- a/composer.json +++ b/composer.json @@ -19,11 +19,12 @@ "support" : { "issues" : "https://github.com/PHPCSStandards/PHPCSUtils/issues", "source" : "https://github.com/PHPCSStandards/PHPCSUtils", - "docs" : "https://phpcsutils.com/" + "docs" : "https://phpcsutils.com/", + "security": "https://github.com/PHPCSStandards/PHPCSUtils/security/policy" }, "require" : { "php" : ">=5.4", - "squizlabs/php_codesniffer" : "^3.7.1 || 4.0.x-dev@dev", + "squizlabs/php_codesniffer" : "^3.10.0 || 4.0.x-dev@dev", "dealerdirect/phpcodesniffer-composer-installer" : "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7 || ^1.0" }, "require-dev" : { @@ -31,7 +32,7 @@ "phpcsstandards/phpcsdevcs": "^1.1.6", "php-parallel-lint/php-parallel-lint": "^1.3.2", "php-parallel-lint/php-console-highlighter": "^1.0", - "yoast/phpunit-polyfills": "^1.0.5" + "yoast/phpunit-polyfills": "^1.1.0 || ^2.0.0" }, "minimum-stability": "dev", "prefer-stable": true, @@ -66,16 +67,26 @@ "test": [ "@php ./vendor/phpunit/phpunit/phpunit --no-coverage" ], + "test10": [ + "@php ./vendor/phpunit/phpunit/phpunit -c phpunit10.xml.dist --no-coverage" + ], "coverage": [ "@php ./vendor/phpunit/phpunit/phpunit" ], + "coverage10": [ + "@php ./vendor/phpunit/phpunit/phpunit -c phpunit10.xml.dist" + ], "coverage-local": [ "@php ./vendor/phpunit/phpunit/phpunit --coverage-html ./build/coverage-html" + ], + "coverage-local10": [ + "@php ./vendor/phpunit/phpunit/phpunit -c phpunit10.xml.dist --coverage-html ./build/coverage-html" ] }, "config": { "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true - } + }, + "lock": false } } diff --git a/docs/_config.yml b/docs/_config.yml index d39e168a..7650fa64 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -15,6 +15,7 @@ plugins: phpcsutils: packagist: phpcsstandards/phpcsutils + open_collective: php_codesniffer # Theme info. title: PHPCSUtils @@ -26,11 +27,13 @@ google_analytics: # SEO info. tagline: "PHPCSUtils: A suite of utility functions for use with PHP_CodeSniffer." twitter: - username: jrf_nl + username: PHP_CodeSniffer card: summary hashtags: PHPCSUtils +mastodon: + username: "@phpcs@phpc.social" author: - twitter: jrf_nl + twitter: PHP_CodeSniffer # Needed so the select HTML tags do not get removed *sigh* commonmark: diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index b6bd3b8e..7cdfaae9 100644 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -45,7 +45,21 @@

{{ site.title | default: site.github.repo

Visit the Project on GitHub {{ site.github.repository_nwo }}

-

+

+ +

+ + + +
+ +
@@ -76,5 +90,21 @@

{{ site.title | default: site.github.repo + + + diff --git a/docs/assets/css/style.scss b/docs/assets/css/style.scss index 582c75ac..8e6c4129 100644 --- a/docs/assets/css/style.scss +++ b/docs/assets/css/style.scss @@ -110,6 +110,40 @@ header .install pre.highlight { padding-top: 1em; } +.mastodon-share-button { + font-size: 80%; + margin: 0 1em 0 0; +} + +.mastodon-share-button .btn { + display: inline-block; + text-align: center; + vertical-align: middle; + padding: .25em 1em; + border-radius: 1rem; + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out; + color: #ffffff; + background-color: #007bff; +} +.mastodon-share-button .btn:before { + content: url('data:image/svg+xml;charset=UTF-8,'); +} + +#modal { + clear: both; + margin: 10px 0; +} + +#modal #msb-share { + text-align: center; + vertical-align: middle; + padding: .25em 1em; + border-radius: 1rem; + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out; + color: #ffffff; + background-color: #007bff; +} + /* General space usage/layout */ .wrapper{ width:100%; diff --git a/docs/assets/js/mastodon.js b/docs/assets/js/mastodon.js new file mode 100644 index 00000000..421fdb2a --- /dev/null +++ b/docs/assets/js/mastodon.js @@ -0,0 +1,177 @@ +// Source: https://github.com/Aly-ve/Mastodon-share-button + +"use strict"; + +const COOKIE_NAME = 'instance-address' +const URL_REGEX = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([\/\w .-]*)*\/?$/ + +function msbShareButtonAction(name, target) { + let msbInstanceAddress = '' + + msbInstanceAddress = msbGetCookie('instance-address') + if (msbInstanceAddress.length > 0) { + window.open(`${msbInstanceAddress}/share?text=${name}%20${target}`, `__blank`) + } + else { + if (msbConfig && msbConfig.openModal && msbConfig.addressFieldSelector) { + + if (document.querySelector(msbConfig.buttonModalSelector)) { + let bms = document.querySelector(msbConfig.buttonModalSelector) + bms.data = { target, name } + bms.addEventListener('click', () => msbOnShare(), false) + + } + msbConfig.openModal(name, target) + } + } +} + +function msbOnShare(_name, _target) { + if (msbConfig && msbConfig.addressFieldSelector && msbConfig.buttonModalSelector) { + + let name = !!_name ? _name : document.querySelector(msbConfig.buttonModalSelector).data.name + let target = !!_target ? _target : document.querySelector(msbConfig.buttonModalSelector).data.target + let msbInstanceAddress = document.querySelector(`${msbConfig.addressFieldSelector}`).value + + if (!msbInstanceAddress.startsWith('http')) { + msbInstanceAddress = 'https://' + msbInstanceAddress; + } + if (msbInstanceAddress.match(URL_REGEX)) { + if (msbConfig.memorizeFieldId) { + let msbMemorizeIsChecked = document.querySelector(`#${msbConfig.memorizeFieldId}`).checked + if (msbConfig.memorizeFieldId && !msbGetCookie(COOKIE_NAME).length > 0 && msbMemorizeIsChecked) { + msbSetCookie(COOKIE_NAME, msbInstanceAddress, 7); + } + } + + window.open(`${msbInstanceAddress}/share?text=${name}%20${target}`, `__blank`) + if (msbConfig && msbConfig.openModal && msbConfig.closeModal) { + msbConfig.closeModal() + } + } + } +} + +function msbGetCookie(cname) { + var name = cname + "="; + var ca = document.cookie.split(';'); + for(var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == ' ') { + c = c.substring(1); + } + if (c.indexOf(name) == 0) { + return c.substring(name.length, c.length); + } + } + return ""; +} + +function msbSetCookie(name, value, days) { + let d = new Date() + d.setTime(d.getTime() + days*86400000) + let expires = 'expires=' + d.toUTCString() + document.cookie = `${name}=${value}; ${expires}; path=/` +} + +(function() { + + let msbButtons = document.querySelectorAll('.mastodon-share-button') + + for(let i = 0; i < msbButtons.length; i++) { + (function(j) { + + let msbTarget = msbButtons[j].dataset.target + let msbName = msbButtons[j].dataset.name + let msbButtonStyle = msbButtons[j].dataset.buttonstyle + let msbText = msbButtons[j].dataset.text + + // Replace hashtab by html code + msbName = msbName.replace(/#/g, '%23') + + /** + * Create buttons + */ + let button = document.createElement('button') + let buttonText = null + + /** + * Add text button... or not + */ + if (msbConfig && (msbConfig.buttonDisplayText || msbConfig.buttonDisplayText === undefined)) { + buttonText = !!msbText ? document.createTextNode(msbText) : document.createTextNode(msbI18n()) + } + else { + buttonText = document.createTextNode('') + } + + + if (msbButtonStyle) { + button.setAttribute('class', msbButtonStyle) + } + + button.appendChild(buttonText) + msbButtons[j].appendChild(button) + + /** + * Add icon to the button if buttonIconHtml is setted + */ + if (msbConfig && msbConfig.buttonIconHtml) { + button.innerHTML = `${msbConfig.buttonIconHtml} ${button.innerHTML}` + } + + /** + * Set the listener in each button + */ + button.addEventListener('click', () => { msbShareButtonAction(msbName, msbTarget) }, true) + + })(i) + } + +})() + +function msbI18n() { + let language = navigator.language || navigator.userLanguage + let publish = { + 'ar': 'بوّق', + 'bg': 'Раздумай', + 'cs': 'Tootnout', + 'de': 'Tröt', + 'eo': 'Hué', + 'es': 'Tootear', + 'eu': 'Tut', + 'fa': 'بوق', + 'fi': 'Tuuttaa', + 'fr': 'Pouet', + 'gl': 'ללחוש', + 'he': 'ללחוש', + 'hu': 'Tülk', + 'hy': 'Թթել', + 'io': 'Siflar', + 'ja': 'トゥート', + 'ko': '툿', + 'no': 'Tut', + 'oc': 'Tut', + 'pl': 'Wyślij', + 'pt-BR': 'Publicar', + 'pt': 'Publicar', + 'ru': 'Трубить', + 'sr-Latn': 'Tutni', + 'sr': 'Тутни', + 'uk': 'Дмухнути', + 'zh-CN': '嘟嘟', + 'zh-HK': '發文', + 'zh-TW': '貼掉', + 'default': 'Toot' + } + + let text = null + try { + text = publish[language] + } + catch (error) { + text = publish.default + } + + return text +} diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 90596a78..1722ab6f 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -5,7 +5,7 @@ @@ -48,6 +48,19 @@ + + + + + + + + + + ./Tests/Internal/Cache/GetClearTest.php + ./Tests/Internal/Cache/SetTest.php + ./Tests/Internal/NoFileCache/GetClearTest.php + ./Tests/Internal/NoFileCache/SetTest.php + + + ./Tests/Utils/Namespaces/NamespaceTypeTest.php + + + ./Tests/ + + Tests/Internal/Cache/GetClearTest.php + Tests/Internal/Cache/SetTest.php + Tests/Internal/NoFileCache/GetClearTest.php + Tests/Internal/NoFileCache/SetTest.php + + Tests/Utils/Namespaces/NamespaceTypeTest.php + + + + + + compareWithPHPCS + + xtra + + + + + + + ./PHPCSUtils/ + + + + + + + + + + +