From 550312ab6bd14c65c65bea4acfcd2692763c8295 Mon Sep 17 00:00:00 2001 From: JBlond Date: Tue, 26 Oct 2021 20:38:24 +0200 Subject: [PATCH 01/46] Optimize code base #103 --- example/cli.php | 6 ++-- example/example.php | 8 ++--- lib/jblond/Diff.php | 2 +- lib/jblond/Diff/DiffUtils.php | 4 ++- lib/jblond/Diff/Renderer/Html/Merged.php | 4 +-- lib/jblond/Diff/Renderer/Html/SideBySide.php | 6 ++-- lib/jblond/Diff/Renderer/Html/Unified.php | 6 ++-- lib/jblond/Diff/Renderer/MainRenderer.php | 24 +++++++-------- .../Diff/Renderer/MainRendererAbstract.php | 2 +- lib/jblond/Diff/Renderer/Text/Context.php | 2 +- lib/jblond/Diff/Renderer/Text/InlineCli.php | 4 +-- lib/jblond/Diff/SequenceMatcher.php | 30 +++++++++---------- lib/jblond/Diff/Similarity.php | 14 ++++----- .../Diff/Renderer/Html/HtmlRenderersTest.php | 6 ++-- tests/Diff/Renderer/MainRendererTest.php | 8 ++--- .../Diff/Renderer/Text/TextRenderersTest.php | 8 ++--- tests/Diff/SequenceMatcherTest.php | 17 ++++++----- tests/Diff/SimilarityTest.php | 2 +- 18 files changed, 76 insertions(+), 77 deletions(-) diff --git a/example/cli.php b/example/cli.php index 8b3ea7de..6c456acd 100644 --- a/example/cli.php +++ b/example/cli.php @@ -6,7 +6,7 @@ use jblond\Diff\Renderer\Text\UnifiedCli; // Validate the interpreter. -if (php_sapi_name() !== 'cli') { +if (PHP_SAPI !== 'cli') { echo 'This script demonstrates console support for the php-diff package.
'; echo 'Please execute it from a cli interpreter.'; throw new RuntimeException('Script for CLI use only!'); @@ -17,8 +17,8 @@ require '../vendor/autoload.php'; // Include two sample files for comparison. -$sampleA = file_get_contents(dirname(__FILE__) . '/a.txt'); -$sampleB = file_get_contents(dirname(__FILE__) . '/b.txt'); +$sampleA = file_get_contents(__DIR__ . '/a.txt'); +$sampleB = file_get_contents(__DIR__ . '/b.txt'); $customOptions = [ 'context' => 2, diff --git a/example/example.php b/example/example.php index e4d7ed04..04c0deb9 100644 --- a/example/example.php +++ b/example/example.php @@ -11,8 +11,8 @@ require '../vendor/autoload.php'; // Include two sample files for comparison. -$sampleA = file_get_contents(dirname(__FILE__) . '/a.txt'); -$sampleB = file_get_contents(dirname(__FILE__) . '/b.txt'); +$sampleA = file_get_contents(__DIR__ . '/a.txt'); +$sampleB = file_get_contents(__DIR__ . '/b.txt'); // Options for generating the diff. $diffOptions = [ @@ -20,7 +20,7 @@ 'trimEqual' => false, 'ignoreWhitespace' => true, 'ignoreCase' => true, - 'ignoreLines' => Diff::DIFF_IGNORE_LINE_EMPTY, + 'ignoreLines' => Diff\ConstantsInterface::DIFF_IGNORE_LINE_EMPTY, ]; // Choose one of the initializations. @@ -29,7 +29,7 @@ // Options for rendering the diff. $rendererOptions = [ - 'inlineMarking' => $_GET['inlineMarking'] ?? Diff\Renderer\MainRenderer::CHANGE_LEVEL_LINE, + 'inlineMarking' => $_GET['inlineMarking'] ?? Diff\Renderer\MainRendererAbstract::CHANGE_LEVEL_LINE, ] ?> diff --git a/lib/jblond/Diff.php b/lib/jblond/Diff.php index 86c4350e..9e1cf536 100644 --- a/lib/jblond/Diff.php +++ b/lib/jblond/Diff.php @@ -148,7 +148,7 @@ public function getArgumentType($var): int * When a keyName matches the name of a default option, that option's value will be overridden by the key's value. * Any other keyName (and it's value) will be added as an option, but will not be used if not implemented. */ - public function setOptions(array $options) + public function setOptions(array $options): void { $this->options = array_merge($this->defaultOptions, $options); } diff --git a/lib/jblond/Diff/DiffUtils.php b/lib/jblond/Diff/DiffUtils.php index 0dee1f0c..76fe272e 100644 --- a/lib/jblond/Diff/DiffUtils.php +++ b/lib/jblond/Diff/DiffUtils.php @@ -30,7 +30,9 @@ public static function tupleSort(array $aArray, array $bArray): int for ($counter = 0; $counter < $max; ++$counter) { if ($aArray[$counter] < $bArray[$counter]) { return -1; - } elseif ($aArray[$counter] > $bArray[$counter]) { + } + + if ($aArray[$counter] > $bArray[$counter]) { return 1; } } diff --git a/lib/jblond/Diff/Renderer/Html/Merged.php b/lib/jblond/Diff/Renderer/Html/Merged.php index 5b20e811..e7e87428 100644 --- a/lib/jblond/Diff/Renderer/Html/Merged.php +++ b/lib/jblond/Diff/Renderer/Html/Merged.php @@ -62,9 +62,9 @@ public function __construct(array $options = []) */ public function render() { - $changes = parent::renderSequences(); + $changes = $this->renderSequences(); - return parent::renderOutput($changes, $this); + return $this->renderOutput($changes, $this); } /** diff --git a/lib/jblond/Diff/Renderer/Html/SideBySide.php b/lib/jblond/Diff/Renderer/Html/SideBySide.php index 9fddd544..dc3026e8 100644 --- a/lib/jblond/Diff/Renderer/Html/SideBySide.php +++ b/lib/jblond/Diff/Renderer/Html/SideBySide.php @@ -60,9 +60,9 @@ public function __construct(array $options = []) */ public function render() { - $changes = parent::renderSequences(); + $changes = $this->renderSequences(); - return parent::renderOutput($changes, $this); + return $this->renderOutput($changes, $this); } /** @@ -284,7 +284,7 @@ public function generateDiffFooter(): string } /** - * @inheritDoc + * * * @return string Html code representing table rows showing ignored text. */ diff --git a/lib/jblond/Diff/Renderer/Html/Unified.php b/lib/jblond/Diff/Renderer/Html/Unified.php index df1b3cff..59c5f98d 100644 --- a/lib/jblond/Diff/Renderer/Html/Unified.php +++ b/lib/jblond/Diff/Renderer/Html/Unified.php @@ -60,9 +60,9 @@ public function __construct(array $options = []) */ public function render() { - $changes = parent::renderSequences(); + $changes = $this->renderSequences(); - return parent::renderOutput($changes, $this); + return $this->renderOutput($changes, $this); } /** @@ -220,7 +220,7 @@ public function generateLinesReplace(array $changes): string } /** - * @inheritDoc + * * * @return string Html code representing table rows showing modified text. */ diff --git a/lib/jblond/Diff/Renderer/MainRenderer.php b/lib/jblond/Diff/Renderer/MainRenderer.php index 4ee80d44..d5a23eb7 100644 --- a/lib/jblond/Diff/Renderer/MainRenderer.php +++ b/lib/jblond/Diff/Renderer/MainRenderer.php @@ -68,9 +68,9 @@ public function renderOutput(array $changes, object $subRenderer) $deprecationTriggered = false; foreach ($blocks as $change) { if ( - $subRenderer instanceof MainRenderer && + $subRenderer instanceof self && !method_exists($subRenderer, 'generateLinesIgnore') && - $change['tag'] == 'ignore' + $change['tag'] === 'ignore' ) { if (!$deprecationTriggered) { trigger_error( @@ -157,7 +157,7 @@ protected function renderSequences(): array $blockSizeOld = $endOld - $startOld; $blockSizeNew = $endNew - $startNew; - if (($tag == 'replace') && ($blockSizeOld == $blockSizeNew)) { + if (($tag === 'replace') && ($blockSizeOld == $blockSizeNew)) { // Inline differences between old and new block. $this->markInlineChanges($oldText, $newText, $startOld, $endOld, $startNew); } @@ -168,14 +168,14 @@ protected function renderSequences(): array $oldBlock = $this->formatLines(array_slice($oldText, $startOld, $blockSizeOld)); $newBlock = $this->formatLines(array_slice($newText, $startNew, $blockSizeNew)); - if ($tag != 'delete' && $tag != 'insert') { + if ($tag !== 'delete' && $tag !== 'insert') { // Old block "equals" New block or is replaced. $blocks[$lastBlock]['base']['lines'] += $oldBlock; $blocks[$lastBlock]['changed']['lines'] += $newBlock; continue; } - if ($tag == 'delete') { + if ($tag === 'delete') { // Block of version1 doesn't exist in version2. $blocks[$lastBlock]['base']['lines'] += $oldBlock; continue; @@ -266,14 +266,14 @@ private function markInnerChange(array &$oldText, array &$newText, int $startOld foreach ($opCodes as $group) { foreach ($group as [$tag, $changeStartOld, $changeEndOld, $changeStartNew, $changeEndNew]) { - if ($tag == 'equal') { + if ($tag === 'equal') { continue; } - if ($tag == 'replace' || $tag == 'delete') { + if ($tag === 'replace' || $tag === 'delete') { $oldLine[$changeStartOld] = "\0" . $oldLine[$changeStartOld]; $oldLine[$changeEndOld] = "\1" . $oldLine[$changeEndOld]; } - if ($tag == 'replace' || $tag == 'insert') { + if ($tag === 'replace' || $tag === 'insert') { $newLine[$changeStartNew] = "\0" . $newLine[$changeStartNew]; $newLine[$changeEndNew] = "\1" . $newLine[$changeEndNew]; } @@ -380,7 +380,7 @@ private function getOuterChange(string $oldString, string $newString): array } $end = -1; - $limit = $limit - $start; + $limit -= $start; // Find the position of the last character which is different between old and new. // Starts at the end of the shortest string. @@ -453,10 +453,10 @@ function ($line) { ); } - if (strtolower($this->options['format']) == 'html') { + if (strtolower($this->options['format']) === 'html') { // Convert special characters to HTML entities $strings = array_map( - function ($line) { + static function ($line) { return htmlspecialchars($line, ENT_NOQUOTES); }, $strings @@ -466,7 +466,7 @@ function ($line) { foreach ($strings as &$line) { $line = preg_replace_callback( '/(^[ \0\1]*)/', - function ($matches) { + static function ($matches) { return str_replace(' ', ' ', $matches[0]); }, $line diff --git a/lib/jblond/Diff/Renderer/MainRendererAbstract.php b/lib/jblond/Diff/Renderer/MainRendererAbstract.php index 4cedfcb9..b45f089a 100644 --- a/lib/jblond/Diff/Renderer/MainRendererAbstract.php +++ b/lib/jblond/Diff/Renderer/MainRendererAbstract.php @@ -95,7 +95,7 @@ public function __construct(array $options = []) * @see MainRendererAbstract::$mainOptions * */ - public function setOptions(array $options) + public function setOptions(array $options): void { $this->options = array_merge($this->mainOptions, $this->options, $options); } diff --git a/lib/jblond/Diff/Renderer/Text/Context.php b/lib/jblond/Diff/Renderer/Text/Context.php index c9523593..812cce8e 100644 --- a/lib/jblond/Diff/Renderer/Text/Context.php +++ b/lib/jblond/Diff/Renderer/Text/Context.php @@ -110,7 +110,7 @@ private function filterGroups(array $groups, string $excludedTag): array { return array_filter( $groups, - function ($operation) use ($excludedTag) { + static function ($operation) use ($excludedTag) { return $operation[0] != $excludedTag; } ); diff --git a/lib/jblond/Diff/Renderer/Text/InlineCli.php b/lib/jblond/Diff/Renderer/Text/InlineCli.php index d5167379..6580eba2 100644 --- a/lib/jblond/Diff/Renderer/Text/InlineCli.php +++ b/lib/jblond/Diff/Renderer/Text/InlineCli.php @@ -48,9 +48,9 @@ public function __construct(array $options = []) */ public function render() { - $changes = parent::renderSequences(); + $changes = $this->renderSequences(); - return parent::renderOutput($changes, $this); + return $this->renderOutput($changes, $this); } diff --git a/lib/jblond/Diff/SequenceMatcher.php b/lib/jblond/Diff/SequenceMatcher.php index 73ce32c6..27ce2ca7 100644 --- a/lib/jblond/Diff/SequenceMatcher.php +++ b/lib/jblond/Diff/SequenceMatcher.php @@ -102,7 +102,7 @@ public function __construct($old, $new, array $options = [], $junkCallback = nul /** * @param array $options */ - public function setOptions(array $options) + public function setOptions(array $options): void { if (isset($options['context']) && $options['context'] < 0) { throw new InvalidArgumentException('The context option cannot be a negative value!'); @@ -115,8 +115,9 @@ public function setOptions(array $options) * * @param string|array $version1 A string or array containing the lines to compare against. * @param string|array $version2 A string or array containing the lines to compare. + * @return void */ - public function setSequences($version1, $version2) + public function setSequences($version1, $version2): void { $this->setSeq1($version1); $this->setSeq2($version2); @@ -127,9 +128,10 @@ public function setSequences($version1, $version2) * * Also resets internal caches to indicate that, when calling the calculation methods, we need to recalculate them. * - * @param string|array $version1 The sequence to set as the first sequence. + * @param string|array|void $version1 The sequence to set as the first sequence. + * @return void */ - public function setSeq1($version1) + public function setSeq1($version1): void { if (!is_array($version1)) { $version1 = str_split($version1); @@ -148,7 +150,7 @@ public function setSeq1($version1) * * Also resets internal caches to indicate that, when calling the calculation methods, we need to recalculate them. * - * @param string|array $version2 The sequence to set as the second sequence. + * @param string|array|void $version2 The sequence to set as the second sequence. */ public function setSeq2($version2) { @@ -169,14 +171,14 @@ public function setSeq2($version2) * Generate the internal arrays containing the list of junk and non-junk * characters for the second ($b) sequence. */ - private function chainB() + private function chainB(): void { $length = count($this->new); $this->b2j = []; $popularDict = []; - for ($i = 0; $i < $length; ++$i) { - $char = $this->new[$i]; + foreach ($this->new as $i => $iValue) { + $char = $iValue; if (isset($this->b2j[$char])) { if ($length >= 200 && count($this->b2j[$char]) * 100 > $length) { $popularDict[$char] = 1; @@ -352,13 +354,13 @@ public function getOpCodes(): array if ($this->options['ignoreLines'] == 2) { array_walk( $slice1, - function (&$line) { + static function (&$line) { $line = trim($line); } ); array_walk( $slice2, - function (&$line) { + static function (&$line) { $line = trim($line); } ); @@ -461,7 +463,7 @@ public function getMatchingBlocks(): array usort( $matchingBlocks, - function ($aArray, $bArray) { + static function ($aArray, $bArray) { return DiffUtils::tupleSort($aArray, $bArray); } ); @@ -647,10 +649,6 @@ public function linesAreDifferent(int $aIndex, int $bIndex): bool $lineB = strtolower($lineB); } - if ($lineA != $lineB) { - return true; - } - - return false; + return $lineA != $lineB; } } diff --git a/lib/jblond/Diff/Similarity.php b/lib/jblond/Diff/Similarity.php index 1b8a3070..77a205d8 100644 --- a/lib/jblond/Diff/Similarity.php +++ b/lib/jblond/Diff/Similarity.php @@ -47,7 +47,7 @@ class Similarity extends SequenceMatcher /** * @inheritDoc */ - public function setSeq2($version2) + public function setSeq2($version2): void { $this->uniqueCount2 = null; parent::setSeq2($version2); @@ -147,18 +147,16 @@ private function getRatioFast(): float if ($this->uniqueCount2 === null) { // Build unless cached. $this->uniqueCount2 = []; - $bLength = count($this->new); - for ($iterator = 0; $iterator < $bLength; ++$iterator) { - $char = $this->new[$iterator]; + foreach ($this->new as $iteratorValue) { + $char = $iteratorValue; $this->uniqueCount2[$char] = ($this->uniqueCount2[$char] ?? 0) + 1; } } $avail = []; $matches = 0; - $aLength = count($this->old); - for ($iterator = 0; $iterator < $aLength; ++$iterator) { - $char = $this->old[$iterator]; + foreach ($this->old as $iteratorValue) { + $char = $iteratorValue; $numb = $avail[$char] ?? ($this->uniqueCount2[$char] ?? 0); $avail[$char] = $numb - 1; if ($numb > 0) { @@ -189,7 +187,7 @@ private function calculateRatio(int $matches, int $length = 0): float return $returnValue; } - private function restoreLines() + private function restoreLines(): void { foreach (['old', 'new'] as $version) { foreach ($this->stripped[$version] as $index => $line) { diff --git a/tests/Diff/Renderer/Html/HtmlRenderersTest.php b/tests/Diff/Renderer/Html/HtmlRenderersTest.php index 3054e6de..4df97271 100644 --- a/tests/Diff/Renderer/Html/HtmlRenderersTest.php +++ b/tests/Diff/Renderer/Html/HtmlRenderersTest.php @@ -48,7 +48,7 @@ public function __construct($name = null, array $data = [], $dataName = '') * * @covers \jblond\Diff\Renderer\Html\SideBySide */ - public function testSideBySide() + public function testSideBySide(): void { $diff = new Diff( file_get_contents('tests/resources/a.txt'), @@ -69,7 +69,7 @@ public function testSideBySide() * * @covers \jblond\Diff\Renderer\Html\Merged */ - public function testMerged() + public function testMerged(): void { $diff = new Diff( file_get_contents('tests/resources/a.txt'), @@ -90,7 +90,7 @@ public function testMerged() * * @covers \jblond\Diff\Renderer\Html\Unified */ - public function testUnified() + public function testUnified(): void { $diff = new Diff( file_get_contents('tests/resources/a.txt'), diff --git a/tests/Diff/Renderer/MainRendererTest.php b/tests/Diff/Renderer/MainRendererTest.php index 67719d97..2ffc33e4 100644 --- a/tests/Diff/Renderer/MainRendererTest.php +++ b/tests/Diff/Renderer/MainRendererTest.php @@ -44,7 +44,7 @@ class MainRendererTest extends TestCase /** * Test if a sequence of version1 which is removed from version2 is caught by the MainRenderer. */ - public function testRenderSimpleDelete() + public function testRenderSimpleDelete(): void { $renderer = new MainRenderer(); $renderer->diff = new Diff(['a'], []); @@ -92,7 +92,7 @@ public function invokeMethod(object $object, string $methodName, array $paramete /** * Test if leading spaces of a sequence are replaced with html entities. */ - public function testRenderFixesSpaces() + public function testRenderFixesSpaces(): void { $renderer = new MainRenderer($this->rendererOptions); $renderer->diff = new Diff( @@ -130,7 +130,7 @@ public function testRenderFixesSpaces() * * @throws ReflectionException When invoking the method fails. */ - public function testMarkOuterChange() + public function testMarkOuterChange(): void { $renderer = new MainRenderer(); $text1 = ['one two three four']; @@ -150,7 +150,7 @@ public function testMarkOuterChange() * * @throws ReflectionException When invoking the method fails. */ - public function testMarkInnerChange() + public function testMarkInnerChange(): void { $renderer = new MainRenderer(); diff --git a/tests/Diff/Renderer/Text/TextRenderersTest.php b/tests/Diff/Renderer/Text/TextRenderersTest.php index 016c6076..337eab36 100644 --- a/tests/Diff/Renderer/Text/TextRenderersTest.php +++ b/tests/Diff/Renderer/Text/TextRenderersTest.php @@ -47,7 +47,7 @@ public function __construct($name = null, array $data = [], $dataName = '') * * @covers \jblond\Diff\Renderer\Text\Context */ - public function testContext() + public function testContext(): void { $diff = new Diff( file_get_contents('tests/resources/a.txt'), @@ -68,7 +68,7 @@ public function testContext() * * @covers \jblond\Diff\Renderer\Text\Unified */ - public function testUnified() + public function testUnified(): void { $diff = new Diff( file_get_contents('tests/resources/a.txt'), @@ -89,7 +89,7 @@ public function testUnified() * * @covers \jblond\Diff\Renderer\Text\UnifiedCli */ - public function testUnifiedCli() + public function testUnifiedCli(): void { $diff = new Diff( file_get_contents('tests/resources/a.txt'), @@ -109,7 +109,7 @@ public function testUnifiedCli() * * @covers \jblond\Diff\Renderer\Text\InlineCli */ - public function testInlineCli() + public function testInlineCli(): void { $diff = new Diff( file_get_contents('tests/resources/a.txt'), diff --git a/tests/Diff/SequenceMatcherTest.php b/tests/Diff/SequenceMatcherTest.php index 3900a145..47a40134 100644 --- a/tests/Diff/SequenceMatcherTest.php +++ b/tests/Diff/SequenceMatcherTest.php @@ -2,6 +2,7 @@ namespace Tests\Diff; +use jblond\Diff\ConstantsInterface; use jblond\Diff\SequenceMatcher; use PHPUnit\Framework\TestCase; @@ -23,7 +24,7 @@ class SequenceMatcherTest extends TestCase /** * Test the opCodes of the differences between version1 and version2 with the default options. */ - public function testGetGroupedOpCodesDefault() + public function testGetGroupedOpCodesDefault(): void { // Test with default options. $sequenceMatcher = new SequenceMatcher( @@ -46,7 +47,7 @@ public function testGetGroupedOpCodesDefault() /** * Test the opCodes of the differences between version1 and version2 with option trimEqual disabled. */ - public function testGetGroupedOpCodesTrimEqualFalse() + public function testGetGroupedOpCodesTrimEqualFalse(): void { // Test with trimEqual disabled. // First and last context lines of the sequences are included. @@ -69,7 +70,7 @@ public function testGetGroupedOpCodesTrimEqualFalse() /** * Test the opCodes of the differences between version1 and version2 with option IgnoreWhitespace enabled. */ - public function testGetGroupedOpCodesIgnoreWhitespaceTrue() + public function testGetGroupedOpCodesIgnoreWhitespaceTrue(): void { // Test with ignoreWhitespace enabled. Both sequences are considered to be the same. // Note: The sequenceMatcher evaluates the string character by character. Option ignoreWhitespace will ignore @@ -86,7 +87,7 @@ public function testGetGroupedOpCodesIgnoreWhitespaceTrue() /** * Test the opCodes of the differences between version1 and version2 with option ignoreCase enabled. */ - public function testGetGroupedOpCodesIgnoreCaseTrue() + public function testGetGroupedOpCodesIgnoreCaseTrue(): void { // Test with ignoreCase enabled. Both sequences are considered to be the same. $sequenceMatcher = new SequenceMatcher( @@ -101,13 +102,13 @@ public function testGetGroupedOpCodesIgnoreCaseTrue() /** * Test the opCodes of the differences between version1 and version2 with option ignoreLines set to empty. */ - public function testGetGroupedOpCodesIgnoreLinesEmpty() + public function testGetGroupedOpCodesIgnoreLinesEmpty(): void { // Test with ignoreCase enabled. Both sequences are considered to be the same. $sequenceMatcher = new SequenceMatcher( [0, 1, 2, 3], [0, 1, '', 2, 3], - ['ignoreLines' => SequenceMatcher::DIFF_IGNORE_LINE_EMPTY] + ['ignoreLines' => ConstantsInterface::DIFF_IGNORE_LINE_EMPTY] ); $this->assertEquals( @@ -125,13 +126,13 @@ public function testGetGroupedOpCodesIgnoreLinesEmpty() /** * Test the opCodes of the differences between version1 and version2 with option ignoreLines set to blank. */ - public function testGetGroupedOpCodesIgnoreLinesBlank() + public function testGetGroupedOpCodesIgnoreLinesBlank(): void { // Test with ignoreCase enabled. Both sequences are considered to be the same. $sequenceMatcher = new SequenceMatcher( [0, 1, 2, 3], [0, 1, "\t", 2, 3], - ['ignoreLines' => SequenceMatcher::DIFF_IGNORE_LINE_BLANK] + ['ignoreLines' => ConstantsInterface::DIFF_IGNORE_LINE_BLANK] ); $this->assertEquals( diff --git a/tests/Diff/SimilarityTest.php b/tests/Diff/SimilarityTest.php index 410a6fe9..ea4701e0 100644 --- a/tests/Diff/SimilarityTest.php +++ b/tests/Diff/SimilarityTest.php @@ -23,7 +23,7 @@ class SimilarityTest extends TestCase /** * Test the similarity ratio between two sequences with different methods. */ - public function testGetSimilarity() + public function testGetSimilarity(): void { $similarity = new Similarity(range(1, 10), range(1, 5)); From 962623ddacbae5c88c0dec1574fec94dc2660a8f Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 27 Oct 2021 10:25:13 +0200 Subject: [PATCH 02/46] Fix phpdoc and return type --- lib/jblond/Diff/SequenceMatcher.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/jblond/Diff/SequenceMatcher.php b/lib/jblond/Diff/SequenceMatcher.php index 27ce2ca7..01a9da51 100644 --- a/lib/jblond/Diff/SequenceMatcher.php +++ b/lib/jblond/Diff/SequenceMatcher.php @@ -150,9 +150,10 @@ public function setSeq1($version1): void * * Also resets internal caches to indicate that, when calling the calculation methods, we need to recalculate them. * - * @param string|array|void $version2 The sequence to set as the second sequence. + * @param string|array $version2 The sequence to set as the second sequence. + * @return void */ - public function setSeq2($version2) + public function setSeq2($version2): void { if (!is_array($version2)) { $version2 = str_split($version2); From 013918b0eb90b8b49bef58cfda9aa7ae31f979d7 Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 27 Oct 2021 10:46:57 +0200 Subject: [PATCH 03/46] Revert changes suggested by DigiLive --- lib/jblond/Diff/Renderer/Html/Merged.php | 2 +- lib/jblond/Diff/Renderer/Html/SideBySide.php | 2 +- lib/jblond/Diff/Renderer/Html/Unified.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/jblond/Diff/Renderer/Html/Merged.php b/lib/jblond/Diff/Renderer/Html/Merged.php index e7e87428..cc976ecb 100644 --- a/lib/jblond/Diff/Renderer/Html/Merged.php +++ b/lib/jblond/Diff/Renderer/Html/Merged.php @@ -62,7 +62,7 @@ public function __construct(array $options = []) */ public function render() { - $changes = $this->renderSequences(); + $changes = parent::renderSequences(); return $this->renderOutput($changes, $this); } diff --git a/lib/jblond/Diff/Renderer/Html/SideBySide.php b/lib/jblond/Diff/Renderer/Html/SideBySide.php index dc3026e8..0e7c0d3c 100644 --- a/lib/jblond/Diff/Renderer/Html/SideBySide.php +++ b/lib/jblond/Diff/Renderer/Html/SideBySide.php @@ -60,7 +60,7 @@ public function __construct(array $options = []) */ public function render() { - $changes = $this->renderSequences(); + $changes = parent::renderSequences(); return $this->renderOutput($changes, $this); } diff --git a/lib/jblond/Diff/Renderer/Html/Unified.php b/lib/jblond/Diff/Renderer/Html/Unified.php index 59c5f98d..75c72942 100644 --- a/lib/jblond/Diff/Renderer/Html/Unified.php +++ b/lib/jblond/Diff/Renderer/Html/Unified.php @@ -60,7 +60,7 @@ public function __construct(array $options = []) */ public function render() { - $changes = $this->renderSequences(); + $changes = parent::renderSequences(); return $this->renderOutput($changes, $this); } From 3486ace2438829649c79df221368d1b929e4303a Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 27 Oct 2021 10:48:47 +0200 Subject: [PATCH 04/46] Revert changes suggested by DigiLive --- example/example.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/example.php b/example/example.php index 04c0deb9..c619eb60 100644 --- a/example/example.php +++ b/example/example.php @@ -20,7 +20,7 @@ 'trimEqual' => false, 'ignoreWhitespace' => true, 'ignoreCase' => true, - 'ignoreLines' => Diff\ConstantsInterface::DIFF_IGNORE_LINE_EMPTY, + 'ignoreLines' => Diff::DIFF_IGNORE_LINE_EMPTY, ]; // Choose one of the initializations. From 2ebc3efdb37e6751ecf81223840c4099c546027d Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 27 Oct 2021 10:51:19 +0200 Subject: [PATCH 05/46] Remove no longer working sensio labs --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3ad115ef..631f2d3b 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # PHP Diff Class -[![SensioLabsInsight](https://insight.sensiolabs.com/projects/aa609edb-cdb1-45cf-ad51-afbdab48f6a1/mini.png)](https://insight.sensiolabs.com/projects/aa609edb-cdb1-45cf-ad51-afbdab48f6a1) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/db5f8d57b1234502aeb852afc87e0dfe)](https://www.codacy.com/app/leet31337/php-diff) - -[![Latest Version](https://img.shields.io/github/release/JBlond/php-diff.svg?style=flat-square&label=Release)](https://github.com/JBlond/php-diff/releases) [![Packagist Installs](https://badgen.net/packagist/dt/JBlond/php-diff)](https://packagist.org/packages/jblond/php-diff) +[[![Codacy Badge](https://api.codacy.com/project/badge/Grade/db5f8d57b1234502aeb852afc87e0dfe)](https://www.codacy.com/app/leet31337/php-diff) +[![Latest Version](https://img.shields.io/github/release/JBlond/php-diff.svg?style=flat-square&label=Release)](https://github.com/JBlond/php-diff/releases) +[![Packagist Installs](https://badgen.net/packagist/dt/JBlond/php-diff)](https://packagist.org/packages/jblond/php-diff) ## Introduction From 07a75ba1b62dfd0134a73f89278158c2b603c54b Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 27 Oct 2021 10:55:24 +0200 Subject: [PATCH 06/46] Revert PHPDoc changes --- lib/jblond/Diff/Renderer/Html/SideBySide.php | 2 +- lib/jblond/Diff/Renderer/Html/Unified.php | 2 +- tests/Diff/SequenceMatcherTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/jblond/Diff/Renderer/Html/SideBySide.php b/lib/jblond/Diff/Renderer/Html/SideBySide.php index 0e7c0d3c..30e23116 100644 --- a/lib/jblond/Diff/Renderer/Html/SideBySide.php +++ b/lib/jblond/Diff/Renderer/Html/SideBySide.php @@ -284,7 +284,7 @@ public function generateDiffFooter(): string } /** - * + * @inheritDoc * * @return string Html code representing table rows showing ignored text. */ diff --git a/lib/jblond/Diff/Renderer/Html/Unified.php b/lib/jblond/Diff/Renderer/Html/Unified.php index 75c72942..aa8aafa9 100644 --- a/lib/jblond/Diff/Renderer/Html/Unified.php +++ b/lib/jblond/Diff/Renderer/Html/Unified.php @@ -220,7 +220,7 @@ public function generateLinesReplace(array $changes): string } /** - * + * @inheritDoc * * @return string Html code representing table rows showing modified text. */ diff --git a/tests/Diff/SequenceMatcherTest.php b/tests/Diff/SequenceMatcherTest.php index 47a40134..92192f1e 100644 --- a/tests/Diff/SequenceMatcherTest.php +++ b/tests/Diff/SequenceMatcherTest.php @@ -108,7 +108,7 @@ public function testGetGroupedOpCodesIgnoreLinesEmpty(): void $sequenceMatcher = new SequenceMatcher( [0, 1, 2, 3], [0, 1, '', 2, 3], - ['ignoreLines' => ConstantsInterface::DIFF_IGNORE_LINE_EMPTY] + ['ignoreLines' => SequenceMatcher::DIFF_IGNORE_LINE_EMPTY] ); $this->assertEquals( From 63b7366111dfb3fc8aab71216fe4404b080d1e70 Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 27 Oct 2021 11:00:16 +0200 Subject: [PATCH 07/46] Revert strict comparison --- example/example.php | 2 +- lib/jblond/Diff/Renderer/MainRenderer.php | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example/example.php b/example/example.php index c619eb60..ba2cf80d 100644 --- a/example/example.php +++ b/example/example.php @@ -29,7 +29,7 @@ // Options for rendering the diff. $rendererOptions = [ - 'inlineMarking' => $_GET['inlineMarking'] ?? Diff\Renderer\MainRendererAbstract::CHANGE_LEVEL_LINE, + 'inlineMarking' => $_GET['inlineMarking'] ?? Diff\Renderer\MainRenderer::CHANGE_LEVEL_LINE, ] ?> diff --git a/lib/jblond/Diff/Renderer/MainRenderer.php b/lib/jblond/Diff/Renderer/MainRenderer.php index d5a23eb7..2100cdcf 100644 --- a/lib/jblond/Diff/Renderer/MainRenderer.php +++ b/lib/jblond/Diff/Renderer/MainRenderer.php @@ -70,7 +70,7 @@ public function renderOutput(array $changes, object $subRenderer) if ( $subRenderer instanceof self && !method_exists($subRenderer, 'generateLinesIgnore') && - $change['tag'] === 'ignore' + $change['tag'] == 'ignore' ) { if (!$deprecationTriggered) { trigger_error( @@ -157,7 +157,7 @@ protected function renderSequences(): array $blockSizeOld = $endOld - $startOld; $blockSizeNew = $endNew - $startNew; - if (($tag === 'replace') && ($blockSizeOld == $blockSizeNew)) { + if (($tag == 'replace') && ($blockSizeOld == $blockSizeNew)) { // Inline differences between old and new block. $this->markInlineChanges($oldText, $newText, $startOld, $endOld, $startNew); } @@ -168,14 +168,14 @@ protected function renderSequences(): array $oldBlock = $this->formatLines(array_slice($oldText, $startOld, $blockSizeOld)); $newBlock = $this->formatLines(array_slice($newText, $startNew, $blockSizeNew)); - if ($tag !== 'delete' && $tag !== 'insert') { + if ($tag != 'delete' && $tag != 'insert') { // Old block "equals" New block or is replaced. $blocks[$lastBlock]['base']['lines'] += $oldBlock; $blocks[$lastBlock]['changed']['lines'] += $newBlock; continue; } - if ($tag === 'delete') { + if ($tag == 'delete') { // Block of version1 doesn't exist in version2. $blocks[$lastBlock]['base']['lines'] += $oldBlock; continue; @@ -266,14 +266,14 @@ private function markInnerChange(array &$oldText, array &$newText, int $startOld foreach ($opCodes as $group) { foreach ($group as [$tag, $changeStartOld, $changeEndOld, $changeStartNew, $changeEndNew]) { - if ($tag === 'equal') { + if ($tag == 'equal') { continue; } - if ($tag === 'replace' || $tag === 'delete') { + if ($tag == 'replace' || $tag == 'delete') { $oldLine[$changeStartOld] = "\0" . $oldLine[$changeStartOld]; $oldLine[$changeEndOld] = "\1" . $oldLine[$changeEndOld]; } - if ($tag === 'replace' || $tag === 'insert') { + if ($tag == 'replace' || $tag == 'insert') { $newLine[$changeStartNew] = "\0" . $newLine[$changeStartNew]; $newLine[$changeEndNew] = "\1" . $newLine[$changeEndNew]; } @@ -453,7 +453,7 @@ function ($line) { ); } - if (strtolower($this->options['format']) === 'html') { + if (strtolower($this->options['format']) == 'html') { // Convert special characters to HTML entities $strings = array_map( static function ($line) { From 5bcf6051bf81721ad35f62becd62f76b9e047152 Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 27 Oct 2021 11:05:52 +0200 Subject: [PATCH 08/46] Revert Parent class changes --- lib/jblond/Diff/Renderer/MainRenderer.php | 2 +- tests/Diff/SequenceMatcherTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/jblond/Diff/Renderer/MainRenderer.php b/lib/jblond/Diff/Renderer/MainRenderer.php index 2100cdcf..76a5dcfa 100644 --- a/lib/jblond/Diff/Renderer/MainRenderer.php +++ b/lib/jblond/Diff/Renderer/MainRenderer.php @@ -68,7 +68,7 @@ public function renderOutput(array $changes, object $subRenderer) $deprecationTriggered = false; foreach ($blocks as $change) { if ( - $subRenderer instanceof self && + $subRenderer instanceof MainRenderer && !method_exists($subRenderer, 'generateLinesIgnore') && $change['tag'] == 'ignore' ) { diff --git a/tests/Diff/SequenceMatcherTest.php b/tests/Diff/SequenceMatcherTest.php index 92192f1e..787f8a30 100644 --- a/tests/Diff/SequenceMatcherTest.php +++ b/tests/Diff/SequenceMatcherTest.php @@ -132,7 +132,7 @@ public function testGetGroupedOpCodesIgnoreLinesBlank(): void $sequenceMatcher = new SequenceMatcher( [0, 1, 2, 3], [0, 1, "\t", 2, 3], - ['ignoreLines' => ConstantsInterface::DIFF_IGNORE_LINE_BLANK] + ['ignoreLines' => SequenceMatcher::DIFF_IGNORE_LINE_BLANK] ); $this->assertEquals( From bf8ec7db375d1cc65a64ce87eb77b8ed300a420e Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 27 Oct 2021 14:14:13 +0200 Subject: [PATCH 09/46] Revert to parent call --- lib/jblond/Diff/Renderer/Html/Merged.php | 2 +- lib/jblond/Diff/Renderer/Html/SideBySide.php | 2 +- lib/jblond/Diff/Renderer/Html/Unified.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/jblond/Diff/Renderer/Html/Merged.php b/lib/jblond/Diff/Renderer/Html/Merged.php index cc976ecb..5b20e811 100644 --- a/lib/jblond/Diff/Renderer/Html/Merged.php +++ b/lib/jblond/Diff/Renderer/Html/Merged.php @@ -64,7 +64,7 @@ public function render() { $changes = parent::renderSequences(); - return $this->renderOutput($changes, $this); + return parent::renderOutput($changes, $this); } /** diff --git a/lib/jblond/Diff/Renderer/Html/SideBySide.php b/lib/jblond/Diff/Renderer/Html/SideBySide.php index 30e23116..9fddd544 100644 --- a/lib/jblond/Diff/Renderer/Html/SideBySide.php +++ b/lib/jblond/Diff/Renderer/Html/SideBySide.php @@ -62,7 +62,7 @@ public function render() { $changes = parent::renderSequences(); - return $this->renderOutput($changes, $this); + return parent::renderOutput($changes, $this); } /** diff --git a/lib/jblond/Diff/Renderer/Html/Unified.php b/lib/jblond/Diff/Renderer/Html/Unified.php index aa8aafa9..df1b3cff 100644 --- a/lib/jblond/Diff/Renderer/Html/Unified.php +++ b/lib/jblond/Diff/Renderer/Html/Unified.php @@ -62,7 +62,7 @@ public function render() { $changes = parent::renderSequences(); - return $this->renderOutput($changes, $this); + return parent::renderOutput($changes, $this); } /** From bc30dd0a1b0c09abdeedf86803c44c42a6414ab0 Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 27 Oct 2021 14:15:30 +0200 Subject: [PATCH 10/46] Revert to parent call --- lib/jblond/Diff/Renderer/Text/InlineCli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/jblond/Diff/Renderer/Text/InlineCli.php b/lib/jblond/Diff/Renderer/Text/InlineCli.php index 6580eba2..d5167379 100644 --- a/lib/jblond/Diff/Renderer/Text/InlineCli.php +++ b/lib/jblond/Diff/Renderer/Text/InlineCli.php @@ -48,9 +48,9 @@ public function __construct(array $options = []) */ public function render() { - $changes = $this->renderSequences(); + $changes = parent::renderSequences(); - return $this->renderOutput($changes, $this); + return parent::renderOutput($changes, $this); } From ff0bb2990cbf9349566fb1cd950627a656c21cbb Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 27 Oct 2021 14:19:13 +0200 Subject: [PATCH 11/46] Fix Readme Typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 631f2d3b..87bd71cc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # PHP Diff Class -[[![Codacy Badge](https://api.codacy.com/project/badge/Grade/db5f8d57b1234502aeb852afc87e0dfe)](https://www.codacy.com/app/leet31337/php-diff) +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/db5f8d57b1234502aeb852afc87e0dfe)](https://www.codacy.com/app/leet31337/php-diff) [![Latest Version](https://img.shields.io/github/release/JBlond/php-diff.svg?style=flat-square&label=Release)](https://github.com/JBlond/php-diff/releases) [![Packagist Installs](https://badgen.net/packagist/dt/JBlond/php-diff)](https://packagist.org/packages/jblond/php-diff) From ed1f204403c63bf2504e5003a17d46324d7ff5fd Mon Sep 17 00:00:00 2001 From: JBlond Date: Mon, 1 Nov 2021 11:05:18 +0100 Subject: [PATCH 12/46] Add statistics function for #97 --- example/example.php | 7 +++++- lib/jblond/Diff.php | 11 ++++++++++ lib/jblond/Diff/Similarity.php | 35 ++++++++++++++++++++++++++++++ tests/Diff/SequenceMatcherTest.php | 1 - tests/Diff/SimilarityTest.php | 17 +++++++++++++++ 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/example/example.php b/example/example.php index ba2cf80d..d2f03fc3 100644 --- a/example/example.php +++ b/example/example.php @@ -72,8 +72,13 @@ function changeCSS(cssFile, cssLinkIndex) {

Informational

Between the two versions, there's a getStatistics(); echo round($diff->getSimilarity(), 2) * 100; - ?>% match. + ?>% match.
+ Inserted lines:
+ Deleted lines:
+ Not modified lines:
+ Lines with replacement:

diff --git a/lib/jblond/Diff.php b/lib/jblond/Diff.php index 9e1cf536..adeccfd4 100644 --- a/lib/jblond/Diff.php +++ b/lib/jblond/Diff.php @@ -287,4 +287,15 @@ public function getSimilarity(int $method = Similarity::CALC_DEFAULT): float return $this->similarity; } + + /** + * Get diff statistics + * + * @return array + */ + public function getStatistics(): array + { + $similarity = new Similarity($this->version1, $this->version2, $this->options); + return $similarity->getDifference(); + } } diff --git a/lib/jblond/Diff/Similarity.php b/lib/jblond/Diff/Similarity.php index 77a205d8..2ac87b78 100644 --- a/lib/jblond/Diff/Similarity.php +++ b/lib/jblond/Diff/Similarity.php @@ -223,4 +223,39 @@ private function ratioReduce(int $sum, array $triple): int { return $sum + ($triple[count($triple) - 1]); } + + /** + * Get diff statistics + * + * @return array + */ + public function getDifference(): array + { + $return = [ + 'inserted' => 0, + 'deleted' => 0, + 'notModified' => 0, + 'replaced' => 0, + ]; + + foreach ($this->getGroupedOpCodes() as $chunk) { + foreach ($chunk as [$string, $one, $two, $three, $four]) { + switch ($string) { + case 'delete': + $return['deleted'] += $two - $one; + break; + case 'insert': + $return['inserted'] += $four - $three; + break; + case 'replace': + $return['replaced'] += $two - $one; + break; + } + } + } + + $return['notModified'] = count($this->old) - $return['replaced'] - $return['deleted']; + + return $return; + } } diff --git a/tests/Diff/SequenceMatcherTest.php b/tests/Diff/SequenceMatcherTest.php index 787f8a30..18073d14 100644 --- a/tests/Diff/SequenceMatcherTest.php +++ b/tests/Diff/SequenceMatcherTest.php @@ -2,7 +2,6 @@ namespace Tests\Diff; -use jblond\Diff\ConstantsInterface; use jblond\Diff\SequenceMatcher; use PHPUnit\Framework\TestCase; diff --git a/tests/Diff/SimilarityTest.php b/tests/Diff/SimilarityTest.php index ea4701e0..1d5ee8e7 100644 --- a/tests/Diff/SimilarityTest.php +++ b/tests/Diff/SimilarityTest.php @@ -31,4 +31,21 @@ public function testGetSimilarity(): void $this->assertEquals(2 / 3, $similarity->getSimilarity(Similarity::CALC_FAST)); $this->assertEquals(2 / 3, $similarity->getSimilarity(Similarity::CALC_FASTEST)); } + + /** + * Test the statistics function + */ + public function testGetDifference(): void + { + $similarity = new Similarity(range(0, 10), range(1, 23)); + $this->assertEquals( + [ + 'inserted' => 13, + 'deleted' => 1, + 'notModified' => 10, + 'replaced' => 0, + ], + $similarity->getDifference() + ); + } } From 188f25853df7c60d118e3b0a0d833bb14c9a26c8 Mon Sep 17 00:00:00 2001 From: JBlond Date: Mon, 1 Nov 2021 15:39:14 +0100 Subject: [PATCH 13/46] Add statistics function for #97 "equal" in the switch rather than "notModified" --- example/example.php | 2 +- lib/jblond/Diff/Similarity.php | 10 +++++----- tests/Diff/SimilarityTest.php | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/example/example.php b/example/example.php index d2f03fc3..8b8b6cd8 100644 --- a/example/example.php +++ b/example/example.php @@ -77,7 +77,7 @@ function changeCSS(cssFile, cssLinkIndex) { ?>% match.
Inserted lines:
Deleted lines:
- Not modified lines:
+ Not modified lines:
Lines with replacement:

diff --git a/lib/jblond/Diff/Similarity.php b/lib/jblond/Diff/Similarity.php index 2ac87b78..34b1664b 100644 --- a/lib/jblond/Diff/Similarity.php +++ b/lib/jblond/Diff/Similarity.php @@ -232,10 +232,10 @@ private function ratioReduce(int $sum, array $triple): int public function getDifference(): array { $return = [ - 'inserted' => 0, - 'deleted' => 0, - 'notModified' => 0, - 'replaced' => 0, + 'inserted' => 0, + 'deleted' => 0, + 'equal' => 0, + 'replaced' => 0, ]; foreach ($this->getGroupedOpCodes() as $chunk) { @@ -254,7 +254,7 @@ public function getDifference(): array } } - $return['notModified'] = count($this->old) - $return['replaced'] - $return['deleted']; + $return['equal'] = count($this->old) - $return['replaced'] - $return['deleted']; return $return; } diff --git a/tests/Diff/SimilarityTest.php b/tests/Diff/SimilarityTest.php index 1d5ee8e7..4d262495 100644 --- a/tests/Diff/SimilarityTest.php +++ b/tests/Diff/SimilarityTest.php @@ -42,7 +42,7 @@ public function testGetDifference(): void [ 'inserted' => 13, 'deleted' => 1, - 'notModified' => 10, + 'equal' => 10, 'replaced' => 0, ], $similarity->getDifference() From 54c0e03f08c9aa9f40368654661d03e2c75b6418 Mon Sep 17 00:00:00 2001 From: JBlond Date: Mon, 1 Nov 2021 16:39:05 +0100 Subject: [PATCH 14/46] Remove array element since it will be written a few lines later --- lib/jblond/Diff/Similarity.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/jblond/Diff/Similarity.php b/lib/jblond/Diff/Similarity.php index 34b1664b..5beb60d6 100644 --- a/lib/jblond/Diff/Similarity.php +++ b/lib/jblond/Diff/Similarity.php @@ -234,7 +234,6 @@ public function getDifference(): array $return = [ 'inserted' => 0, 'deleted' => 0, - 'equal' => 0, 'replaced' => 0, ]; From c07c8ac6fbfe20a5a1dfa55300c12a6e47b3d1ee Mon Sep 17 00:00:00 2001 From: JBlond Date: Tue, 16 Nov 2021 10:20:38 +0100 Subject: [PATCH 15/46] Add composer test command --- composer.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e8ea5228..b2602d0e 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,12 @@ "php_src": "phpcs --standard=phpcs.xml -s -p --colors ./lib/", "php_test": "phpcs --standard=phpcs.xml -s -p --colors ./tests/", "phpmd": "phpmd ./ ansi cleancode,codesize,controversial,design,naming,unusedcode --exclude vendor", - "changelog": "php generateChangelog.php" + "changelog": "php generateChangelog.php", + "test": [ + "@php_src", + "@php_test", + "phpunit --colors=always --testdox" + ] }, "scripts-descriptions": { "phpunit": "Run PHPUnit tests", From a0323ed13a0203789065de0362e4e2ea57fca126 Mon Sep 17 00:00:00 2001 From: JBlond Date: Tue, 16 Nov 2021 10:43:06 +0100 Subject: [PATCH 16/46] Add TupleSort test --- tests/Diff/DiffUtilsTest.php | 155 +++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 tests/Diff/DiffUtilsTest.php diff --git a/tests/Diff/DiffUtilsTest.php b/tests/Diff/DiffUtilsTest.php new file mode 100644 index 00000000..d69c60d5 --- /dev/null +++ b/tests/Diff/DiffUtilsTest.php @@ -0,0 +1,155 @@ + + * @author Ferry Cools + * @copyright (c) 2021 Mario Brandt + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.4.0 + * @link https://github.com/JBlond/php-diff + */ +class DiffUtilsTest extends TestCase +{ + /** + * Test the sorting of an array by the nested arrays it contains + */ + public function testTupleSort(): void + { + $this->assertEquals( + 1, + DiffUtils::tupleSort( + [ + + 0 => [ + 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', + 'title' => 'Flower', + 'order' => 3, + ], + 1 => [ + 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', + 'title' => 'Free', + 'order' => 2, + ], + + 2 => [ + 'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b', + 'title' => 'Ready', + 'order' => 1 + ] + ], + [ + + 0 => [ + 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', + 'title' => 'Flower', + 'order' => 3, + ], + 1 => [ + 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', + 'title' => 'Free', + 'order' => 2, + ], + + 2 => [ + ] + ], + ) + ); + + $this->assertEquals( + 0, + DiffUtils::tupleSort( + [ + + 0 => [ + 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', + 'title' => 'Flower', + 'order' => 3, + ], + 1 => [ + 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', + 'title' => 'Free', + 'order' => 2, + ], + + 2 => [ + 'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b', + 'title' => 'Ready', + 'order' => 1 + ] + ], + [ + + 0 => [ + 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', + 'title' => 'Flower', + 'order' => 3, + ], + 1 => [ + 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', + 'title' => 'Free', + 'order' => 2, + ], + + 2 => [ + 'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b', + 'title' => 'Ready', + 'order' => 1 + ] + ], + ) + ); + + $this->assertEquals( + -1, + DiffUtils::tupleSort( + [ + + 0 => [ + 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', + 'title' => 'Flower', + 'order' => 3, + ], + 1 => [ + 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', + 'title' => 'Free', + 'order' => 2, + ], + + 2 => [ + + ] + ], + [ + + 0 => [ + 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', + 'title' => 'Flower', + 'order' => 3, + ], + 1 => [ + 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', + 'title' => 'Free', + 'order' => 2, + ], + + 2 => [ + 'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b', + 'title' => 'Ready', + 'order' => 1 + ] + ], + ) + ); + } +} From 7b9bce94484976269832318742664dcc541c9cf6 Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 17 Nov 2021 21:33:16 +0100 Subject: [PATCH 17/46] Fix test function length --- tests/Diff/DiffUtilsTest.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/Diff/DiffUtilsTest.php b/tests/Diff/DiffUtilsTest.php index d69c60d5..b46d5597 100644 --- a/tests/Diff/DiffUtilsTest.php +++ b/tests/Diff/DiffUtilsTest.php @@ -23,7 +23,7 @@ class DiffUtilsTest extends TestCase /** * Test the sorting of an array by the nested arrays it contains */ - public function testTupleSort(): void + public function testTupleSortOne(): void { $this->assertEquals( 1, @@ -65,7 +65,13 @@ public function testTupleSort(): void ], ) ); + } + /** + * Test the sorting of an array by the nested arrays it contains + */ + public function testTupleSortZero(): void + { $this->assertEquals( 0, DiffUtils::tupleSort( @@ -109,7 +115,13 @@ public function testTupleSort(): void ], ) ); + } + /** + * Test the sorting of an array by the nested arrays it contains + */ + public function testTupleSortMinusOne(): void + { $this->assertEquals( -1, DiffUtils::tupleSort( From d0391861f476b18760ed8a3944b8c9cc05ceae94 Mon Sep 17 00:00:00 2001 From: JBlond Date: Thu, 18 Nov 2021 10:10:38 +0100 Subject: [PATCH 18/46] Add coverage test --- .gitignore | 1 + composer.json | 7 +++++-- phpunit.xml | 22 ++++++++++++++++------ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 67b315d0..ddbe8d8f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ ### Composer ### composer.phar +/codeCoverage /vendor/ /composer.lock /.phpunit.result.cache diff --git a/composer.json b/composer.json index b2602d0e..dd9b68bb 100644 --- a/composer.json +++ b/composer.json @@ -64,13 +64,16 @@ "@php_src", "@php_test", "phpunit --colors=always --testdox" - ] + ], + "coverage": "phpunit --colors=always --coverage-html codeCoverage" }, "scripts-descriptions": { "phpunit": "Run PHPUnit tests", "php_src": "Run code sniffer on lib directory", "php_test": "Run code sniffer on tests directory", "phpmd": "Run php mess detector", - "changelog": "generate changelog from commits" + "changelog": "generate changelog from commits", + "test": "Run code formatting test and phpunit", + "coverage": "Run phpunit code overage" } } diff --git a/phpunit.xml b/phpunit.xml index 8152c643..b0543e73 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,7 +1,17 @@ - - - - tests - - + + + + + ./lib + + + + + tests + + From 56ed81df3d8006f68f098c347109725205457d02 Mon Sep 17 00:00:00 2001 From: JBlond Date: Fri, 19 Nov 2021 09:44:58 +0100 Subject: [PATCH 19/46] Optimize SequenceMatcher.php sort. The native PHP sort function is sufficient. There is no need for a callback function tupleSort. --- lib/jblond/Diff/DiffUtils.php | 1 + lib/jblond/Diff/SequenceMatcher.php | 7 +------ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/jblond/Diff/DiffUtils.php b/lib/jblond/Diff/DiffUtils.php index 76fe272e..74380786 100644 --- a/lib/jblond/Diff/DiffUtils.php +++ b/lib/jblond/Diff/DiffUtils.php @@ -23,6 +23,7 @@ class DiffUtils * @param array $bArray Second array to compare. * * @return int -1, 0 or 1, as expected by the usort function. + * @deprecated */ public static function tupleSort(array $aArray, array $bArray): int { diff --git a/lib/jblond/Diff/SequenceMatcher.php b/lib/jblond/Diff/SequenceMatcher.php index 01a9da51..bf120b3d 100644 --- a/lib/jblond/Diff/SequenceMatcher.php +++ b/lib/jblond/Diff/SequenceMatcher.php @@ -462,12 +462,7 @@ public function getMatchingBlocks(): array } } - usort( - $matchingBlocks, - static function ($aArray, $bArray) { - return DiffUtils::tupleSort($aArray, $bArray); - } - ); + sort($matchingBlocks); $i1 = 0; $j1 = 0; From 0ecdd1657a694d11c6311865ec21896684d73f90 Mon Sep 17 00:00:00 2001 From: DigiLive Date: Mon, 22 Nov 2021 14:52:44 +0100 Subject: [PATCH 20/46] Keep "Out Of Context" lines in opCodes Instead of removing the lines which are out of context from the opCodes, They're now kept in the opCodes, but tagged as "outOfContext". This replaces the `generateLinesSkipped()` methods of the renderers. Other changes present like code reformatting and comments. --- lib/jblond/Diff/Renderer/Html/Merged.php | 4 +- lib/jblond/Diff/Renderer/Html/SideBySide.php | 4 +- lib/jblond/Diff/Renderer/Html/Unified.php | 4 +- lib/jblond/Diff/Renderer/MainRenderer.php | 28 +++--- .../Diff/Renderer/SubRendererInterface.php | 6 +- lib/jblond/Diff/Renderer/Text/Context.php | 8 +- lib/jblond/Diff/Renderer/Text/InlineCli.php | 4 +- lib/jblond/Diff/Renderer/Text/Unified.php | 8 +- lib/jblond/Diff/Renderer/Text/UnifiedCli.php | 13 ++- lib/jblond/Diff/SequenceMatcher.php | 92 ++++++++++--------- tests/Diff/SequenceMatcherTest.php | 2 + 11 files changed, 94 insertions(+), 79 deletions(-) diff --git a/lib/jblond/Diff/Renderer/Html/Merged.php b/lib/jblond/Diff/Renderer/Html/Merged.php index 5b20e811..1ac26263 100644 --- a/lib/jblond/Diff/Renderer/Html/Merged.php +++ b/lib/jblond/Diff/Renderer/Html/Merged.php @@ -97,9 +97,9 @@ public function generateBlockHeader(array $changes): string /** * @inheritDoc * - * @return string Representation of skipped lines. + * @return string HTML code representing table rows showing text which is 'Out Of Context' */ - public function generateSkippedLines(): string + public function generateLinesOutOfContext($change): string { $marker = '…'; $headerClass = ''; diff --git a/lib/jblond/Diff/Renderer/Html/SideBySide.php b/lib/jblond/Diff/Renderer/Html/SideBySide.php index 9fddd544..67b6e2ef 100644 --- a/lib/jblond/Diff/Renderer/Html/SideBySide.php +++ b/lib/jblond/Diff/Renderer/Html/SideBySide.php @@ -86,9 +86,9 @@ public function generateDiffHeader(): string /** * @inheritDoc * - * @return string HTML code representation of a table's header. + * @return string HTML code representing table rows showing text which is "Out Of Context" */ - public function generateSkippedLines(): string + public function generateLinesOutOfContext($change): string { return << diff --git a/lib/jblond/Diff/Renderer/Html/Unified.php b/lib/jblond/Diff/Renderer/Html/Unified.php index df1b3cff..a3128106 100644 --- a/lib/jblond/Diff/Renderer/Html/Unified.php +++ b/lib/jblond/Diff/Renderer/Html/Unified.php @@ -87,9 +87,9 @@ public function generateDiffHeader(): string /** * @inheritDoc * - * @return string HTML code representation of skipped lines. + * @return string HTML code representing table rows showing text which is 'Out Of Context' */ - public function generateSkippedLines(): string + public function generateLinesOutOfContext($change): string { return << diff --git a/lib/jblond/Diff/Renderer/MainRenderer.php b/lib/jblond/Diff/Renderer/MainRenderer.php index 76a5dcfa..6aa38b44 100644 --- a/lib/jblond/Diff/Renderer/MainRenderer.php +++ b/lib/jblond/Diff/Renderer/MainRenderer.php @@ -51,13 +51,7 @@ public function renderOutput(array $changes, object $subRenderer) $output = $subRenderer->generateDiffHeader(); - foreach ($changes as $iterator => $blocks) { - if ($iterator > 0) { - // If this is a separate block, we're condensing code to indicate a significant portion of the code - // has been collapsed as it did not change. - $output .= $subRenderer->generateSkippedLines(); - } - + foreach ($changes as $blocks) { $this->maxLineMarkerWidth = max( strlen($this->options['insertMarkers'][0]), strlen($this->options['deleteMarkers'][0]), @@ -100,6 +94,10 @@ public function renderOutput(array $changes, object $subRenderer) // TODO: Keep backward compatible with renderers? $output .= $subRenderer->generateLinesIgnore($change); break; + case 'outOfContext': + // TODO: Keep backward compatible with renderers? + $output .= $subRenderer->generateLinesOutOfContext($change); + break; } $output .= $subRenderer->generateBlockFooter($change); @@ -335,17 +333,15 @@ private function markOuterChange(array &$oldText, array &$newText, int $startOld // Changes between the lines exist. // Add markers around the changed character sequence in the old string. $sequenceEnd = mb_strlen($oldString) + $end; - $oldString - = mb_substr($oldString, 0, $start) . "\0" . - mb_substr($oldString, $start, $sequenceEnd - $start) . "\1" . - mb_substr($oldString, $sequenceEnd); + $oldString = mb_substr($oldString, 0, $start) . "\0" . + mb_substr($oldString, $start, $sequenceEnd - $start) . "\1" . + mb_substr($oldString, $sequenceEnd); // Add markers around the changed character sequence in the new string. $sequenceEnd = mb_strlen($newString) + $end; - $newString - = mb_substr($newString, 0, $start) . "\0" . - mb_substr($newString, $start, $sequenceEnd - $start) . "\1" . - mb_substr($newString, $sequenceEnd); + $newString = mb_substr($newString, 0, $start) . "\0" . + mb_substr($newString, $start, $sequenceEnd - $start) . "\1" . + mb_substr($newString, $sequenceEnd); // Overwrite the strings in the old and new text so the changed lines include the markers. $oldText[$startOld + $iterator] = $oldString; @@ -397,7 +393,7 @@ private function getOuterChange(string $oldString, string $newString): array /** * Helper function that will fill the changes-array for the renderer with default values. - * Every time an operation changes (specified by $tag) , a new element will be appended to this array. + * Every time an operation changes (specified by $tag), a new element will be appended to this array. * * The index of the last element of the array is always returned. * diff --git a/lib/jblond/Diff/Renderer/SubRendererInterface.php b/lib/jblond/Diff/Renderer/SubRendererInterface.php index cc12eadc..48d8069e 100644 --- a/lib/jblond/Diff/Renderer/SubRendererInterface.php +++ b/lib/jblond/Diff/Renderer/SubRendererInterface.php @@ -63,11 +63,11 @@ public function generateLinesEqual(array $changes): string; public function generateLinesInsert(array $changes): string; /** - * Generate a string representation of lines that are skipped in the diff view. + * Generate a string representation of lines that are "Out Of Context" for the diff view. * - * @return string Representation of skipped lines. + * @return string Representation of 'Out Of Context' lines. */ - public function generateSkippedLines(): string; + public function generateLinesOutOfContext($change): string; /** * Generate a string representation of lines with ignored differences between both versions. diff --git a/lib/jblond/Diff/Renderer/Text/Context.php b/lib/jblond/Diff/Renderer/Text/Context.php index 812cce8e..5e037882 100644 --- a/lib/jblond/Diff/Renderer/Text/Context.php +++ b/lib/jblond/Diff/Renderer/Text/Context.php @@ -44,9 +44,13 @@ public function render() $diff = false; $opCodes = $this->diff->getGroupedOpCodes(); - foreach ($opCodes as $group) { + foreach ($opCodes as $key => $group) { + if ($key % 2) { + // Skip lines which are Out Of Context. + continue; + } $diff .= "***************\n"; - $lastItem = count($group) - 1; + $lastItem = array_key_last($group); $start1 = $group['0']['1']; $end1 = $group[$lastItem]['2']; $start2 = $group['0']['3']; diff --git a/lib/jblond/Diff/Renderer/Text/InlineCli.php b/lib/jblond/Diff/Renderer/Text/InlineCli.php index d5167379..74e0951d 100644 --- a/lib/jblond/Diff/Renderer/Text/InlineCli.php +++ b/lib/jblond/Diff/Renderer/Text/InlineCli.php @@ -77,9 +77,9 @@ public function generateBlockHeader(array $changes): string /** * @inheritDoc * - * @return string Representation of skipped lines. + * @return string HTML code representing table rows showing text which is 'Out Of Context' */ - public function generateSkippedLines(): string + public function generateLinesOutOfContext($change): string { return "...\n"; } diff --git a/lib/jblond/Diff/Renderer/Text/Unified.php b/lib/jblond/Diff/Renderer/Text/Unified.php index da8fc182..0c497e4c 100644 --- a/lib/jblond/Diff/Renderer/Text/Unified.php +++ b/lib/jblond/Diff/Renderer/Text/Unified.php @@ -34,8 +34,12 @@ public function render() { $diff = false; $opCodes = $this->diff->getGroupedOpCodes(); - foreach ($opCodes as $group) { - $lastItem = count($group) - 1; + foreach ($opCodes as $key => $group) { + if ($key % 2) { + // Skip lines which are Out Of Context. + continue; + } + $lastItem = array_key_last($group); $i1 = $group['0']['1']; $i2 = $group[$lastItem]['2']; $j1 = $group['0']['3']; diff --git a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php index 96c67953..0af4c4af 100644 --- a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php +++ b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php @@ -66,8 +66,12 @@ private function output(): string { $diff = ''; $opCodes = $this->diff->getGroupedOpCodes(); - foreach ($opCodes as $group) { - $lastItem = count($group) - 1; + foreach ($opCodes as $key => $group) { + if ($key % 2) { + // Skip lines which are Out Of Context. + continue; + } + $lastItem = array_key_last($group); $i1 = $group['0']['1']; $i2 = $group[$lastItem]['2']; $j1 = $group['0']['3']; @@ -82,6 +86,7 @@ private function output(): string '@@ -' . ($i1 + 1) . ',' . ($i2 - $i1) . ' +' . ($j1 + 1) . ',' . ($j2 - $j1) . " @@\n", 'purple' ); + foreach ($group as [$tag, $i1, $i2, $j1, $j2]) { if ($tag == 'equal') { $string = implode( @@ -112,8 +117,8 @@ private function output(): string } /** - * @param string $string - * @param string $color + * @param string $string + * @param string $color * * @return string */ diff --git a/lib/jblond/Diff/SequenceMatcher.php b/lib/jblond/Diff/SequenceMatcher.php index bf120b3d..1942436c 100644 --- a/lib/jblond/Diff/SequenceMatcher.php +++ b/lib/jblond/Diff/SequenceMatcher.php @@ -115,6 +115,7 @@ public function setOptions(array $options): void * * @param string|array $version1 A string or array containing the lines to compare against. * @param string|array $version2 A string or array containing the lines to compare. + * * @return void */ public function setSequences($version1, $version2): void @@ -129,6 +130,7 @@ public function setSequences($version1, $version2): void * Also resets internal caches to indicate that, when calling the calculation methods, we need to recalculate them. * * @param string|array|void $version1 The sequence to set as the first sequence. + * * @return void */ public function setSeq1($version1): void @@ -150,7 +152,8 @@ public function setSeq1($version1): void * * Also resets internal caches to indicate that, when calling the calculation methods, we need to recalculate them. * - * @param string|array $version2 The sequence to set as the second sequence. + * @param string|array $version2 The sequence to set as the second sequence. + * * @return void */ public function setSeq2($version2): void @@ -186,9 +189,11 @@ private function chainB(): void unset($this->b2j[$char]); continue; } + $this->b2j[$char][] = $i; continue; } + $this->b2j[$char] = [$i]; } @@ -216,49 +221,34 @@ private function chainB(): void } /** - * Return a series of nested arrays containing different groups of generated - * op codes for the differences between the strings with up to $this->options['context'] lines - * of surrounding content. + * Return a series of nested arrays containing different groups of generated op codes for the differences between + * the strings with up to $this->options['context'] lines of surrounding content. * - * Essentially what happens here is any big equal blocks of strings are stripped - * out, the smaller subsets of changes are then arranged in to their groups. - * This means that the sequence matcher and diffs do not need to include the full - * content of the different files but can still provide context as to where the - * changes are. + * Any large equal block of strings is separated into smaller subsets which are "Within- or Out Of Context". * * @return array Nested array of all the grouped op codes. */ public function getGroupedOpCodes(): array { $opCodes = $this->getOpCodes(); - if (empty($opCodes)) { - $opCodes = [ - [ - 'equal', - 0, - 1, - 0, - 1, - ], - ]; - } + $opCodes = $opCodes ?: [['equal', 0, 1, 0, 1,],]; if ($this->options['trimEqual']) { - if ($opCodes['0']['0'] == 'equal') { - // Remove sequences at the start of the text, but keep the context lines. - $opCodes['0'] = [ - $opCodes['0']['0'], - max($opCodes['0']['1'], $opCodes['0']['2'] - $this->options['context']), - $opCodes['0']['2'], - max($opCodes['0']['3'], $opCodes['0']['4'] - $this->options['context']), - $opCodes['0']['4'], + if ($opCodes[0][0] == 'equal') { + // Remove equal sequences at the start of the text, but keep the context lines. + $opCodes[0] = [ + $opCodes[0][0], + max($opCodes[0][1], $opCodes[0][2] - $this->options['context']), + $opCodes[0][2], + max($opCodes[0][3], $opCodes[0][4] - $this->options['context']), + $opCodes[0][4], ]; } - $lastItem = count($opCodes) - 1; - if ($opCodes[$lastItem]['0'] == 'equal') { + $lastItem = array_key_last($opCodes); + if ($opCodes[$lastItem][0] == 'equal') { + // Remove equal sequences at the end of the text, but keep the context lines. [$tag, $item1, $item2, $item3, $item4] = $opCodes[$lastItem]; - // Remove sequences at the end of the text, but keep the context lines. $opCodes[$lastItem] = [ $tag, $item1, @@ -271,35 +261,49 @@ public function getGroupedOpCodes(): array $maxRange = $this->options['context'] * 2; $groups = []; - $group = []; + $newGroup = []; foreach ($opCodes as [$tag, $item1, $item2, $item3, $item4]) { if ($tag == 'equal' && $item2 - $item1 > $maxRange) { - $group[] = [ + // Count of equal lines is greater than defined maximum context. + // Define lines before "Out of Context". + $newGroup[] = [ $tag, $item1, min($item2, $item1 + $this->options['context']), $item3, min($item4, $item3 + $this->options['context']), ]; - $groups[] = $group; - $group = []; + + $groups[] = $newGroup; + + // Define lines which are "Out Of Context". + $newGroup = []; + $newGroup[] = [ + 'outOfContext', + min($item2, $item1 + $this->options['context']), + max($item1, $item2 - $this->options['context']), + min($item4, $item3 + $this->options['context']), + max($item3, $item4 - $this->options['context']), + ]; + $groups[] = $newGroup; + + // Define start of lines after "Out Of Context". + $newGroup = []; $item1 = max($item1, $item2 - $this->options['context']); $item3 = max($item3, $item4 - $this->options['context']); } - $group[] = [ - $tag, - $item1, - $item2, - $item3, - $item4, - ]; + // Define lines "Within Context". + $newGroup[] = [$tag, $item1, $item2, $item3, $item4,]; } - if (!$this->options['trimEqual'] || (!empty($group) && !(count($group) == 1 && $group[0][0] == 'equal'))) { + if ( + !$this->options['trimEqual'] || + (!empty($newGroup) && !(count($newGroup) == 1 && $newGroup[0][0] == 'equal')) + ) { // Add the last sequences when !trimEqual || When there are no differences between both versions. - $groups[] = $group; + $groups[] = $newGroup; } return $groups; diff --git a/tests/Diff/SequenceMatcherTest.php b/tests/Diff/SequenceMatcherTest.php index 18073d14..3a767489 100644 --- a/tests/Diff/SequenceMatcherTest.php +++ b/tests/Diff/SequenceMatcherTest.php @@ -59,7 +59,9 @@ public function testGetGroupedOpCodesTrimEqualFalse(): void $this->assertEquals( [ [['equal', 0, 3, 0, 3]], + [['outOfContext', 3, 4, 3, 4]], [['equal', 4, 7, 4, 7], ['replace', 7, 8, 7, 8], ['equal', 8, 11, 8, 11]], + [['outOfContext', 11, 12, 11, 12]], [['equal', 12, 15, 12, 15]], ], $sequenceMatcher->getGroupedOpCodes() From e74c993713b617e0966bc1c18d752980740b28d8 Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 27 Jan 2022 13:39:26 +0100 Subject: [PATCH 21/46] Upate Link from Xiphe to DigiLive jQuery-Merge-for-php-diff --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 87bd71cc..251ed218 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ You can also fork this repository and open a PR. Xiphe has build a jQuery plugin with that you can merge the compared files. Have a look -at [jQuery-Merge-for-php-diff](https://github.com/Xiphe/jQuery-Merge-for-php-diff) +at [jQuery-Merge-for-php-diff](https://github.com/DigiLive/jQuery-Merge-for-php-diff) . ## Todo From c8e40897e15009f2224b9a4e93dbfd11b1c3306b Mon Sep 17 00:00:00 2001 From: DigiLive Date: Mon, 21 Feb 2022 18:56:49 +0100 Subject: [PATCH 22/46] Refactor array indexes --- lib/jblond/Diff/Renderer/Text/Context.php | 8 ++++---- lib/jblond/Diff/Renderer/Text/Unified.php | 8 ++++---- lib/jblond/Diff/Renderer/Text/UnifiedCli.php | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/jblond/Diff/Renderer/Text/Context.php b/lib/jblond/Diff/Renderer/Text/Context.php index 5e037882..75d9b46a 100644 --- a/lib/jblond/Diff/Renderer/Text/Context.php +++ b/lib/jblond/Diff/Renderer/Text/Context.php @@ -51,10 +51,10 @@ public function render() } $diff .= "***************\n"; $lastItem = array_key_last($group); - $start1 = $group['0']['1']; - $end1 = $group[$lastItem]['2']; - $start2 = $group['0']['3']; - $end2 = $group[$lastItem]['4']; + $start1 = $group[0][1]; + $end1 = $group[$lastItem][2]; + $start2 = $group[0][3]; + $end2 = $group[$lastItem][4]; // Line to line header for version 1. $diffStart = $end1 - $start1 >= 2 ? $start1 + 1 . ',' : ''; diff --git a/lib/jblond/Diff/Renderer/Text/Unified.php b/lib/jblond/Diff/Renderer/Text/Unified.php index 0c497e4c..0fdb5f52 100644 --- a/lib/jblond/Diff/Renderer/Text/Unified.php +++ b/lib/jblond/Diff/Renderer/Text/Unified.php @@ -40,10 +40,10 @@ public function render() continue; } $lastItem = array_key_last($group); - $i1 = $group['0']['1']; - $i2 = $group[$lastItem]['2']; - $j1 = $group['0']['3']; - $j2 = $group[$lastItem]['4']; + $i1 = $group[0][1]; + $i2 = $group[$lastItem][2]; + $j1 = $group[0][3]; + $j2 = $group[$lastItem][4]; if ($i1 == 0 && $i2 == 0) { $i1 = -1; diff --git a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php index 0af4c4af..ae0e2092 100644 --- a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php +++ b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php @@ -72,10 +72,10 @@ private function output(): string continue; } $lastItem = array_key_last($group); - $i1 = $group['0']['1']; - $i2 = $group[$lastItem]['2']; - $j1 = $group['0']['3']; - $j2 = $group[$lastItem]['4']; + $i1 = $group[0][1]; + $i2 = $group[$lastItem][2]; + $j1 = $group[0][3]; + $j2 = $group[$lastItem][4]; if ($i1 == 0 && $i2 == 0) { $i1 = -1; From 11bc0fc4c78f9b4d4dc4b41a13577cfe7bb745ef Mon Sep 17 00:00:00 2001 From: DigiLive Date: Mon, 21 Feb 2022 18:57:59 +0100 Subject: [PATCH 23/46] Refactor test resources --- tests/resources/htmlMerged.txt | 4 ++-- tests/resources/htmlSideBySide.txt | 4 ++-- tests/resources/htmlUnified.txt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/resources/htmlMerged.txt b/tests/resources/htmlMerged.txt index 666263db..ead95a7c 100644 --- a/tests/resources/htmlMerged.txt +++ b/tests/resources/htmlMerged.txt @@ -71,10 +71,10 @@ 22         <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.</p> - + … … - + 25         <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.</p> diff --git a/tests/resources/htmlSideBySide.txt b/tests/resources/htmlSideBySide.txt index 67ce275c..9d114465 100644 --- a/tests/resources/htmlSideBySide.txt +++ b/tests/resources/htmlSideBySide.txt @@ -207,12 +207,12 @@         <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.</p> - + … … … … - + 25         <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.</p> diff --git a/tests/resources/htmlUnified.txt b/tests/resources/htmlUnified.txt index f8add881..5eb2dc15 100644 --- a/tests/resources/htmlUnified.txt +++ b/tests/resources/htmlUnified.txt @@ -151,11 +151,11 @@ 22 22         <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.</p> - + … … … - + 25 25         <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.</p> From 073a478a5ffe4f2c78b80367f2d56078f5b22ef5 Mon Sep 17 00:00:00 2001 From: DigiLive Date: Mon, 21 Feb 2022 19:31:35 +0100 Subject: [PATCH 24/46] Cut redundant suppression --- lib/jblond/Diff/SequenceMatcher.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/jblond/Diff/SequenceMatcher.php b/lib/jblond/Diff/SequenceMatcher.php index 1942436c..47117aa4 100644 --- a/lib/jblond/Diff/SequenceMatcher.php +++ b/lib/jblond/Diff/SequenceMatcher.php @@ -437,11 +437,6 @@ public function getMatchingBlocks(): array $matchingBlocks = []; while (!empty($queue)) { [$aLower, $aUpper, $bLower, $bUpper] = array_pop($queue); - /** - * @noinspection PhpStrictTypeCheckingInspection - * $aLower, $aUpper, $bLower, $bUpper reported as wrong type because of multiple definitions of function - * count above. - */ $longestMatch = $this->findLongestMatch($aLower, $aUpper, $bLower, $bUpper); [$list1, $list2, $list3] = $longestMatch; if ($list3) { From a9635beb2098986d894b7a0774e2b0cfad62d784 Mon Sep 17 00:00:00 2001 From: DigiLive Date: Mon, 21 Feb 2022 19:55:35 +0100 Subject: [PATCH 25/46] Fix docblock --- lib/jblond/Diff/Renderer/Html/Unified.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jblond/Diff/Renderer/Html/Unified.php b/lib/jblond/Diff/Renderer/Html/Unified.php index a3128106..af61751d 100644 --- a/lib/jblond/Diff/Renderer/Html/Unified.php +++ b/lib/jblond/Diff/Renderer/Html/Unified.php @@ -222,7 +222,7 @@ public function generateLinesReplace(array $changes): string /** * @inheritDoc * - * @return string Html code representing table rows showing modified text. + * @return string Html code representing table rows showing ignored text. */ public function generateLinesIgnore(array $changes): string { From cfa3033487de8a6c73c70c590023acb42c87ffe6 Mon Sep 17 00:00:00 2001 From: DigiLive Date: Mon, 21 Feb 2022 19:57:45 +0100 Subject: [PATCH 26/46] Bump PHPUnit xml schema to version 9.5 --- phpunit.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpunit.xml b/phpunit.xml index b0543e73..7b889f61 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" bootstrap="vendor/autoload.php" - xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"> ./lib From 160a3ae6472fc357aff71e03f4bf26a0453df0d2 Mon Sep 17 00:00:00 2001 From: DigiLive Date: Mon, 21 Feb 2022 20:08:48 +0100 Subject: [PATCH 27/46] Fix potentially polymorphic call --- lib/jblond/Diff/Renderer/MainRenderer.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/jblond/Diff/Renderer/MainRenderer.php b/lib/jblond/Diff/Renderer/MainRenderer.php index 6aa38b44..eea64cb1 100644 --- a/lib/jblond/Diff/Renderer/MainRenderer.php +++ b/lib/jblond/Diff/Renderer/MainRenderer.php @@ -37,12 +37,13 @@ class MainRenderer extends MainRendererAbstract * * This method is called by the renderers which extends this class. * - * @param array $changes Contains the op-codes about the differences between version1 and version2. - * @param object $subRenderer Renderer which is subClass of this class. + * @param array $changes Contains the op-codes about the differences between version1 and + * version2. + * @param SubRendererInterface $subRenderer Renderer which is child class of this class. * * @return string|false String representation of the differences or false when versions are identical. */ - public function renderOutput(array $changes, object $subRenderer) + public function renderOutput(array $changes, SubRendererInterface $subRenderer) { if (!$changes) { //No changes between version1 and version2 From 40f418f5ad741ff925db484e027477dadd5ee1d7 Mon Sep 17 00:00:00 2001 From: DigiLive Date: Mon, 21 Feb 2022 20:27:09 +0100 Subject: [PATCH 28/46] Fix grammar --- lib/jblond/Diff/ConstantsInterface.php | 2 +- lib/jblond/Diff/Renderer/MainRenderer.php | 2 +- lib/jblond/Diff/SequenceMatcher.php | 8 ++++---- lib/jblond/Diff/Similarity.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/jblond/Diff/ConstantsInterface.php b/lib/jblond/Diff/ConstantsInterface.php index 4166a608..c41e6055 100644 --- a/lib/jblond/Diff/ConstantsInterface.php +++ b/lib/jblond/Diff/ConstantsInterface.php @@ -27,7 +27,7 @@ interface ConstantsInterface */ public const DIFF_IGNORE_LINE_EMPTY = 1; /** - * Flag to ignore blank lines. (Lines which contain no or only non printable characters.) + * Flag to ignore blank lines. (Lines which contain no or only non-printable characters.) */ public const DIFF_IGNORE_LINE_BLANK = 2; } diff --git a/lib/jblond/Diff/Renderer/MainRenderer.php b/lib/jblond/Diff/Renderer/MainRenderer.php index eea64cb1..db0d4cd1 100644 --- a/lib/jblond/Diff/Renderer/MainRenderer.php +++ b/lib/jblond/Diff/Renderer/MainRenderer.php @@ -429,7 +429,7 @@ private function appendChangesArray(array &$blocks, string $tag, int $lineInOld, } /** - * Format a series of strings which are suitable for output in a HTML rendered diff. + * Format a series of strings which are suitable for output in an HTML rendered diff. * * This involves replacing tab characters with spaces, making the HTML safe for output by ensuring that double * spaces are replaced with   etc. diff --git a/lib/jblond/Diff/SequenceMatcher.php b/lib/jblond/Diff/SequenceMatcher.php index 47117aa4..31313e59 100644 --- a/lib/jblond/Diff/SequenceMatcher.php +++ b/lib/jblond/Diff/SequenceMatcher.php @@ -51,12 +51,12 @@ class SequenceMatcher implements ConstantsInterface */ private $b2j = []; /** - * @var array A list of all of the op-codes for the differences between the compared strings. + * @var array A list of all the op-codes for the differences between the compared strings. */ private $opCodes; /** - * @var array A nested set of arrays for all of the matching sub-sequences the compared strings. + * @var array A nested set of arrays for all the matching sub-sequences the compared strings. */ private $matchingBlocks; @@ -623,8 +623,8 @@ private function isBJunk(string $bString): bool /** * Check if the two lines at the given indexes are different or not. * - * @param int $aIndex Line number to check against in a. - * @param int $bIndex Line number to check against in b. + * @param int $aIndex Number of line to check against in A. + * @param int $bIndex Number of line to check against in B. * * @return bool True if the lines are different and false if not. */ diff --git a/lib/jblond/Diff/Similarity.php b/lib/jblond/Diff/Similarity.php index 5beb60d6..59ace0c8 100644 --- a/lib/jblond/Diff/Similarity.php +++ b/lib/jblond/Diff/Similarity.php @@ -71,7 +71,7 @@ public function setSeq2($version2): void public function getSimilarity(int $type = self::CALC_DEFAULT): float { if ($this->options['ignoreLines']) { - // Backup original sequences and filter non blank lines. + // Backup original sequences and filter non-blank lines. $this->stripLines(); } From 0d45b031654d5bc97476c07bf3aa5df751d3e8ef Mon Sep 17 00:00:00 2001 From: JBlond Date: Mon, 16 May 2022 11:08:31 +0200 Subject: [PATCH 29/46] Fix: #112 Call to function unset() contains undefined variable $line. --- composer.json | 3 ++- lib/jblond/Diff/SequenceMatcher.php | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index dd9b68bb..bdbc4bad 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,8 @@ "squizlabs/php_codesniffer": "*", "phpmd/phpmd": "2.*", "jblond/php-cli": "^1.0", - "digilive/git-changelog": "^1" + "digilive/git-changelog": "^1", + "vimeo/psalm": "^4.23" }, "suggest": { "jblond/php-cli": "^1.0" diff --git a/lib/jblond/Diff/SequenceMatcher.php b/lib/jblond/Diff/SequenceMatcher.php index 31313e59..0ee8ab22 100644 --- a/lib/jblond/Diff/SequenceMatcher.php +++ b/lib/jblond/Diff/SequenceMatcher.php @@ -369,7 +369,6 @@ static function (&$line) { $line = trim($line); } ); - unset($line); } if ( From e1a9ec5bbd9a2eedb4736987667e262238f78786 Mon Sep 17 00:00:00 2001 From: JBlond Date: Mon, 16 May 2022 11:11:41 +0200 Subject: [PATCH 30/46] Remove package --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index bdbc4bad..dd9b68bb 100644 --- a/composer.json +++ b/composer.json @@ -36,8 +36,7 @@ "squizlabs/php_codesniffer": "*", "phpmd/phpmd": "2.*", "jblond/php-cli": "^1.0", - "digilive/git-changelog": "^1", - "vimeo/psalm": "^4.23" + "digilive/git-changelog": "^1" }, "suggest": { "jblond/php-cli": "^1.0" From 42ea73b7b455abf3385ea1c02be73b45ee17c5b8 Mon Sep 17 00:00:00 2001 From: JBlond Date: Tue, 12 Jul 2022 11:13:39 +0200 Subject: [PATCH 31/46] Optimize Remove unused tupleSort function --- lib/jblond/Diff/DiffUtils.php | 50 ---------- tests/Diff/DiffUtilsTest.php | 167 ---------------------------------- 2 files changed, 217 deletions(-) delete mode 100644 lib/jblond/Diff/DiffUtils.php delete mode 100644 tests/Diff/DiffUtilsTest.php diff --git a/lib/jblond/Diff/DiffUtils.php b/lib/jblond/Diff/DiffUtils.php deleted file mode 100644 index 74380786..00000000 --- a/lib/jblond/Diff/DiffUtils.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright (c) 2020 Mario Brandt - * @license New BSD License http://www.opensource.org/licenses/bsd-license.php - * @version 2.4.0 - * @link https://github.com/JBlond/php-diff - */ -class DiffUtils -{ - /** - * Sort an array by the nested arrays it contains. Helper function for getMatchingBlocks - * - * @param array $aArray First array to compare. - * @param array $bArray Second array to compare. - * - * @return int -1, 0 or 1, as expected by the usort function. - * @deprecated - */ - public static function tupleSort(array $aArray, array $bArray): int - { - $max = max(count($aArray), count($bArray)); - for ($counter = 0; $counter < $max; ++$counter) { - if ($aArray[$counter] < $bArray[$counter]) { - return -1; - } - - if ($aArray[$counter] > $bArray[$counter]) { - return 1; - } - } - - if (count($aArray) == count($bArray)) { - return 0; - } - if (count($aArray) < count($bArray)) { - return -1; - } - - return 1; - } -} diff --git a/tests/Diff/DiffUtilsTest.php b/tests/Diff/DiffUtilsTest.php deleted file mode 100644 index b46d5597..00000000 --- a/tests/Diff/DiffUtilsTest.php +++ /dev/null @@ -1,167 +0,0 @@ - - * @author Ferry Cools - * @copyright (c) 2021 Mario Brandt - * @license New BSD License http://www.opensource.org/licenses/bsd-license.php - * @version 2.4.0 - * @link https://github.com/JBlond/php-diff - */ -class DiffUtilsTest extends TestCase -{ - /** - * Test the sorting of an array by the nested arrays it contains - */ - public function testTupleSortOne(): void - { - $this->assertEquals( - 1, - DiffUtils::tupleSort( - [ - - 0 => [ - 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', - 'title' => 'Flower', - 'order' => 3, - ], - 1 => [ - 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', - 'title' => 'Free', - 'order' => 2, - ], - - 2 => [ - 'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b', - 'title' => 'Ready', - 'order' => 1 - ] - ], - [ - - 0 => [ - 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', - 'title' => 'Flower', - 'order' => 3, - ], - 1 => [ - 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', - 'title' => 'Free', - 'order' => 2, - ], - - 2 => [ - ] - ], - ) - ); - } - - /** - * Test the sorting of an array by the nested arrays it contains - */ - public function testTupleSortZero(): void - { - $this->assertEquals( - 0, - DiffUtils::tupleSort( - [ - - 0 => [ - 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', - 'title' => 'Flower', - 'order' => 3, - ], - 1 => [ - 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', - 'title' => 'Free', - 'order' => 2, - ], - - 2 => [ - 'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b', - 'title' => 'Ready', - 'order' => 1 - ] - ], - [ - - 0 => [ - 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', - 'title' => 'Flower', - 'order' => 3, - ], - 1 => [ - 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', - 'title' => 'Free', - 'order' => 2, - ], - - 2 => [ - 'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b', - 'title' => 'Ready', - 'order' => 1 - ] - ], - ) - ); - } - - /** - * Test the sorting of an array by the nested arrays it contains - */ - public function testTupleSortMinusOne(): void - { - $this->assertEquals( - -1, - DiffUtils::tupleSort( - [ - - 0 => [ - 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', - 'title' => 'Flower', - 'order' => 3, - ], - 1 => [ - 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', - 'title' => 'Free', - 'order' => 2, - ], - - 2 => [ - - ] - ], - [ - - 0 => [ - 'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4', - 'title' => 'Flower', - 'order' => 3, - ], - 1 => [ - 'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594', - 'title' => 'Free', - 'order' => 2, - ], - - 2 => [ - 'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b', - 'title' => 'Ready', - 'order' => 1 - ] - ], - ) - ); - } -} From 54124a65d4eb28caa21f0b4c67e0b6c2403a29a0 Mon Sep 17 00:00:00 2001 From: JBlond Date: Tue, 12 Jul 2022 11:21:34 +0200 Subject: [PATCH 32/46] Fix "Opening brace must not be followed by a blank" --- lib/jblond/Diff/Renderer/Text/UnifiedCli.php | 1 - tests/Diff/Renderer/MainRendererTest.php | 1 - tests/Diff/SimilarityTest.php | 1 - 3 files changed, 3 deletions(-) diff --git a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php index ae0e2092..c4338a33 100644 --- a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php +++ b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php @@ -20,7 +20,6 @@ */ class UnifiedCli extends MainRendererAbstract { - /** * @var CliColors */ diff --git a/tests/Diff/Renderer/MainRendererTest.php b/tests/Diff/Renderer/MainRendererTest.php index 2ffc33e4..e6f0ba15 100644 --- a/tests/Diff/Renderer/MainRendererTest.php +++ b/tests/Diff/Renderer/MainRendererTest.php @@ -33,7 +33,6 @@ */ class MainRendererTest extends TestCase { - /** * @var string[] Defines the main renderer options. */ diff --git a/tests/Diff/SimilarityTest.php b/tests/Diff/SimilarityTest.php index 4d262495..abab54c7 100644 --- a/tests/Diff/SimilarityTest.php +++ b/tests/Diff/SimilarityTest.php @@ -19,7 +19,6 @@ */ class SimilarityTest extends TestCase { - /** * Test the similarity ratio between two sequences with different methods. */ From d62afcf55fb1e335f5d4c0ff31789cf50be659fe Mon Sep 17 00:00:00 2001 From: JBlond Date: Tue, 12 Jul 2022 11:35:58 +0200 Subject: [PATCH 33/46] Fix PHPMD warnings --- lib/jblond/Diff/SequenceMatcher.php | 80 +++++++++---------- .../Diff/Renderer/Text/TextRenderersTest.php | 2 +- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/lib/jblond/Diff/SequenceMatcher.php b/lib/jblond/Diff/SequenceMatcher.php index 0ee8ab22..48497634 100644 --- a/lib/jblond/Diff/SequenceMatcher.php +++ b/lib/jblond/Diff/SequenceMatcher.php @@ -337,24 +337,24 @@ public function getOpCodes(): array return $this->opCodes; } - $i = 0; - $j = 0; + $iFrom = 0; + $jFrom = 0; $this->opCodes = []; $blocks = $this->getMatchingBlocks(); - foreach ($blocks as [$ai, $bj, $size]) { + foreach ($blocks as [$blockA, $blockB, $size]) { $tag = ''; - if ($i < $ai && $j < $bj) { + if ($iFrom < $blockA && $jFrom < $blockB) { $tag = 'replace'; - } elseif ($i < $ai) { + } elseif ($iFrom < $blockA) { $tag = 'delete'; - } elseif ($j < $bj) { + } elseif ($jFrom < $blockB) { $tag = 'insert'; } if ($this->options['ignoreLines']) { - $slice1 = array_slice($this->old, $i, $ai - $i); - $slice2 = array_slice($this->new, $j, $bj - $j); + $slice1 = array_slice($this->old, $iFrom, $blockA - $iFrom); + $slice2 = array_slice($this->new, $jFrom, $blockB - $jFrom); if ($this->options['ignoreLines'] == 2) { array_walk( @@ -382,23 +382,23 @@ static function (&$line) { if ($tag) { $this->opCodes[] = [ $tag, - $i, - $ai, - $j, - $bj, + $iFrom, + $blockA, + $jFrom, + $blockB, ]; } - $i = $ai + $size; - $j = $bj + $size; + $iFrom = $blockA + $size; + $jFrom = $blockB + $size; if ($size) { $this->opCodes[] = [ 'equal', - $ai, - $i, - $bj, - $j, + $blockA, + $iFrom, + $blockB, + $jFrom, ]; } } @@ -462,34 +462,34 @@ public function getMatchingBlocks(): array sort($matchingBlocks); - $i1 = 0; - $j1 = 0; - $k1 = 0; + $iMatchingBlock = 0; + $jMatchingBlock = 0; + $kMatchingBlock = 0; $nonAdjacent = []; foreach ($matchingBlocks as [$list4, $list5, $list6]) { - if ($i1 + $k1 == $list4 && $j1 + $k1 == $list5) { - $k1 += $list6; + if ($iMatchingBlock + $kMatchingBlock == $list4 && $jMatchingBlock + $kMatchingBlock == $list5) { + $kMatchingBlock += $list6; continue; } - if ($k1) { + if ($kMatchingBlock) { $nonAdjacent[] = [ - $i1, - $j1, - $k1, + $iMatchingBlock, + $jMatchingBlock, + $kMatchingBlock, ]; } - $i1 = $list4; - $j1 = $list5; - $k1 = $list6; + $iMatchingBlock = $list4; + $jMatchingBlock = $list5; + $kMatchingBlock = $list6; } - if ($k1) { + if ($kMatchingBlock) { $nonAdjacent[] = [ - $i1, - $j1, - $k1, + $iMatchingBlock, + $jMatchingBlock, + $kMatchingBlock, ]; } @@ -547,12 +547,12 @@ public function findLongestMatch(int $aLower, int $aUpper, int $bLower, int $bUp break; } - $k = ($j2Len[$j - 1] ?? 0) + 1; - $newJ2Len[$j] = $k; - if ($k > $bestSize) { - $bestI = $i - $k + 1; - $bestJ = $j - $k + 1; - $bestSize = $k; + $kRatio = ($j2Len[$j - 1] ?? 0) + 1; + $newJ2Len[$j] = $kRatio; + if ($kRatio > $bestSize) { + $bestI = $i - $kRatio + 1; + $bestJ = $j - $kRatio + 1; + $bestSize = $kRatio; } } diff --git a/tests/Diff/Renderer/Text/TextRenderersTest.php b/tests/Diff/Renderer/Text/TextRenderersTest.php index 337eab36..f76484f0 100644 --- a/tests/Diff/Renderer/Text/TextRenderersTest.php +++ b/tests/Diff/Renderer/Text/TextRenderersTest.php @@ -27,7 +27,7 @@ class TextRenderersTest extends TestCase /** * @var bool Store the renderer's output in a file, when set to true. */ - private $genOutputFiles = false; + protected $genOutputFiles = false; /** * TextRenderersTest constructor. From 839b0f068f7f609ef3e6aaea7a70d726c1447d0d Mon Sep 17 00:00:00 2001 From: JBlond Date: Tue, 12 Jul 2022 11:42:00 +0200 Subject: [PATCH 34/46] Fix PHPMD warnings --- lib/jblond/Diff/Renderer/Text/Unified.php | 24 ++++++++++---------- lib/jblond/Diff/Renderer/Text/UnifiedCli.php | 24 ++++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/jblond/Diff/Renderer/Text/Unified.php b/lib/jblond/Diff/Renderer/Text/Unified.php index 0fdb5f52..897c30d5 100644 --- a/lib/jblond/Diff/Renderer/Text/Unified.php +++ b/lib/jblond/Diff/Renderer/Text/Unified.php @@ -40,23 +40,23 @@ public function render() continue; } $lastItem = array_key_last($group); - $i1 = $group[0][1]; - $i2 = $group[$lastItem][2]; - $j1 = $group[0][3]; - $j2 = $group[$lastItem][4]; + $iGroup1 = $group[0][1]; + $iGroup2 = $group[$lastItem][2]; + $jGroup1 = $group[0][3]; + $jGroup2 = $group[$lastItem][4]; - if ($i1 == 0 && $i2 == 0) { - $i1 = -1; - $i2 = -1; + if ($iGroup1 == 0 && $iGroup2 == 0) { + $iGroup1 = -1; + $iGroup2 = -1; } - $diff .= '@@ -' . ($i1 + 1) . ',' . ($i2 - $i1) . ' +' . ($j1 + 1) . ',' . ($j2 - $j1) . " @@\n"; - foreach ($group as [$tag, $i1, $i2, $j1, $j2]) { + $diff .= '@@ -' . ($iGroup1 + 1) . ',' . ($iGroup2 - $iGroup1) . ' +' . ($jGroup1 + 1) . ',' . ($jGroup2 - $jGroup1) . " @@\n"; + foreach ($group as [$tag, $iGroup1, $iGroup2, $jGroup1, $jGroup2]) { if ($tag == 'equal') { $diff .= ' ' . implode( "\n ", - $this->diff->getArrayRange($this->diff->getVersion1(), $i1, $i2) + $this->diff->getArrayRange($this->diff->getVersion1(), $iGroup1, $iGroup2) ) . "\n"; continue; } @@ -64,14 +64,14 @@ public function render() $diff .= '-' . implode( "\n-", - $this->diff->getArrayRange($this->diff->getVersion1(), $i1, $i2) + $this->diff->getArrayRange($this->diff->getVersion1(), $iGroup1, $iGroup2) ) . "\n"; } if ($tag == 'replace' || $tag == 'insert') { $diff .= '+' . implode( "\n+", - $this->diff->getArrayRange($this->diff->getVersion2(), $j1, $j2) + $this->diff->getArrayRange($this->diff->getVersion2(), $jGroup1, $jGroup2) ) . "\n"; } } diff --git a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php index c4338a33..6d5a74b2 100644 --- a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php +++ b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php @@ -71,26 +71,26 @@ private function output(): string continue; } $lastItem = array_key_last($group); - $i1 = $group[0][1]; - $i2 = $group[$lastItem][2]; - $j1 = $group[0][3]; - $j2 = $group[$lastItem][4]; + $iGroup1 = $group[0][1]; + $iGroup2 = $group[$lastItem][2]; + $jGroup1 = $group[0][3]; + $jGroup2 = $group[$lastItem][4]; - if ($i1 == 0 && $i2 == 0) { - $i1 = -1; - $i2 = -1; + if ($iGroup1 == 0 && $iGroup2 == 0) { + $iGroup1 = -1; + $iGroup2 = -1; } $diff .= $this->colorizeString( - '@@ -' . ($i1 + 1) . ',' . ($i2 - $i1) . ' +' . ($j1 + 1) . ',' . ($j2 - $j1) . " @@\n", + '@@ -' . ($iGroup1 + 1) . ',' . ($iGroup2 - $iGroup1) . ' +' . ($jGroup1 + 1) . ',' . ($jGroup2 - $jGroup1) . " @@\n", 'purple' ); - foreach ($group as [$tag, $i1, $i2, $j1, $j2]) { + foreach ($group as [$tag, $iGroup1, $iGroup2, $jGroup1, $jGroup2]) { if ($tag == 'equal') { $string = implode( "\n ", - $this->diff->getArrayRange($this->diff->getVersion1(), $i1, $i2) + $this->diff->getArrayRange($this->diff->getVersion1(), $iGroup1, $iGroup2) ); $diff .= $this->colorizeString(' ' . $string . "\n", 'grey'); continue; @@ -98,14 +98,14 @@ private function output(): string if ($tag == 'replace' || $tag == 'delete') { $string = implode( "\n- ", - $this->diff->getArrayRange($this->diff->getVersion1(), $i1, $i2) + $this->diff->getArrayRange($this->diff->getVersion1(), $iGroup1, $iGroup2) ); $diff .= $this->colorizeString('-' . $string . "\n", 'light_red'); } if ($tag == 'replace' || $tag == 'insert') { $string = implode( "\n+", - $this->diff->getArrayRange($this->diff->getVersion2(), $j1, $j2) + $this->diff->getArrayRange($this->diff->getVersion2(), $jGroup1, $jGroup2) ); $diff .= $this->colorizeString('+' . $string . "\n", 'light_green'); } From 7cbae823c99077b3a69aaf885a409c68b81f50bc Mon Sep 17 00:00:00 2001 From: JBlond Date: Mon, 12 Dec 2022 14:56:41 +0100 Subject: [PATCH 35/46] Update: digilive/git-changelog --- composer.json | 2 +- generateChangelog.php | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index dd9b68bb..3f3b1233 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,7 @@ "squizlabs/php_codesniffer": "*", "phpmd/phpmd": "2.*", "jblond/php-cli": "^1.0", - "digilive/git-changelog": "^1" + "digilive/git-changelog": "^2" }, "suggest": { "jblond/php-cli": "^1.0" diff --git a/generateChangelog.php b/generateChangelog.php index ceab516e..6c99c338 100644 --- a/generateChangelog.php +++ b/generateChangelog.php @@ -13,8 +13,9 @@ $changeLog = new MarkDown(); -$changeLog->commitUrl = 'https://github.com/JBlond/php-diff/commit/{hash}'; -$changeLog->issueUrl = 'https://github.com/JBlond/php-diff/issues/{issue}'; +$changeLog->setUrl('commit', 'https://github.com/JBlond/php-diff/commit/{hash}'); +$changeLog->setUrl('issue', 'https://github.com/JBlond/php-diff/issues/{issue}'); + try { $changeLog->setOptions($changelogOptions); } catch (Exception $exception) { @@ -26,4 +27,4 @@ } catch (Exception $exception) { echo $exception->getMessage(); } -$changeLog->save('changelog.md'); +file_put_contents('changelog.md', $changeLog->get()); From 2ec33c940ac690c40af9d07f3343c302cd1927ac Mon Sep 17 00:00:00 2001 From: JBlond Date: Mon, 12 Dec 2022 15:55:24 +0100 Subject: [PATCH 36/46] Fix: Commit URL in changelog --- generateChangelog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generateChangelog.php b/generateChangelog.php index 6c99c338..f834c5b7 100644 --- a/generateChangelog.php +++ b/generateChangelog.php @@ -13,7 +13,7 @@ $changeLog = new MarkDown(); -$changeLog->setUrl('commit', 'https://github.com/JBlond/php-diff/commit/{hash}'); +$changeLog->setUrl('commit', 'https://github.com/JBlond/php-diff/commit/{commit}'); $changeLog->setUrl('issue', 'https://github.com/JBlond/php-diff/issues/{issue}'); try { From 21e12d1fbc8edff044d8f932186f870a244d87e9 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 13 Dec 2022 08:38:45 +0100 Subject: [PATCH 37/46] Update codacy link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 251ed218..0ccb5eab 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # PHP Diff Class -[![Codacy Badge](https://api.codacy.com/project/badge/Grade/db5f8d57b1234502aeb852afc87e0dfe)](https://www.codacy.com/app/leet31337/php-diff) +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/db5f8d57b1234502aeb852afc87e0dfe)](https://app.codacy.com/gh/JBlond/php-diff/dashboard) [![Latest Version](https://img.shields.io/github/release/JBlond/php-diff.svg?style=flat-square&label=Release)](https://github.com/JBlond/php-diff/releases) [![Packagist Installs](https://badgen.net/packagist/dt/JBlond/php-diff)](https://packagist.org/packages/jblond/php-diff) From 46528f26b40d2e981312836bb12bb348a4f1918a Mon Sep 17 00:00:00 2001 From: JBlond Date: Wed, 1 Feb 2023 12:11:38 +0100 Subject: [PATCH 38/46] Add: Json renderer --- composer.json | 1 + lib/jblond/Diff/Renderer/Text/Json.php | 61 ++++ .../Diff/Renderer/Text/TextRenderersTest.php | 19 ++ tests/resources/textResult.json | 319 ++++++++++++++++++ 4 files changed, 400 insertions(+) create mode 100644 lib/jblond/Diff/Renderer/Text/Json.php create mode 100644 tests/resources/textResult.json diff --git a/composer.json b/composer.json index 3f3b1233..bda77fcb 100644 --- a/composer.json +++ b/composer.json @@ -39,6 +39,7 @@ "digilive/git-changelog": "^2" }, "suggest": { + "ext-json": "*", "jblond/php-cli": "^1.0" }, "autoload": { diff --git a/lib/jblond/Diff/Renderer/Text/Json.php b/lib/jblond/Diff/Renderer/Text/Json.php new file mode 100644 index 00000000..ed86e1f5 --- /dev/null +++ b/lib/jblond/Diff/Renderer/Text/Json.php @@ -0,0 +1,61 @@ + + * @copyright (c) 2023 Mario Brandt + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.4.0 + * @link https://github.com/JBlond/php-diff + */ + +/** + * Class Diff_Renderer_Text_Json + */ +class Json extends MainRendererAbstract +{ + /** + * @return false|string + */ + public function render() + { + $return = []; + $opCodes = $this->diff->getGroupedOpCodes(); + + foreach ($opCodes as $key => $group) { + $return[] = $this->toArray($group); + } + return json_encode($return, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + } + + /** + * @param $group + * @return array + */ + protected function toArray($group): array + { + $return = []; + foreach ($group as [$tag, $iGroup1, $iGroup2, $jGroup1, $jGroup2]) { + $return[] = [ + 'tag' => $tag, + 'old' => [ + 'offset' => $iGroup1, + 'lines' => $this->diff->getArrayRange($this->diff->getVersion1(), $iGroup1, $iGroup2) + ], + 'new' => [ + 'offset' => $jGroup1, + 'lines' => $this->diff->getArrayRange($this->diff->getVersion2(), $jGroup1, $jGroup2) + ], + ]; + } + return $return; + } +} diff --git a/tests/Diff/Renderer/Text/TextRenderersTest.php b/tests/Diff/Renderer/Text/TextRenderersTest.php index f76484f0..1452e74f 100644 --- a/tests/Diff/Renderer/Text/TextRenderersTest.php +++ b/tests/Diff/Renderer/Text/TextRenderersTest.php @@ -130,4 +130,23 @@ public function testInlineCli(): void } $this->assertStringEqualsFile('tests/resources/textInlineCli.txt', $result); } + + /** + * Test the output of the JSON text renderer + * + * @covers \jblond\Diff\Renderer\Text\Json + */ + public function testJson(): void + { + $diff = new Diff( + file_get_contents('tests/resources/a.txt'), + file_get_contents('tests/resources/b.txt') + ); + $renderer = new Diff\Renderer\Text\Json(); + $result = $diff->render($renderer); + if ($this->genOutputFiles) { + file_put_contents('results.json', $result); + } + $this->assertStringEqualsFile('tests/resources/textResult.json', $result); + } } diff --git a/tests/resources/textResult.json b/tests/resources/textResult.json new file mode 100644 index 00000000..0f1c1b16 --- /dev/null +++ b/tests/resources/textResult.json @@ -0,0 +1,319 @@ +[ + [ + { + "tag": "equal", + "old": { + "offset": 0, + "lines": [ + "", + " ", + " " + ] + }, + "new": { + "offset": 0, + "lines": [ + "", + " ", + " " + ] + } + }, + { + "tag": "replace", + "old": { + "offset": 3, + "lines": [ + " Hello World!<\/title>" + ] + }, + "new": { + "offset": 3, + "lines": [ + " <title>Hello You!<\/title>" + ] + } + }, + { + "tag": "equal", + "old": { + "offset": 4, + "lines": [ + " <\/head>", + " <body>", + " <h1>This is demo content to show features of the php-diff package.<\/h1>" + ] + }, + "new": { + "offset": 4, + "lines": [ + " <\/head>", + " <body>", + " <h1>This is demo content to show features of the php-diff package.<\/h1>" + ] + } + }, + { + "tag": "delete", + "old": { + "offset": 7, + "lines": [ + " <h2>This line is removed from version2.<\/h2>" + ] + }, + "new": { + "offset": 7, + "lines": [] + } + }, + { + "tag": "equal", + "old": { + "offset": 8, + "lines": [ + " <h2>This line is the same for both versions.<\/h2>" + ] + }, + "new": { + "offset": 7, + "lines": [ + " <h2>This line is the same for both versions.<\/h2>" + ] + } + }, + { + "tag": "replace", + "old": { + "offset": 9, + "lines": [ + " <h2>this line has inline differences between both versions.<\/h2>" + ] + }, + "new": { + "offset": 8, + "lines": [ + " <h2>This line has differences between both versions.<\/h2>" + ] + } + }, + { + "tag": "equal", + "old": { + "offset": 10, + "lines": [ + " <h2>This line is the same for both versions.<\/h2>" + ] + }, + "new": { + "offset": 9, + "lines": [ + " <h2>This line is the same for both versions.<\/h2>" + ] + } + }, + { + "tag": "replace", + "old": { + "offset": 11, + "lines": [ + " <h2>This line also has inline differences between both versions.<\/h2>" + ] + }, + "new": { + "offset": 10, + "lines": [ + " <h2>This line also has InLine differences between both versions.<\/h2>" + ] + } + }, + { + "tag": "equal", + "old": { + "offset": 12, + "lines": [ + " <h2>This line is the same for both versions.<\/h2>" + ] + }, + "new": { + "offset": 11, + "lines": [ + " <h2>This line is the same for both versions.<\/h2>" + ] + } + }, + { + "tag": "insert", + "old": { + "offset": 13, + "lines": [] + }, + "new": { + "offset": 12, + "lines": [ + " <h2>This line is added to version2.<\/h2>" + ] + } + }, + { + "tag": "equal", + "old": { + "offset": 13, + "lines": [ + "", + " <p>", + " It's also compatible with multibyte characters (like Chinese and emoji) as shown below:" + ] + }, + "new": { + "offset": 13, + "lines": [ + "", + " <p>", + " It's also compatible with multibyte characters (like Chinese and emoji) as shown below:" + ] + } + }, + { + "tag": "replace", + "old": { + "offset": 16, + "lines": [ + " 另外我覺得那個評價的白色櫃子有點沒有必要欸。外觀我就不說了 ,怎麼連空間都那麼狹隘。不過倒是從這個地方看出所謂的“改革”", + " Do you know what \"金槍魚罐頭\" means in Chinese?", + " 🍏🍎🙂" + ] + }, + "new": { + "offset": 16, + "lines": [ + " 另外我覺得那個評鑑的白色櫃子有點沒有必要欸。外觀我就不說了 ,怎麼連空間都那麼狹隘。不過倒是從這個地方看出所謂的“改革”", + " Do you know what \"魚の缶詰\" means in Chinese?", + " 🍎🍏🙂" + ] + } + }, + { + "tag": "equal", + "old": { + "offset": 19, + "lines": [ + " <\/p>", + "", + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>" + ] + }, + "new": { + "offset": 19, + "lines": [ + " <\/p>", + "", + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>" + ] + } + } + ], + [ + { + "tag": "outOfContext", + "old": { + "offset": 22, + "lines": [ + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>", + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>" + ] + }, + "new": { + "offset": 22, + "lines": [ + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>", + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>" + ] + } + } + ], + [ + { + "tag": "equal", + "old": { + "offset": 24, + "lines": [ + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>", + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>", + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>" + ] + }, + "new": { + "offset": 24, + "lines": [ + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>", + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>", + " <p>Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.<\/p>" + ] + } + }, + { + "tag": "replace", + "old": { + "offset": 27, + "lines": [ + "\t\t<h2>This line also has inline differences between both versions. It's the whitespace in front.<\/h2>" + ] + }, + "new": { + "offset": 27, + "lines": [ + " <h2>This line also has inline differences between both versions. It's the whitespace in front.<\/h2>" + ] + } + }, + { + "tag": "equal", + "old": { + "offset": 28, + "lines": [ + " <h2>This line is the same for both versions.<\/h2>" + ] + }, + "new": { + "offset": 28, + "lines": [ + " <h2>This line is the same for both versions.<\/h2>" + ] + } + }, + { + "tag": "replace", + "old": { + "offset": 29, + "lines": [ + " <h2>This line also has inline differences between both versions.<\/h2>" + ] + }, + "new": { + "offset": 29, + "lines": [ + " <h2>This line also has inline differences between both versions!<\/h2>" + ] + } + }, + { + "tag": "equal", + "old": { + "offset": 30, + "lines": [ + " <\/body>", + "<\/html>", + "" + ] + }, + "new": { + "offset": 30, + "lines": [ + " <\/body>", + "<\/html>", + "" + ] + } + } + ] +] \ No newline at end of file From 8bee18d285745b0a93d26ef8bf0e44eae8b0453f Mon Sep 17 00:00:00 2001 From: JBlond <leet31337@web.de> Date: Wed, 1 Feb 2023 12:29:15 +0100 Subject: [PATCH 39/46] Add: Json renderer Options --- README.md | 7 ++++--- lib/jblond/Diff/Renderer/Text/Json.php | 24 +++++++++++++++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0ccb5eab..349971fd 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ standard formats including: * Side by Side HTML * Unified HTML * Unified Commandline colored output +* JSON The logic behind the core of the diff engine (ie, the sequence matcher) is primarily based on the Python difflib package. The reason for doing so is @@ -147,9 +148,9 @@ at [jQuery-Merge-for-php-diff](https://github.com/DigiLive/jQuery-Merge-for-php- Contributors since I forked the repo. -* maxxer -* Creris -* jfcherng +* [maxxer](https://github.com/maxxer) +* [Creris](https://github.com/Creris) +* [jfcherng](https://github.com/jfcherng) * [DigiLive](https://github.com/DigiLive) ### License (BSD License) diff --git a/lib/jblond/Diff/Renderer/Text/Json.php b/lib/jblond/Diff/Renderer/Text/Json.php index ed86e1f5..07946227 100644 --- a/lib/jblond/Diff/Renderer/Text/Json.php +++ b/lib/jblond/Diff/Renderer/Text/Json.php @@ -22,6 +22,28 @@ */ class Json extends MainRendererAbstract { + + /** + * @var array Associative array containing the default options available for this renderer and their default + * value. + */ + private $subOptions = [ + 'json' => JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE + ]; + + /** + * InlineCli constructor. + * + * @param array $options Custom defined options for the InlineCli diff renderer. + * + * @see Json::$subOptions + */ + public function __construct(array $options = []) + { + parent::__construct($this->subOptions); + $this->setOptions($options); + } + /** * @return false|string */ @@ -33,7 +55,7 @@ public function render() foreach ($opCodes as $key => $group) { $return[] = $this->toArray($group); } - return json_encode($return, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + return json_encode($return, $this->options['json']); } /** From 94460efa113d10b1190e4e62dfe7cf6601a99b8d Mon Sep 17 00:00:00 2001 From: JBlond <leet31337@web.de> Date: Wed, 1 Feb 2023 13:55:06 +0100 Subject: [PATCH 40/46] Add: Json renderer Options --- lib/jblond/Diff/Renderer/Text/Json.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/jblond/Diff/Renderer/Text/Json.php b/lib/jblond/Diff/Renderer/Text/Json.php index 07946227..1c2ddd6a 100644 --- a/lib/jblond/Diff/Renderer/Text/Json.php +++ b/lib/jblond/Diff/Renderer/Text/Json.php @@ -22,7 +22,6 @@ */ class Json extends MainRendererAbstract { - /** * @var array Associative array containing the default options available for this renderer and their default * value. From 104e77fd84f87eb627a9492627585d8ddaba9f27 Mon Sep 17 00:00:00 2001 From: JBlond <leet31337@web.de> Date: Tue, 14 Feb 2023 09:53:31 +0100 Subject: [PATCH 41/46] Fix: Title, check if ext-json is loaded --- lib/jblond/Diff/Renderer/Text/Json.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/jblond/Diff/Renderer/Text/Json.php b/lib/jblond/Diff/Renderer/Text/Json.php index 1c2ddd6a..bffce672 100644 --- a/lib/jblond/Diff/Renderer/Text/Json.php +++ b/lib/jblond/Diff/Renderer/Text/Json.php @@ -2,10 +2,11 @@ namespace jblond\Diff\Renderer\Text; +use RuntimeException; use jblond\Diff\Renderer\MainRendererAbstract; /** - * Unified diff generator for PHP DiffLib. + * json diff generator for PHP DiffLib. * * PHP version 7.3 or greater * @@ -27,23 +28,28 @@ class Json extends MainRendererAbstract * value. */ private $subOptions = [ - 'json' => JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE + 'json' => JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR ]; /** - * InlineCli constructor. + * json constructor. * - * @param array $options Custom defined options for the InlineCli diff renderer. + * @param array $options Custom defined options for the json diff renderer. * * @see Json::$subOptions */ public function __construct(array $options = []) { + if (!extension_loaded('json')) { + throw new RuntimeException('json extension is not available'); + } parent::__construct($this->subOptions); $this->setOptions($options); } /** + * @inheritDoc + * * @return false|string */ public function render() @@ -51,13 +57,14 @@ public function render() $return = []; $opCodes = $this->diff->getGroupedOpCodes(); - foreach ($opCodes as $key => $group) { + foreach ($opCodes as $group) { $return[] = $this->toArray($group); } return json_encode($return, $this->options['json']); } /** + * Convert the * @param $group * @return array */ From bd5d3d322ffb826767f92f62df972bd92208848b Mon Sep 17 00:00:00 2001 From: JBlond <leet31337@web.de> Date: Tue, 14 Feb 2023 10:00:27 +0100 Subject: [PATCH 42/46] Fix: Line length and CLI test --- lib/jblond/Diff/Renderer/Text/Unified.php | 3 ++- lib/jblond/Diff/Renderer/Text/UnifiedCli.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/jblond/Diff/Renderer/Text/Unified.php b/lib/jblond/Diff/Renderer/Text/Unified.php index 897c30d5..261760f4 100644 --- a/lib/jblond/Diff/Renderer/Text/Unified.php +++ b/lib/jblond/Diff/Renderer/Text/Unified.php @@ -50,7 +50,8 @@ public function render() $iGroup2 = -1; } - $diff .= '@@ -' . ($iGroup1 + 1) . ',' . ($iGroup2 - $iGroup1) . ' +' . ($jGroup1 + 1) . ',' . ($jGroup2 - $jGroup1) . " @@\n"; + $diff .= '@@ -' . ($iGroup1 + 1) . ',' . ($iGroup2 - $iGroup1) . ' +' . ($jGroup1 + 1) + . ',' . ($jGroup2 - $jGroup1) . " @@\n"; foreach ($group as [$tag, $iGroup1, $iGroup2, $jGroup1, $jGroup2]) { if ($tag == 'equal') { $diff .= ' ' . diff --git a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php index 6d5a74b2..dd0285d1 100644 --- a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php +++ b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php @@ -82,7 +82,8 @@ private function output(): string } $diff .= $this->colorizeString( - '@@ -' . ($iGroup1 + 1) . ',' . ($iGroup2 - $iGroup1) . ' +' . ($jGroup1 + 1) . ',' . ($jGroup2 - $jGroup1) . " @@\n", + '@@ -' . ($iGroup1 + 1) . ',' . ($iGroup2 - $iGroup1) . ' +' . ($jGroup1 + 1) + . ',' . ($jGroup2 - $jGroup1) . " @@\n", 'purple' ); From 7f64374a3c6553a80029bb981cb3697caa39cb9a Mon Sep 17 00:00:00 2001 From: DigiLive <info@digiLive.nl> Date: Sun, 19 Feb 2023 10:33:42 +0100 Subject: [PATCH 43/46] Fix #125 - Make str_split multibyte save str_split() will split into bytes, rather than characters when dealing with a multi-byte encoded string. Use mb_str_split() to split the string into code points. --- composer.json | 3 ++- lib/jblond/Diff/SequenceMatcher.php | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 3f3b1233..490cce8a 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,8 @@ "require": { "php": ">=7.3", "ext-mbstring": "*", - "ext-pcre": "*" + "ext-pcre": "*", + "symfony/polyfill-mbstring": "^1" }, "require-dev": { "phpunit/phpunit": "^8 || ^9", diff --git a/lib/jblond/Diff/SequenceMatcher.php b/lib/jblond/Diff/SequenceMatcher.php index 48497634..ded67ee1 100644 --- a/lib/jblond/Diff/SequenceMatcher.php +++ b/lib/jblond/Diff/SequenceMatcher.php @@ -136,7 +136,7 @@ public function setSequences($version1, $version2): void public function setSeq1($version1): void { if (!is_array($version1)) { - $version1 = str_split($version1); + $version1 = mb_str_split($version1); } if ($version1 == $this->old) { return; @@ -159,7 +159,7 @@ public function setSeq1($version1): void public function setSeq2($version2): void { if (!is_array($version2)) { - $version2 = str_split($version2); + $version2 = mb_str_split($version2); } if ($version2 == $this->new) { return; From 06d1b8f4dd5b34b961501e21c8be00845cc6f616 Mon Sep 17 00:00:00 2001 From: JBlond <leet31337@web.de> Date: Tue, 1 Aug 2023 15:34:07 +0200 Subject: [PATCH 44/46] Add: Docker compose dev environment. --- docker-compose.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..7bfd6bb6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +version: '3.9' +# For all options see +# https://dockerfile.readthedocs.io/en/latest/content/DockerImages/dockerfiles/php-nginx-dev.html +services: + php: + image: webdevops/php-nginx-dev:8.2 + container_name: diff + working_dir: /app + environment: + - WEB_DOCUMENT_ROOT=/app/example + - WEB_DOCUMENT_INDEX=example.php + - PHP_DISPLAY_ERRORS=1 + - PHP_MEMORY_LIMIT=2048M + - PHP_MAX_EXECUTION_TIME=-1 + - PHP_DATE_TIMEZONE = Europe/Berlin + - XDEBUG_IDE_KEY=PHPSTORM + ports: + - "88:80" + - "9000:9000" + volumes: + - ./:/app:rw,cached From 0428dff7ac7fa2b96f5c32dd00b851e9edfff98f Mon Sep 17 00:00:00 2001 From: Mario <JBlond@users.noreply.github.com> Date: Tue, 15 Oct 2024 10:46:28 +0200 Subject: [PATCH 45/46] Version number is depricated --- docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7bfd6bb6..18e3520f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3.9' # For all options see # https://dockerfile.readthedocs.io/en/latest/content/DockerImages/dockerfiles/php-nginx-dev.html services: From 994211443fd4d8f7873afb800845513cd17db375 Mon Sep 17 00:00:00 2001 From: Mario <JBlond@users.noreply.github.com> Date: Sat, 10 May 2025 12:25:23 +0200 Subject: [PATCH 46/46] Update docker-compose.yml Fix ENV entry --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 18e3520f..c4a37646 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ services: - PHP_DISPLAY_ERRORS=1 - PHP_MEMORY_LIMIT=2048M - PHP_MAX_EXECUTION_TIME=-1 - - PHP_DATE_TIMEZONE = Europe/Berlin + - PHP_DATE_TIMEZONE=Europe/Berlin - XDEBUG_IDE_KEY=PHPSTORM ports: - "88:80"