Path: blob/master/src/infrastructure/diff/prose/__tests__/PhutilProseDiffTestCase.php
12242 views
<?php12final class PhutilProseDiffTestCase3extends PhabricatorTestCase {45public function testTrimApart() {6$map = array(7'' => array(),8'a' => array('a'),9' a ' => array(10' ',11'a',12' ',13),14' a' => array(15' ',16'a',17),18'a ' => array(19'a',20' ',21),22' a b ' => array(23' ',24'a b',25' ',26),27);2829foreach ($map as $input => $expect) {30$actual = PhutilProseDifferenceEngine::trimApart($input);31$this->assertEqual(32$expect,33$actual,34pht('Trim Apart: %s', $input));35}36}3738public function testProseDiffsDistance() {39$this->assertProseParts(40'',41'',42array(),43pht('Empty'));4445$this->assertProseParts(46"xxx\nyyy",47"xxx\nzzz\nyyy",48array(49"= xxx\n",50"+ zzz\n",51'= yyy',52),53pht('Add Paragraph'));5455$this->assertProseParts(56"xxx\nzzz\nyyy",57"xxx\nyyy",58array(59"= xxx\n",60"- zzz\n",61'= yyy',62),63pht('Remove Paragraph'));6465$this->assertProseParts(66'xxx',67"xxxyyy\n.zzz",68array(69'= xxx',70"+ yyy\n.zzz",71),72pht('Amend paragraph, and add paragraph starting with punctuation'));7374// Without smoothing, the alogorithm identifies that "shark" and "cat"75// both contain the letter "a" and tries to express this as a very76// fine-grained edit which replaces "sh" with "c" and then "rk" with "t".77// This is technically correct, but it is much easier for human viewers to78// parse if we smooth this into a single removal and a single addition.7980$this->assertProseParts(81'They say the shark has nine lives.',82'They say the cat has nine lives.',83array(84'= They say the ',85'- shark',86'+ cat',87'= has nine lives.',88),89pht('"Shark/cat" word edit smoothenss.'));9091$this->assertProseParts(92'Rising quickly, she says',93'Rising quickly, she remarks:',94array(95'= Rising quickly, she ',96'- says',97'+ remarks:',98),99pht('"Says/remarks" word edit smoothenss.'));100101$this->assertProseParts(102'See screenshots',103'Viewed video files',104array(105'- See screenshots',106'+ Viewed video files',107),108pht('Complete paragraph rewrite.'));109110$this->assertProseParts(111'xaaax',112'xbbbx',113array(114'- xaaax',115'+ xbbbx',116),117pht('Whole word rewrite with common prefix and suffix.'));118119$this->assertProseParts(120' aaa ',121' bbb ',122array(123'= ',124'- aaa',125'+ bbb',126'= ',127),128pht('Whole word rewrite with whitespace prefix and suffix.'));129130$this->assertSummaryProseParts(131"a\nb\nc\nd\ne\nf\ng\nh\n",132"a\nb\nc\nd\nX\nf\ng\nh\n",133array(134'.',135"= d\n",136'- e',137'+ X',138"= \nf",139'.',140),141pht('Summary diff with middle change.'));142143$this->assertSummaryProseParts(144"a\nb\nc\nd\ne\nf\ng\nh\n",145"X\nb\nc\nd\ne\nf\ng\nh\n",146array(147'- a',148'+ X',149"= \nb",150'.',151),152pht('Summary diff with head change.'));153154$this->assertSummaryProseParts(155"a\nb\nc\nd\ne\nf\ng\nh\n",156"a\nb\nc\nd\ne\nf\ng\nX\n",157array(158'.',159"= g\n",160'- h',161'+ X',162"= \n",163),164pht('Summary diff with last change.'));165166$this->assertProseParts(167'aaa aaa aaa aaa, bbb bbb bbb bbb.',168"aaa aaa aaa aaa, bbb bbb bbb bbb.\n\n- ccc ccc ccc",169array(170'= aaa aaa aaa aaa, bbb bbb bbb bbb.',171"+ \n\n- ccc ccc ccc",172),173pht('Diff with new trailing content.'));174175$this->assertProseParts(176'aaa aaa aaa aaa, bbb bbb bbb bbb.',177'aaa aaa aaa aaa bbb bbb bbb bbb.',178array(179'= aaa aaa aaa aaa',180'- ,',181'= bbb bbb bbb bbb.',182),183pht('Diff with a removed comma.'));184185$this->assertProseParts(186'aaa aaa aaa aaa, bbb bbb bbb bbb.',187"aaa aaa aaa aaa bbb bbb bbb bbb.\n\n- ccc ccc ccc!",188array(189'= aaa aaa aaa aaa',190'- ,',191'= bbb bbb bbb bbb.',192"+ \n\n- ccc ccc ccc!",193),194pht('Diff with a removed comma and new trailing content.'));195196$this->assertProseParts(197'[ ] Walnuts',198'[X] Walnuts',199array(200'= [',201'- ',202'+ X',203'= ] Walnuts',204),205pht('Diff adding a tickmark to a checkbox list.'));206207$this->assertProseParts(208'[[ ./week49 ]]',209'[[ ./week50 ]]',210array(211'= [[ ./week',212'- 49',213'+ 50',214'= ]]',215),216pht('Diff changing a remarkup wiki link target.'));217218// Create a large corpus with many sentences and paragraphs.219$large_paragraph = 'xyz. ';220$large_paragraph = str_repeat($large_paragraph, 50);221$large_paragraph = rtrim($large_paragraph);222223$large_corpus = $large_paragraph."\n\n";224$large_corpus = str_repeat($large_corpus, 50);225$large_corpus = rtrim($large_corpus);226227$this->assertProseParts(228$large_corpus,229"aaa\n\n".$large_corpus."\n\nzzz",230array(231"+ aaa\n\n",232'= '.$large_corpus,233"+ \n\nzzz",234),235pht('Adding initial and final lines to a large corpus.'));236237}238239private function assertProseParts($old, $new, array $expect_parts, $label) {240$engine = new PhutilProseDifferenceEngine();241$diff = $engine->getDiff($old, $new);242243$parts = $diff->getParts();244245$this->assertParts($expect_parts, $parts, $label);246}247248private function assertSummaryProseParts(249$old,250$new,251array $expect_parts,252$label) {253254$engine = new PhutilProseDifferenceEngine();255$diff = $engine->getDiff($old, $new);256257$parts = $diff->getSummaryParts();258259$this->assertParts($expect_parts, $parts, $label);260}261262private function assertParts(263array $expect,264array $actual_parts,265$label) {266267$actual = array();268foreach ($actual_parts as $actual_part) {269$type = $actual_part['type'];270$text = $actual_part['text'];271272switch ($type) {273case '.':274$actual[] = $type;275break;276default:277$actual[] = "{$type} {$text}";278break;279}280}281282$this->assertEqual($expect, $actual, $label);283}284285286}287288289