From bf8e6c7dfe5c2c85b461a3ff6db5c0191fa33414 Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 16:07:59 +0300 Subject: [PATCH 01/12] Setup github actions --- .github/workflows/coding-standards.yml | 47 ++++++++++++++++++++++++ .github/workflows/coverage.yml | 51 ++++++++++++++++++++++++++ .github/workflows/phpunit.yml | 51 ++++++++++++++++++++++++++ .github/workflows/psalm.yml | 47 ++++++++++++++++++++++++ .travis.yml | 33 ----------------- 5 files changed, 196 insertions(+), 33 deletions(-) create mode 100644 .github/workflows/coding-standards.yml create mode 100644 .github/workflows/coverage.yml create mode 100644 .github/workflows/phpunit.yml create mode 100644 .github/workflows/psalm.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml new file mode 100644 index 0000000..74be215 --- /dev/null +++ b/.github/workflows/coding-standards.yml @@ -0,0 +1,47 @@ +name: "Check Coding Standards" +on: + pull_request: + push: + branches: + - "master" +jobs: + coding-standards: + name: "Check Coding Standards" + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + dependencies: + - "locked" + php-version: + - "7.4" + operating-system: + - "ubuntu-latest" + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "pcov" + php-version: "${{ matrix.php-version }}" + ini-values: memory_limit=-1 + tools: composer:v2, cs2pr + - name: "Cache dependencies" + uses: "actions/cache@v2" + with: + path: | + ~/.composer/cache + vendor + key: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + restore-keys: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + - name: "Install lowest dependencies" + if: ${{ matrix.dependencies == 'lowest' }} + run: "composer update --prefer-lowest --no-interaction --no-progress --no-suggest" + - name: "Install highest dependencies" + if: ${{ matrix.dependencies == 'highest' }} + run: "composer update --no-interaction --no-progress --no-suggest" + - name: "Install locked dependencies" + if: ${{ matrix.dependencies == 'locked' }} + run: "composer install --no-interaction --no-progress --no-suggest" + - name: "Coding Standard" + run: "vendor/bin/phpcs -q --report=checkstyle | cs2pr" diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..f90b2cf --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,51 @@ +name: "Code coverage" +on: + pull_request: + push: + branches: + - "master" +jobs: + coverage: + name: "Code coverage" + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + dependencies: + - "locked" + php-version: + - "7.4" + operating-system: + - "ubuntu-latest" + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "pcov" + php-version: "${{ matrix.php-version }}" + ini-values: memory_limit=-1 + - name: "Cache dependencies" + uses: "actions/cache@v2" + with: + path: | + ~/.composer/cache + vendor + key: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + restore-keys: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + - name: "Install lowest dependencies" + if: ${{ matrix.dependencies == 'lowest' }} + run: "composer update --prefer-lowest --no-interaction --no-progress --no-suggest" + - name: "Install highest dependencies" + if: ${{ matrix.dependencies == 'highest' }} + run: "composer update --no-interaction --no-progress --no-suggest" + - name: "Install locked dependencies" + if: ${{ matrix.dependencies == 'locked' }} + run: "composer install --no-interaction --no-progress --no-suggest" + - name: "Code coverage" + run: | + vendor/bin/phpunit --testsuite=unit,functional --coverage-clover build/logs/clover.xml + wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.4.3/php-coveralls.phar + php php-coveralls.phar --verbose + env: + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml new file mode 100644 index 0000000..0d3737e --- /dev/null +++ b/.github/workflows/phpunit.yml @@ -0,0 +1,51 @@ +name: "PHPUnit tests" +on: + pull_request: + push: + branches: + - "master" +jobs: + phpunit: + name: "PHPUnit tests" + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + dependencies: + - "lowest" + - "highest" + - "locked" + php-version: + - "7.2" + - "7.3" + - "7.4" + operating-system: + - "ubuntu-latest" + - "windows-latest" + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "pcov" + php-version: "${{ matrix.php-version }}" + ini-values: memory_limit=-1 + - name: "Cache dependencies" + uses: "actions/cache@v2" + with: + path: | + ~/.composer/cache + vendor + key: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + restore-keys: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + - name: "Install lowest dependencies" + if: ${{ matrix.dependencies == 'lowest' }} + run: "composer update --prefer-lowest --no-interaction --no-progress --no-suggest" + - name: "Install highest dependencies" + if: ${{ matrix.dependencies == 'highest' }} + run: "composer update --no-interaction --no-progress --no-suggest" + - name: "Install locked dependencies" + if: ${{ matrix.dependencies == 'locked' }} + run: "composer install --no-interaction --no-progress --no-suggest" + - name: "Tests" + run: "vendor/bin/phpunit --fail-on-warning" diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml new file mode 100644 index 0000000..6fa8458 --- /dev/null +++ b/.github/workflows/psalm.yml @@ -0,0 +1,47 @@ +name: "Static Analysis by Psalm" +on: + pull_request: + push: + branches: + - "master" +jobs: + static-analysis-psalm: + name: "Static Analysis by Psalm" + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + dependencies: + - "locked" + php-version: + - "7.4" + operating-system: + - "ubuntu-latest" + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "pcov" + php-version: "${{ matrix.php-version }}" + ini-values: memory_limit=-1 + tools: composer:v2, cs2pr + - name: "Cache dependencies" + uses: "actions/cache@v2" + with: + path: | + ~/.composer/cache + vendor + key: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + restore-keys: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + - name: "Install lowest dependencies" + if: ${{ matrix.dependencies == 'lowest' }} + run: "composer update --prefer-lowest --no-interaction --no-progress --no-suggest" + - name: "Install highest dependencies" + if: ${{ matrix.dependencies == 'highest' }} + run: "composer update --no-interaction --no-progress --no-suggest" + - name: "Install locked dependencies" + if: ${{ matrix.dependencies == 'locked' }} + run: "composer install --no-interaction --no-progress --no-suggest" + - name: "psalm" + run: "vendor/bin/psalm --output-format=github --shepherd --stats" diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 95e4f80..0000000 --- a/.travis.yml +++ /dev/null @@ -1,33 +0,0 @@ -dist: trusty -sudo: false -language: php - -cache: - directories: - - $HOME/.composer/cache - -php: - - 7.2 - - 7.3 - - 7.4 - - nightly - -install: - - travis_retry composer self-update - - travis_retry composer install --prefer-dist - -script: ./vendor/bin/phpunit - -jobs: - allow_failures: - - php: nightly - include: - - stage: Psalm - php: 7.4 - script: - - ./vendor/bin/psalm - - - stage: Code Style - php: 7.4 - script: - - ./vendor/bin/phpcs \ No newline at end of file From 9f6a6eb8d33e1b6e03c139630aa219403c175b98 Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 16:13:08 +0300 Subject: [PATCH 02/12] Update code style --- composer.json | 2 +- src/ReservedWords.php | 18 +++++++++--------- src/ReservedWordsLookupError.php | 3 ++- tests/ReservedWordsListTest.php | 5 +++-- tests/ReservedWordsTest.php | 17 +++++++++-------- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/composer.json b/composer.json index ccef1e2..352d00a 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "php": ">=7.2.0" }, "require-dev": { - "doctrine/coding-standard": "^7.0", + "doctrine/coding-standard": "^8.2", "phpunit/phpunit": "^8", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^3.8" diff --git a/src/ReservedWords.php b/src/ReservedWords.php index 0d5a285..83756a4 100644 --- a/src/ReservedWords.php +++ b/src/ReservedWords.php @@ -37,7 +37,7 @@ public function __construct(array $reservedWords = ReservedWordsList::PHP_RESERV * This method also returns true for words that are marked as "soft" reserved in the PHP docs and may * become reserved in future versions of the language. */ - public function isReserved(string $string) : bool + public function isReserved(string $string): bool { return array_key_exists(strtolower($string), $this->reservedWords); } @@ -45,7 +45,7 @@ public function isReserved(string $string) : bool /** * Checks that the word cannot be used as a constant name */ - public function isReservedConstantName(string $string, ?string $phpVersion = null) : bool + public function isReservedConstantName(string $string, ?string $phpVersion = null): bool { return $this->isReservedAs($string, 'constant', $phpVersion); } @@ -53,7 +53,7 @@ public function isReservedConstantName(string $string, ?string $phpVersion = nul /** * Checks that the word cannot be used as a namespace part or class/interface/trait name */ - public function isReservedNamespaceName(string $string, ?string $phpVersion = null) : bool + public function isReservedNamespaceName(string $string, ?string $phpVersion = null): bool { return $this->isReservedAs($string, 'namespace', $phpVersion); } @@ -61,7 +61,7 @@ public function isReservedNamespaceName(string $string, ?string $phpVersion = nu /** * Checks that the word cannot be used as a function name */ - public function isReservedFunctionName(string $string, ?string $phpVersion = null) : bool + public function isReservedFunctionName(string $string, ?string $phpVersion = null): bool { return $this->isReservedAs($string, 'function', $phpVersion); } @@ -69,12 +69,12 @@ public function isReservedFunctionName(string $string, ?string $phpVersion = nul /** * Checks that the word cannot be used as a method name */ - public function isReservedMethodName(string $string, ?string $phpVersion = null) : bool + public function isReservedMethodName(string $string, ?string $phpVersion = null): bool { return $this->isReservedAs($string, 'method', $phpVersion); } - private function isReservedAs(string $string, string $checkKey, ?string $phpVersion = null) : bool + private function isReservedAs(string $string, string $checkKey, ?string $phpVersion = null): bool { if (! $this->isReserved($string)) { return false; @@ -101,17 +101,17 @@ private function isReservedAs(string $string, string $checkKey, ?string $phpVers return false; } - private function firstVersionEqualsOrHigherThanSecond(string $firstVersion, string $secondVersion) : bool + private function firstVersionEqualsOrHigherThanSecond(string $firstVersion, string $secondVersion): bool { return version_compare($firstVersion, $secondVersion) >= 0; } - private function firstVersionLessThanSecond(string $firstVersion, string $secondVersion) : bool + private function firstVersionLessThanSecond(string $firstVersion, string $secondVersion): bool { return version_compare($firstVersion, $secondVersion) === -1; } - private function getPhpVersion(?string $phpVersion = null) : string + private function getPhpVersion(?string $phpVersion = null): string { if ($phpVersion === null) { return (string) phpversion(); diff --git a/src/ReservedWordsLookupError.php b/src/ReservedWordsLookupError.php index 4c82208..a2e49c4 100644 --- a/src/ReservedWordsLookupError.php +++ b/src/ReservedWordsLookupError.php @@ -5,11 +5,12 @@ namespace sspat\ReservedWords; use RuntimeException; + use function sprintf; class ReservedWordsLookupError extends RuntimeException { - public static function invalidPhpVersion(string $phpVersion, string $correctFormat) : self + public static function invalidPhpVersion(string $phpVersion, string $correctFormat): self { return new self( sprintf('Invalid PHP version: %s, the correct format is: %s', $phpVersion, $correctFormat) diff --git a/tests/ReservedWordsListTest.php b/tests/ReservedWordsListTest.php index f3b5aab..ba26840 100644 --- a/tests/ReservedWordsListTest.php +++ b/tests/ReservedWordsListTest.php @@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase; use sspat\ReservedWords\ReservedWords; use sspat\ReservedWords\ReservedWordsList; + use function array_keys; use function count; use function is_array; @@ -16,7 +17,7 @@ class ReservedWordsListTest extends TestCase { - public function testReservedWordsList() : void + public function testReservedWordsList(): void { $errorMessage = 'Invalid reserved word configuration for %s'; @@ -50,7 +51,7 @@ public function testReservedWordsList() : void /** * @param string|bool|array $constraint */ - private function isValidConstraint($constraint) : bool + private function isValidConstraint($constraint): bool { return $constraint === false || (is_string($constraint) && preg_match(ReservedWords::PHP_VERSION_REGEXP, $constraint)) || diff --git a/tests/ReservedWordsTest.php b/tests/ReservedWordsTest.php index 1e9239e..1c67760 100644 --- a/tests/ReservedWordsTest.php +++ b/tests/ReservedWordsTest.php @@ -6,11 +6,12 @@ use PHPUnit\Framework\TestCase; use sspat\ReservedWords\ReservedWords; + use function strtoupper; class ReservedWordsTest extends TestCase { - public function testDefaultReservedWordsLoaded() : void + public function testDefaultReservedWordsLoaded(): void { $reservedWord = 'list'; $reservedWords = new ReservedWords(); @@ -18,7 +19,7 @@ public function testDefaultReservedWordsLoaded() : void $this->assertTrue($reservedWords->isReserved($reservedWord)); } - public function testIsReserved() : void + public function testIsReserved(): void { $reservedWord = 'reserved-word'; $notReservedWord = 'not-reserved-word'; @@ -28,7 +29,7 @@ public function testIsReserved() : void $this->assertFalse($reservedWords->isReserved($notReservedWord)); } - public function testIsReservedCaseInsensitive() : void + public function testIsReservedCaseInsensitive(): void { $reservedWord = 'reserved-word'; $reservedWords = new ReservedWords([$reservedWord => []]); @@ -46,7 +47,7 @@ public function testConstantName( array $reservedWordParameters, string $phpVersion, bool $isReserved - ) : void { + ): void { $reservedWords = new ReservedWords([$reservedWord => $reservedWordParameters]); $this->assertEquals($isReserved, $reservedWords->isReservedConstantName($reservedWord, $phpVersion)); @@ -62,7 +63,7 @@ public function testNamespaceName( array $reservedWordParameters, string $phpVersion, bool $isReserved - ) : void { + ): void { $reservedWords = new ReservedWords([$reservedWord => $reservedWordParameters]); $this->assertEquals($isReserved, $reservedWords->isReservedNamespaceName($reservedWord, $phpVersion)); @@ -78,7 +79,7 @@ public function testFunctionName( array $reservedWordParameters, string $phpVersion, bool $isReserved - ) : void { + ): void { $reservedWords = new ReservedWords([$reservedWord => $reservedWordParameters]); $this->assertEquals($isReserved, $reservedWords->isReservedFunctionName($reservedWord, $phpVersion)); @@ -94,7 +95,7 @@ public function testMethodName( array $reservedWordParameters, string $phpVersion, bool $isReserved - ) : void { + ): void { $reservedWords = new ReservedWords([$reservedWord => $reservedWordParameters]); $this->assertEquals($isReserved, $reservedWords->isReservedMethodName($reservedWord, $phpVersion)); @@ -103,7 +104,7 @@ public function testMethodName( /** * @return array>>> */ - public function reservedWordsList() : array + public function reservedWordsList(): array { return [ [ From bc34e6a8ba6f6c9f6b934fe97f8188f19eb0b93b Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 16:34:08 +0300 Subject: [PATCH 03/12] Rollback coveralls version --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index f90b2cf..769afb7 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -45,7 +45,7 @@ jobs: - name: "Code coverage" run: | vendor/bin/phpunit --testsuite=unit,functional --coverage-clover build/logs/clover.xml - wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.4.3/php-coveralls.phar + wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.1.0/php-coveralls.phar php php-coveralls.phar --verbose env: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} From 0b9e277199fde5d95fe05a9884e337c427ab4dcc Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 16:46:54 +0300 Subject: [PATCH 04/12] Updated psalm --- composer.json | 2 +- psalm.xml | 55 +++++++-------------------------------------------- 2 files changed, 8 insertions(+), 49 deletions(-) diff --git a/composer.json b/composer.json index 352d00a..b96a388 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "doctrine/coding-standard": "^8.2", "phpunit/phpunit": "^8", "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^3.8" + "vimeo/psalm": "^4.3" }, "autoload": { "psr-4": { diff --git a/psalm.xml b/psalm.xml index a9b5764..f986edd 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,55 +1,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From d7e7c4f69ee627ca10910e0066e94f546dc6875d Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 16:49:50 +0300 Subject: [PATCH 05/12] Add type coverage badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3a6e7f7..155c29a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Latest Version](https://img.shields.io/github/v/release/sspat/reserved-words)](https://github.com/sspat/reserved-words/releases) [![Build](https://img.shields.io/travis/sspat/reserved-words/master)](https://travis-ci.org/sspat/reserved-words) +[![Type Coverage](https://shepherd.dev/github/sspat/reserved-words/coverage.svg)](https://shepherd.dev/github/sspat/reserved-words) [![License](https://img.shields.io/github/license/sspat/reserved-words)](https://github.com/sspat/reserved-words/blob/master/LICENSE) [![Email](https://img.shields.io/badge/email-studio22@mail.ru-blue.svg?style=flat-square)](mailto:studio22@mail.ru) From f11fd668129907cda0881c7bdd288ed47ff778c5 Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 16:57:58 +0300 Subject: [PATCH 06/12] Code coverage --- README.md | 1 + phpunit.xml.dist | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 155c29a..28c123e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Latest Version](https://img.shields.io/github/v/release/sspat/reserved-words)](https://github.com/sspat/reserved-words/releases) [![Build](https://img.shields.io/travis/sspat/reserved-words/master)](https://travis-ci.org/sspat/reserved-words) +[![Test Coverage](https://coveralls.io/repos/github/sspat/reserved-words/badge.svg?branch=master)](https://coveralls.io/github/sspat/reserved-words?branch=master) [![Type Coverage](https://shepherd.dev/github/sspat/reserved-words/coverage.svg)](https://shepherd.dev/github/sspat/reserved-words) [![License](https://img.shields.io/github/license/sspat/reserved-words)](https://github.com/sspat/reserved-words/blob/master/LICENSE) [![Email](https://img.shields.io/badge/email-studio22@mail.ru-blue.svg?style=flat-square)](mailto:studio22@mail.ru) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 10671d7..ab33fa9 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -7,14 +7,18 @@ bootstrap="./tests/bootstrap.php" > - + ./tests/ - - - ./src/ + + ./src/ - \ No newline at end of file + + + + + + From d14691b334ff71c5133092e847820a1edffb4959 Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 17:14:27 +0300 Subject: [PATCH 07/12] Adde phpstan --- .github/workflows/phpstan.yml | 47 ++++++++++++++++++++++++++++++++ composer.json | 10 +++++-- phpstan.neon | 21 ++++++++++++++ src/ReservedWords.php | 4 +-- src/ReservedWordsLookupError.php | 2 +- tests/ReservedWordsListTest.php | 33 +++++++++++----------- tests/ReservedWordsTest.php | 17 ++++++------ 7 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 .github/workflows/phpstan.yml create mode 100644 phpstan.neon diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 0000000..23f06cd --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,47 @@ +name: "Static Analysis by PHPStan" +on: + pull_request: + push: + branches: + - "master" +jobs: + static-analysis-phpstan: + name: "Static Analysis by PHPStan" + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + dependencies: + - "locked" + php-version: + - "7.4" + operating-system: + - "ubuntu-latest" + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "pcov" + php-version: "${{ matrix.php-version }}" + ini-values: memory_limit=-1 + tools: composer:v2, cs2pr + - name: "Cache dependencies" + uses: "actions/cache@v2" + with: + path: | + ~/.composer/cache + vendor + key: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + restore-keys: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + - name: "Install lowest dependencies" + if: ${{ matrix.dependencies == 'lowest' }} + run: "composer update --prefer-lowest --no-interaction --no-progress --no-suggest" + - name: "Install highest dependencies" + if: ${{ matrix.dependencies == 'highest' }} + run: "composer update --no-interaction --no-progress --no-suggest" + - name: "Install locked dependencies" + if: ${{ matrix.dependencies == 'locked' }} + run: "composer install --no-interaction --no-progress --no-suggest" + - name: "phpstan" + run: "vendor/bin/phpstan analyse --memory-limit=-1" diff --git a/composer.json b/composer.json index b96a388..6949576 100644 --- a/composer.json +++ b/composer.json @@ -16,12 +16,17 @@ } ], "require": { - "php": ">=7.2.0" + "php": ">=7.2.0", + "thecodingmachine/safe": "^1.3" }, "require-dev": { "doctrine/coding-standard": "^8.2", + "phpstan/phpstan": "^0.12.64", + "phpstan/phpstan-phpunit": "^0.12.17", + "phpstan/phpstan-strict-rules": "^0.12.7", "phpunit/phpunit": "^8", "squizlabs/php_codesniffer": "^3.5", + "thecodingmachine/phpstan-safe-rule": "^1.0", "vimeo/psalm": "^4.3" }, "autoload": { @@ -42,7 +47,8 @@ "cs": "phpcs", "csfix": "phpcbf", "psalm": "psalm", + "stan": "phpstan analyze", "test": "phpunit", - "all": "composer psalm && composer test && composer cs" + "all": "composer psalm && composer stan && composer test && composer cs" } } diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..44c2601 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,21 @@ +parameters: + level: 8 + paths: + - src + - tests + checkMissingIterableValueType: false + treatPhpDocTypesAsCertain: false + ignoreErrors: + - + message: '#Call to static method PHPUnit\\Framework\\Assert::assertIsString\(\) with string will always evaluate to true\.#' + paths: + - %currentWorkingDirectory%/tests/ReservedWordsListTest.php + - + message: '#Call to static method PHPUnit\\Framework\\Assert::assertIsArray\(\) with array.+will always evaluate to true\.#' + paths: + - %currentWorkingDirectory%/tests/ReservedWordsListTest.php +includes: + - vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon + - vendor/phpstan/phpstan-phpunit/extension.neon + - vendor/phpstan/phpstan-phpunit/rules.neon + - vendor/phpstan/phpstan-strict-rules/rules.neon diff --git a/src/ReservedWords.php b/src/ReservedWords.php index 83756a4..0438eb5 100644 --- a/src/ReservedWords.php +++ b/src/ReservedWords.php @@ -9,7 +9,7 @@ use function is_array; use function is_string; use function phpversion; -use function preg_match; +use function Safe\preg_match; use function strtolower; use function version_compare; @@ -117,7 +117,7 @@ private function getPhpVersion(?string $phpVersion = null): string return (string) phpversion(); } - if (preg_match(self::PHP_VERSION_REGEXP, $phpVersion)) { + if (preg_match(self::PHP_VERSION_REGEXP, $phpVersion) === 1) { return $phpVersion; } diff --git a/src/ReservedWordsLookupError.php b/src/ReservedWordsLookupError.php index a2e49c4..7c90a97 100644 --- a/src/ReservedWordsLookupError.php +++ b/src/ReservedWordsLookupError.php @@ -6,7 +6,7 @@ use RuntimeException; -use function sprintf; +use function Safe\sprintf; class ReservedWordsLookupError extends RuntimeException { diff --git a/tests/ReservedWordsListTest.php b/tests/ReservedWordsListTest.php index ba26840..88912b0 100644 --- a/tests/ReservedWordsListTest.php +++ b/tests/ReservedWordsListTest.php @@ -4,6 +4,7 @@ namespace sspat\ReservedWords\Tests; +use PHPUnit\Framework\Assert; use PHPUnit\Framework\TestCase; use sspat\ReservedWords\ReservedWords; use sspat\ReservedWords\ReservedWordsList; @@ -12,8 +13,8 @@ use function count; use function is_array; use function is_string; -use function preg_match; -use function sprintf; +use function Safe\preg_match; +use function Safe\sprintf; class ReservedWordsListTest extends TestCase { @@ -22,26 +23,26 @@ public function testReservedWordsList(): void $errorMessage = 'Invalid reserved word configuration for %s'; foreach (ReservedWordsList::PHP_RESERVED_WORDS as $reservedWord => $reservedWordConfig) { - $this->assertIsString($reservedWord); - $this->assertIsArray($reservedWordConfig); - $this->assertCount(4, $reservedWordConfig); - $this->assertArrayHasKey('constant', $reservedWordConfig); - $this->assertArrayHasKey('namespace', $reservedWordConfig); - $this->assertArrayHasKey('function', $reservedWordConfig); - $this->assertArrayHasKey('method', $reservedWordConfig); - $this->assertTrue( + Assert::assertIsString($reservedWord); + Assert::assertIsArray($reservedWordConfig); + Assert::assertCount(4, $reservedWordConfig); + Assert::assertArrayHasKey('constant', $reservedWordConfig); + Assert::assertArrayHasKey('namespace', $reservedWordConfig); + Assert::assertArrayHasKey('function', $reservedWordConfig); + Assert::assertArrayHasKey('method', $reservedWordConfig); + Assert::assertTrue( $this->isValidConstraint($reservedWordConfig['constant']), sprintf($errorMessage, $reservedWord) ); - $this->assertTrue( + Assert::assertTrue( $this->isValidConstraint($reservedWordConfig['namespace']), sprintf($errorMessage, $reservedWord) ); - $this->assertTrue( + Assert::assertTrue( $this->isValidConstraint($reservedWordConfig['function']), sprintf($errorMessage, $reservedWord) ); - $this->assertTrue( + Assert::assertTrue( $this->isValidConstraint($reservedWordConfig['method']), sprintf($errorMessage, $reservedWord) ); @@ -54,13 +55,13 @@ public function testReservedWordsList(): void private function isValidConstraint($constraint): bool { return $constraint === false || - (is_string($constraint) && preg_match(ReservedWords::PHP_VERSION_REGEXP, $constraint)) || + (is_string($constraint) && preg_match(ReservedWords::PHP_VERSION_REGEXP, $constraint) === 1) || ( is_array($constraint) && count($constraint) === 2 && array_keys($constraint) === [0, 1] && - preg_match(ReservedWords::PHP_VERSION_REGEXP, $constraint[0]) && - preg_match(ReservedWords::PHP_VERSION_REGEXP, $constraint[1]) + preg_match(ReservedWords::PHP_VERSION_REGEXP, $constraint[0]) === 1 && + preg_match(ReservedWords::PHP_VERSION_REGEXP, $constraint[1]) === 1 ); } } diff --git a/tests/ReservedWordsTest.php b/tests/ReservedWordsTest.php index 1c67760..3668c30 100644 --- a/tests/ReservedWordsTest.php +++ b/tests/ReservedWordsTest.php @@ -4,6 +4,7 @@ namespace sspat\ReservedWords\Tests; +use PHPUnit\Framework\Assert; use PHPUnit\Framework\TestCase; use sspat\ReservedWords\ReservedWords; @@ -16,7 +17,7 @@ public function testDefaultReservedWordsLoaded(): void $reservedWord = 'list'; $reservedWords = new ReservedWords(); - $this->assertTrue($reservedWords->isReserved($reservedWord)); + Assert::assertTrue($reservedWords->isReserved($reservedWord)); } public function testIsReserved(): void @@ -25,8 +26,8 @@ public function testIsReserved(): void $notReservedWord = 'not-reserved-word'; $reservedWords = new ReservedWords([$reservedWord => []]); - $this->assertTrue($reservedWords->isReserved($reservedWord)); - $this->assertFalse($reservedWords->isReserved($notReservedWord)); + Assert::assertTrue($reservedWords->isReserved($reservedWord)); + Assert::assertFalse($reservedWords->isReserved($notReservedWord)); } public function testIsReservedCaseInsensitive(): void @@ -34,7 +35,7 @@ public function testIsReservedCaseInsensitive(): void $reservedWord = 'reserved-word'; $reservedWords = new ReservedWords([$reservedWord => []]); - $this->assertTrue($reservedWords->isReserved(strtoupper($reservedWord))); + Assert::assertTrue($reservedWords->isReserved(strtoupper($reservedWord))); } /** @@ -50,7 +51,7 @@ public function testConstantName( ): void { $reservedWords = new ReservedWords([$reservedWord => $reservedWordParameters]); - $this->assertEquals($isReserved, $reservedWords->isReservedConstantName($reservedWord, $phpVersion)); + Assert::assertEquals($isReserved, $reservedWords->isReservedConstantName($reservedWord, $phpVersion)); } /** @@ -66,7 +67,7 @@ public function testNamespaceName( ): void { $reservedWords = new ReservedWords([$reservedWord => $reservedWordParameters]); - $this->assertEquals($isReserved, $reservedWords->isReservedNamespaceName($reservedWord, $phpVersion)); + Assert::assertEquals($isReserved, $reservedWords->isReservedNamespaceName($reservedWord, $phpVersion)); } /** @@ -82,7 +83,7 @@ public function testFunctionName( ): void { $reservedWords = new ReservedWords([$reservedWord => $reservedWordParameters]); - $this->assertEquals($isReserved, $reservedWords->isReservedFunctionName($reservedWord, $phpVersion)); + Assert::assertEquals($isReserved, $reservedWords->isReservedFunctionName($reservedWord, $phpVersion)); } /** @@ -98,7 +99,7 @@ public function testMethodName( ): void { $reservedWords = new ReservedWords([$reservedWord => $reservedWordParameters]); - $this->assertEquals($isReserved, $reservedWords->isReservedMethodName($reservedWord, $phpVersion)); + Assert::assertEquals($isReserved, $reservedWords->isReservedMethodName($reservedWord, $phpVersion)); } /** From 36a794c54e5559c344647dbf69ff674fd8857240 Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 18:05:23 +0300 Subject: [PATCH 08/12] Added mutation testing --- .github/workflows/mutation-test.yml | 49 ++++++++++++++++++++++++++ README.md | 2 +- composer.json | 5 ++- infection.json | 21 +++++++++++ phpcs.xml.dist | 3 ++ src/ReservedWords.php | 11 +++--- src/ReservedWordsLookupError.php | 2 +- tests/ReservedWordsListTest.php | 5 ++- tests/ReservedWordsLookupErrorTest.php | 21 +++++++++++ tests/ReservedWordsTest.php | 41 +++++++++++++++++---- 10 files changed, 143 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/mutation-test.yml create mode 100644 infection.json create mode 100644 tests/ReservedWordsLookupErrorTest.php diff --git a/.github/workflows/mutation-test.yml b/.github/workflows/mutation-test.yml new file mode 100644 index 0000000..dc5e6ab --- /dev/null +++ b/.github/workflows/mutation-test.yml @@ -0,0 +1,49 @@ +name: "Mutation tests" +on: + pull_request: + push: + branches: + - "master" +jobs: + mutation-tests: + name: "Mutation tests" + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + dependencies: + - "locked" + php-version: + - "7.4" + operating-system: + - "ubuntu-latest" + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "pcov" + php-version: "${{ matrix.php-version }}" + ini-values: memory_limit=-1 + - name: "Cache dependencies" + uses: "actions/cache@v2" + with: + path: | + ~/.composer/cache + vendor + key: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + restore-keys: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}" + - name: "Install lowest dependencies" + if: ${{ matrix.dependencies == 'lowest' }} + run: "composer update --prefer-lowest --no-interaction --no-progress --no-suggest" + - name: "Install highest dependencies" + if: ${{ matrix.dependencies == 'highest' }} + run: "composer update --no-interaction --no-progress --no-suggest" + - name: "Install locked dependencies" + if: ${{ matrix.dependencies == 'locked' }} + run: "composer install --no-interaction --no-progress --no-suggest" + - name: "Infection" + run: "vendor/bin/roave-infection-static-analysis-plugin" + env: + INFECTION_BADGE_API_KEY: ${{ secrets.INFECTION_BADGE_API_KEY }} + STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }} diff --git a/README.md b/README.md index 28c123e..804d33d 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ [![Latest Version](https://img.shields.io/github/v/release/sspat/reserved-words)](https://github.com/sspat/reserved-words/releases) [![Build](https://img.shields.io/travis/sspat/reserved-words/master)](https://travis-ci.org/sspat/reserved-words) +[![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fsspat%2Freserved-words%2Fmaster)](https://dashboard.stryker-mutator.io/reports/github.com/sspat/reserved-words/master) [![Test Coverage](https://coveralls.io/repos/github/sspat/reserved-words/badge.svg?branch=master)](https://coveralls.io/github/sspat/reserved-words?branch=master) [![Type Coverage](https://shepherd.dev/github/sspat/reserved-words/coverage.svg)](https://shepherd.dev/github/sspat/reserved-words) [![License](https://img.shields.io/github/license/sspat/reserved-words)](https://github.com/sspat/reserved-words/blob/master/LICENSE) -[![Email](https://img.shields.io/badge/email-studio22@mail.ru-blue.svg?style=flat-square)](mailto:studio22@mail.ru) ## About diff --git a/composer.json b/composer.json index 6949576..e2e44e6 100644 --- a/composer.json +++ b/composer.json @@ -21,10 +21,12 @@ }, "require-dev": { "doctrine/coding-standard": "^8.2", + "infection/infection": "^0.20.2", "phpstan/phpstan": "^0.12.64", "phpstan/phpstan-phpunit": "^0.12.17", "phpstan/phpstan-strict-rules": "^0.12.7", "phpunit/phpunit": "^8", + "roave/infection-static-analysis-plugin": "^1.6", "squizlabs/php_codesniffer": "^3.5", "thecodingmachine/phpstan-safe-rule": "^1.0", "vimeo/psalm": "^4.3" @@ -49,6 +51,7 @@ "psalm": "psalm", "stan": "phpstan analyze", "test": "phpunit", - "all": "composer psalm && composer stan && composer test && composer cs" + "mutation": "roave-infection-static-analysis-plugin", + "all": "composer psalm && composer stan && composer test && composer mutation && composer cs" } } diff --git a/infection.json b/infection.json new file mode 100644 index 0000000..bb832b1 --- /dev/null +++ b/infection.json @@ -0,0 +1,21 @@ +{ + "source": { + "directories": [ + "src" + ] + }, + "timeout": 3, + "logs": { + "text": "php://stderr", + "badge": { + "branch": "master" + } + }, + "mutators": { + "@default": true, + "IdenticalEqual": false, + "NotIdenticalNotEqual": false + }, + "minMsi": 100, + "minCoveredMsi": 100 +} diff --git a/phpcs.xml.dist b/phpcs.xml.dist index f12f61b..2fe15c8 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -16,4 +16,7 @@ src/ tests/ + + + diff --git a/src/ReservedWords.php b/src/ReservedWords.php index 0438eb5..7b88a5f 100644 --- a/src/ReservedWords.php +++ b/src/ReservedWords.php @@ -13,7 +13,7 @@ use function strtolower; use function version_compare; -class ReservedWords +final class ReservedWords { public const PHP_VERSION_REGEXP = '/^\d\.\d\.?\d*$/'; @@ -83,10 +83,6 @@ private function isReservedAs(string $string, string $checkKey, ?string $phpVers $targetPhpVersion = $this->getPhpVersion($phpVersion); $reservedVersion = $this->reservedWords[strtolower($string)][$checkKey]; - if ($reservedVersion === false) { - return false; - } - if (is_string($reservedVersion)) { return $this->firstVersionEqualsOrHigherThanSecond($targetPhpVersion, $reservedVersion); } @@ -114,7 +110,10 @@ private function firstVersionLessThanSecond(string $firstVersion, string $second private function getPhpVersion(?string $phpVersion = null): string { if ($phpVersion === null) { - return (string) phpversion(); + /** @var string $version */ + $version = phpversion(); + + return $version; } if (preg_match(self::PHP_VERSION_REGEXP, $phpVersion) === 1) { diff --git a/src/ReservedWordsLookupError.php b/src/ReservedWordsLookupError.php index 7c90a97..e8c2ea8 100644 --- a/src/ReservedWordsLookupError.php +++ b/src/ReservedWordsLookupError.php @@ -8,7 +8,7 @@ use function Safe\sprintf; -class ReservedWordsLookupError extends RuntimeException +final class ReservedWordsLookupError extends RuntimeException { public static function invalidPhpVersion(string $phpVersion, string $correctFormat): self { diff --git a/tests/ReservedWordsListTest.php b/tests/ReservedWordsListTest.php index 88912b0..3dee361 100644 --- a/tests/ReservedWordsListTest.php +++ b/tests/ReservedWordsListTest.php @@ -16,7 +16,10 @@ use function Safe\preg_match; use function Safe\sprintf; -class ReservedWordsListTest extends TestCase +/** + * @covers \sspat\ReservedWords\ReservedWordsList + */ +final class ReservedWordsListTest extends TestCase { public function testReservedWordsList(): void { diff --git a/tests/ReservedWordsLookupErrorTest.php b/tests/ReservedWordsLookupErrorTest.php new file mode 100644 index 0000000..430a5ab --- /dev/null +++ b/tests/ReservedWordsLookupErrorTest.php @@ -0,0 +1,21 @@ +expectExceptionMessage('Invalid PHP version: 7, the correct format is: /\d+/'); + + throw ReservedWordsLookupError::invalidPhpVersion('7', '/\d+/'); + } +} diff --git a/tests/ReservedWordsTest.php b/tests/ReservedWordsTest.php index 3668c30..38be7fd 100644 --- a/tests/ReservedWordsTest.php +++ b/tests/ReservedWordsTest.php @@ -7,10 +7,14 @@ use PHPUnit\Framework\Assert; use PHPUnit\Framework\TestCase; use sspat\ReservedWords\ReservedWords; +use sspat\ReservedWords\ReservedWordsLookupError; use function strtoupper; -class ReservedWordsTest extends TestCase +/** + * @covers \sspat\ReservedWords\ReservedWords + */ +final class ReservedWordsTest extends TestCase { public function testDefaultReservedWordsLoaded(): void { @@ -22,20 +26,33 @@ public function testDefaultReservedWordsLoaded(): void public function testIsReserved(): void { - $reservedWord = 'reserved-word'; - $notReservedWord = 'not-reserved-word'; - $reservedWords = new ReservedWords([$reservedWord => []]); + $reservedWord = 'reserved-word'; + $reservedWords = new ReservedWords([$reservedWord => []]); Assert::assertTrue($reservedWords->isReserved($reservedWord)); - Assert::assertFalse($reservedWords->isReserved($notReservedWord)); + } + + public function testIsNotReserved(): void + { + $notReservedWord = 'not-reserved-word'; + $reservedWords = new ReservedWords([]); + + Assert::assertFalse($reservedWords->isReservedMethodName($notReservedWord)); } public function testIsReservedCaseInsensitive(): void { $reservedWord = 'reserved-word'; - $reservedWords = new ReservedWords([$reservedWord => []]); + $reservedWords = new ReservedWords([ + $reservedWord => [ + 'constant' => '7.0', + 'namespace' => '7.0', + 'function' => '7.0', + 'method' => '7.0', + ], + ]); - Assert::assertTrue($reservedWords->isReserved(strtoupper($reservedWord))); + Assert::assertTrue($reservedWords->isReservedMethodName(strtoupper($reservedWord), '7.0')); } /** @@ -102,6 +119,16 @@ public function testMethodName( Assert::assertEquals($isReserved, $reservedWords->isReservedMethodName($reservedWord, $phpVersion)); } + public function testInvalidPhpVersion(): void + { + $reservedWord = 'reserved-word'; + $reservedWords = new ReservedWords([$reservedWord => []]); + + $this->expectException(ReservedWordsLookupError::class); + $this->expectErrorMessage('Invalid PHP version: 7, the correct format is: /^\d\.\d\.?\d*$/'); + $reservedWords->isReservedMethodName($reservedWord, '7'); + } + /** * @return array>>> */ From 568acda0149203ef1403dfa6e9d3412a4ffaf40e Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 18:12:23 +0300 Subject: [PATCH 09/12] Drop 7.2 support --- .github/workflows/mutation-test.yml | 2 +- .github/workflows/phpunit.yml | 1 - composer.json | 113 ++++++++++++++-------------- 3 files changed, 57 insertions(+), 59 deletions(-) diff --git a/.github/workflows/mutation-test.yml b/.github/workflows/mutation-test.yml index dc5e6ab..05893cf 100644 --- a/.github/workflows/mutation-test.yml +++ b/.github/workflows/mutation-test.yml @@ -43,7 +43,7 @@ jobs: if: ${{ matrix.dependencies == 'locked' }} run: "composer install --no-interaction --no-progress --no-suggest" - name: "Infection" - run: "vendor/bin/roave-infection-static-analysis-plugin" + run: "vendor/bin/infection" env: INFECTION_BADGE_API_KEY: ${{ secrets.INFECTION_BADGE_API_KEY }} STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }} diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 0d3737e..1a57c44 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -15,7 +15,6 @@ jobs: - "highest" - "locked" php-version: - - "7.2" - "7.3" - "7.4" operating-system: diff --git a/composer.json b/composer.json index e2e44e6..d8a802b 100644 --- a/composer.json +++ b/composer.json @@ -1,57 +1,56 @@ -{ - "name": "sspat/reserved-words", - "description": "Validates strings against reserved words of a specific php version", - "type": "library", - "version": "1.0.0", - "keywords": [ - "reserved", - "words", - "php" - ], - "license": "MIT", - "authors": [ - { - "name": "Patrik Foldes", - "email": "studio22@mail.ru" - } - ], - "require": { - "php": ">=7.2.0", - "thecodingmachine/safe": "^1.3" - }, - "require-dev": { - "doctrine/coding-standard": "^8.2", - "infection/infection": "^0.20.2", - "phpstan/phpstan": "^0.12.64", - "phpstan/phpstan-phpunit": "^0.12.17", - "phpstan/phpstan-strict-rules": "^0.12.7", - "phpunit/phpunit": "^8", - "roave/infection-static-analysis-plugin": "^1.6", - "squizlabs/php_codesniffer": "^3.5", - "thecodingmachine/phpstan-safe-rule": "^1.0", - "vimeo/psalm": "^4.3" - }, - "autoload": { - "psr-4": { - "sspat\\ReservedWords\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "sspat\\ReservedWords\\Tests\\": "tests/" - } - }, - "config": { - "sort-packages": true, - "preferred-install": "dist" - }, - "scripts": { - "cs": "phpcs", - "csfix": "phpcbf", - "psalm": "psalm", - "stan": "phpstan analyze", - "test": "phpunit", - "mutation": "roave-infection-static-analysis-plugin", - "all": "composer psalm && composer stan && composer test && composer mutation && composer cs" - } -} +{ + "name": "sspat/reserved-words", + "description": "Validates strings against reserved words of a specific php version", + "type": "library", + "version": "1.0.0", + "keywords": [ + "reserved", + "words", + "php" + ], + "license": "MIT", + "authors": [ + { + "name": "Patrik Foldes", + "email": "studio22@mail.ru" + } + ], + "require": { + "php": ">=7.3.0", + "thecodingmachine/safe": "^1.3" + }, + "require-dev": { + "doctrine/coding-standard": "^8.2", + "infection/infection": "^0.18.2", + "phpstan/phpstan": "^0.12.64", + "phpstan/phpstan-phpunit": "^0.12.17", + "phpstan/phpstan-strict-rules": "^0.12.7", + "phpunit/phpunit": "^8", + "squizlabs/php_codesniffer": "^3.5", + "thecodingmachine/phpstan-safe-rule": "^1.0", + "vimeo/psalm": "^4.3" + }, + "autoload": { + "psr-4": { + "sspat\\ReservedWords\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "sspat\\ReservedWords\\Tests\\": "tests/" + } + }, + "config": { + "sort-packages": true, + "preferred-install": "dist" + }, + "scripts": { + "cs": "phpcs", + "csfix": "phpcbf", + "psalm": "psalm", + "stan": "phpstan analyze", + "test": "phpunit", + "mutation": "infection", + "all": "composer psalm && composer stan && composer test && composer mutation && composer cs" + } +} From da63b51f82c3bb68f3b88d4cbb39e0dbe73bacfd Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 18:17:57 +0300 Subject: [PATCH 10/12] Update phpunit --- composer.json | 2 +- phpunit.xml.dist | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index d8a802b..30ed622 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "phpstan/phpstan": "^0.12.64", "phpstan/phpstan-phpunit": "^0.12.17", "phpstan/phpstan-strict-rules": "^0.12.7", - "phpunit/phpunit": "^8", + "phpunit/phpunit": "^9.5", "squizlabs/php_codesniffer": "^3.5", "thecodingmachine/phpstan-safe-rule": "^1.0", "vimeo/psalm": "^4.3" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ab33fa9..604b932 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -11,11 +11,11 @@ ./tests/ - - - ./src/ - - + + + ./src + + From 9658add1bef877eb0d9c8f2a11ca97b679da4b57 Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 18:26:10 +0300 Subject: [PATCH 11/12] php 8 support --- .github/workflows/coding-standards.yml | 2 +- .github/workflows/coverage.yml | 2 +- .github/workflows/mutation-test.yml | 2 +- .github/workflows/phpstan.yml | 2 +- .github/workflows/phpunit.yml | 1 + .github/workflows/psalm.yml | 2 +- composer.json | 3 +-- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 74be215..6b4744a 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -13,7 +13,7 @@ jobs: dependencies: - "locked" php-version: - - "7.4" + - "8.0" operating-system: - "ubuntu-latest" steps: diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 769afb7..722b233 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -13,7 +13,7 @@ jobs: dependencies: - "locked" php-version: - - "7.4" + - "8.0" operating-system: - "ubuntu-latest" steps: diff --git a/.github/workflows/mutation-test.yml b/.github/workflows/mutation-test.yml index 05893cf..ffe5554 100644 --- a/.github/workflows/mutation-test.yml +++ b/.github/workflows/mutation-test.yml @@ -13,7 +13,7 @@ jobs: dependencies: - "locked" php-version: - - "7.4" + - "8.0" operating-system: - "ubuntu-latest" steps: diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 23f06cd..a832e3f 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -13,7 +13,7 @@ jobs: dependencies: - "locked" php-version: - - "7.4" + - "8.0" operating-system: - "ubuntu-latest" steps: diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 1a57c44..80b7b03 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -17,6 +17,7 @@ jobs: php-version: - "7.3" - "7.4" + - "8.0" operating-system: - "ubuntu-latest" - "windows-latest" diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml index 6fa8458..453f89e 100644 --- a/.github/workflows/psalm.yml +++ b/.github/workflows/psalm.yml @@ -13,7 +13,7 @@ jobs: dependencies: - "locked" php-version: - - "7.4" + - "8.0" operating-system: - "ubuntu-latest" steps: diff --git a/composer.json b/composer.json index 30ed622..c1592d2 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,6 @@ "name": "sspat/reserved-words", "description": "Validates strings against reserved words of a specific php version", "type": "library", - "version": "1.0.0", "keywords": [ "reserved", "words", @@ -16,7 +15,7 @@ } ], "require": { - "php": ">=7.3.0", + "php": "^7.3|^8.0", "thecodingmachine/safe": "^1.3" }, "require-dev": { From b56d530e7a2603e3cb6595cb237c67df3f4ffc55 Mon Sep 17 00:00:00 2001 From: Patrik Foldes Date: Sat, 26 Dec 2020 19:31:48 +0300 Subject: [PATCH 12/12] Updated reserved words for php 8.0 --- CHANGELOG.md | 15 ++ README.md | 13 +- src/ReservedWords.php | 10 +- src/ReservedWordsList.php | 264 ++++++++++++++++++++++---------- tests/ReservedWordsListTest.php | 7 +- tests/ReservedWordsTest.php | 26 ++++ 6 files changed, 247 insertions(+), 88 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..48af0af --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,15 @@ +### 2.0.0 (26.12.2020) + +* Added support for PHP 8.0 +* BC Break: Dropped support of PHP 7.2 +* BC Break: Added new keyword reserved in php 8 - `match` +* BC Break: Updated `mixed` keyword to reflect changes in php 8 +* BC Break: Updated all keywords except `namespace` and `__halt_compiler` + to reflect that they can be used as namespace parts since php 8.0 +* BC Break: Added new method `isReservedClassName` to check for reserved words in + class/trait/interface names. The method `isReservedNamespaceName` should + be now used only for checking for reserved words in namespaces. + These changes are necessary because php 8 changed the reserved words behavior for namespaces. +* Migrated CI to GitHub actions +* Added mutation testing +* Added phpstan static analysis diff --git a/README.md b/README.md index 804d33d..d9ca8b0 100644 --- a/README.md +++ b/README.md @@ -49,9 +49,17 @@ $isReserved = $reservedWords->isReserved($word); */ $cannotUseAsConstantName = $reservedWords->isReservedConstantName($word); /** - * Checks that the word cannot be used as a namespace part or class/interface/trait name in your current php version. + * Checks that the word cannot be used as a namespace part in your current php version. + * + * This is used for checking parts of namespaces, not full namespace strings. + * E.g. calling this with `Some\Namespace\String` is incorrect, you should make three separate calls + * with `Some`, `Namespace` and `String`. */ $cannotUseAsNamespaceName = $reservedWords->isReservedNamespaceName($word); +/** + * Checks that the word cannot be used as a class/interface/trait name in your current php version. + */ +$cannotUseAsNamespaceName = $reservedWords->isReservedClassName($word); /** * Checks that the word cannot be used as a function name in your current php version. */ @@ -66,6 +74,7 @@ $cannotUseAsMethodName = $reservedWords->isReservedMethodName($word); */ $cannotUseAsConstantName = $reservedWords->isReservedConstantName($word, '5.6'); $cannotUseAsNamespaceName = $reservedWords->isReservedNamespaceName($word, '5.6.1'); -$cannotUseAsFunctionName = $reservedWords->isReservedFunctionName($word, '7.0'); +$cannotUseAsNamespaceName = $reservedWords->isReservedClassName($word, '5.6.1'); +$cannotUseAsFunctionName = $reservedWords->isReservedFunctionName($word, '8.0'); $cannotUseAsMethodName = $reservedWords->isReservedMethodName($word, '7.4.2'); ``` diff --git a/src/ReservedWords.php b/src/ReservedWords.php index 7b88a5f..9ef5071 100644 --- a/src/ReservedWords.php +++ b/src/ReservedWords.php @@ -51,13 +51,21 @@ public function isReservedConstantName(string $string, ?string $phpVersion = nul } /** - * Checks that the word cannot be used as a namespace part or class/interface/trait name + * Checks that the word cannot be used as a namespace part */ public function isReservedNamespaceName(string $string, ?string $phpVersion = null): bool { return $this->isReservedAs($string, 'namespace', $phpVersion); } + /** + * Checks that the word cannot be used as a class/interface/trait name + */ + public function isReservedClassName(string $string, ?string $phpVersion = null): bool + { + return $this->isReservedAs($string, 'class', $phpVersion); + } + /** * Checks that the word cannot be used as a function name */ diff --git a/src/ReservedWordsList.php b/src/ReservedWordsList.php index 147c804..534440d 100644 --- a/src/ReservedWordsList.php +++ b/src/ReservedWordsList.php @@ -11,7 +11,8 @@ final class ReservedWordsList * * The nested array keys have the following meaning: * "constant" - whether the reserved word can be used as a constant name - * "namespace" - whether the reserved word can be used as part of a namespace, class, interface or trait name. + * "namespace" - whether the reserved word can be used as part of a namespace + * "class" - whether the reserved word can be used as a class, interface or trait name * "function" - whether the reserved word can be used as a function name * "method" - whether the reserved word can be used as a method name * @@ -24,528 +25,623 @@ final class ReservedWordsList '__halt_compiler' => [ 'constant' => ['5.1', '7.0'], 'namespace' => '5.1', + 'class' => '5.1', 'function' => '5.1', 'method' => ['5.1', '7.0'], ], 'abstract' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'and' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'array' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'as' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'break' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'callable' => [ 'constant' => ['5.4', '7.0'], - 'namespace' => '5.4', + 'namespace' => ['5.4', '8.0'], + 'class' => '5.4', 'function' => '5.4', 'method' => ['5.4', '7.0'], ], 'case' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'catch' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'class' => [ 'constant' => '4.0', - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'clone' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'const' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'continue' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'declare' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'default' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'die' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'do' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'echo' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'else' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'elseif' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'empty' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'enddeclare' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'endfor' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'endforeach' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'endif' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'endswitch' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'endwhile' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'eval' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'exit' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'extends' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'final' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'finally' => [ 'constant' => ['5.5', '7.0'], - 'namespace' => '5.5', + 'namespace' => ['5.5', '8.0'], + 'class' => '5.5', 'function' => '5.5', 'method' => ['5.5', '7.0'], ], 'for' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'foreach' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'function' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'global' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'goto' => [ 'constant' => ['5.3', '7.0'], - 'namespace' => '5.3', + 'namespace' => ['5.3', '8.0'], + 'class' => '5.3', 'function' => '5.3', 'method' => ['5.3', '7.0'], ], 'if' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'implements' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'include' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'include_once' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'instanceof' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'insteadof' => [ 'constant' => ['5.4', '7.0'], - 'namespace' => '5.4', + 'namespace' => ['5.4', '8.0'], + 'class' => '5.4', 'function' => '5.4', 'method' => ['5.4', '7.0'], ], 'interface' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'isset' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'list' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], + 'match' => [ + 'constant' => false, + 'namespace' => false, + 'class' => '8.0', + 'function' => '8.0', + 'method' => false, + ], 'namespace' => [ 'constant' => ['5.3', '7.0'], 'namespace' => '5.3', + 'class' => '5.3', 'function' => '5.3', 'method' => ['5.3', '7.0'], ], 'new' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'or' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'print' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'private' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'protected' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'public' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'require' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'require_once' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'return' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'static' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'switch' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'throw' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'trait' => [ 'constant' => ['5.4', '7.0'], - 'namespace' => '5.4', + 'namespace' => ['5.4', '8.0'], + 'class' => '5.4', 'function' => '5.4', 'method' => ['5.4', '7.0'], ], 'try' => [ 'constant' => ['5.0', '7.0'], - 'namespace' => '5.0', + 'namespace' => ['5.0', '8.0'], + 'class' => '5.0', 'function' => '5.0', 'method' => ['5.0', '7.0'], ], 'unset' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'use' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'var' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'while' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'xor' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], 'yield' => [ 'constant' => ['5.5', '7.0'], - 'namespace' => '5.5', + 'namespace' => ['5.5', '8.0'], + 'class' => '5.5', 'function' => '5.5', 'method' => ['5.5', '7.0'], ], '__class__' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], '__dir__' => [ 'constant' => ['5.3', '7.0'], - 'namespace' => '5.3', + 'namespace' => ['5.3', '8.0'], + 'class' => '5.3', 'function' => '5.3', 'method' => ['5.3', '7.0'], ], '__file__' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], '__function__' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], '__line__' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], '__method__' => [ 'constant' => ['4.0', '7.0'], - 'namespace' => '4.0', + 'namespace' => ['4.0', '8.0'], + 'class' => '4.0', 'function' => '4.0', 'method' => ['4.0', '7.0'], ], '__namespace__' => [ 'constant' => ['5.3', '7.0'], - 'namespace' => '5.3', + 'namespace' => ['5.3', '8.0'], + 'class' => '5.3', 'function' => '5.3', 'method' => ['5.3', '7.0'], ], '__trait__' => [ 'constant' => ['5.4', '7.0'], - 'namespace' => '5.4', + 'namespace' => ['5.4', '8.0'], + 'class' => '5.4', 'function' => '5.4', 'method' => ['5.4', '7.0'], ], 'int' => [ 'constant' => false, - 'namespace' => '7.0', + 'namespace' => ['7.0', '8.0'], + 'class' => '7.0', 'function' => false, 'method' => false, ], 'float' => [ 'constant' => false, - 'namespace' => '7.0', + 'namespace' => ['7.0', '8.0'], + 'class' => '7.0', 'function' => false, 'method' => false, ], 'bool' => [ 'constant' => false, - 'namespace' => '7.0', + 'namespace' => ['7.0', '8.0'], + 'class' => '7.0', 'function' => false, 'method' => false, ], 'string' => [ 'constant' => false, - 'namespace' => '7.0', + 'namespace' => ['7.0', '8.0'], + 'class' => '7.0', 'function' => false, 'method' => false, ], 'true' => [ 'constant' => false, - 'namespace' => '7.0', + 'namespace' => ['7.0', '8.0'], + 'class' => '7.0', 'function' => false, 'method' => false, ], 'false' => [ 'constant' => false, - 'namespace' => '7.0', + 'namespace' => ['7.0', '8.0'], + 'class' => '7.0', 'function' => false, 'method' => false, ], 'null' => [ 'constant' => false, - 'namespace' => '7.0', + 'namespace' => ['7.0', '8.0'], + 'class' => '7.0', 'function' => false, 'method' => false, ], 'void' => [ 'constant' => false, - 'namespace' => '7.1', + 'namespace' => ['7.0', '8.0'], + 'class' => '7.0', 'function' => false, 'method' => false, ], 'iterable' => [ 'constant' => false, - 'namespace' => '7.1', + 'namespace' => ['7.1', '8.0'], + 'class' => '7.1', 'function' => false, 'method' => false, ], 'object' => [ 'constant' => false, - 'namespace' => '7.2', + 'namespace' => ['7.2', '8.0'], + 'class' => '7.2', 'function' => false, 'method' => false, ], 'resource' => [ 'constant' => false, 'namespace' => false, + 'class' => false, 'function' => false, 'method' => false, ], 'mixed' => [ 'constant' => false, 'namespace' => false, + 'class' => '8.0', 'function' => false, 'method' => false, ], 'numeric' => [ 'constant' => false, 'namespace' => false, + 'class' => false, 'function' => false, 'method' => false, ], diff --git a/tests/ReservedWordsListTest.php b/tests/ReservedWordsListTest.php index 3dee361..c455465 100644 --- a/tests/ReservedWordsListTest.php +++ b/tests/ReservedWordsListTest.php @@ -28,9 +28,10 @@ public function testReservedWordsList(): void foreach (ReservedWordsList::PHP_RESERVED_WORDS as $reservedWord => $reservedWordConfig) { Assert::assertIsString($reservedWord); Assert::assertIsArray($reservedWordConfig); - Assert::assertCount(4, $reservedWordConfig); + Assert::assertCount(5, $reservedWordConfig); Assert::assertArrayHasKey('constant', $reservedWordConfig); Assert::assertArrayHasKey('namespace', $reservedWordConfig); + Assert::assertArrayHasKey('class', $reservedWordConfig); Assert::assertArrayHasKey('function', $reservedWordConfig); Assert::assertArrayHasKey('method', $reservedWordConfig); Assert::assertTrue( @@ -41,6 +42,10 @@ public function testReservedWordsList(): void $this->isValidConstraint($reservedWordConfig['namespace']), sprintf($errorMessage, $reservedWord) ); + Assert::assertTrue( + $this->isValidConstraint($reservedWordConfig['class']), + sprintf($errorMessage, $reservedWord) + ); Assert::assertTrue( $this->isValidConstraint($reservedWordConfig['function']), sprintf($errorMessage, $reservedWord) diff --git a/tests/ReservedWordsTest.php b/tests/ReservedWordsTest.php index 38be7fd..80bd400 100644 --- a/tests/ReservedWordsTest.php +++ b/tests/ReservedWordsTest.php @@ -87,6 +87,22 @@ public function testNamespaceName( Assert::assertEquals($isReserved, $reservedWords->isReservedNamespaceName($reservedWord, $phpVersion)); } + /** + * @param array> $reservedWordParameters + * + * @dataProvider reservedWordsList + */ + public function testClassName( + string $reservedWord, + array $reservedWordParameters, + string $phpVersion, + bool $isReserved + ): void { + $reservedWords = new ReservedWords([$reservedWord => $reservedWordParameters]); + + Assert::assertEquals($isReserved, $reservedWords->isReservedClassName($reservedWord, $phpVersion)); + } + /** * @param array> $reservedWordParameters * @@ -140,6 +156,7 @@ public function reservedWordsList(): array 'reservedWordParameters' => [ 'constant' => false, 'namespace' => false, + 'class' => false, 'function' => false, 'method' => false, ], @@ -151,6 +168,7 @@ public function reservedWordsList(): array 'reservedWordParameters' => [ 'constant' => '7.0', 'namespace' => '7.0', + 'class' => '7.0', 'function' => '7.0', 'method' => '7.0', ], @@ -162,6 +180,7 @@ public function reservedWordsList(): array 'reservedWordParameters' => [ 'constant' => '7.0', 'namespace' => '7.0', + 'class' => '7.0', 'function' => '7.0', 'method' => '7.0', ], @@ -173,6 +192,7 @@ public function reservedWordsList(): array 'reservedWordParameters' => [ 'constant' => '7.0', 'namespace' => '7.0', + 'class' => '7.0', 'function' => '7.0', 'method' => '7.0', ], @@ -184,6 +204,7 @@ public function reservedWordsList(): array 'reservedWordParameters' => [ 'constant' => '7.0', 'namespace' => '7.0', + 'class' => '7.0', 'function' => '7.0', 'method' => '7.0', ], @@ -195,6 +216,7 @@ public function reservedWordsList(): array 'reservedWordParameters' => [ 'constant' => ['5.0', '7.0'], 'namespace' => ['5.0', '7.0'], + 'class' => ['5.0', '7.0'], 'function' => ['5.0', '7.0'], 'method' => ['5.0', '7.0'], ], @@ -206,6 +228,7 @@ public function reservedWordsList(): array 'reservedWordParameters' => [ 'constant' => ['5.0', '7.0'], 'namespace' => ['5.0', '7.0'], + 'class' => ['5.0', '7.0'], 'function' => ['5.0', '7.0'], 'method' => ['5.0', '7.0'], ], @@ -217,6 +240,7 @@ public function reservedWordsList(): array 'reservedWordParameters' => [ 'constant' => ['5.0', '7.0'], 'namespace' => ['5.0', '7.0'], + 'class' => ['5.0', '7.0'], 'function' => ['5.0', '7.0'], 'method' => ['5.0', '7.0'], ], @@ -228,6 +252,7 @@ public function reservedWordsList(): array 'reservedWordParameters' => [ 'constant' => ['5.0', '7.0'], 'namespace' => ['5.0', '7.0'], + 'class' => ['5.0', '7.0'], 'function' => ['5.0', '7.0'], 'method' => ['5.0', '7.0'], ], @@ -239,6 +264,7 @@ public function reservedWordsList(): array 'reservedWordParameters' => [ 'constant' => ['5.0', '7.0'], 'namespace' => ['5.0', '7.0'], + 'class' => ['5.0', '7.0'], 'function' => ['5.0', '7.0'], 'method' => ['5.0', '7.0'], ],