Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/infrastructure/diff/prose/__tests__/PhutilProseDiffTestCase.php
12242 views
1
<?php
2
3
final class PhutilProseDiffTestCase
4
extends PhabricatorTestCase {
5
6
public function testTrimApart() {
7
$map = array(
8
'' => array(),
9
'a' => array('a'),
10
' a ' => array(
11
' ',
12
'a',
13
' ',
14
),
15
' a' => array(
16
' ',
17
'a',
18
),
19
'a ' => array(
20
'a',
21
' ',
22
),
23
' a b ' => array(
24
' ',
25
'a b',
26
' ',
27
),
28
);
29
30
foreach ($map as $input => $expect) {
31
$actual = PhutilProseDifferenceEngine::trimApart($input);
32
$this->assertEqual(
33
$expect,
34
$actual,
35
pht('Trim Apart: %s', $input));
36
}
37
}
38
39
public function testProseDiffsDistance() {
40
$this->assertProseParts(
41
'',
42
'',
43
array(),
44
pht('Empty'));
45
46
$this->assertProseParts(
47
"xxx\nyyy",
48
"xxx\nzzz\nyyy",
49
array(
50
"= xxx\n",
51
"+ zzz\n",
52
'= yyy',
53
),
54
pht('Add Paragraph'));
55
56
$this->assertProseParts(
57
"xxx\nzzz\nyyy",
58
"xxx\nyyy",
59
array(
60
"= xxx\n",
61
"- zzz\n",
62
'= yyy',
63
),
64
pht('Remove Paragraph'));
65
66
$this->assertProseParts(
67
'xxx',
68
"xxxyyy\n.zzz",
69
array(
70
'= xxx',
71
"+ yyy\n.zzz",
72
),
73
pht('Amend paragraph, and add paragraph starting with punctuation'));
74
75
// Without smoothing, the alogorithm identifies that "shark" and "cat"
76
// both contain the letter "a" and tries to express this as a very
77
// fine-grained edit which replaces "sh" with "c" and then "rk" with "t".
78
// This is technically correct, but it is much easier for human viewers to
79
// parse if we smooth this into a single removal and a single addition.
80
81
$this->assertProseParts(
82
'They say the shark has nine lives.',
83
'They say the cat has nine lives.',
84
array(
85
'= They say the ',
86
'- shark',
87
'+ cat',
88
'= has nine lives.',
89
),
90
pht('"Shark/cat" word edit smoothenss.'));
91
92
$this->assertProseParts(
93
'Rising quickly, she says',
94
'Rising quickly, she remarks:',
95
array(
96
'= Rising quickly, she ',
97
'- says',
98
'+ remarks:',
99
),
100
pht('"Says/remarks" word edit smoothenss.'));
101
102
$this->assertProseParts(
103
'See screenshots',
104
'Viewed video files',
105
array(
106
'- See screenshots',
107
'+ Viewed video files',
108
),
109
pht('Complete paragraph rewrite.'));
110
111
$this->assertProseParts(
112
'xaaax',
113
'xbbbx',
114
array(
115
'- xaaax',
116
'+ xbbbx',
117
),
118
pht('Whole word rewrite with common prefix and suffix.'));
119
120
$this->assertProseParts(
121
' aaa ',
122
' bbb ',
123
array(
124
'= ',
125
'- aaa',
126
'+ bbb',
127
'= ',
128
),
129
pht('Whole word rewrite with whitespace prefix and suffix.'));
130
131
$this->assertSummaryProseParts(
132
"a\nb\nc\nd\ne\nf\ng\nh\n",
133
"a\nb\nc\nd\nX\nf\ng\nh\n",
134
array(
135
'.',
136
"= d\n",
137
'- e',
138
'+ X',
139
"= \nf",
140
'.',
141
),
142
pht('Summary diff with middle change.'));
143
144
$this->assertSummaryProseParts(
145
"a\nb\nc\nd\ne\nf\ng\nh\n",
146
"X\nb\nc\nd\ne\nf\ng\nh\n",
147
array(
148
'- a',
149
'+ X',
150
"= \nb",
151
'.',
152
),
153
pht('Summary diff with head change.'));
154
155
$this->assertSummaryProseParts(
156
"a\nb\nc\nd\ne\nf\ng\nh\n",
157
"a\nb\nc\nd\ne\nf\ng\nX\n",
158
array(
159
'.',
160
"= g\n",
161
'- h',
162
'+ X',
163
"= \n",
164
),
165
pht('Summary diff with last change.'));
166
167
$this->assertProseParts(
168
'aaa aaa aaa aaa, bbb bbb bbb bbb.',
169
"aaa aaa aaa aaa, bbb bbb bbb bbb.\n\n- ccc ccc ccc",
170
array(
171
'= aaa aaa aaa aaa, bbb bbb bbb bbb.',
172
"+ \n\n- ccc ccc ccc",
173
),
174
pht('Diff with new trailing content.'));
175
176
$this->assertProseParts(
177
'aaa aaa aaa aaa, bbb bbb bbb bbb.',
178
'aaa aaa aaa aaa bbb bbb bbb bbb.',
179
array(
180
'= aaa aaa aaa aaa',
181
'- ,',
182
'= bbb bbb bbb bbb.',
183
),
184
pht('Diff with a removed comma.'));
185
186
$this->assertProseParts(
187
'aaa aaa aaa aaa, bbb bbb bbb bbb.',
188
"aaa aaa aaa aaa bbb bbb bbb bbb.\n\n- ccc ccc ccc!",
189
array(
190
'= aaa aaa aaa aaa',
191
'- ,',
192
'= bbb bbb bbb bbb.',
193
"+ \n\n- ccc ccc ccc!",
194
),
195
pht('Diff with a removed comma and new trailing content.'));
196
197
$this->assertProseParts(
198
'[ ] Walnuts',
199
'[X] Walnuts',
200
array(
201
'= [',
202
'- ',
203
'+ X',
204
'= ] Walnuts',
205
),
206
pht('Diff adding a tickmark to a checkbox list.'));
207
208
$this->assertProseParts(
209
'[[ ./week49 ]]',
210
'[[ ./week50 ]]',
211
array(
212
'= [[ ./week',
213
'- 49',
214
'+ 50',
215
'= ]]',
216
),
217
pht('Diff changing a remarkup wiki link target.'));
218
219
// Create a large corpus with many sentences and paragraphs.
220
$large_paragraph = 'xyz. ';
221
$large_paragraph = str_repeat($large_paragraph, 50);
222
$large_paragraph = rtrim($large_paragraph);
223
224
$large_corpus = $large_paragraph."\n\n";
225
$large_corpus = str_repeat($large_corpus, 50);
226
$large_corpus = rtrim($large_corpus);
227
228
$this->assertProseParts(
229
$large_corpus,
230
"aaa\n\n".$large_corpus."\n\nzzz",
231
array(
232
"+ aaa\n\n",
233
'= '.$large_corpus,
234
"+ \n\nzzz",
235
),
236
pht('Adding initial and final lines to a large corpus.'));
237
238
}
239
240
private function assertProseParts($old, $new, array $expect_parts, $label) {
241
$engine = new PhutilProseDifferenceEngine();
242
$diff = $engine->getDiff($old, $new);
243
244
$parts = $diff->getParts();
245
246
$this->assertParts($expect_parts, $parts, $label);
247
}
248
249
private function assertSummaryProseParts(
250
$old,
251
$new,
252
array $expect_parts,
253
$label) {
254
255
$engine = new PhutilProseDifferenceEngine();
256
$diff = $engine->getDiff($old, $new);
257
258
$parts = $diff->getSummaryParts();
259
260
$this->assertParts($expect_parts, $parts, $label);
261
}
262
263
private function assertParts(
264
array $expect,
265
array $actual_parts,
266
$label) {
267
268
$actual = array();
269
foreach ($actual_parts as $actual_part) {
270
$type = $actual_part['type'];
271
$text = $actual_part['text'];
272
273
switch ($type) {
274
case '.':
275
$actual[] = $type;
276
break;
277
default:
278
$actual[] = "{$type} {$text}";
279
break;
280
}
281
}
282
283
$this->assertEqual($expect, $actual, $label);
284
}
285
286
287
}
288
289