Page MenuHomePhabricator

D16097.diff
No OneTemporary

D16097.diff

diff --git a/src/utils/PhutilProseDiff.php b/src/utils/PhutilProseDiff.php
--- a/src/utils/PhutilProseDiff.php
+++ b/src/utils/PhutilProseDiff.php
@@ -16,6 +16,66 @@
return $this->parts;
}
+ /**
+ * Get diff parts, but replace large blocks of unchanged text with "."
+ * parts representing missing context.
+ */
+ public function getSummaryParts() {
+ $parts = $this->getParts();
+
+ $head_key = head_key($parts);
+ $last_key = last_key($parts);
+
+ $results = array();
+ foreach ($parts as $key => $part) {
+ $is_head = ($key == $head_key);
+ $is_last = ($key == $last_key);
+
+ switch ($part['type']) {
+ case '=':
+ $pieces = $this->splitTextForSummary($part['text']);
+
+ if ($is_head || $is_last) {
+ $need = 2;
+ } else {
+ $need = 3;
+ }
+
+ // We don't have enough pieces to omit anything, so just continue.
+ if (count($pieces) < $need) {
+ $results[] = $part;
+ break;
+ }
+
+ if (!$is_head) {
+ $results[] = array(
+ 'type' => '=',
+ 'text' => head($pieces),
+ );
+ }
+
+ $results[] = array(
+ 'type' => '.',
+ 'text' => null,
+ );
+
+ if (!$is_last) {
+ $results[] = array(
+ 'type' => '=',
+ 'text' => last($pieces),
+ );
+ }
+ break;
+ default:
+ $results[] = $part;
+ break;
+ }
+ }
+
+ return $results;
+ }
+
+
public function reorderParts() {
// Reorder sequences of removed and added sections to put all the "-"
// parts together first, then all the "+" parts together. This produces
@@ -191,5 +251,30 @@
);
}
+ private function splitTextForSummary($text) {
+ $matches = null;
+
+ $ok = preg_match('/^(\n*[^\n]+)\n/', $text, $matches);
+ if (!$ok) {
+ return array($text);
+ }
+
+ $head = $matches[1];
+ $text = substr($text, strlen($head));
+
+ $ok = preg_match('/\n([^\n]+\n*)\z/', $text, $matches);
+ if (!$ok) {
+ return array($text);
+ }
+
+ $last = $matches[1];
+ $text = substr($text, 0, -strlen($last));
+
+ if (!strlen(trim($text))) {
+ return array($head, $last);
+ } else {
+ return array($head, $text, $last);
+ }
+ }
}
diff --git a/src/utils/__tests__/PhutilProseDiffTestCase.php b/src/utils/__tests__/PhutilProseDiffTestCase.php
--- a/src/utils/__tests__/PhutilProseDiffTestCase.php
+++ b/src/utils/__tests__/PhutilProseDiffTestCase.php
@@ -86,6 +86,42 @@
),
pht('Whole word rewrite with whitespace prefix and suffix.'));
+ $this->assertSummaryProseParts(
+ "a\nb\nc\nd\ne\nf\ng\nh\n",
+ "a\nb\nc\nd\nX\nf\ng\nh\n",
+ array(
+ '.',
+ "= d\n",
+ '- e',
+ '+ X',
+ "= \nf",
+ '.',
+ ),
+ pht('Summary diff with middle change.'));
+
+ $this->assertSummaryProseParts(
+ "a\nb\nc\nd\ne\nf\ng\nh\n",
+ "X\nb\nc\nd\ne\nf\ng\nh\n",
+ array(
+ '- a',
+ '+ X',
+ "= \nb",
+ '.',
+ ),
+ pht('Summary diff with head change.'));
+
+ $this->assertSummaryProseParts(
+ "a\nb\nc\nd\ne\nf\ng\nh\n",
+ "a\nb\nc\nd\ne\nf\ng\nX\n",
+ array(
+ '.',
+ "= g\n",
+ '- h',
+ '+ X',
+ "= \n",
+ ),
+ pht('Summary diff with last change.'));
+
}
private function assertProseParts($old, $new, array $expect_parts, $label) {
@@ -94,12 +130,44 @@
$parts = $diff->getParts();
+ $this->assertParts($expect_parts, $parts, $label);
+ }
+
+ private function assertSummaryProseParts(
+ $old,
+ $new,
+ array $expect_parts,
+ $label) {
+
+ $engine = new PhutilProseDifferenceEngine();
+ $diff = $engine->getDiff($old, $new);
+
+ $parts = $diff->getSummaryParts();
+
+ $this->assertParts($expect_parts, $parts, $label);
+ }
+
+ private function assertParts(
+ array $expect,
+ array $actual_parts,
+ $label) {
+
$actual = array();
- foreach ($parts as $part) {
- $actual[] = $part['type'].' '.$part['text'];
+ foreach ($actual_parts as $actual_part) {
+ $type = $actual_part['type'];
+ $text = $actual_part['text'];
+
+ switch ($type) {
+ case '.':
+ $actual[] = $type;
+ break;
+ default:
+ $actual[] = "{$type} {$text}";
+ break;
+ }
}
- $this->assertEqual($expect_parts, $actual, $label);
+ $this->assertEqual($expect, $actual, $label);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 12, 1:26 PM (1 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7587557
Default Alt Text
D16097.diff (4 KB)

Event Timeline