##// END OF EJS Templates
revlog: subclass the new `repository.iverifyproblem` Protocol class...
revlog: subclass the new `repository.iverifyproblem` Protocol class This is the same transformation as 3a90a6fd710d did for dirstate, but the CamelCase naming was already cleaned up here. We shouldn't have to explicitly subclass, but I'm doing so to test the interplay of regular attributes and the `attrs` class. Also, PyCharm has a nifty feature that puts a jump point in the gutter to navigate back and forth between the base class and subclasses (and override functions and base class functions) when there's an explicit subclassing. Additionally, PyCharm will immediately flag signature mismatches without a 40m pytype run.

File last commit:

r49730:6000f5b2 default
r53365:4ef6dbc2 default
Show More
test-bdiff.py
187 lines | 5.5 KiB | text/x-python | PythonLexer
import collections
import struct
import unittest
from mercurial import mdiff
class diffreplace(collections.namedtuple('diffreplace', 'start end from_ to')):
def __repr__(self):
return 'diffreplace(%r, %r, %r, %r)' % self
class BdiffTests(unittest.TestCase):
def assert_bdiff_applies(self, a, b):
d = mdiff.textdiff(a, b)
c = a
if d:
c = mdiff.patches(a, [d])
self.assertEqual(
c,
b,
(
"bad diff+patch result from\n %r to\n "
"%r: \nbdiff: %r\npatched: %r" % (a, b, d, c[:200])
),
)
def assert_bdiff(self, a, b):
self.assert_bdiff_applies(a, b)
self.assert_bdiff_applies(b, a)
def test_bdiff_basic(self):
cases = [
(b"a\nc\n\n\n\n", b"a\nb\n\n\n"),
(b"a\nb\nc\n", b"a\nc\n"),
(b"", b""),
(b"a\nb\nc", b"a\nb\nc"),
(b"a\nb\nc\nd\n", b"a\nd\n"),
(b"a\nb\nc\nd\n", b"a\nc\ne\n"),
(b"a\nb\nc\n", b"a\nc\n"),
(b"a\n", b"c\na\nb\n"),
(b"a\n", b""),
(b"a\n", b"b\nc\n"),
(b"a\n", b"c\na\n"),
(b"", b"adjfkjdjksdhfksj"),
(b"", b"ab"),
(b"", b"abc"),
(b"a", b"a"),
(b"ab", b"ab"),
(b"abc", b"abc"),
(b"a\n", b"a\n"),
(b"a\nb", b"a\nb"),
]
for a, b in cases:
self.assert_bdiff(a, b)
def showdiff(self, a, b):
bin = mdiff.textdiff(a, b)
pos = 0
q = 0
actions = []
while pos < len(bin):
p1, p2, l = struct.unpack(">lll", bin[pos : pos + 12])
pos += 12
if p1:
actions.append(a[q:p1])
actions.append(diffreplace(p1, p2, a[p1:p2], bin[pos : pos + l]))
pos += l
q = p2
if q < len(a):
actions.append(a[q:])
return actions
def test_issue1295(self):
cases = [
(
b"x\n\nx\n\nx\n\nx\n\nz\n",
b"x\n\nx\n\ny\n\nx\n\nx\n\nz\n",
[
b'x\n\nx\n\n',
diffreplace(6, 6, b'', b'y\n\n'),
b'x\n\nx\n\nz\n',
],
),
(
b"x\n\nx\n\nx\n\nx\n\nz\n",
b"x\n\nx\n\ny\n\nx\n\ny\n\nx\n\nz\n",
[
b'x\n\nx\n\n',
diffreplace(6, 6, b'', b'y\n\n'),
b'x\n\n',
diffreplace(9, 9, b'', b'y\n\n'),
b'x\n\nz\n',
],
),
]
for old, new, want in cases:
self.assertEqual(self.showdiff(old, new), want)
def test_issue1295_varies_on_pure(self):
# we should pick up abbbc. rather than bc.de as the longest match
got = self.showdiff(
b"a\nb\nb\nb\nc\n.\nd\ne\n.\nf\n",
b"a\nb\nb\na\nb\nb\nb\nc\n.\nb\nc\n.\nd\ne\nf\n",
)
want_c = [
b'a\nb\nb\n',
diffreplace(6, 6, b'', b'a\nb\nb\nb\nc\n.\n'),
b'b\nc\n.\nd\ne\n',
diffreplace(16, 18, b'.\n', b''),
b'f\n',
]
want_pure = [
diffreplace(0, 0, b'', b'a\nb\nb\n'),
b'a\nb\nb\nb\nc\n.\n',
diffreplace(12, 12, b'', b'b\nc\n.\n'),
b'd\ne\n',
diffreplace(16, 18, b'.\n', b''),
b'f\n',
]
self.assertTrue(
got in (want_c, want_pure),
'got: %r, wanted either %r or %r' % (got, want_c, want_pure),
)
def test_fixws(self):
cases = [
(b" \ta\r b\t\n", b"ab\n", 1),
(b" \ta\r b\t\n", b" a b\n", 0),
(b"", b"", 1),
(b"", b"", 0),
]
for a, b, allws in cases:
c = mdiff.fixws(a, allws)
self.assertEqual(
c, b, 'fixws(%r) want %r got %r (allws=%r)' % (a, b, c, allws)
)
def test_nice_diff_for_trivial_change(self):
self.assertEqual(
self.showdiff(
b''.join(b'<%d\n-\n' % i for i in range(5)),
b''.join(b'>%d\n-\n' % i for i in range(5)),
),
[
diffreplace(0, 3, b'<0\n', b'>0\n'),
b'-\n',
diffreplace(5, 8, b'<1\n', b'>1\n'),
b'-\n',
diffreplace(10, 13, b'<2\n', b'>2\n'),
b'-\n',
diffreplace(15, 18, b'<3\n', b'>3\n'),
b'-\n',
diffreplace(20, 23, b'<4\n', b'>4\n'),
b'-\n',
],
)
def test_prefer_appending(self):
# 1 line to 3 lines
self.assertEqual(
self.showdiff(b'a\n', b'a\n' * 3),
[b'a\n', diffreplace(2, 2, b'', b'a\na\n')],
)
# 1 line to 5 lines
self.assertEqual(
self.showdiff(b'a\n', b'a\n' * 5),
[b'a\n', diffreplace(2, 2, b'', b'a\na\na\na\n')],
)
def test_prefer_removing_trailing(self):
# 3 lines to 1 line
self.assertEqual(
self.showdiff(b'a\n' * 3, b'a\n'),
[b'a\n', diffreplace(2, 6, b'a\na\n', b'')],
)
# 5 lines to 1 line
self.assertEqual(
self.showdiff(b'a\n' * 5, b'a\n'),
[b'a\n', diffreplace(2, 10, b'a\na\na\na\n', b'')],
)
if __name__ == '__main__':
import silenttestrunner
silenttestrunner.main(__name__)