From d223be0ee90cd6001c21af39573fbc2f600a0bbe Mon Sep 17 00:00:00 2001 From: Viacheslav Poturaev Date: Fri, 17 Sep 2021 15:39:44 +0200 Subject: [PATCH] Prepare for PHP 8.1 (#42) --- .github/workflows/cloc.yml | 35 ++++ .github/workflows/lint.yml | 37 +++++ .github/workflows/test-unit-cov.yml | 38 +++++ .github/workflows/test-unit.yml | 37 +++++ .gitlab-ci.yml | 39 ----- .travis.yml | 34 ---- CHANGELOG.md | 6 + Makefile | 12 +- phpstan.neon | 8 + src/JsonPatch.php | 3 +- tests/phpunit.patch | 167 +++++++++++++++++++ tests/src/DiffTest.php | 2 +- tests/src/Issues/Issue40Test.php | 245 ++++++++++++++++++++++++++++ tests/src/Issues/Issue6Test.php | 2 +- tests/src/RearrangeArrayTest.php | 4 +- 15 files changed, 588 insertions(+), 81 deletions(-) create mode 100644 .github/workflows/cloc.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/test-unit-cov.yml create mode 100644 .github/workflows/test-unit.yml delete mode 100644 .gitlab-ci.yml delete mode 100644 .travis.yml create mode 100644 tests/phpunit.patch create mode 100644 tests/src/Issues/Issue40Test.php diff --git a/.github/workflows/cloc.yml b/.github/workflows/cloc.yml new file mode 100644 index 0000000..28cce0b --- /dev/null +++ b/.github/workflows/cloc.yml @@ -0,0 +1,35 @@ +name: cloc +on: + pull_request: +jobs: + cloc: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + with: + path: pr + - name: Checkout base code + uses: actions/checkout@v2 + with: + ref: ${{ github.event.pull_request.base.sha }} + path: base + - name: Count Lines Of Code + id: loc + run: | + curl -OL https://github.com/vearutop/sccdiff/releases/download/v1.0.1/linux_amd64.tar.gz && tar xf linux_amd64.tar.gz + OUTPUT=$(cd pr && ../sccdiff -basedir ../base) + OUTPUT="${OUTPUT//'%'/'%25'}" + OUTPUT="${OUTPUT//$'\n'/'%0A'}" + OUTPUT="${OUTPUT//$'\r'/'%0D'}" + echo "::set-output name=diff::$OUTPUT" + + - name: Comment Code Lines + uses: marocchino/sticky-pull-request-comment@v2 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + header: LOC + message: | + ### Lines Of Code + + ${{ steps.loc.outputs.diff }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..b147d4b --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,37 @@ +name: lint +on: + push: + branches: + - master + - main + pull_request: +jobs: + run: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: [ 'ubuntu-latest' ] + php-versions: [ '7.4' ] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache vendor + uses: actions/cache@v2 + with: + path: | + vendor + key: vendor-${{ hashFiles('composer.lock') }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + ini-values: post_max_size=256M, max_execution_time=180 + tools: composer + + - name: Populate vendor + run: '[ -e vendor ] || composer install' + + - name: Lint + run: make lint \ No newline at end of file diff --git a/.github/workflows/test-unit-cov.yml b/.github/workflows/test-unit-cov.yml new file mode 100644 index 0000000..819d420 --- /dev/null +++ b/.github/workflows/test-unit-cov.yml @@ -0,0 +1,38 @@ +name: test-unit-cov +on: + push: + branches: + - master + - main + pull_request: +jobs: + run: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: [ 'ubuntu-latest' ] + php-versions: [ '7.4' ] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache vendor + uses: actions/cache@v2 + with: + path: | + vendor + key: deps-${{ hashFiles('composer.lock') }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + ini-values: post_max_size=256M, max_execution_time=180 + coverage: xdebug + tools: composer + + - name: Populate vendor + run: '[ -e vendor ] || (composer install && patch -s -p0 < ./tests/phpunit.patch)' + + - name: Run Tests With Coverage + run: make deps test-coverage && bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml new file mode 100644 index 0000000..02ba09e --- /dev/null +++ b/.github/workflows/test-unit.yml @@ -0,0 +1,37 @@ +name: test-unit +on: + push: + branches: + - master + - main + pull_request: +jobs: + run: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: [ 'ubuntu-latest' ] + php-versions: [ '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '8.0', '8.1' ] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache vendor + uses: actions/cache@v2 + with: + path: | + vendor + key: deps-${{ hashFiles('composer.lock') }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + ini-values: post_max_size=256M, max_execution_time=180 + tools: composer + + - name: Populate vendor + run: '[ -e vendor ] || (composer install && patch -s -p0 < ./tests/phpunit.patch)' + + - name: Run Tests + run: make deps test \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 35b70e3..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,39 +0,0 @@ -before_script: -- apt-get update -yqq -- apt-get install git unzip -yqq -- curl https://composer.github.io/installer.sig | tr -d '\n' > installer.sig -- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -- php -r "if (hash_file('SHA384', 'composer-setup.php') === file_get_contents('installer.sig')) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" -- php composer-setup.php -- php -r "unlink('composer-setup.php'); unlink('installer.sig');" -- php composer.phar install --prefer-dist --no-ansi --no-interaction --no-progress - -test:5.6: - image: php:5.6 - script: - - pecl install xdebug-2.5.5 - - docker-php-ext-enable xdebug - - vendor/bin/phpunit --configuration phpunit.xml -v --coverage-text --colors=never --stderr - -test:7.0: - image: php:7.0 - script: - - pecl install xdebug - - docker-php-ext-enable xdebug - - vendor/bin/phpunit --configuration phpunit.xml -v --coverage-text --colors=never --stderr - -test:7.1: - image: php:7.1 - script: - - pecl install xdebug - - docker-php-ext-enable xdebug - - vendor/bin/phpunit --configuration phpunit.xml -v --coverage-text --colors=never --stderr - -test:7.2: - image: php:7.2 - script: - - pecl install xdebug - - docker-php-ext-enable xdebug - - vendor/bin/phpunit --configuration phpunit.xml -v --coverage-text --colors=never --stderr - - curl https://github.com/phpstan/phpstan/releases/download/0.9.2/phpstan.phar -sLo ./phpstan.phar - - php phpstan.phar analyze -l 7 ./src diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8950af2..0000000 --- a/.travis.yml +++ /dev/null @@ -1,34 +0,0 @@ -language: php -php: - - nightly - - 7.3 - - 7.2 - - 7.1 - - 7.0 - - 5.6 - - 5.5 - - 5.4 - -sudo: false -dist: trusty - -## Cache composer bits -cache: - directories: - - $HOME/.cache/composer - -before_script: - - composer install --dev --no-interaction --prefer-dist - - if ! [[ $(phpenv version-name) =~ 7.3 ]] ; then phpenv config-rm xdebug.ini || true ; fi - -matrix: - allow_failures: - - php: nightly - fast_finish: true - -script: - - if [[ $(phpenv version-name) =~ 7.3 ]] ; then make test-coverage; else make test; fi - - if [[ $(phpenv version-name) =~ 7.2 ]] ; then make lint bench bench-master bench-compare; fi - -after_script: - - if [[ $(phpenv version-name) =~ 7.3 ]] ; then bash <(curl -s https://codecov.io/bash); fi diff --git a/CHANGELOG.md b/CHANGELOG.md index a873ae8..1cef708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.8.2] - 2021-09-17 + +### Fixed +- PHP 8.1 Deprecation notices with missing returns. + ## [3.8.1] - 2020-09-25 ### Fixed @@ -55,6 +60,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Compatibility option to `TOLERATE_ASSOCIATIVE_ARRAYS` that mimic JSON objects. +[3.8.2]: https://github.com/swaggest/json-diff/compare/v3.8.1...v3.8.2 [3.8.1]: https://github.com/swaggest/json-diff/compare/v3.8.0...v3.8.1 [3.8.0]: https://github.com/swaggest/json-diff/compare/v3.7.5...v3.8.0 [3.7.5]: https://github.com/swaggest/json-diff/compare/v3.7.4...v3.7.5 diff --git a/Makefile b/Makefile index 26c5116..0eaaf33 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PHPSTAN_VERSION ?= 0.11.19 +PHPSTAN_VERSION ?= 0.12.99 PHPBENCH_VERSION ?= 0.16.10 deps: @@ -11,11 +11,17 @@ lint: docker-lint: @docker run -v $$PWD:/app --rm phpstan/phpstan analyze -l 7 -c phpstan.neon ./src +docker-test-new: + @docker run -v $$PWD:/app -w /app --rm php:8.1.0RC1-zts-buster php vendor/bin/phpunit --configuration phpunit.xml + +docker-test-old: + @docker run -v $$PWD:/app -w /app --rm php:5.4-cli php vendor/bin/phpunit --configuration phpunit.xml + test: - @php -derror_reporting="E_ALL & ~E_DEPRECATED" vendor/bin/phpunit --configuration phpunit.xml + @php vendor/bin/phpunit --configuration phpunit.xml test-coverage: - @php -derror_reporting="E_ALL & ~E_DEPRECATED" -dzend_extension=xdebug.so vendor/bin/phpunit --configuration phpunit.xml --coverage-text --coverage-clover=coverage.xml + @php -dzend_extension=xdebug.so vendor/bin/phpunit --configuration phpunit.xml --coverage-text --coverage-clover=coverage.xml phpbench: @test -f ${HOME}/.cache/composer/phpbench-${PHPBENCH_VERSION}.phar || (mkdir -p ${HOME}/.cache/composer/ && wget https://github.com/phpbench/phpbench/releases/download/${PHPBENCH_VERSION}/phpbench.phar -O ${HOME}/.cache/composer/phpbench-${PHPBENCH_VERSION}.phar) diff --git a/phpstan.neon b/phpstan.neon index e69de29..e80a7d5 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -0,0 +1,8 @@ +parameters: + inferPrivatePropertyTypeFromConstructor: true + checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false + ignoreErrors: + - '#has no return typehint specified#' + - '#with no typehint specified#' + - '#has no typehint specified#' diff --git a/src/JsonPatch.php b/src/JsonPatch.php index eac3510..7cfa92b 100644 --- a/src/JsonPatch.php +++ b/src/JsonPatch.php @@ -55,7 +55,7 @@ public static function import(array $data) { $result = new JsonPatch(); foreach ($data as $operation) { - /** @var OpPath|OpPathValue|OpPathFrom $operation */ + /** @var OpPath|OpPathValue|OpPathFrom|array $operation */ if (is_array($operation)) { $operation = (object)$operation; } @@ -124,6 +124,7 @@ public function op(OpPath $op) return $this; } + #[\ReturnTypeWillChange] public function jsonSerialize() { return self::export($this); diff --git a/tests/phpunit.patch b/tests/phpunit.patch new file mode 100644 index 0000000..5f44950 --- /dev/null +++ b/tests/phpunit.patch @@ -0,0 +1,167 @@ +diff -ruN ./vendor/phpunit/phpunit/src/Framework/Constraint.php ./vendor/phpunit/phpunit/src/Framework/Constraint.php +--- ./vendor/phpunit/phpunit/src/Framework/Constraint.php 2017-06-21 10:07:12.000000000 +0200 ++++ ./vendor/phpunit/phpunit/src/Framework/Constraint.php 2021-09-17 15:09:21.000000000 +0200 +@@ -81,6 +81,7 @@ + * + * @since Method available since Release 3.4.0 + */ ++ #[\ReturnTypeWillChange] + public function count() + { + return 1; +diff -ruN ./vendor/phpunit/phpunit/src/Util/Configuration.php ./vendor/phpunit/phpunit/src/Util/Configuration.php +--- ./vendor/phpunit/phpunit/src/Util/Configuration.php 2017-06-21 10:07:12.000000000 +0200 ++++ ./vendor/phpunit/phpunit/src/Util/Configuration.php 2021-09-17 14:46:32.000000000 +0200 +@@ -162,7 +162,7 @@ + /** + * @since Method available since Release 3.4.0 + */ +- final private function __clone() ++ private function __clone() + { + } + +@@ -516,7 +516,7 @@ + // See https://github.com/sebastianbergmann/phpunit/issues/277 + switch ($array) { + case 'var': +- $target = &$GLOBALS; ++// $target = &$GLOBALS; + break; + + case 'server': +diff -ruN ./vendor/phpunit/phpunit/src/Util/Getopt.php ./vendor/phpunit/phpunit/src/Util/Getopt.php +--- ./vendor/phpunit/phpunit/src/Util/Getopt.php 2017-06-21 10:07:12.000000000 +0200 ++++ ./vendor/phpunit/phpunit/src/Util/Getopt.php 2021-09-17 15:04:26.000000000 +0200 +@@ -21,7 +21,7 @@ + return array(array(), array()); + } + +- $opts = array(); ++ $opts = array(); + $non_opts = array(); + + if ($long_options) { +@@ -35,7 +35,10 @@ + reset($args); + array_map('trim', $args); + +- while (list($i, $arg) = each($args)) { ++ ++ for ($i = 0; $i < count($args); $i++) { ++ $arg = $args[$i]; ++ + if ($arg == '') { + continue; + } +@@ -45,24 +48,30 @@ + break; + } + ++ $nextArg = isset($args[$i]) ? $args[$i] : null; ++ + if ($arg[0] != '-' || + (strlen($arg) > 1 && $arg[1] == '-' && !$long_options)) { + $non_opts[] = $args[$i]; + continue; + } elseif (strlen($arg) > 1 && $arg[1] == '-') { +- self::parseLongOption( ++ if (self::parseLongOption( + substr($arg, 2), + $long_options, + $opts, +- $args +- ); ++ $nextArg ++ )) { ++ $i++; ++ } + } else { +- self::parseShortOption( ++ if (self::parseShortOption( + substr($arg, 1), + $short_options, + $opts, +- $args +- ); ++ $nextArg ++ )) { ++ $i++; ++ } + } + } + +@@ -74,7 +83,7 @@ + $argLen = strlen($arg); + + for ($i = 0; $i < $argLen; $i++) { +- $opt = $arg[$i]; ++ $opt = $arg[$i]; + $opt_arg = null; + + if (($spec = strstr($short_options, $opt)) === false || +@@ -107,11 +116,11 @@ + } + } + +- protected static function parseLongOption($arg, $long_options, &$opts, &$args) ++ protected static function parseLongOption($arg, $long_options, &$opts, $nextArg) + { +- $count = count($long_options); +- $list = explode('=', $arg); +- $opt = $list[0]; ++ $count = count($long_options); ++ $list = explode('=', $arg); ++ $opt = $list[0]; + $opt_arg = null; + + if (count($list) > 1) { +@@ -121,7 +130,7 @@ + $opt_len = strlen($opt); + + for ($i = 0; $i < $count; $i++) { +- $long_opt = $long_options[$i]; ++ $long_opt = $long_options[$i]; + $opt_start = substr($long_opt, 0, $opt_len); + + if ($opt_start != $opt) { +@@ -131,20 +140,24 @@ + $opt_rest = substr($long_opt, $opt_len); + + if ($opt_rest != '' && $opt[0] != '=' && $i + 1 < $count && +- $opt == substr($long_options[$i+1], 0, $opt_len)) { ++ $opt == substr($long_options[$i + 1], 0, $opt_len)) { + throw new PHPUnit_Framework_Exception( + "option --$opt is ambiguous" + ); + } + ++ $ret = false; ++ + if (substr($long_opt, -1) == '=') { + if (substr($long_opt, -2) != '==') { +- if (!strlen($opt_arg) && +- !(list(, $opt_arg) = each($args))) { ++ if (empty($opt_arg) && ++ empty($nextArg) /*false*/) { + throw new PHPUnit_Framework_Exception( + "option --$opt requires an argument" + ); + } ++ ++ $ret = true; + } + } elseif ($opt_arg) { + throw new PHPUnit_Framework_Exception( +@@ -153,9 +166,9 @@ + } + + $full_option = '--' . preg_replace('/={1,2}$/', '', $long_opt); +- $opts[] = array($full_option, $opt_arg); ++ $opts[] = array($full_option, $opt_arg); + +- return; ++ return $ret; + } + + throw new PHPUnit_Framework_Exception("unrecognized option --$opt"); diff --git a/tests/src/DiffTest.php b/tests/src/DiffTest.php index 3d0c8e8..eed0a9f 100644 --- a/tests/src/DiffTest.php +++ b/tests/src/DiffTest.php @@ -34,7 +34,7 @@ public function testSkipPatch() $this->assertSame(1, $diff->getModifiedCnt()); $diff = new JsonDiff($original, $new, JsonDiff::REARRANGE_ARRAYS); - $this->assertEquals('[{"op":"remove","path":"/root/a"},{"value":2,"op":"test","path":"/root/b"},{"value":3,"op":"replace","path":"/root/b"},{"value":4,"op":"add","path":"/root/c"}]', + $this->assertJsonStringEqualsJsonString('[{"op":"remove","path":"/root/a"},{"value":2,"op":"test","path":"/root/b"},{"value":3,"op":"replace","path":"/root/b"},{"value":4,"op":"add","path":"/root/c"}]', json_encode($diff->getPatch(), JSON_UNESCAPED_SLASHES)); $this->assertSame(3, $diff->getDiffCnt()); $this->assertSame(1, $diff->getAddedCnt()); diff --git a/tests/src/Issues/Issue40Test.php b/tests/src/Issues/Issue40Test.php new file mode 100644 index 0000000..e1a1366 --- /dev/null +++ b/tests/src/Issues/Issue40Test.php @@ -0,0 +1,245 @@ +getPatch()->export($diff->getPatch()); + + $patch = JsonPatch::import($exportedPatch); + + var_dump($patch->apply($j1)); + } +} \ No newline at end of file diff --git a/tests/src/Issues/Issue6Test.php b/tests/src/Issues/Issue6Test.php index 36292ed..b3d4df2 100644 --- a/tests/src/Issues/Issue6Test.php +++ b/tests/src/Issues/Issue6Test.php @@ -19,7 +19,7 @@ public function testDefault() $diff = new JsonDiff($json1, $json2); $patch = $diff->getPatch(); - $this->assertSame(<<<'JSON' + $this->assertJsonStringEqualsJsonString(<<<'JSON' [ { "value": "a", diff --git a/tests/src/RearrangeArrayTest.php b/tests/src/RearrangeArrayTest.php index a115503..2dded6d 100644 --- a/tests/src/RearrangeArrayTest.php +++ b/tests/src/RearrangeArrayTest.php @@ -196,7 +196,7 @@ public function testEqualItemsDiff() json_decode('{"data": [{"B": 2},{"A": 1, "C": [5,3,2,1]}]}'), JsonDiff::REARRANGE_ARRAYS); - $this->assertEquals('[{"value":4,"op":"test","path":"/data/0/C/3"},{"value":5,"op":"replace","path":"/data/0/C/3"}]', + $this->assertJsonStringEqualsJsonString('[{"value":4,"op":"test","path":"/data/0/C/3"},{"value":5,"op":"replace","path":"/data/0/C/3"}]', json_encode($diff->getPatch(), JSON_UNESCAPED_SLASHES)); } @@ -207,7 +207,7 @@ public function testExample() json_decode('[{"name": "Joe", "height": 179},{"name": "Jane", "height": 168},{"name": "Alex", "height": 180}]'), JsonDiff::REARRANGE_ARRAYS); - $this->assertEquals('[{"value":165,"op":"test","path":"/2/height"},{"value":168,"op":"replace","path":"/2/height"}]', + $this->assertJsonStringEqualsJsonString('[{"value":165,"op":"test","path":"/2/height"},{"value":168,"op":"replace","path":"/2/height"}]', json_encode($diff->getPatch(), JSON_UNESCAPED_SLASHES)); }