diff --git a/example/cli.php b/example/cli.php index 77cf8f50..18054cf2 100644 --- a/example/cli.php +++ b/example/cli.php @@ -2,18 +2,23 @@ use jblond\cli\Cli; use jblond\Diff; +use jblond\Diff\Renderer\Text\InlineCli; use jblond\Diff\Renderer\Text\UnifiedCli; -// Include and instantiate autoloader. -require '../vendor/autoload.php'; +// Validate the interpreter. +if (php_sapi_name() !== '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!'); +} -// jblond\cli\Cli -$cli = new Cli(); +// Include and instantiate autoloader. +require '../vendor/autoload.php'; // Include two sample files for comparison. -$a = file_get_contents(dirname(__FILE__) . '/a.txt'); -$b = file_get_contents(dirname(__FILE__) . '/b.txt'); +$sampleA = file_get_contents(dirname(__FILE__) . '/a.txt'); +$sampleB = file_get_contents(dirname(__FILE__) . '/b.txt'); $customOptions = [ 'context' => 2, @@ -23,18 +28,48 @@ ]; // Choose one of the initializations. -$diff = new Diff($a, $b); +$diff = new Diff($sampleA, $sampleB); +//$diff = new Diff($a, $b, $customOptions); // Initialize the diff class with custom options. +// Instantiate Cli wrapper +$cli = new Cli(); // Generate a unified diff. -// \jblond\Diff\Renderer\Text $renderer = new UnifiedCli(); +echo "-= Unified Default =-\n\n"; +$cli->output($diff->render($renderer)); + +echo "\n\n-= Unified Colored =-\n\n"; + +$renderer = new UnifiedCli( +// Define renderer options. + [ + 'cliColor' => 'simple', + ] +); + +$cli->output($diff->render($renderer)); +// Generate an inline diff. +$renderer = new InlineCli( +// Define renderer options. + [ + 'deleteMarkers' => ['-', '-'], + 'insertMarkers' => ['+', '+'], + 'equalityMarkers' => ['=', 'x'], + ] +); +echo "-= Inline Marked =-\n\n"; $cli->output($diff->render($renderer)); -echo "\n\n Now Colored\n\n"; +echo "-= Inline Colored =-\n\n"; -$coloredRenderer = new UnifiedCli(['cliColor'=>'simple']); +$coloredRenderer = new InlineCli( +// Define renderer options. + [ + 'cliColor' => true, + ] +); $cli->output($diff->render($coloredRenderer)); diff --git a/example/example.php b/example/example.php index f0546a2b..f3637528 100644 --- a/example/example.php +++ b/example/example.php @@ -2,8 +2,8 @@ use jblond\Diff; use jblond\Diff\Renderer\Html\Inline; -use jblond\Diff\Renderer\Html\Unified as HtmlUnified; use jblond\Diff\Renderer\Html\SideBySide; +use jblond\Diff\Renderer\Html\Unified as HtmlUnified; use jblond\Diff\Renderer\Text\Context; use jblond\Diff\Renderer\Text\Unified; @@ -11,8 +11,8 @@ require '../vendor/autoload.php'; // Include two sample files for comparison. -$a = file_get_contents(dirname(__FILE__) . '/a.txt'); -$b = file_get_contents(dirname(__FILE__) . '/b.txt'); +$sampleA = file_get_contents(dirname(__FILE__) . '/a.txt'); +$sampleB = file_get_contents(dirname(__FILE__) . '/b.txt'); // Options for generating the diff. $customOptions = [ @@ -23,7 +23,7 @@ ]; // Choose one of the initializations. -$diff = new Diff($a, $b); // Initialize the diff class with default options. +$diff = new Diff($sampleA, $sampleB); // Initialize the diff class with default options. //$diff = new Diff($a, $b, $customOptions); // Initialize the diff class with custom options. ?> @@ -34,14 +34,14 @@ @@ -52,17 +52,13 @@ function changeCSS(cssFile, cssLinkIndex) { Light Theme Dark Theme -
+

HTML Side by Side Diff

