diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 24e45e3..ba83636 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,11 @@ jobs: - { php: 5.6, flags: --prefer-lowest } - { php: '7.0', flags: --prefer-lowest } - { php: 7.1, flags: --prefer-lowest } + # Explicitly exercise the sebastian/comparator 8.0 / 8.1 range — the + # versions that still lack the #158 serialization fix and therefore + # still need this patch (requires PHP >= 8.4). + - { php: 8.4, comparator: 8.0.* } + - { php: 8.5, comparator: 8.1.* } steps: - uses: actions/checkout@v3 @@ -26,7 +31,11 @@ jobs: with: php-version: ${{ matrix.php }} - - run: composer require phpunit/phpunit --dev ${{ matrix.flags }} - - run: composer show | grep -E '^(phpunit/phpunit|sebastian/comparator)' + - name: Pin sebastian/comparator + if: ${{ matrix.comparator }} + run: composer require "sebastian/comparator:${{ matrix.comparator }}" --no-update + + - run: composer require phpunit/phpunit --dev ${{ matrix.flags }} ${{ matrix.comparator && '-W' || '' }} + - run: composer show | grep -E '^(phpunit/phpunit|sebastian/comparator|sebastian/diff)' - run: 'vendor/bin/phpunit --migrate-configuration || :' - run: vendor/bin/phpunit diff --git a/README.md b/README.md index 5def956..0ce9b8a 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,16 @@ Fixes `assertSame()`/`assertEquals()` serialization errors running in separate processes. +> [!IMPORTANT] +> **`sebastian/comparator` `8.2.0` fixes this upstream**, so this patch is only needed below that version. +> See [sebastianbergmann/comparator#158](https://github.com/sebastianbergmann/comparator/issues/158): as of `8.2.0`, `ComparisonFailure` implements `__serialize()`/`__unserialize()` and can be serialized across process-isolation boundaries even when its stack trace references non-serializable objects (e.g. a `PDO` passed as a method argument) — exactly the case this package works around. +> This package is therefore constrained to `sebastian/comparator` `<8.2`. On `comparator` `>=8.2` you do **not** need it (and shouldn't install it: it would override the upstream-fixed class). + ## Requirements - php: `>=5.3.3` - [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit): `>=4.8.0` -- [sebastianbergmann/comparator](https://github.com/sebastianbergmann/comparator): `^1.0 || ^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0` +- [sebastianbergmann/comparator](https://github.com/sebastianbergmann/comparator): `^1.0 || ^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0 || >=8.0 <8.2` ## Installing diff --git a/composer.json b/composer.json index ebdc4ef..ee9b16f 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,17 @@ "email": "ryosuke_i_628@yahoo.co.jp" } ], - "keywords": ["phpunit", "isolation", "serialization", "separate", "process", "processes", "patch", "fix", "bug"], + "keywords": [ + "phpunit", + "isolation", + "serialization", + "separate", + "process", + "processes", + "patch", + "fix", + "bug" + ], "autoload": { "files": [ "./files/ComparisonFailure.php" @@ -28,7 +38,7 @@ }, "require": { "php": ">=5.3.3", - "sebastian/comparator": "^1.0 || ^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" + "sebastian/comparator": "^1.0 || ^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0 || >=8.0 <8.2" }, "require-dev": { "phpunit/phpunit": ">=4.8" diff --git a/files/ComparisonFailure.php b/files/ComparisonFailure.php index 3c5b97c..ac1adc2 100644 --- a/files/ComparisonFailure.php +++ b/files/ComparisonFailure.php @@ -110,10 +110,26 @@ public function getDiff() } $header = "\n--- Expected\n+++ Actual\n"; + $builder = $header; if (\class_exists('SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder')) { - $header = new UnifiedDiffOutputBuilder($header); + // sebastian/diff >=8 (pulled in by sebastian/comparator ^8) adds an + // `emitNoLineEndEofWarning` constructor argument that defaults to true, + // which injects `\ No newline at end of file` markers into the diff. + // Disable it when available to keep the legacy output format; older + // diff releases lack the argument, so fall back to the 1-argument form. + $emitsNoLineEndEofWarning = false; + $constructor = new \ReflectionMethod('SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder', '__construct'); + foreach ($constructor->getParameters() as $parameter) { + if ($parameter->getName() === 'emitNoLineEndEofWarning') { + $emitsNoLineEndEofWarning = true; + break; + } + } + $builder = $emitsNoLineEndEofWarning + ? new UnifiedDiffOutputBuilder($header, false, 3, false) + : new UnifiedDiffOutputBuilder($header); } - $differ = new Differ($header); + $differ = new Differ($builder); return $differ->diff($this->expectedAsString, $this->actualAsString); }