diff --git a/composer.lock b/composer.lock index 83028d37ed5..8300ec52bd4 100644 --- a/composer.lock +++ b/composer.lock @@ -446,7 +446,7 @@ "dist": { "type": "path", "url": "core", - "reference": "9e2d1532ca02ec3d0fb258d23a5c404533bcac43" + "reference": "4a6aa3700723fe42a3a8add8c27af45f8710ddb2" }, "require": { "asm89/stack-cors": "^2.1", @@ -474,6 +474,7 @@ "pear/archive_tar": "^1.4.14", "php": ">=8.1.0", "psr/log": "^3.0", + "sebastian/diff": "^4", "symfony/console": "^6.2", "symfony/dependency-injection": "^6.2", "symfony/event-dispatcher": "^6.2", @@ -1824,6 +1825,72 @@ }, "time": "2019-03-08T08:55:37+00:00" }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, { "name": "symfony/console", "version": "v6.2.5", @@ -6765,72 +6832,6 @@ ], "time": "2020-10-26T15:52:27+00:00" }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, { "name": "sebastian/environment", "version": "5.1.4", diff --git a/composer/Metapackage/CoreRecommended/composer.json b/composer/Metapackage/CoreRecommended/composer.json index 13f29dc1bed..ecddbf12355 100644 --- a/composer/Metapackage/CoreRecommended/composer.json +++ b/composer/Metapackage/CoreRecommended/composer.json @@ -30,6 +30,7 @@ "psr/http-message": "~1.0.1", "psr/log": "~3.0.0", "ralouphie/getallheaders": "~3.0.3", + "sebastian/diff": "~4.0.4", "symfony/console": "~v6.2.5", "symfony/dependency-injection": "~v6.2.6", "symfony/deprecation-contracts": "~v3.2.0", diff --git a/composer/Metapackage/PinnedDevDependencies/composer.json b/composer/Metapackage/PinnedDevDependencies/composer.json index f2d192bd710..6d6d88f4841 100644 --- a/composer/Metapackage/PinnedDevDependencies/composer.json +++ b/composer/Metapackage/PinnedDevDependencies/composer.json @@ -49,7 +49,6 @@ "sebastian/code-unit-reverse-lookup": "2.0.3", "sebastian/comparator": "4.0.8", "sebastian/complexity": "2.0.2", - "sebastian/diff": "4.0.4", "sebastian/environment": "5.1.4", "sebastian/exporter": "4.0.5", "sebastian/global-state": "5.0.5", diff --git a/core/composer.json b/core/composer.json index 37167210361..92a7ab8e82c 100644 --- a/core/composer.json +++ b/core/composer.json @@ -42,7 +42,8 @@ "asm89/stack-cors": "^2.1", "pear/archive_tar": "^1.4.14", "psr/log": "^3.0", - "mck89/peast": "^1.14" + "mck89/peast": "^1.14", + "sebastian/diff": "^4" }, "conflict": { "drush/drush": "<8.1.10" diff --git a/core/lib/Drupal/Component/Diff/Diff.php b/core/lib/Drupal/Component/Diff/Diff.php index 289bab5f0e7..1b5c40a7051 100644 --- a/core/lib/Drupal/Component/Diff/Diff.php +++ b/core/lib/Drupal/Component/Diff/Diff.php @@ -2,17 +2,15 @@ namespace Drupal\Component\Diff; -use Drupal\Component\Diff\Engine\DiffEngine; +use SebastianBergmann\Diff\Differ; /** * Class representing a 'diff' between two sequences of strings. - * @todo document - * @subpackage DifferenceEngine * - * Copied from https://www.drupal.org/project/diff which was based PHP diff - * engine for phpwiki. (Taken from phpwiki-1.3.3) The original code in phpwiki - * was copyright (C) 2000, 2001 Geoffrey T. Dairiki and - * licensed under GPL. + * Component code originally taken from https://www.drupal.org/project/diff + * which was itself based on the PHP diff engine for phpwiki. The original code + * in phpwiki was copyright (C) 2000, 2001 Geoffrey T. Dairiki + * and licensed under GPL. */ class Diff { @@ -34,9 +32,9 @@ class Diff { * An array of strings. */ public function __construct($from_lines, $to_lines) { - $eng = new DiffEngine(); - $this->edits = $eng->diff($from_lines, $to_lines); - //$this->_check($from_lines, $to_lines); + $diffOpBuilder = new DiffOpOutputBuilder(); + $differ = new Differ($diffOpBuilder); + $this->edits = $diffOpBuilder->toOpsArray($differ->diffToArray($from_lines, $to_lines)); } /** @@ -48,8 +46,14 @@ class Diff { * $rev = $diff->reverse(); * @return object * A Diff object representing the inverse of the original diff. + * + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 */ public function reverse() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); $rev = $this; $rev->edits = []; foreach ($this->edits as $edit) { @@ -62,8 +66,14 @@ class Diff { * Check for empty diff. * * @return bool True iff two sequences were identical. + * + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 */ public function isEmpty() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); foreach ($this->edits as $edit) { if ($edit->type != 'copy') { return FALSE; @@ -78,8 +88,14 @@ class Diff { * This is mostly for diagnostic purposed. * * @return int The length of the LCS. + * + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 */ public function lcs() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); $lcs = 0; foreach ($this->edits as $edit) { if ($edit->type == 'copy') { @@ -96,8 +112,14 @@ class Diff { * constructor. * * @return array The original sequence of strings. + * + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 */ public function orig() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); $lines = []; foreach ($this->edits as $edit) { @@ -115,8 +137,14 @@ class Diff { * constructor. * * @return array The sequence of strings. + * + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 */ public function closing() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); $lines = []; foreach ($this->edits as $edit) { @@ -131,8 +159,14 @@ class Diff { * Check a Diff for validity. * * This is here only for debugging purposes. + * + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 */ public function check($from_lines, $to_lines) { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); if (serialize($from_lines) != serialize($this->orig())) { trigger_error("Reconstructed original doesn't match", E_USER_ERROR); } diff --git a/core/lib/Drupal/Component/Diff/DiffOpOutputBuilder.php b/core/lib/Drupal/Component/Diff/DiffOpOutputBuilder.php new file mode 100644 index 00000000000..c872a92f50e --- /dev/null +++ b/core/lib/Drupal/Component/Diff/DiffOpOutputBuilder.php @@ -0,0 +1,138 @@ +toOpsArray($diff)); + } + + /** + * Converts the output of Differ to an array of DiffOp* value objects. + * + * @param array $diff + * The array output of Differ::diffToArray(). + * + * @return \Drupal\Component\Diff\Engine\DiffOp[] + * An array of DiffOp* value objects. + */ + public function toOpsArray(array $diff): array { + $ops = []; + $hunkMode = NULL; + $hunkSource = []; + $hunkTarget = []; + + for ($i = 0; $i < count($diff); $i++) { + + // Handle a sequence of removals + additions as a sequence of changes, and + // manages the tail if required. + if ($diff[$i][1] === Differ::REMOVED) { + if ($hunkMode !== NULL) { + $ops[] = $this->hunkOp($hunkMode, $hunkSource, $hunkTarget); + $hunkSource = []; + $hunkTarget = []; + } + for ($n = $i; $n < count($diff) && $diff[$n][1] === Differ::REMOVED; $n++) { + $hunkSource[] = $diff[$n][0]; + } + for (; $n < count($diff) && $diff[$n][1] === Differ::ADDED; $n++) { + $hunkTarget[] = $diff[$n][0]; + } + if (count($hunkTarget) === 0) { + $ops[] = $this->hunkOp(Differ::REMOVED, $hunkSource, $hunkTarget); + } + elseif (count($hunkSource) === count($hunkTarget)) { + $ops[] = $this->hunkOp(self::CHANGED, $hunkSource, $hunkTarget); + } + elseif (count($hunkSource) > count($hunkTarget)) { + $ops[] = $this->hunkOp(self::CHANGED, array_slice($hunkSource, 0, count($hunkTarget)), $hunkTarget); + $ops[] = $this->hunkOp(Differ::REMOVED, array_slice($hunkSource, count($hunkTarget)), []); + } + else { + $ops[] = $this->hunkOp(self::CHANGED, $hunkSource, array_slice($hunkTarget, 0, count($hunkSource))); + $ops[] = $this->hunkOp(Differ::ADDED, array_slice($hunkTarget, count($hunkSource)), []); + } + $hunkMode = NULL; + $hunkSource = []; + $hunkTarget = []; + $i = $n - 1; + continue; + } + + // When here, we are adding or copying the item. Removing or changing is + // managed above. + if ($hunkMode === NULL) { + $hunkMode = $diff[$i][1]; + } + elseif ($hunkMode !== $diff[$i][1]) { + $ops[] = $this->hunkOp($hunkMode, $hunkSource, $hunkTarget); + $hunkMode = $diff[$i][1]; + $hunkSource = []; + $hunkTarget = []; + } + + $hunkSource[] = $diff[$i][0]; + } + + if ($hunkMode !== NULL) { + $ops[] = $this->hunkOp($hunkMode, $hunkSource, $hunkTarget); + } + + return $ops; + } + + /** + * Returns the proper DiffOp object based on the hunk mode. + * + * @param int $mode + * A Differ constant or self::CHANGED. + * @param string[] $source + * An array of strings to be changed/added/removed/copied. + * @param string[] $source + * The array of strings to be changed to when self::CHANGED is specified. + * + * @return \Drupal\Component\Diff\Engine\DiffOp + * A DiffOp* value object. + * + * @throw \InvalidArgumentException + * When $mode is not valid. + */ + private function hunkOp(int $mode, array $source, array $target): DiffOp { + switch ($mode) { + case Differ::OLD: + return new DiffOpCopy($source); + + case self::CHANGED: + return new DiffOpChange($source, $target); + + case Differ::ADDED: + return new DiffOpAdd($source); + + case Differ::REMOVED: + return new DiffOpDelete($source); + + } + throw new \InvalidArgumentException("Invalid \$mode {$mode} specified"); + } + +} diff --git a/core/lib/Drupal/Component/Diff/Engine/DiffEngine.php b/core/lib/Drupal/Component/Diff/Engine/DiffEngine.php index 75dfc46ee5a..1289f96ebaf 100644 --- a/core/lib/Drupal/Component/Diff/Engine/DiffEngine.php +++ b/core/lib/Drupal/Component/Diff/Engine/DiffEngine.php @@ -24,6 +24,11 @@ namespace Drupal\Component\Diff\Engine; * @author Geoffrey T. Dairiki, Tim Starling * @private * @subpackage DifferenceEngine + * + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use + * sebastianbergmann/diff instead. + * + * @see https://www.drupal.org/node/3337942 */ #[\AllowDynamicProperties] class DiffEngine { @@ -32,6 +37,10 @@ class DiffEngine { const MAX_XREF_LENGTH = 10000; + public function __construct() { + @trigger_error('Drupal\Component\Diff\Engine\DiffEngine is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use sebastianbergmann/diff instead. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); + } + public function diff($from_lines, $to_lines) { $n_from = sizeof($from_lines); diff --git a/core/lib/Drupal/Component/Diff/Engine/DiffOp.php b/core/lib/Drupal/Component/Diff/Engine/DiffOp.php index 29d749dc7c8..735669dc147 100644 --- a/core/lib/Drupal/Component/Diff/Engine/DiffOp.php +++ b/core/lib/Drupal/Component/Diff/Engine/DiffOp.php @@ -12,15 +12,36 @@ class DiffOp { public $orig; public $closing; + /** + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 + */ public function reverse() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); trigger_error('pure virtual', E_USER_ERROR); } + /** + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 + */ public function norig() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); return $this->orig ? sizeof($this->orig) : 0; } + /** + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 + */ public function nclosing() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); return $this->closing ? sizeof($this->closing) : 0; } diff --git a/core/lib/Drupal/Component/Diff/Engine/DiffOpAdd.php b/core/lib/Drupal/Component/Diff/Engine/DiffOpAdd.php index 14429c251d6..df954302f6c 100644 --- a/core/lib/Drupal/Component/Diff/Engine/DiffOpAdd.php +++ b/core/lib/Drupal/Component/Diff/Engine/DiffOpAdd.php @@ -15,7 +15,14 @@ class DiffOpAdd extends DiffOp { $this->orig = FALSE; } + /** + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 + */ public function reverse() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); return new DiffOpDelete($this->closing); } diff --git a/core/lib/Drupal/Component/Diff/Engine/DiffOpChange.php b/core/lib/Drupal/Component/Diff/Engine/DiffOpChange.php index 4abd6acc01f..93d15db885b 100644 --- a/core/lib/Drupal/Component/Diff/Engine/DiffOpChange.php +++ b/core/lib/Drupal/Component/Diff/Engine/DiffOpChange.php @@ -15,7 +15,14 @@ class DiffOpChange extends DiffOp { $this->closing = $closing; } + /** + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 + */ public function reverse() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); return new DiffOpChange($this->closing, $this->orig); } diff --git a/core/lib/Drupal/Component/Diff/Engine/DiffOpCopy.php b/core/lib/Drupal/Component/Diff/Engine/DiffOpCopy.php index 4128d573291..c82e2a61b99 100644 --- a/core/lib/Drupal/Component/Diff/Engine/DiffOpCopy.php +++ b/core/lib/Drupal/Component/Diff/Engine/DiffOpCopy.php @@ -18,7 +18,14 @@ class DiffOpCopy extends DiffOp { $this->closing = $closing; } + /** + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 + */ public function reverse() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); return new DiffOpCopy($this->closing, $this->orig); } diff --git a/core/lib/Drupal/Component/Diff/Engine/DiffOpDelete.php b/core/lib/Drupal/Component/Diff/Engine/DiffOpDelete.php index e402d66b61f..4aa84be1300 100644 --- a/core/lib/Drupal/Component/Diff/Engine/DiffOpDelete.php +++ b/core/lib/Drupal/Component/Diff/Engine/DiffOpDelete.php @@ -15,7 +15,14 @@ class DiffOpDelete extends DiffOp { $this->closing = FALSE; } + /** + * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no + * replacement. + * + * @see https://www.drupal.org/node/3337942 + */ public function reverse() { + @trigger_error(__METHOD__ . '() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942', E_USER_DEPRECATED); return new DiffOpAdd($this->orig); } diff --git a/core/lib/Drupal/Component/Diff/composer.json b/core/lib/Drupal/Component/Diff/composer.json index 972c5e2f771..57a07592ff8 100644 --- a/core/lib/Drupal/Component/Diff/composer.json +++ b/core/lib/Drupal/Component/Diff/composer.json @@ -7,7 +7,8 @@ "homepage": "https://www.drupal.org/project/drupal", "license": "GPL-2.0-or-later", "require": { - "php": ">=8.1.0" + "php": ">=8.1.0", + "sebastian/diff": "^4" }, "autoload": { "psr-4": { diff --git a/core/misc/cspell/dictionary.txt b/core/misc/cspell/dictionary.txt index 66fb08a96f1..f12aa133a46 100644 --- a/core/misc/cspell/dictionary.txt +++ b/core/misc/cspell/dictionary.txt @@ -1043,6 +1043,7 @@ screenreaders scriptable scrollbars searchdirs +sebastianbergmann sebe seld selectbox diff --git a/core/tests/Drupal/Tests/Component/Diff/DiffOpOutputBuilderTest.php b/core/tests/Drupal/Tests/Component/Diff/DiffOpOutputBuilderTest.php new file mode 100644 index 00000000000..bb0f70de2e1 --- /dev/null +++ b/core/tests/Drupal/Tests/Component/Diff/DiffOpOutputBuilderTest.php @@ -0,0 +1,114 @@ + [[], [], []], + 'add' => [[new DiffOpAdd(['a'])], [], ['a']], + 'copy' => [[new DiffOpCopy(['a'])], ['a'], ['a']], + 'change' => [[new DiffOpChange(['a'], ['b'])], ['a'], ['b']], + 'copy-and-change' => [ + [ + new DiffOpCopy(['a']), + new DiffOpChange(['b'], ['c']), + ], + ['a', 'b'], + ['a', 'c'], + ], + 'copy-change-copy' => [ + [ + new DiffOpCopy(['a']), + new DiffOpChange(['b'], ['c']), + new DiffOpCopy(['d']), + ], + ['a', 'b', 'd'], + ['a', 'c', 'd'], + ], + 'copy-change-copy-add' => [ + [ + new DiffOpCopy(['a']), + new DiffOpChange(['b'], ['c']), + new DiffOpCopy(['d']), + new DiffOpAdd(['e']), + ], + ['a', 'b', 'd'], + ['a', 'c', 'd', 'e'], + ], + 'copy-delete' => [ + [ + new DiffOpCopy(['a']), + new DiffOpDelete(['b', 'd']), + ], + ['a', 'b', 'd'], + ['a'], + ], + ]; + } + + /** + * Tests whether op classes returned match expectations. + * + * @covers ::toOpsArray + * @dataProvider provideTestDiff + */ + public function testToOpsArray(array $expected, array $from, array $to): void { + $diffOpBuilder = new DiffOpOutputBuilder(); + $differ = new Differ($diffOpBuilder); + $diff = $differ->diffToArray($from, $to); + $this->assertEquals($expected, $diffOpBuilder->toOpsArray($diff)); + } + + /** + * @covers ::getDiff + * @dataProvider provideTestDiff + */ + public function testGetDiff(array $expected, array $from, array $to): void { + $differ = new Differ(new DiffOpOutputBuilder()); + $diff = $differ->diff($from, $to); + $this->assertEquals($expected, unserialize($diff)); + } + + /** + * Tests that two files can be successfully diffed. + * + * @covers ::toOpsArray + */ + public function testDiffInfiniteLoop(): void { + $from = explode("\n", file_get_contents(__DIR__ . '/Engine/fixtures/file1.txt')); + $to = explode("\n", file_get_contents(__DIR__ . '/Engine/fixtures/file2.txt')); + $diffOpBuilder = new DiffOpOutputBuilder(); + $differ = new Differ($diffOpBuilder); + $diff = $differ->diffToArray($from, $to); + $diffOps = $diffOpBuilder->toOpsArray($diff); + $this->assertCount(5, $diffOps); + $this->assertEquals($diffOps[0], new DiffOpAdd([' - image.style.max_325x325'])); + $this->assertEquals($diffOps[1], new DiffOpCopy([' - image.style.max_650x650'])); + $this->assertEquals($diffOps[2], new DiffOpChange([' - image.style.max_325x325'], ['_core:'])); + $this->assertEquals($diffOps[3], new DiffOpAdd([' default_config_hash: 3mjM9p-kQ8syzH7N8T0L9OnCJDSPvHAZoi3q6jcXJKM'])); + $this->assertEquals($diffOps[4], new DiffOpCopy(['fallback_image_style: max_325x325', ''])); + } + +} diff --git a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php index 895faebeb50..1020373e6ac 100644 --- a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php +++ b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php @@ -8,6 +8,7 @@ use Drupal\Component\Diff\Engine\DiffOpCopy; use Drupal\Component\Diff\Engine\DiffOpChange; use Drupal\Component\Diff\Engine\DiffOpDelete; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; /** * Test DiffEngine class. @@ -15,9 +16,12 @@ use PHPUnit\Framework\TestCase; * @coversDefaultClass \Drupal\Component\Diff\Engine\DiffEngine * * @group Diff + * @group legacy */ class DiffEngineTest extends TestCase { + use ExpectDeprecationTrait; + /** * @return array * - Expected output in terms of return class. A list of class names @@ -76,6 +80,7 @@ class DiffEngineTest extends TestCase { * @dataProvider provideTestDiff */ public function testDiff($expected, $from, $to) { + $this->expectDeprecation('Drupal\Component\Diff\Engine\DiffEngine is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use sebastianbergmann/diff instead. See https://www.drupal.org/node/3337942'); $diff_engine = new DiffEngine(); $diff = $diff_engine->diff($from, $to); // Make sure we have the same number of results as expected. @@ -92,6 +97,7 @@ class DiffEngineTest extends TestCase { * @covers ::diff */ public function testDiffInfiniteLoop() { + $this->expectDeprecation('Drupal\Component\Diff\Engine\DiffEngine is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use sebastianbergmann/diff instead. See https://www.drupal.org/node/3337942'); $from = explode("\n", file_get_contents(__DIR__ . '/fixtures/file1.txt')); $to = explode("\n", file_get_contents(__DIR__ . '/fixtures/file2.txt')); $diff_engine = new DiffEngine(); diff --git a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php index 76f0064e7d9..a8c7ac72baf 100644 --- a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php +++ b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php @@ -4,6 +4,7 @@ namespace Drupal\Tests\Component\Diff\Engine; use Drupal\Component\Diff\Engine\DiffOp; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; /** * Test DiffOp base class. @@ -15,15 +16,19 @@ use PHPUnit\Framework\TestCase; * @coversDefaultClass \Drupal\Component\Diff\Engine\DiffOp * * @group Diff + * @group legacy */ class DiffOpTest extends TestCase { + use ExpectDeprecationTrait; + /** * DiffOp::reverse() always throws an error. * * @covers ::reverse */ public function testReverse() { + $this->expectDeprecation('Drupal\Component\Diff\Engine\DiffOp::reverse() is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. There is no replacement. See https://www.drupal.org/node/3337942'); $this->expectError(); $op = new DiffOp(); $result = $op->reverse();