'Custom title for version1', - 'title2' => 'Custom title for version2', - ]); + $renderer = new SideBySide(); echo $diff->Render($renderer); ?> @@ -71,7 +67,6 @@ function changeCSS(cssFile, cssLinkIndex) { render($renderer); ?> @@ -79,7 +74,6 @@ function changeCSS(cssFile, cssLinkIndex) {

HTML Unified Diff

{$diff->render($renderer)}"; ?> @@ -87,7 +81,6 @@ function changeCSS(cssFile, cssLinkIndex) {

Text Unified Diff

' . htmlspecialchars($diff->render($renderer)) . ''; ?> @@ -95,7 +88,6 @@ function changeCSS(cssFile, cssLinkIndex) {

Text Context Diff

' . htmlspecialchars($diff->render($renderer)) . ''; ?> diff --git a/lib/jblond/Diff/Renderer/Html/Inline.php b/lib/jblond/Diff/Renderer/Html/Inline.php index 49ba0ec8..9937c51a 100644 --- a/lib/jblond/Diff/Renderer/Html/Inline.php +++ b/lib/jblond/Diff/Renderer/Html/Inline.php @@ -4,41 +4,75 @@ namespace jblond\Diff\Renderer\Html; +use jblond\Diff\Renderer\MainRenderer; +use jblond\Diff\Renderer\SubRendererInterface; + /** * Inline HTML diff generator for PHP DiffLib. * * PHP version 7.2 or greater * - * @package jblond\Diff\Renderer\Html - * @author Chris Boulton - * @author Mario Brandt - * @author Ferry Cools - * @copyright (c) 2020 Mario Brandt - * @license New BSD License http://www.opensource.org/licenses/bsd-license.php - * @version 2.1.1 - * @link https://github.com/JBlond/php-diff + * @package jblond\Diff\Renderer\Html + * @author Chris Boulton + * @author Mario Brandt + * @author Ferry Cools + * @copyright (c) 2009 Chris Boulton + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.0.0 + * @link https://github.com/JBlond/php-diff */ -class Inline extends HtmlArray +class Inline extends MainRenderer implements SubRendererInterface { /** - * Render a and return diff-view with changes between the two sequences displayed side by side. (under each other) + * @var array Associative array containing the default options available for this renderer and their default + * value. + * - format Format of the texts. + * - insertMarkers Markers for inserted text. + * - deleteMarkers Markers for removed text. + * - title1 Title of the 1st version of text. + * - title2 Title of the 2nd version of text. + */ + protected $subOptions = [ + 'format' => 'html', + 'insertMarkers' => ['', ''], + 'deleteMarkers' => ['', ''], + 'title1' => 'Version1', + 'title2' => 'Version2', + ]; + + /** + * Inline constructor. + * + * @param array $options Custom defined options for the inline diff renderer. + * + * @see Inline::$subOptions + */ + public function __construct(array $options = []) + { + parent::__construct(); + $this->setOptions($this->subOptions); + $this->setOptions($options); + } + + /** + * Render and return a diff-view with changes between the two sequences displayed inline (under each other). * * @return string The generated inline diff-view. */ public function render(): string { - $changes = parent::render(); + $changes = parent::renderSequences(); - return parent::renderHtml($changes, $this); + return parent::renderOutput($changes, $this); } - /** - * Generates a string representation of the opening of a predefined table and its header with titles from options. + * Generates a string representation of the opening of a table and its header with titles from the sub renderer's + * options. * * @return string HTML code representation of a table's header. */ - public function generateTableHeader(): string + public function generateDiffHeader(): string { return << @@ -53,11 +87,11 @@ public function generateTableHeader(): string } /** - * Generates a string representation of table rows showing lines are skipped. + * Generates a string representation of table rows with lines that are skipped. * - * @return string HTML code representation of a table's header. + * @return string HTML code representation of skipped lines. */ - public function generateTableRowsSkipped(): string + public function generateSkippedLines(): string { return << @@ -69,13 +103,13 @@ public function generateTableRowsSkipped(): string } /** - * Generates a string representation of table rows showing text with no difference. + * Generate a string representation of table rows with lines without differences between both versions. * * @param array $changes Contains the op-codes about the changes between two blocks. * - * @return string HTML code representing table rows showing text with no difference. + * @return string HTML code representing table rows showing text without differences. */ - public function generateTableRowsEqual(array $changes): string + public function generateLinesEqual(array $changes): string { $html = ''; @@ -96,13 +130,13 @@ public function generateTableRowsEqual(array $changes): string } /** - * Generates a string representation of table rows showing added text. + * Generates a string representation of table rows with lines that are added to the 2nd version. * * @param array $changes Contains the op-codes about the changes between two blocks of text. * * @return string HTML code representing table rows showing with added text. */ - public function generateTableRowsInsert(array $changes): string + public function generateLinesInsert(array $changes): string { $html = ''; @@ -125,13 +159,13 @@ public function generateTableRowsInsert(array $changes): string } /** - * Generates a string representation of table rows showing removed text. + * Generates a string representation of table rows with lines that are removed from the 2nd version. * * @param array $changes Contains the op-codes about the changes between two blocks of text. * * @return string HTML code representing table rows showing removed text. */ - public function generateTableRowsDelete(array $changes): string + public function generateLinesDelete(array $changes): string { $html = ''; @@ -154,20 +188,20 @@ public function generateTableRowsDelete(array $changes): string } /** - * Generates a string representation of table rows showing partially modified text. + * Generates a string representation of table rows with lines that are partially modified. * * @param array $changes Contains the op-codes about the changes between two blocks of text. * * @return string Html code representing table rows showing modified text. */ - public function generateTableRowsReplace(array $changes): string + public function generateLinesReplace(array $changes): string { $html = ''; foreach ($changes['base']['lines'] as $lineNo => $line) { $fromLine = $changes['base']['offset'] + $lineNo + 1; - - $html .= <<options['deleteMarkers'], $line); + $html .= << $fromLine   @@ -180,8 +214,8 @@ public function generateTableRowsReplace(array $changes): string foreach ($changes['changed']['lines'] as $lineNo => $line) { $toLine = $changes['changed']['offset'] + $lineNo + 1; - - $html .= <<options['insertMarkers'], $line); + $html .= <<   $toLine @@ -194,4 +228,38 @@ public function generateTableRowsReplace(array $changes): string return $html; } + + /** + * Generate a string representation of the start of a block. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string Start of the diff view. + */ + public function generateBlockHeader(array $changes): string + { + return ''; + } + + /** + * Generate a string representation of the end of a block. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string End of the block. + */ + public function generateBlockFooter(array $changes): string + { + return ''; + } + + /** + * Generate a string representation of the end of a diff view. + * + * @return string End of the diff view. + */ + public function generateDiffFooter(): string + { + return ''; + } } diff --git a/lib/jblond/Diff/Renderer/Html/SideBySide.php b/lib/jblond/Diff/Renderer/Html/SideBySide.php index 56336539..d406ce89 100644 --- a/lib/jblond/Diff/Renderer/Html/SideBySide.php +++ b/lib/jblond/Diff/Renderer/Html/SideBySide.php @@ -4,6 +4,9 @@ namespace jblond\Diff\Renderer\Html; +use jblond\Diff\Renderer\MainRenderer; +use jblond\Diff\Renderer\SubRendererInterface; + /** * Side by Side HTML diff generator for PHP DiffLib. * @@ -15,11 +18,42 @@ * @author Ferry Cools * @copyright (c) 2009 Chris Boulton * @license New BSD License http://www.opensource.org/licenses/bsd-license.php - * @version 2.1.1 + * @version 2.0.0 * @link https://github.com/JBlond/php-diff */ -class SideBySide extends HtmlArray +class SideBySide extends MainRenderer implements SubRendererInterface { + /** + * @var array Associative array containing the default options available for this renderer and their default + * value. + * - format Format of the texts. + * - insertMarkers Markers for inserted text. + * - deleteMarkers Markers for removed text. + * - title1 Title of the 1st version of text. + * - title2 Title of the 2nd version of text. + */ + protected $subOptions = [ + 'format' => 'html', + 'insertMarkers' => ['', ''], + 'deleteMarkers' => ['', ''], + 'title1' => 'Version1', + 'title2' => 'Version2', + ]; + + /** + * SideBySide constructor. + * + * @param array $options Custom defined options for the inline diff renderer. + * + * @see Inline::$subOptions + */ + public function __construct(array $options = []) + { + parent::__construct(); + $this->setOptions($this->subOptions); + $this->setOptions($options); + } + /** * Render a and return diff-view with changes between the two sequences displayed side by side. * @@ -27,9 +61,9 @@ class SideBySide extends HtmlArray */ public function render(): string { - $changes = parent::render(); + $changes = parent::renderSequences(); - return parent::renderHtml($changes, $this); + return parent::renderOutput($changes, $this); } /** @@ -37,7 +71,7 @@ public function render(): string * * @return string HTML code representation of a table's header. */ - public function generateTableHeader(): string + public function generateDiffHeader(): string { return << @@ -51,11 +85,11 @@ public function generateTableHeader(): string } /** - * Generates a string representation of table rows showing lines are skipped. + * Generates a string representation of table rows with lines that are skipped. * * @return string HTML code representation of a table's header. */ - public function generateTableRowsSkipped(): string + public function generateSkippedLines(): string { return << @@ -68,13 +102,13 @@ public function generateTableRowsSkipped(): string } /** - * Generates a string representation of table rows showing text with no difference. + * Generate a string representation of table rows with lines without differences between both versions. * * @param array $changes Contains the op-codes about the changes between two blocks. * * @return string HTML code representing table rows showing text with no difference. */ - public function generateTableRowsEqual(array $changes): string + public function generateLinesEqual(array $changes): string { $html = ''; @@ -100,13 +134,13 @@ public function generateTableRowsEqual(array $changes): string } /** - * Generates a string representation of table rows showing added text. + * Generates a string representation of table rows with lines that are added to the 2nd version. * * @param array $changes Contains the op-codes about the changes between two blocks of text. * * @return string HTML code representing table rows showing with added text. */ - public function generateTableRowsInsert(array $changes): string + public function generateLinesInsert(array $changes): string { $html = ''; @@ -129,13 +163,13 @@ public function generateTableRowsInsert(array $changes): string } /** - * Generates a string representation of table rows showing removed text. + * Generates a string representation of table rows with lines that are removed from the 2nd version. * * @param array $changes Contains the op-codes about the changes between two blocks of text. * * @return string HTML code representing table rows showing removed text. */ - public function generateTableRowsDelete(array $changes): string + public function generateLinesDelete(array $changes): string { $html = ''; @@ -158,13 +192,13 @@ public function generateTableRowsDelete(array $changes): string } /** - * Generates a string representation of table rows showing partially modified text. + * Generates a string representation of table rows with lines that are partially modified. * * @param array $changes Contains the op-codes about the changes between two blocks of text. * * @return string Html code representing table rows showing modified text. */ - public function generateTableRowsReplace(array $changes): string + public function generateLinesReplace(array $changes): string { $html = ''; @@ -174,11 +208,15 @@ public function generateTableRowsReplace(array $changes): string $fromLine = $changes['base']['offset'] + $lineNo + 1; $toLine = " "; $changedLine = " "; + if (isset($changes['changed']['lines'][$lineNo])) { $toLine = $changes['changed']['offset'] + $lineNo + 1; $changedLine = $changes['changed']['lines'][$lineNo]; } + $line = str_replace(["\0", "\1"], $this->options['deleteMarkers'], $line); + $changedLine = str_replace(["\0", "\1"], $this->options['insertMarkers'], $changedLine); + $html .= << $fromLine @@ -192,33 +230,42 @@ public function generateTableRowsReplace(array $changes): string HTML; } - - return $html; } - foreach ($changes['changed']['lines'] as $lineNo => $changedLine) { - $toLine = $changes['changed']['offset'] + $lineNo + 1; - $fromLine = " "; - $line = " "; - if (isset($changes['base']['lines'][$lineNo])) { - $fromLine = $changes['base']['offset'] + $lineNo + 1; - $line = $changes['base']['lines'][$lineNo]; - } + return $html; + } - $html .= << - $fromLine - - $line - - $toLine - - $changedLine - - -HTML; - } + /** + * Generate a string representation of the start of a block. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string Start of the diff view. + */ + public function generateBlockHeader(array $changes): string + { + return ''; + } - return $html; + /** + * Generate a string representation of the end of a block. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string End of the block. + */ + public function generateBlockFooter(array $changes): string + { + return ''; + } + + /** + * Generate a string representation of the end of a diff view. + * + * @return string End of the diff view. + */ + public function generateDiffFooter(): string + { + return ''; } } diff --git a/lib/jblond/Diff/Renderer/Html/Unified.php b/lib/jblond/Diff/Renderer/Html/Unified.php index 33977de0..42164d59 100644 --- a/lib/jblond/Diff/Renderer/Html/Unified.php +++ b/lib/jblond/Diff/Renderer/Html/Unified.php @@ -4,94 +4,91 @@ namespace jblond\Diff\Renderer\Html; +use jblond\Diff\Renderer\MainRenderer; +use jblond\Diff\Renderer\SubRendererInterface; + /** * Unified HTML diff generator for PHP DiffLib. * * PHP version 7.2 or greater * - * @package jblond\Diff\Renderer\Html - * @author Mario Brandt - * @author Ferry Cools - * @copyright (c) 2020 Mario Brandt - * @license New BSD License http://www.opensource.org/licenses/bsd-license.php - * @version 2.1.1 - * @link https://github.com/JBlond/php-diff + * @package jblond\Diff\Renderer\Html + * @author Chris Boulton + * @author Mario Brandt + * @author Ferry Cools + * @copyright (c) 2009 Chris Boulton + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.0.0 + * @link https://github.com/JBlond/php-diff */ -class Unified extends HtmlArray +class Unified extends MainRenderer implements SubRendererInterface { /** - * Render and return a unified diff-view with changes between the two sequences displayed inline (under each other). + * @var array Associative array containing the default options available for this renderer and their default + * value. + * - format Format of the texts. + * - insertMarkers Markers for inserted text. + * - deleteMarkers Markers for removed text. + * - title1 Title of the "old" version of text. + * - title2 Title of the "new" version of text. + */ + protected $subOptions = [ + 'format' => 'html', + 'insertMarkers' => ['', ''], + 'deleteMarkers' => ['', ''], + 'title1' => 'Version1', + 'title2' => 'Version2', + ]; + + /** + * Unified constructor. + * + * @param array $options Custom defined options for the inline diff renderer. + * + * @see Inline::$subOptions + */ + public function __construct(array $options = []) + { + parent::__construct(); + $this->setOptions($this->subOptions); + $this->setOptions($options); + } + + /** + * Render a and return diff-view with changes between the two sequences (under each other). * - * @return string The generated inline diff-view. + * @return string The generated unified diff-view. */ public function render(): string { - $changes = parent::render(); + $changes = parent::renderSequences(); - return $this->renderHtml($changes); + return parent::renderOutput($changes, $this); } /** - * Render the unified diff-view as html. + * Generates a string representation of the opening of a predefined table and its header with titles from options. * - * Since this class extends the "HtmlArray" class which in turn extends "RendererAbstract" class, this method needs - * to match the signature of RendererAbstract::renderHTML(). However the second parameter isn't used and can be - * omitted. - * - * @param array $changes Contains the op-codes about the differences between "old and "new". - * @param null $object Unused. - * - * @return string HTML code containing the unified differences. + * @return string HTML code representation of the diff-view header. */ - public function renderHtml($changes, $object = null): string + public function generateDiffHeader(): string { - if (empty($changes)) { - //No changes between "old" and "new" - return 'No differences found.'; - } - - $html = ''; - - foreach ($changes as $i => $blocks) { - if ($i > 0) { - // If this is a separate block, we're condensing code to output …, - // indicating a significant portion of the code has been collapsed as it did not change. - $html .= <<… -HTML; - } - - foreach ($blocks as $change) { - $html .= ''; - switch ($change['tag']) { - case 'equal': - // Add unmodified lines. - $html .= $this->generateLinesEqual($change); - break; - case 'insert': - // Add Added lines. - $html .= $this->generateLinesInsert($change); - break; - case 'delete': - // Add deleted lines. - $html .= $this->generateLinesDelete($change); - break; - case 'replace': - // Add modified lines. - $html .= $this->generateLinesReplace($change); - break; - } - $html .= ''; - } - } - $html .= ''; + return ''; + } - return $html; + /** + * Generates a string representation of lines that are skipped. + * + * @return string HTML code representation of a table's header. + */ + public function generateSkippedLines(): string + { + return '
'; } /** - * Generates a string representation of blocks of text with no difference. + * Generate a string representation of lines without differences between both versions. * * @param array $change Contains the op-codes about the changes between two blocks. * @@ -109,7 +106,7 @@ public function generateLinesEqual(array $change): string } /** - * Generates a string representation of a block of text, where new text was added. + * Generates a string representation of lines that are added to the 2nd version. * * @param array $change Contains the op-codes about the changes between two blocks. * @@ -127,7 +124,7 @@ public function generateLinesInsert(array $change): string } /** - * Generates a string representation of a block of text, where text was removed. + * Generates a string representation of lines that are removed from the 2nd version. * * @param array $change Contains the op-codes about the changes between two blocks. * @@ -144,7 +141,7 @@ public function generateLinesDelete(array $change): string } /** - * Generates a string representation of a block of text, where text was partially modified. + * Generates a string representation of a lines that are partially modified. * * @param array $change Contains the op-codes about the changes between two blocks. * @@ -156,14 +153,50 @@ public function generateLinesReplace(array $change): string // Lines with characters removed. foreach ($change['base']['lines'] as $line) { + $line = str_replace(["\0", "\1"], $this->options['deleteMarkers'], $line); $html .= '' . $line . '
'; } // Lines with characters added. foreach ($change['changed']['lines'] as $line) { + $line = str_replace(["\0", "\1"], $this->options['insertMarkers'], $line); $html .= '' . $line . '
'; } return $html; } + + /** + * Generate a string representation of the start of a block. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string Start of the diff view. + */ + public function generateBlockHeader(array $changes): string + { + return ''; + } + + /** + * Generate a string representation of the end of a block. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string End of the block. + */ + public function generateBlockFooter(array $changes): string + { + return ''; + } + + /** + * Generate a string representation of the end of a diff view. + * + * @return string End of the diff view. + */ + public function generateDiffFooter(): string + { + return '
'; + } } diff --git a/lib/jblond/Diff/Renderer/Html/HtmlArray.php b/lib/jblond/Diff/Renderer/MainRenderer.php similarity index 70% rename from lib/jblond/Diff/Renderer/Html/HtmlArray.php rename to lib/jblond/Diff/Renderer/MainRenderer.php index d906ff04..c44c1b15 100644 --- a/lib/jblond/Diff/Renderer/Html/HtmlArray.php +++ b/lib/jblond/Diff/Renderer/MainRenderer.php @@ -2,43 +2,31 @@ declare(strict_types=1); -namespace jblond\Diff\Renderer\Html; - -use jblond\Diff\Renderer\RendererAbstract; +namespace jblond\Diff\Renderer; /** - * Base renderer for rendering HTML based diffs for PHP DiffLib. + * Base renderer for rendering diffs for PHP DiffLib. * * PHP version 7.2 or greater * - * @package jblond\Diff\Renderer\Html - * @author Chris Boulton - * @author Mario Brandt - * @author Ferry Cools - * @copyright (c) 2020 Mario Brandt - * @license New BSD License http://www.opensource.org/licenses/bsd-license.php - * @version 2.1.1 - * @link https://github.com/JBlond/php-diff + * @package jblond\Diff\Renderer\Html + * @author Chris Boulton + * @author Mario Brandt + * @author Ferry Cools + * @copyright (c) 2009 Chris Boulton + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.0.0 + * @link https://github.com/JBlond/php-diff */ -class HtmlArray extends RendererAbstract +class MainRenderer extends MainRendererAbstract { /** - * @var array Associative array containing the default options available - * for this renderer and their default value. - * - * - tabSize The amount of spaces to replace a tab character with. - * - title_a Title of the "old" version of text. - * - title_b Title of the "new" version of text. + * @var int */ - protected $defaultOptions = [ - 'tabSize' => 4, - 'title1' => 'Version1', - 'title2' => 'Version2', - ]; - + protected $maxLineMarkerWidth = 0; /** * @var string The last operation which was recorded in the array which contains the changes, used by the renderer. - * @see HtmlArray::appendChangesArray() + * @see MainRenderer::appendChangesArray() */ private $lastTag; @@ -47,66 +35,74 @@ class HtmlArray extends RendererAbstract * * This method is called by the renderers which extends this class. * - * @param array $changes Contains the op-codes about the differences between "old and "new". - * @param object|Inline|SideBySide|Unified $htmlRenderer Renderer which extends this class. + * @param array $changes Contains the op-codes about the differences between "old and "new". + * @param object $subRenderer Renderer which is subClass of this class. * - * @return string HTML representation of the differences. + * @return string Representation of the differences. */ - public function renderHtml(array $changes, object $htmlRenderer): string + public function renderOutput(array $changes, object $subRenderer): string { - if (empty($changes)) { + if (!$changes) { //No changes between "old" and "new" return 'No differences found.'; } - $html = $htmlRenderer->generateTableHeader(); + $output = $subRenderer->generateDiffHeader(); - foreach ($changes as $i => $blocks) { - if ($i > 0) { - // If this is a separate block, we're condensing code to output …, - // indicating a significant portion of the code has been collapsed as it did not change. - $html .= $htmlRenderer->generateTableRowsSkipped(); + 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(); + } + + if ($this->options['format'] == 'plain') { + $this->maxLineMarkerWidth = + max( + strlen($this->options['insertMarkers'][0]), + strlen($this->options['deleteMarkers'][0]), + strlen($this->options['equalityMarkers'][0]), + strlen($this->options['equalityMarkers'][1]) + ); } foreach ($blocks as $change) { - $html .= ''; + $output .= $subRenderer->generateBlockHeader($change); switch ($change['tag']) { - // Equal changes should be shown on both sides of the diff case 'equal': - $html .= $htmlRenderer->generateTableRowsEqual($change); + $output .= $subRenderer->generateLinesEqual($change); break; - // Added lines only on the right side case 'insert': - $html .= $htmlRenderer->generateTableRowsInsert($change); + $output .= $subRenderer->generateLinesInsert($change); break; - // Show deleted lines only on the left side case 'delete': - $html .= $htmlRenderer->generateTableRowsDelete($change); + $output .= $subRenderer->generateLinesDelete($change); break; - // Show modified lines on both sides case 'replace': - $html .= $htmlRenderer->generateTableRowsReplace($change); + $output .= $subRenderer->generateLinesReplace($change); break; } - $html .= ''; + $output .= $subRenderer->generateBlockFooter($change); } } - $html .= ''; + $output .= $subRenderer->generateDiffFooter(); - return $html; + return $output; } /** - * Render and return an array structure suitable for generating HTML based differences. + * Render the sequences where differences between them are marked. + * + * The marked sequences are returned as array which is suitable for rendering the final output. * - * Generally called by classes which extend this class and that generate a HTML based diff by returning an array of - * the changes to show in the diff. + * Generally called by classes which extend this class and that generate a diff by returning an array of the changes + * to show in the diff. * - * @return array An array of the generated changes, suitable for presentation in HTML. + * @return array An array of marked sequences. */ - public function render() + protected function renderSequences(): array { // The old and New texts are copied so change markers can be added without modifying the original sequences. $oldText = $this->diff->getVersion1(); @@ -160,15 +156,11 @@ public function render() if ($tag == 'replace' || $tag == 'delete') { // Inline differences or old block doesn't exist in the new text. - // Replace the markers, which where added above, by HTML delete tags. - $oldBlock = str_replace(["\0", "\1"], ['', ''], $oldBlock); $blocks[$lastBlock]['base']['lines'] += $oldBlock; } if ($tag == 'replace' || $tag == 'insert') { // Inline differences or the new block doesn't exist in the old text. - // Replace the markers, which where added above, by HTML insert tags. - $newBlock = str_replace(["\0", "\1"], ['', ''], $newBlock); $blocks[$lastBlock]['changed']['lines'] += $newBlock; } } @@ -200,10 +192,10 @@ public function render() */ private function markInlineChange(array &$oldText, array &$newText, $startOld, $endOld, $startNew) { - for ($i = 0; $i < ($endOld - $startOld); ++$i) { + for ($iterator = 0; $iterator < ($endOld - $startOld); ++$iterator) { // Check each line in the block for differences. - $oldString = $oldText[$startOld + $i]; - $newString = $newText[$startNew + $i]; + $oldString = $oldText[$startOld + $iterator]; + $newString = $newText[$startNew + $iterator]; // Determine the start and end position of the line difference. [$start, $end] = $this->getInlineChange($oldString, $newString); @@ -224,8 +216,8 @@ private function markInlineChange(array &$oldText, array &$newText, $startOld, $ mb_substr($newString, $sequenceEnd); // Overwrite the strings in the old and new text so the changed lines include the markers. - $oldText[$startOld + $i] = $oldString; - $newText[$startNew + $i] = $newString; + $oldText[$startOld + $iterator] = $oldString; + $newText[$startNew + $iterator] = $newString; } } } @@ -304,6 +296,7 @@ private function appendChangesArray(array &$blocks, string $tag, int $lineInOld, ]; $this->lastTag = $tag; + return count($blocks) - 1; } @@ -322,32 +315,34 @@ protected function formatLines(array $strings): array if ($this->options['tabSize'] !== false) { // Replace tabs with spaces. $strings = array_map( - function ($item) { - return str_replace("\t", str_repeat(' ', $this->options['tabSize']), $item); + function ($line) { + return str_replace("\t", str_repeat(' ', $this->options['tabSize']), $line); }, $strings ); } - // Convert special characters to HTML entities - $strings = array_map( - function ($item) { - return htmlspecialchars($item, ENT_NOQUOTES, 'UTF-8'); - }, - $strings - ); - - // Replace leading spaces of a line with HTML entities. - foreach ($strings as &$line) { - $line = preg_replace_callback( - '/(^[ \0\1]*)/', - function ($matches) { - return str_replace(' ', " ", $matches[0]); + if (strtolower($this->options['format']) == 'html') { + // Convert special characters to HTML entities + $strings = array_map( + function ($line) { + return htmlspecialchars($line, ENT_NOQUOTES, 'UTF-8'); }, - $line + $strings ); + + // Replace leading spaces of a line with HTML entities. + foreach ($strings as &$line) { + $line = preg_replace_callback( + '/(^[ \0\1]*)/', + function ($matches) { + return str_replace(' ', " ", $matches[0]); + }, + $line + ); + } + unset($line); } - unset($line); return $strings; } diff --git a/lib/jblond/Diff/Renderer/MainRendererAbstract.php b/lib/jblond/Diff/Renderer/MainRendererAbstract.php new file mode 100644 index 00000000..be7b86c4 --- /dev/null +++ b/lib/jblond/Diff/Renderer/MainRendererAbstract.php @@ -0,0 +1,83 @@ + + * @author Ferry Cools + * @copyright (c) 2009 Chris Boulton + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.0.0 + * @link https://github.com/JBlond/php-diff + */ +abstract class MainRendererAbstract +{ + + /** + * @var Diff $diff Instance of the diff class that this renderer is generating the rendered diff for. + */ + public $diff; + + /** + * @var array Associative array containing the default options available for this renderer and their default + * value. + * - tabSize The amount of spaces to replace a tab character with. + * - format The format of the input texts. + * - cliColor Colorized output for cli. + * - deleteMarkers Markers for removed text. + * - insertMarkers Markers for inserted text. + * - equalityMarkers Markers for unchanged and changed lines. + * - insertColors Fore- and background color for inserted text. Only when cloColor = true. + * - deleteColors Fore- and background color for removed text. Only when cloColor = true. + */ + protected $mainOptions = [ + 'tabSize' => 4, + 'format' => 'plain', + 'cliColor' => false, + 'deleteMarkers' => ['', ''], + 'insertMarkers' => ['', ''], + 'equalityMarkers' => ['', ''], + 'insertColors' => ['black', 'green'], + 'deleteColors' => ['black', 'red'], + ]; + + /** + * @var array Array containing a merge between the default options and user applied options for the renderer. + * @see MainRendererAbstract::$mainOptions + */ + protected $options = []; + + /** + * The constructor. Instantiates the rendering engine and if options are passed, + * sets the options for the renderer. + * + * @param array $options Optionally, an array of the options for the renderer. + */ + public function __construct(array $options = []) + { + $this->setOptions($options); + } + + /** + * Set the options of the main renderer to the supplied options. + * + * Options are merged with the default to ensure that there aren't any missing options. + * When custom options are added to the default ones, they can be overwritten, but they can't be removed. + * @see MainRendererAbstract::$mainOptions + * + * @param array $options Array of options to set. + */ + public function setOptions(array $options) + { + $this->options = array_merge($this->mainOptions, $this->options, $options); + } +} diff --git a/lib/jblond/Diff/Renderer/RendererAbstract.php b/lib/jblond/Diff/Renderer/RendererAbstract.php deleted file mode 100644 index 500f4ecf..00000000 --- a/lib/jblond/Diff/Renderer/RendererAbstract.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @author Mario Brandt - * @author Ferry Cools - * @copyright (c) 2020 Mario Brandt - * @license New BSD License http://www.opensource.org/licenses/bsd-license.php - * @version 2.1.1 - * @link https://github.com/JBlond/php-diff - */ -abstract class RendererAbstract -{ - - /** - * @var Diff $diff Instance of the diff class that this renderer is generating the rendered diff for. - */ - public $diff; - - /** - * @var array Array of the default options that apply to this renderer. - */ - protected $defaultOptions = [ - 'title1' => 'Version1', - 'title2' => 'Version2', - ]; - - /** - * @var array Array containing the user applied and merged default options for the renderer. - */ - protected $options = []; - - /** - * The constructor. Instantiates the rendering engine and if options are passed, - * sets the options for the renderer. - * - * @param array $options Optionally, an array of the options for the renderer. - */ - public function __construct(array $options = []) - { - $this->setOptions($options); - } - - /** - * Set the options of the renderer to those supplied in the passed in array. - * Options are merged with the default to ensure that there aren't any missing - * options. - * - * @param array $options Array of options to set. - */ - public function setOptions(array $options) - { - $this->options = array_merge($this->defaultOptions, $options); - } -} diff --git a/lib/jblond/Diff/Renderer/SubRendererInterface.php b/lib/jblond/Diff/Renderer/SubRendererInterface.php new file mode 100644 index 00000000..f9c84e68 --- /dev/null +++ b/lib/jblond/Diff/Renderer/SubRendererInterface.php @@ -0,0 +1,102 @@ + + * @copyright (c) 2020 Ferry Cools + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.0.0 + * @link https://github.com/JBlond/php-diff + */ +interface SubRendererInterface +{ + /** + * Render and return a diff-view with changes between two sequences. + * + * @return string The generated diff-view. + */ + public function render(): string; + + /** + * Generate a string representation of the start of a diff view. + * + * @return string Start of the diff view. + */ + public function generateDiffHeader(): string; + + /** + * Generate a string representation of the start of a block. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string Start of the diff view. + */ + public function generateBlockHeader(array $changes): string; + + /** + * Generate a string representation of lines that are skipped in the diff view. + * + * @return string Representation of skipped lines. + */ + public function generateSkippedLines(): string; + + /** + * Generate a string representation of lines without differences between both versions. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string Text with no difference. + */ + public function generateLinesEqual(array $changes): string; + + /** + * Generate a string representation of lines that are added to the 2nd version. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string Added text. + */ + public function generateLinesInsert(array $changes): string; + + /** + * Generate a string representation of lines that are removed from the 2nd version. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string Removed text. + */ + public function generateLinesDelete(array $changes): string; + + /** + * Generate a string representation of lines that are partially modified. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string Modified text. + */ + public function generateLinesReplace(array $changes): string; + + /** + * Generate a string representation of the end of a block. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string End of the block. + */ + public function generateBlockFooter(array $changes): string; + + /** + * Generate a string representation of the end of a diff view. + * + * @return string End of the diff view. + */ + public function generateDiffFooter(): string; +} diff --git a/lib/jblond/Diff/Renderer/Text/Context.php b/lib/jblond/Diff/Renderer/Text/Context.php index 71ae5f5e..63f086f7 100644 --- a/lib/jblond/Diff/Renderer/Text/Context.php +++ b/lib/jblond/Diff/Renderer/Text/Context.php @@ -4,7 +4,7 @@ namespace jblond\Diff\Renderer\Text; -use jblond\Diff\Renderer\RendererAbstract; +use jblond\Diff\Renderer\MainRendererAbstract; /** * Context diff generator for PHP DiffLib. @@ -20,7 +20,7 @@ * @version 2.1.1 * @link https://github.com/JBlond/php-diff */ -class Context extends RendererAbstract +class Context extends MainRendererAbstract { /** * @var array Array of the different op-code tags and how they map to the context diff-view equivalent. diff --git a/lib/jblond/Diff/Renderer/Text/InlineCli.php b/lib/jblond/Diff/Renderer/Text/InlineCli.php new file mode 100644 index 00000000..5629fac2 --- /dev/null +++ b/lib/jblond/Diff/Renderer/Text/InlineCli.php @@ -0,0 +1,255 @@ + + * @copyright (c) 2020 Ferry Cools + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.0.0 + * @link https://github.com/JBlond/php-diff + */ +class InlineCli extends MainRenderer implements SubRendererInterface +{ + /** + * @var array Associative array containing the default options available for this renderer and their default + * value. + */ + protected $subOptions = []; + + /** + * InlineCli constructor. + * + * @param array $options Custom defined options for the inline diff renderer. + * + * @see Inline::$subOptions + */ + public function __construct(array $options = []) + { + parent::__construct(); + $this->setOptions($this->subOptions); + $this->setOptions($options); + } + + /** + * Render a and return diff-view with changes between the two sequences displayed inline. + * + * @return string The generated diff-view. + */ + public function render(): string + { + $changes = parent::renderSequences(); + + return parent::renderOutput($changes, $this); + } + + + /** + * Generate a string representation of the start of a diff view. + * + * @return string Start of the diff view. + */ + public function generateDiffHeader(): string + { + return ''; + } + + /** + * Generate a string representation of the start of a block. + * + * @param array $changes Contains the op-codes about the changes between two blocks of lines. + * + * @return string Start of the diff view. + */ + public function generateBlockHeader($changes): string + { + return ''; + } + + /** + * Generate a string representation of the lines that are skipped in the diff view. + * + * @return string Representation of skipped lines. + */ + public function generateSkippedLines(): string + { + return '...' . PHP_EOL; + } + + /** + * Generate a string representation lines without differences between the two versions. + * + * @param array $changes Contains the op-codes about the changes between two blocks of lines. + * + * @return string Text with no difference. + */ + public function generateLinesEqual(array $changes): string + { + $returnValue = ''; + $padding = str_repeat(' ', $this->maxLineMarkerWidth - strlen($this->options['equalityMarkers'][0])); + + foreach ($changes['base']['lines'] as $line) { + $returnValue .= $this->options['equalityMarkers'][0] . $padding . '|' . $line . PHP_EOL; + } + + return $returnValue; + } + + /** + * Generate a string representation of lines that are added to the 2nd version. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string Added text. + */ + public function generateLinesInsert(array $changes): string + { + $colorize = new CliColors(); + $returnValue = ''; + $padding = str_repeat(' ', $this->maxLineMarkerWidth - strlen($this->options['insertMarkers'][0])); + + foreach ($changes['changed']['lines'] as $line) { + if ($this->options['cliColor']) { + [$fgColor, $bgColor] = $this->options['insertColors']; + $line = $colorize->getColoredString($line, $fgColor, $bgColor); + } + $returnValue .= $this->options['insertMarkers'][0] . $padding . '|' . $line . PHP_EOL; + } + + return $returnValue; + } + + /** + * Generate a string representation of lines that are removed from the 2nd version. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string Removed text. + */ + public function generateLinesDelete(array $changes): string + { + $colorize = new CliColors(); + $returnValue = ''; + $padding = str_repeat(' ', $this->maxLineMarkerWidth - strlen($this->options['deleteMarkers'][0])); + + foreach ($changes['base']['lines'] as $line) { + if ($this->options['cliColor']) { + [$fgColor, $bgColor] = $this->options['deleteColors']; + $line = $colorize->getColoredString($line, $fgColor, $bgColor); + } + $returnValue .= $this->options['deleteMarkers'][0] . $padding . '|' . $line . PHP_EOL; + } + + return $returnValue; + } + + /** + * Generate a string representation of lines that are partially modified. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string Modified text. + */ + public function generateLinesReplace(array $changes): string + { + $returnValue = ''; + + $changes['base']['lines'] = $this->mergeChanges( + $changes['base']['lines'], + $changes['changed']['lines'], + $this->options['deleteColors'], + $this->options['insertColors'] + ); + + $returnValue .= implode(PHP_EOL, $changes['base']['lines']) . PHP_EOL; + + return $returnValue; + } + + /** + * Merge the changes between two lines together and mark these changes. + * + * @param array $baseLines Lines of version 1. + * @param array $changedLines Lines of version 2. + * @param array|null[] $deleteColors Fore- and background colors of part that is removed from the 2nd version. + * @param array|null[] $insertColors Fore- and background colors of part that is added to the 2nd version. + * + * Option $deleteColors and $insertColors only have affect when this class's cliColors option is set to true. + * + * @return array + */ + private function mergeChanges( + array $baseLines, + array $changedLines, + array $deleteColors = [null, null], + array $insertColors = [null, null] + ): array { + $padding = str_repeat(' ', $this->maxLineMarkerWidth - strlen($this->options['equalityMarkers'][1])); + if ($this->options['cliColor']) { + $colorize = new CliColors(); + } + + foreach ($baseLines as $lineKey => $line) { + $iterator = 0; + $baselineParts = preg_split('/\x00(.*?)\x01/', $line, -1, PREG_SPLIT_DELIM_CAPTURE); + $changedLineParts = preg_split('/\x00(.*?)\x01/', $changedLines[$lineKey], -1, PREG_SPLIT_DELIM_CAPTURE); + + foreach ($baselineParts as $partKey => &$part) { + if ($iterator++ % 2) { + // This part of the line has been changed. Surround it with user defied markers. + $basePart = $this->options['deleteMarkers'][0] . $part . $this->options['deleteMarkers'][1]; + $changedPart = + $this->options['insertMarkers'][0] . + $changedLineParts[$partKey] . + $this->options['insertMarkers'][1]; + + if ($this->options['cliColor']) { + // Colorize the changed part. + [$fgColor, $bgColor] = $deleteColors; + $basePart = $colorize->getColoredString($basePart, $fgColor, $bgColor); + [$fgColor, $bgColor] = $insertColors; + $changedPart = $colorize->getColoredString($changedPart, $fgColor, $bgColor); + } + $part = $basePart . $changedPart; + } + } + unset($part); + $baseLines[$lineKey] = $this->options['equalityMarkers'][1] . $padding . '|' . implode('', $baselineParts); + } + + return $baseLines; + } + + /** + * Generate a string representation of the end of a block. + * + * @param array $changes Contains the op-codes about the changes between two blocks of text. + * + * @return string End of the block + */ + public function generateBlockFooter(array $changes): string + { + return ''; + } + + /** + * Generate a string representation of the end of a diff view. + * + * @return string End of the diff view. + */ + public function generateDiffFooter(): string + { + return ''; + } +} diff --git a/lib/jblond/Diff/Renderer/Text/Unified.php b/lib/jblond/Diff/Renderer/Text/Unified.php index 6e84218e..50a1c58a 100644 --- a/lib/jblond/Diff/Renderer/Text/Unified.php +++ b/lib/jblond/Diff/Renderer/Text/Unified.php @@ -4,7 +4,7 @@ namespace jblond\Diff\Renderer\Text; -use jblond\Diff\Renderer\RendererAbstract; +use jblond\Diff\Renderer\MainRendererAbstract; /** * Unified diff generator for PHP DiffLib. @@ -23,7 +23,7 @@ /** * Class Diff_Renderer_Text_Unified */ -class Unified extends RendererAbstract +class Unified extends MainRendererAbstract { /** * Render and return a unified diff. diff --git a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php index 877ab5f9..3949bbea 100644 --- a/lib/jblond/Diff/Renderer/Text/UnifiedCli.php +++ b/lib/jblond/Diff/Renderer/Text/UnifiedCli.php @@ -4,21 +4,22 @@ use InvalidArgumentException; use jblond\cli\CliColors; -use jblond\Diff\Renderer\RendererAbstract; +use jblond\Diff\Renderer\MainRendererAbstract; /** * Unified diff generator for PHP DiffLib. * * PHP version 7.2 or greater * - * @package jblond\Diff\Renderer\Text - * @author Mario Brandt - * @license New BSD License http://www.opensource.org/licenses/bsd-license.php - * @version 2.1.1 - * @link https://github.com/JBlond/php-diff + * @package jblond\Diff\Renderer\Text + * @author Mario Brandt + * @copyright (c) 2020 Mario Brandt + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.0.0 + * @link https://github.com/JBlond/php-diff */ -class UnifiedCli extends RendererAbstract +class UnifiedCli extends MainRendererAbstract { /** @@ -26,14 +27,9 @@ class UnifiedCli extends RendererAbstract */ private $colors; - /** - * @var array - */ - protected $options; - /** * UnifiedCli constructor. - * @param array $options + * @param array $options */ public function __construct(array $options = []) { @@ -61,11 +57,11 @@ public function render(): string /** - * @param string $string + * @param $string * @param string $color * @return string */ - private function colorizeString(string $string, string $color = ''): string + private function colorizeString($string, $color = ''): string { if (isset($this->options['cliColor']) && $this->options['cliColor'] == 'simple') { return $this->colors->getColoredString($string, $color); diff --git a/tests/Diff/Renderer/Html/HtmlArrayTest.php b/tests/Diff/Renderer/Html/HtmlArrayTest.php deleted file mode 100644 index 5b7313b5..00000000 --- a/tests/Diff/Renderer/Html/HtmlArrayTest.php +++ /dev/null @@ -1,91 +0,0 @@ -diff = new Diff( - ['a'], - [] - ); - $result = $htmlRenderer->render(); - static::assertEquals([ - [ - [ - 'tag' => 'delete', - 'base' => [ - 'offset' => 0, - 'lines' => [ - 'a' - ] - ], - 'changed' => [ - 'offset' => 0, - 'lines' => [] - ] - ] - ] - ], $result); - } - - /** - * - */ - public function testRenderFixesSpaces() - { - $htmlRenderer = new HtmlArray(); - $htmlRenderer->diff = new Diff( - [' a'], - ['a'] - ); - $result = $htmlRenderer->render(); - static::assertEquals([ - [ - [ - 'tag' => 'replace', - 'base' => [ - 'offset' => 0, - 'lines' => [ - "    a", - ] - ], - 'changed' => [ - 'offset' => 0, - 'lines' => [ - 'a' - ] - ] - ] - ] - ], $result); - } -} diff --git a/tests/Diff/Renderer/Html/HtmlRenderersTest.php b/tests/Diff/Renderer/Html/HtmlRenderersTest.php index d88b6a87..a3fff39a 100644 --- a/tests/Diff/Renderer/Html/HtmlRenderersTest.php +++ b/tests/Diff/Renderer/Html/HtmlRenderersTest.php @@ -13,11 +13,17 @@ /** * Class HtmlRendererTest * - * PHPUnit tests to verify the output of the HTML renderers hasn't change by code changes. + * PHPUnit tests to verify that the output of the HTML renderers did not change due to code changes. * - * @package Tests\Diff\Renderer\Html + * @package Tests\Diff\Renderer\Html + * @author Mario Brandt + * @author Ferry Cools + * @copyright (c) 2020 Mario Brandt + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.0.0 + * @link https://github.com/JBlond/php-diff */ -class HtmlRendererTest extends TestCase +class HtmlRenderersTest extends TestCase { /** * @var bool Store the renderer's output in a file, when set to true. @@ -27,9 +33,9 @@ class HtmlRendererTest extends TestCase /** * Constructor. * - * @param null $name - * @param array $data - * @param string $dataName + * @param null $name + * @param array $data + * @param string $dataName */ public function __construct($name = null, array $data = [], $dataName = '') { @@ -38,6 +44,7 @@ public function __construct($name = null, array $data = [], $dataName = '') } /** + * Test the output of the HTML Side by Side renderer. * @covers \jblond\Diff\Renderer\Html\SideBySide */ public function testSideBySide() @@ -47,8 +54,8 @@ public function testSideBySide() file_get_contents('tests/resources/b.txt') ); - $renderer = new SideBySide(); - $result = $diff->render($renderer); + $renderer = new SideBySide(); + $result = $diff->render($renderer); if ($this->genOutputFiles) { file_put_contents('htmlSideBySide.txt', $result); } @@ -57,6 +64,7 @@ public function testSideBySide() } /** + * Test the output of the HTML Inline renderer. * @covers \jblond\Diff\Renderer\Html\Inline */ public function testInline() @@ -66,8 +74,14 @@ public function testInline() file_get_contents('tests/resources/b.txt') ); - $renderer = new Inline(); - $result = $diff->render($renderer); + $renderer = new Inline( + [ + 'format' => 'html', + 'insertMarkers' => ['', ''], + 'deleteMarkers' => ['', ''], + ] + ); + $result = $diff->render($renderer); if ($this->genOutputFiles) { file_put_contents('htmlInline.txt', $result); } @@ -76,6 +90,7 @@ public function testInline() } /** + * Test the output of the HTML Unified renderer. * @covers \jblond\Diff\Renderer\Html\Unified */ public function testUnified() @@ -85,8 +100,8 @@ public function testUnified() file_get_contents('tests/resources/b.txt') ); - $renderer = new Unified(); - $result = $diff->render($renderer); + $renderer = new Unified(); + $result = $diff->render($renderer); if ($this->genOutputFiles) { file_put_contents('htmlUnified.txt', $result); } diff --git a/tests/Diff/Renderer/MainRendererTest.php b/tests/Diff/Renderer/MainRendererTest.php new file mode 100644 index 00000000..f07ff7a5 --- /dev/null +++ b/tests/Diff/Renderer/MainRendererTest.php @@ -0,0 +1,140 @@ + + * @author Ferry Cools + * @copyright (c) 2009 Mario Brandt + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.0.0 + * @link https://github.com/JBlond/php-diff + */ + +/** + * Class MainRendererTest + * @package Tests\Diff\Renderer\Html + */ +class MainRendererTest extends TestCase +{ + + /** + * @var string[] Defines the main renderer options. + */ + public $rendererOptions = [ + 'format' => 'html', + ]; + + /** + * MainRendererTest constructor. + * + * @param null $name + * @param array $data + * @param string $dataName + */ + public function __construct($name = null, array $data = [], $dataName = '') + { + //new \jblond\Autoloader(); + parent::__construct($name, $data, $dataName); + } + + /** + * + */ + public function testRenderSimpleDelete() + { + $renderer = new MainRenderer(); + $renderer->diff = new Diff( + ['a'], + [] + ); + $result = $this->invokeMethod($renderer, 'renderSequences'); + static::assertEquals( + [ + [ + [ + 'tag' => 'delete', + 'base' => [ + 'offset' => 0, + 'lines' => [ + 'a', + ], + ], + 'changed' => [ + 'offset' => 0, + 'lines' => [], + ], + ], + ], + ], + $result + ); + } + + /** + * Call protected/private method of a class. + * + * @param object &$object Instantiated object that we will run method on. + * @param string $methodName Method name to call + * @param array $parameters Array of parameters to pass into method. + * + * @return mixed Method return. + * @throws \ReflectionException If the class doesn't exist. + */ + public function invokeMethod(&$object, $methodName, array $parameters = []) + { + $reflection = new ReflectionClass(get_class($object)); + $method = $reflection->getMethod($methodName); + $method->setAccessible(true); + + return $method->invokeArgs($object, $parameters); + } + + /** + * + */ + public function testRenderFixesSpaces() + { + $renderer = new MainRenderer($this->rendererOptions); + $renderer->diff = new Diff( + [' a'], + ['a'] + ); + $result = $this->invokeMethod($renderer, 'renderSequences'); + + static::assertEquals( + [ + [ + [ + 'tag' => 'replace', + 'base' => [ + 'offset' => 0, + 'lines' => [ + "\0    \1a", + ], + ], + 'changed' => [ + 'offset' => 0, + 'lines' => [ + "\0\1a", + ], + ], + ], + ], + ], + $result + ); + } +} diff --git a/tests/Diff/Renderer/Text/TextRenderersTest.php b/tests/Diff/Renderer/Text/TextRenderersTest.php index eb5abdb5..c3489b0c 100644 --- a/tests/Diff/Renderer/Text/TextRenderersTest.php +++ b/tests/Diff/Renderer/Text/TextRenderersTest.php @@ -12,9 +12,15 @@ /** * Class TextRendererTest * - * PHPUnit tests to verify the output of the text renderers hasn't change by code changes. + * PHPUnit tests to verify that the output of the text renderers did not change due to code changes. * - * @package Tests\Diff\Renderer\Text + * @package Tests\Diff\Renderer\Text + * @author Mario Brandt + * @author Ferry Cools + * @copyright (c) 2019 Mario Brandt + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.0.0 + * @link https://github.com/JBlond/php-diff */ class TextRendererTest extends TestCase { @@ -24,11 +30,11 @@ class TextRendererTest extends TestCase private $genOutputFiles = false; /** - * Constructor. + * TextRendererTest constructor. * - * @param null $name - * @param array $data - * @param string $dataName + * @param null $name + * @param array $data + * @param string $dataName */ public function __construct($name = null, array $data = [], $dataName = '') { @@ -37,7 +43,7 @@ public function __construct($name = null, array $data = [], $dataName = '') } /** - * Test context + * Test the output of the text-context renderer. * @covers \jblond\Diff\Renderer\Text\Context */ public function testContext() @@ -47,8 +53,8 @@ public function testContext() file_get_contents('tests/resources/b.txt') ); - $renderer = new Context(); - $result = $diff->render($renderer); + $renderer = new Context(); + $result = $diff->render($renderer); if ($this->genOutputFiles) { file_put_contents('textContext.txt', $result); } @@ -57,7 +63,7 @@ public function testContext() } /** - * Test Unified + * Test the output of the text-unified renderer. * @covers \jblond\Diff\Renderer\Text\Unified */ public function testUnified() @@ -67,8 +73,8 @@ public function testUnified() file_get_contents('tests/resources/b.txt') ); - $renderer = new Unified(); - $result = $diff->render($renderer); + $renderer = new Unified(); + $result = $diff->render($renderer); if ($this->genOutputFiles) { file_put_contents('textUnified.txt', $result); } @@ -77,7 +83,7 @@ public function testUnified() } /** - * Test Unified Cli + * Test the output of the CLI text-context renderer. * @covers \jblond\Diff\Renderer\Text\UnifiedCli */ public function testUnifiedCli() @@ -92,6 +98,32 @@ public function testUnifiedCli() if ($this->genOutputFiles) { file_put_contents('textUnifiedCli.txt', $result); } - $this->assertStringEqualsFile('tests/resources/ab.diff', $result); + $this->assertStringEqualsFile('tests/resources/textUnifiedCli.txt', $result); + } + + /** + * Test the output of the CLI text-inline renderer. + * @covers \jblond\Diff\Renderer\Text\InlineCli + */ + public function testInlineCli() + { + $diff = new Diff( + file_get_contents('tests/resources/a.txt'), + file_get_contents('tests/resources/b.txt') + ); + + $renderer = new Diff\Renderer\Text\InlineCli( + [ + 'cliColor' => true, + 'deleteMarkers' => ['-', '-'], + 'insertMarkers' => ['+', '+'], + 'equalityMarkers' => ['=', 'x'], + ] + ); + $result = $diff->render($renderer); + if ($this->genOutputFiles) { + file_put_contents('textInlineCli.txt', $result); + } + $this->assertStringEqualsFile('tests/resources/textInlineCli.txt', $result); } } diff --git a/tests/Diff/SequenceMatcherTest.php b/tests/Diff/SequenceMatcherTest.php index f443741e..24c620c9 100644 --- a/tests/Diff/SequenceMatcherTest.php +++ b/tests/Diff/SequenceMatcherTest.php @@ -5,11 +5,25 @@ use jblond\Diff\SequenceMatcher; use PHPUnit\Framework\TestCase; +/** + * PHPUnit Test for the main renderer of PHP DiffLib. + * + * PHP version 7.2 or greater + * + * @package Tests\Diff + * @author Mario Brandt + * @author Ferry Cools + * @copyright (c) 2009 Mario Brandt + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.0.0 + * @link https://github.com/JBlond/php-diff + */ + class SequenceMatcherTest extends TestCase { /** - * Constructor. + * SequenceMatcherTest constructor. * * @param null $name * @param array $data diff --git a/tests/resources/htmlUnified.txt b/tests/resources/htmlUnified.txt index 35b0c9e9..2da3bdd7 100644 --- a/tests/resources/htmlUnified.txt +++ b/tests/resources/htmlUnified.txt @@ -1 +1 @@ -<html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
        <title>Hello World!</title>
        <title>Hello You!</title>
    </head>
    <body>
        <h1>This is demo content to show features of the php-diff package.</h1>
        <h2>This line is removed from version2.</h2>
        <h2>This line is the same for both versions.</h2>
        <h2>This line has inline differences between both versions.</h2>
        <h2>This line has differences between both versions.</h2>
        <h2>This line is the same for both versions.</h2>
        <h2>This line also has inline differences between both versions.</h2>
        <h2>This line also has InLine differences between both versions.</h2>
        <h2>This line is the same for both versions.</h2>
        <h2>This line is added to version2.</h2>

        <p>
            It's also compatible with multibyte characters (like Chinese and emoji) as shown below:
            另外我覺得那個評的白色櫃子有點沒有必要欸。外觀我就不說了 ,怎麼連空間都那麼狹隘。不過倒是從這個地方看出所謂的“改革”
            Do you know what "金槍魚罐頭" means in Chinese?
            🍏🍎🙂
            另外我覺得那個評的白色櫃子有點沒有必要欸。外觀我就不說了 ,怎麼連空間都那麼狹隘。不過倒是從這個地方看出所謂的“改革”
            Do you know what "魚の缶詰" means in Chinese?
            🍎🍏🙂
        </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>
        <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>
        <h2>This line also has inline differences between both versions. It's the whitespace in front.</h2>
        <h2>This line also has inline differences between both versions. It's the whitespace in front.</h2>
        <h2>This line is the same for both versions.</h2>
        <h2>This line also has inline differences between both versions.</h2>
        <h2>This line also has inline differences between both versions!</h2>
    </body>
</html>

\ No newline at end of file +<html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
        <title>Hello World!</title>
        <title>Hello You!</title>
    </head>
    <body>
        <h1>This is demo content to show features of the php-diff package.</h1>
        <h2>This line is removed from version2.</h2>
        <h2>This line is the same for both versions.</h2>
        <h2>This line has inline differences between both versions.</h2>
        <h2>This line has differences between both versions.</h2>
        <h2>This line is the same for both versions.</h2>
        <h2>This line also has inline differences between both versions.</h2>
        <h2>This line also has InLine differences between both versions.</h2>
        <h2>This line is the same for both versions.</h2>
        <h2>This line is added to version2.</h2>

        <p>
            It's also compatible with multibyte characters (like Chinese and emoji) as shown below:
            另外我覺得那個評的白色櫃子有點沒有必要欸。外觀我就不說了 ,怎麼連空間都那麼狹隘。不過倒是從這個地方看出所謂的“改革”
            Do you know what "金槍魚罐頭" means in Chinese?
            🍏🍎🙂
            另外我覺得那個評的白色櫃子有點沒有必要欸。外觀我就不說了 ,怎麼連空間都那麼狹隘。不過倒是從這個地方看出所謂的“改革”
            Do you know what "魚の缶詰" means in Chinese?
            🍎🍏🙂
        </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>
        <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>
        <h2>This line also has inline differences between both versions. It's the whitespace in front.</h2>
        <h2>This line also has inline differences between both versions. It's the whitespace in front.</h2>
        <h2>This line is the same for both versions.</h2>
        <h2>This line also has inline differences between both versions.</h2>
        <h2>This line also has inline differences between both versions!</h2>
    </body>
</html>

\ No newline at end of file diff --git a/tests/resources/textInlineCli.txt b/tests/resources/textInlineCli.txt new file mode 100644 index 00000000..3678f6f4 --- /dev/null +++ b/tests/resources/textInlineCli.txt @@ -0,0 +1,33 @@ +=| +=| +=| +x| Hello -World-+You+! +=| +=| +=|

This is demo content to show features of the php-diff package.

+-|

This line is removed from version2.

 +=|

This line is the same for both versions.

+x|

This line has -inline -++differences between both versions.

+=|

This line is the same for both versions.

+x|

This line also has -inl-+InL+ine differences between both versions.

+=|

This line is the same for both versions.

++|

This line is added to version2.

 +=| +=|

+=| It's also compatible with multibyte characters (like Chinese and emoji) as shown below: +x| 另外我覺得那個評-價-+鑑+的白色櫃子有點沒有必要欸。外觀我就不說了 ,怎麼連空間都那麼狹隘。不過倒是從這個地方看出所謂的“改革” +x| Do you know what "-金槍魚罐頭-+魚の缶詰+" means in Chinese? +x| -🍏🍎-+🍎🍏+🙂 +=|

+=| +=|

Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.

+... +=|

Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.

+=|

Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.

+=|

Just some lines to demonstrate the collapsing of a block of lines which are the same in both versions.

+x|- -+ +

This line also has inline differences between both versions. It's the whitespace in front.

+=|

This line is the same for both versions.

+x|

This line also has inline differences between both versions-.-+!+

+=| +=| +=| diff --git a/tests/resources/ab.diff b/tests/resources/textUnifiedCli.txt similarity index 100% rename from tests/resources/ab.diff rename to tests/resources/textUnifiedCli.txt