sapling/eden/scm/tests/test-fb-hgext-absorb-filefixupstate.py
Jun Wu db7377ae0c py3: fix test-fb-hgext-absorb-filefixupstate.py
Reviewed By: xavierd

Differential Revision: D20928614

fbshipit-source-id: beafe9a1aa260e1ac398056e93795c5231139a06
2020-04-09 13:20:35 -07:00

203 lines
6.2 KiB
Python

from __future__ import absolute_import
import itertools
from edenscm.hgext import absorb
from hghave import require
class simplefctx(object):
def __init__(self, content):
self.content = content.encode("utf-8")
def data(self):
assert isinstance(self.content, bytes)
return self.content
def insertreturns(x):
# insert "\n"s after each single char
if isinstance(x, str):
return "".join(ch + "\n" for ch in x)
else:
return list(map(insertreturns, x))
def removereturns(x):
# the revert of "insertreturns"
if isinstance(x, bytes):
x = x.decode("utf-8")
if isinstance(x, str):
return x.replace("\n", "")
else:
return list(map(removereturns, x))
def assertlistequal(lhs, rhs, decorator=lambda x: x):
if lhs != rhs and decorator(lhs) != decorator(rhs):
raise RuntimeError(
"mismatch:\n actual: %r\n expected: %r"
% tuple(map(decorator, [lhs, rhs]))
)
def testfilefixup(oldcontents, workingcopy, expectedcontents, fixups=None):
"""([str], str, [str], [(rev, a1, a2, b1, b2)]?) -> None
workingcopy is a string, of which every character denotes a single line.
oldcontents, expectedcontents are lists of strings, every character of
every string denots a single line.
if fixups is not None, it's the expected fixups list and will be checked.
"""
expectedcontents = insertreturns(expectedcontents)
oldcontents = insertreturns(oldcontents)
workingcopy = insertreturns(workingcopy)
state = absorb.filefixupstate(list(map(simplefctx, oldcontents)), "path")
state.diffwith(simplefctx(workingcopy))
if fixups is not None:
assertlistequal(state.fixups, fixups)
state.apply()
assertlistequal(state.finalcontents, expectedcontents, removereturns)
def buildcontents(linesrevs):
# linesrevs: [(linecontent : str, revs : [int])]
revs = set(itertools.chain(*[revs for line, revs in linesrevs]))
return [""] + ["".join([l for l, rs in linesrevs if r in rs]) for r in sorted(revs)]
# input case 0: one single commit
case0 = ["", "11"]
# replace a single chunk
testfilefixup(case0, "", ["", ""])
testfilefixup(case0, "2", ["", "2"])
testfilefixup(case0, "22", ["", "22"])
testfilefixup(case0, "222", ["", "222"])
# input case 1: 3 lines, each commit adds one line
case1 = buildcontents([("1", [1, 2, 3]), ("2", [2, 3]), ("3", [3])])
# 1:1 line mapping
testfilefixup(case1, "123", case1)
testfilefixup(case1, "12c", ["", "1", "12", "12c"])
testfilefixup(case1, "1b3", ["", "1", "1b", "1b3"])
testfilefixup(case1, "1bc", ["", "1", "1b", "1bc"])
testfilefixup(case1, "a23", ["", "a", "a2", "a23"])
testfilefixup(case1, "a2c", ["", "a", "a2", "a2c"])
testfilefixup(case1, "ab3", ["", "a", "ab", "ab3"])
testfilefixup(case1, "abc", ["", "a", "ab", "abc"])
# non 1:1 edits
testfilefixup(case1, "abcd", case1)
testfilefixup(case1, "ab", case1)
# deletion
testfilefixup(case1, "", ["", "", "", ""])
testfilefixup(case1, "1", ["", "1", "1", "1"])
testfilefixup(case1, "2", ["", "", "2", "2"])
testfilefixup(case1, "3", ["", "", "", "3"])
testfilefixup(case1, "13", ["", "1", "1", "13"])
# replaces
testfilefixup(case1, "1bb3", ["", "1", "1bb", "1bb3"])
# (confusing) replaces
testfilefixup(case1, "1bbb", case1)
testfilefixup(case1, "bbbb", case1)
testfilefixup(case1, "bbb3", case1)
testfilefixup(case1, "1b", case1)
testfilefixup(case1, "bb", case1)
testfilefixup(case1, "b3", case1)
# insertions at the beginning and the end
testfilefixup(case1, "123c", ["", "1", "12", "123c"])
testfilefixup(case1, "a123", ["", "a1", "a12", "a123"])
# (confusing) insertions
testfilefixup(case1, "1a23", case1)
testfilefixup(case1, "12b3", case1)
# input case 2: delete in the middle
case2 = buildcontents([("11", [1, 2]), ("22", [1]), ("33", [1, 2])])
# deletion (optimize code should make it 2 chunks)
testfilefixup(case2, "", ["", "22", ""], fixups=[(4, 0, 2, 0, 0), (4, 2, 4, 0, 0)])
# 1:1 line mapping
testfilefixup(case2, "aaaa", ["", "aa22aa", "aaaa"])
# non 1:1 edits
# note: unlike case0, the chunk is not "continuous" and no edit allowed
testfilefixup(case2, "aaa", case2)
# input case 3: rev 3 reverts rev 2
case3 = buildcontents([("1", [1, 2, 3]), ("2", [2]), ("3", [1, 2, 3])])
# 1:1 line mapping
testfilefixup(case3, "13", case3)
testfilefixup(case3, "1b", ["", "1b", "12b", "1b"])
testfilefixup(case3, "a3", ["", "a3", "a23", "a3"])
testfilefixup(case3, "ab", ["", "ab", "a2b", "ab"])
# non 1:1 edits
testfilefixup(case3, "a", case3)
testfilefixup(case3, "abc", case3)
# deletion
testfilefixup(case3, "", ["", "", "2", ""])
# insertion
testfilefixup(case3, "a13c", ["", "a13c", "a123c", "a13c"])
# input case 4: a slightly complex case
case4 = buildcontents(
[
("1", [1, 2, 3]),
("2", [2, 3]),
("3", [1, 2]),
("4", [1, 3]),
("5", [3]),
("6", [2, 3]),
("7", [2]),
("8", [2, 3]),
("9", [3]),
]
)
testfilefixup(case4, "1245689", case4)
testfilefixup(case4, "1a2456bbb", case4)
testfilefixup(case4, "1abc5689", case4)
testfilefixup(case4, "1ab5689", ["", "134", "1a3678", "1ab5689"])
testfilefixup(case4, "aa2bcd8ee", ["", "aa34", "aa23d78", "aa2bcd8ee"])
testfilefixup(case4, "aa2bcdd8ee", ["", "aa34", "aa23678", "aa24568ee"])
testfilefixup(case4, "aaaaaa", case4)
testfilefixup(case4, "aa258b", ["", "aa34", "aa2378", "aa258b"])
testfilefixup(case4, "25bb", ["", "34", "23678", "25689"])
testfilefixup(case4, "27", ["", "34", "23678", "245689"])
testfilefixup(case4, "28", ["", "34", "2378", "28"])
testfilefixup(case4, "", ["", "34", "37", ""])
# input case 5: replace a small chunk which is near a deleted line
case5 = buildcontents([("12", [1, 2]), ("3", [1]), ("4", [1, 2])])
testfilefixup(case5, "1cd4", ["", "1cd34", "1cd4"])
# input case 6: base "changeset" is immutable
case6 = ["1357", "0125678"]
testfilefixup(case6, "0125678", case6)
testfilefixup(case6, "0a25678", case6)
testfilefixup(case6, "0a256b8", case6)
testfilefixup(case6, "abcdefg", ["1357", "a1c5e7g"])
testfilefixup(case6, "abcdef", case6)
testfilefixup(case6, "", ["1357", "157"])
testfilefixup(case6, "0123456789", ["1357", "0123456789"])
# input case 7: change an empty file
case7 = [""]
testfilefixup(case7, "1", case7)