Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F97221575
PhutilProseDiffTestCase.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Jan 3, 13:54
Size
5 KB
Mime Type
text/x-php
Expires
Sun, Jan 5, 13:54 (2 d)
Engine
blob
Format
Raw Data
Handle
23357762
Attached To
rPHU libphutil
PhutilProseDiffTestCase.php
View Options
<?php
final
class
PhutilProseDiffTestCase
extends
PhutilTestCase
{
public
function
testProseDiffsDistance
()
{
$this
->
assertProseParts
(
''
,
''
,
array
(),
pht
(
'Empty'
));
$this
->
assertProseParts
(
"xxx
\n
yyy"
,
"xxx
\n
zzz
\n
yyy"
,
array
(
"= xxx
\n
"
,
"+ zzz
\n
"
,
'= yyy'
,
),
pht
(
'Add Paragraph'
));
$this
->
assertProseParts
(
"xxx
\n
zzz
\n
yyy"
,
"xxx
\n
yyy"
,
array
(
"= xxx
\n
"
,
"- zzz
\n
"
,
'= yyy'
,
),
pht
(
'Remove Paragraph'
));
// Without smoothing, the alogorithm identifies that "shark" and "cat"
// both contain the letter "a" and tries to express this as a very
// fine-grained edit which replaces "sh" with "c" and then "rk" with "t".
// This is technically correct, but it is much easier for human viewers to
// parse if we smooth this into a single removal and a single addition.
$this
->
assertProseParts
(
'They say the shark has nine lives.'
,
'They say the cat has nine lives.'
,
array
(
'= They say the '
,
'- shark'
,
'+ cat'
,
'= has nine lives.'
,
),
pht
(
'"Shark/cat" word edit smoothenss.'
));
$this
->
assertProseParts
(
'Rising quickly, she says'
,
'Rising quickly, she remarks:'
,
array
(
'= Rising quickly, she '
,
'- says'
,
'+ remarks:'
,
),
pht
(
'"Says/remarks" word edit smoothenss.'
));
$this
->
assertProseParts
(
'See screenshots'
,
'Viewed video files'
,
array
(
'- See screenshots'
,
'+ Viewed video files'
,
),
pht
(
'Complete paragraph rewrite.'
));
$this
->
assertProseParts
(
'xaaax'
,
'xbbbx'
,
array
(
'- xaaax'
,
'+ xbbbx'
,
),
pht
(
'Whole word rewrite with common prefix and suffix.'
));
$this
->
assertProseParts
(
' aaa '
,
' bbb '
,
array
(
'= '
,
'- aaa'
,
'+ bbb'
,
'= '
,
),
pht
(
'Whole word rewrite with whitespace prefix and suffix.'
));
$this
->
assertSummaryProseParts
(
"a
\n
b
\n
c
\n
d
\n
e
\n
f
\n
g
\n
h
\n
"
,
"a
\n
b
\n
c
\n
d
\n
X
\n
f
\n
g
\n
h
\n
"
,
array
(
'.'
,
"= d
\n
"
,
'- e'
,
'+ X'
,
"=
\n
f"
,
'.'
,
),
pht
(
'Summary diff with middle change.'
));
$this
->
assertSummaryProseParts
(
"a
\n
b
\n
c
\n
d
\n
e
\n
f
\n
g
\n
h
\n
"
,
"X
\n
b
\n
c
\n
d
\n
e
\n
f
\n
g
\n
h
\n
"
,
array
(
'- a'
,
'+ X'
,
"=
\n
b"
,
'.'
,
),
pht
(
'Summary diff with head change.'
));
$this
->
assertSummaryProseParts
(
"a
\n
b
\n
c
\n
d
\n
e
\n
f
\n
g
\n
h
\n
"
,
"a
\n
b
\n
c
\n
d
\n
e
\n
f
\n
g
\n
X
\n
"
,
array
(
'.'
,
"= g
\n
"
,
'- h'
,
'+ X'
,
"=
\n
"
,
),
pht
(
'Summary diff with last change.'
));
$this
->
assertProseParts
(
'aaa aaa aaa aaa, bbb bbb bbb bbb.'
,
"aaa aaa aaa aaa, bbb bbb bbb bbb.
\n\n
- ccc ccc ccc"
,
array
(
'= aaa aaa aaa aaa, bbb bbb bbb bbb.'
,
"+
\n\n
- ccc ccc ccc"
,
),
pht
(
'Diff with new trailing content.'
));
$this
->
assertProseParts
(
'aaa aaa aaa aaa, bbb bbb bbb bbb.'
,
'aaa aaa aaa aaa bbb bbb bbb bbb.'
,
array
(
'= aaa aaa aaa aaa'
,
'- ,'
,
'= bbb bbb bbb bbb.'
,
),
pht
(
'Diff with a removed comma.'
));
$this
->
assertProseParts
(
'aaa aaa aaa aaa, bbb bbb bbb bbb.'
,
"aaa aaa aaa aaa bbb bbb bbb bbb.
\n\n
- ccc ccc ccc!"
,
array
(
'= aaa aaa aaa aaa'
,
'- ,'
,
'= bbb bbb bbb bbb.'
,
"+
\n\n
- ccc ccc ccc!"
,
),
pht
(
'Diff with a removed comma and new trailing content.'
));
$this
->
assertProseParts
(
'[ ] Walnuts'
,
'[X] Walnuts'
,
array
(
'= ['
,
'- '
,
'+ X'
,
'= ] Walnuts'
,
),
pht
(
'Diff adding a tickmark to a checkbox list.'
));
$this
->
assertProseParts
(
'[[ ./week49 ]]'
,
'[[ ./week50 ]]'
,
array
(
'= [[ ./week'
,
'- 49'
,
'+ 50'
,
'= ]]'
,
),
pht
(
'Diff changing a remarkup wiki link target.'
));
// Create a large corpus with many sentences and paragraphs.
$large_paragraph
=
'xyz. '
;
$large_paragraph
=
str_repeat
(
$large_paragraph
,
50
);
$large_paragraph
=
rtrim
(
$large_paragraph
);
$large_corpus
=
$large_paragraph
.
"
\n\n
"
;
$large_corpus
=
str_repeat
(
$large_corpus
,
50
);
$large_corpus
=
rtrim
(
$large_corpus
);
$this
->
assertProseParts
(
$large_corpus
,
"aaa
\n\n
"
.
$large_corpus
.
"
\n\n
zzz"
,
array
(
"+ aaa
\n\n
"
,
'= '
.
$large_corpus
,
"+
\n\n
zzz"
,
),
pht
(
'Adding initial and final lines to a large corpus.'
));
}
private
function
assertProseParts
(
$old
,
$new
,
array
$expect_parts
,
$label
)
{
$engine
=
new
PhutilProseDifferenceEngine
();
$diff
=
$engine
->
getDiff
(
$old
,
$new
);
$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
(
$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
,
$actual
,
$label
);
}
}
Event Timeline
Log In to Comment