comparison tests/test-absorb-filefixupstate.py @ 43076:2372284d9457

formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:45:02 -0400
parents dcda50856843
children 89a2afe31e82
comparison
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
2 2
3 import itertools 3 import itertools
4 from mercurial import pycompat 4 from mercurial import pycompat
5 from hgext import absorb 5 from hgext import absorb
6 6
7
7 class simplefctx(object): 8 class simplefctx(object):
8 def __init__(self, content): 9 def __init__(self, content):
9 self.content = content 10 self.content = content
10 11
11 def data(self): 12 def data(self):
12 return self.content 13 return self.content
14
13 15
14 def insertreturns(x): 16 def insertreturns(x):
15 # insert "\n"s after each single char 17 # insert "\n"s after each single char
16 if isinstance(x, bytes): 18 if isinstance(x, bytes):
17 return b''.join(ch + b'\n' for ch in pycompat.bytestr(x)) 19 return b''.join(ch + b'\n' for ch in pycompat.bytestr(x))
18 else: 20 else:
19 return pycompat.maplist(insertreturns, x) 21 return pycompat.maplist(insertreturns, x)
20 22
23
21 def removereturns(x): 24 def removereturns(x):
22 # the revert of "insertreturns" 25 # the revert of "insertreturns"
23 if isinstance(x, bytes): 26 if isinstance(x, bytes):
24 return x.replace(b'\n', b'') 27 return x.replace(b'\n', b'')
25 else: 28 else:
26 return pycompat.maplist(removereturns, x) 29 return pycompat.maplist(removereturns, x)
27 30
31
28 def assertlistequal(lhs, rhs, decorator=lambda x: x): 32 def assertlistequal(lhs, rhs, decorator=lambda x: x):
29 if lhs != rhs: 33 if lhs != rhs:
30 raise RuntimeError('mismatch:\n actual: %r\n expected: %r' 34 raise RuntimeError(
31 % tuple(map(decorator, [lhs, rhs]))) 35 'mismatch:\n actual: %r\n expected: %r'
36 % tuple(map(decorator, [lhs, rhs]))
37 )
38
32 39
33 def testfilefixup(oldcontents, workingcopy, expectedcontents, fixups=None): 40 def testfilefixup(oldcontents, workingcopy, expectedcontents, fixups=None):
34 """([str], str, [str], [(rev, a1, a2, b1, b2)]?) -> None 41 """([str], str, [str], [(rev, a1, a2, b1, b2)]?) -> None
35 42
36 workingcopy is a string, of which every character denotes a single line. 43 workingcopy is a string, of which every character denotes a single line.
41 if fixups is not None, it's the expected fixups list and will be checked. 48 if fixups is not None, it's the expected fixups list and will be checked.
42 """ 49 """
43 expectedcontents = insertreturns(expectedcontents) 50 expectedcontents = insertreturns(expectedcontents)
44 oldcontents = insertreturns(oldcontents) 51 oldcontents = insertreturns(oldcontents)
45 workingcopy = insertreturns(workingcopy) 52 workingcopy = insertreturns(workingcopy)
46 state = absorb.filefixupstate(pycompat.maplist(simplefctx, oldcontents), 53 state = absorb.filefixupstate(
47 'path') 54 pycompat.maplist(simplefctx, oldcontents), 'path'
55 )
48 state.diffwith(simplefctx(workingcopy)) 56 state.diffwith(simplefctx(workingcopy))
49 if fixups is not None: 57 if fixups is not None:
50 assertlistequal(state.fixups, fixups) 58 assertlistequal(state.fixups, fixups)
51 state.apply() 59 state.apply()
52 assertlistequal(state.finalcontents, expectedcontents, removereturns) 60 assertlistequal(state.finalcontents, expectedcontents, removereturns)
53 61
62
54 def buildcontents(linesrevs): 63 def buildcontents(linesrevs):
55 # linesrevs: [(linecontent : str, revs : [int])] 64 # linesrevs: [(linecontent : str, revs : [int])]
56 revs = set(itertools.chain(*[revs for line, revs in linesrevs])) 65 revs = set(itertools.chain(*[revs for line, revs in linesrevs]))
57 return [b''] + [ 66 return [b''] + [
58 b''.join([l for l, rs in linesrevs if r in rs]) 67 b''.join([l for l, rs in linesrevs if r in rs]) for r in sorted(revs)
59 for r in sorted(revs)
60 ] 68 ]
69
61 70
62 # input case 0: one single commit 71 # input case 0: one single commit
63 case0 = [b'', b'11'] 72 case0 = [b'', b'11']
64 73
65 # replace a single chunk 74 # replace a single chunk
67 testfilefixup(case0, b'2', [b'', b'2']) 76 testfilefixup(case0, b'2', [b'', b'2'])
68 testfilefixup(case0, b'22', [b'', b'22']) 77 testfilefixup(case0, b'22', [b'', b'22'])
69 testfilefixup(case0, b'222', [b'', b'222']) 78 testfilefixup(case0, b'222', [b'', b'222'])
70 79
71 # input case 1: 3 lines, each commit adds one line 80 # input case 1: 3 lines, each commit adds one line
72 case1 = buildcontents([ 81 case1 = buildcontents([(b'1', [1, 2, 3]), (b'2', [2, 3]), (b'3', [3]),])
73 (b'1', [1, 2, 3]),
74 (b'2', [ 2, 3]),
75 (b'3', [ 3]),
76 ])
77 82
78 # 1:1 line mapping 83 # 1:1 line mapping
79 testfilefixup(case1, b'123', case1) 84 testfilefixup(case1, b'123', case1)
80 testfilefixup(case1, b'12c', [b'', b'1', b'12', b'12c']) 85 testfilefixup(case1, b'12c', [b'', b'1', b'12', b'12c'])
81 testfilefixup(case1, b'1b3', [b'', b'1', b'1b', b'1b3']) 86 testfilefixup(case1, b'1b3', [b'', b'1', b'1b', b'1b3'])
88 # non 1:1 edits 93 # non 1:1 edits
89 testfilefixup(case1, b'abcd', case1) 94 testfilefixup(case1, b'abcd', case1)
90 testfilefixup(case1, b'ab', case1) 95 testfilefixup(case1, b'ab', case1)
91 96
92 # deletion 97 # deletion
93 testfilefixup(case1, b'', [b'', b'', b'', b'']) 98 testfilefixup(case1, b'', [b'', b'', b'', b''])
94 testfilefixup(case1, b'1', [b'', b'1', b'1', b'1']) 99 testfilefixup(case1, b'1', [b'', b'1', b'1', b'1'])
95 testfilefixup(case1, b'2', [b'', b'', b'2', b'2']) 100 testfilefixup(case1, b'2', [b'', b'', b'2', b'2'])
96 testfilefixup(case1, b'3', [b'', b'', b'', b'3']) 101 testfilefixup(case1, b'3', [b'', b'', b'', b'3'])
97 testfilefixup(case1, b'13', [b'', b'1', b'1', b'13']) 102 testfilefixup(case1, b'13', [b'', b'1', b'1', b'13'])
98 103
99 # replaces 104 # replaces
100 testfilefixup(case1, b'1bb3', [b'', b'1', b'1bb', b'1bb3']) 105 testfilefixup(case1, b'1bb3', [b'', b'1', b'1bb', b'1bb3'])
101 106
114 # (confusing) insertions 119 # (confusing) insertions
115 testfilefixup(case1, b'1a23', case1) 120 testfilefixup(case1, b'1a23', case1)
116 testfilefixup(case1, b'12b3', case1) 121 testfilefixup(case1, b'12b3', case1)
117 122
118 # input case 2: delete in the middle 123 # input case 2: delete in the middle
119 case2 = buildcontents([ 124 case2 = buildcontents([(b'11', [1, 2]), (b'22', [1]), (b'33', [1, 2]),])
120 (b'11', [1, 2]),
121 (b'22', [1 ]),
122 (b'33', [1, 2]),
123 ])
124 125
125 # deletion (optimize code should make it 2 chunks) 126 # deletion (optimize code should make it 2 chunks)
126 testfilefixup(case2, b'', [b'', b'22', b''], 127 testfilefixup(
127 fixups=[(4, 0, 2, 0, 0), (4, 2, 4, 0, 0)]) 128 case2, b'', [b'', b'22', b''], fixups=[(4, 0, 2, 0, 0), (4, 2, 4, 0, 0)]
129 )
128 130
129 # 1:1 line mapping 131 # 1:1 line mapping
130 testfilefixup(case2, b'aaaa', [b'', b'aa22aa', b'aaaa']) 132 testfilefixup(case2, b'aaaa', [b'', b'aa22aa', b'aaaa'])
131 133
132 # non 1:1 edits 134 # non 1:1 edits
133 # note: unlike case0, the chunk is not "continuous" and no edit allowed 135 # note: unlike case0, the chunk is not "continuous" and no edit allowed
134 testfilefixup(case2, b'aaa', case2) 136 testfilefixup(case2, b'aaa', case2)
135 137
136 # input case 3: rev 3 reverts rev 2 138 # input case 3: rev 3 reverts rev 2
137 case3 = buildcontents([ 139 case3 = buildcontents([(b'1', [1, 2, 3]), (b'2', [2]), (b'3', [1, 2, 3]),])
138 (b'1', [1, 2, 3]),
139 (b'2', [ 2 ]),
140 (b'3', [1, 2, 3]),
141 ])
142 140
143 # 1:1 line mapping 141 # 1:1 line mapping
144 testfilefixup(case3, b'13', case3) 142 testfilefixup(case3, b'13', case3)
145 testfilefixup(case3, b'1b', [b'', b'1b', b'12b', b'1b']) 143 testfilefixup(case3, b'1b', [b'', b'1b', b'12b', b'1b'])
146 testfilefixup(case3, b'a3', [b'', b'a3', b'a23', b'a3']) 144 testfilefixup(case3, b'a3', [b'', b'a3', b'a23', b'a3'])
155 153
156 # insertion 154 # insertion
157 testfilefixup(case3, b'a13c', [b'', b'a13c', b'a123c', b'a13c']) 155 testfilefixup(case3, b'a13c', [b'', b'a13c', b'a123c', b'a13c'])
158 156
159 # input case 4: a slightly complex case 157 # input case 4: a slightly complex case
160 case4 = buildcontents([ 158 case4 = buildcontents(
161 (b'1', [1, 2, 3]), 159 [
162 (b'2', [ 2, 3]), 160 (b'1', [1, 2, 3]),
163 (b'3', [1, 2, ]), 161 (b'2', [2, 3]),
164 (b'4', [1, 3]), 162 (b'3', [1, 2,]),
165 (b'5', [ 3]), 163 (b'4', [1, 3]),
166 (b'6', [ 2, 3]), 164 (b'5', [3]),
167 (b'7', [ 2 ]), 165 (b'6', [2, 3]),
168 (b'8', [ 2, 3]), 166 (b'7', [2]),
169 (b'9', [ 3]), 167 (b'8', [2, 3]),
170 ]) 168 (b'9', [3]),
169 ]
170 )
171 171
172 testfilefixup(case4, b'1245689', case4) 172 testfilefixup(case4, b'1245689', case4)
173 testfilefixup(case4, b'1a2456bbb', case4) 173 testfilefixup(case4, b'1a2456bbb', case4)
174 testfilefixup(case4, b'1abc5689', case4) 174 testfilefixup(case4, b'1abc5689', case4)
175 testfilefixup(case4, b'1ab5689', [b'', b'134', b'1a3678', b'1ab5689']) 175 testfilefixup(case4, b'1ab5689', [b'', b'134', b'1a3678', b'1ab5689'])
176 testfilefixup(case4, b'aa2bcd8ee', [b'', b'aa34', b'aa23d78', b'aa2bcd8ee']) 176 testfilefixup(case4, b'aa2bcd8ee', [b'', b'aa34', b'aa23d78', b'aa2bcd8ee'])
177 testfilefixup(case4, b'aa2bcdd8ee',[b'', b'aa34', b'aa23678', b'aa24568ee']) 177 testfilefixup(case4, b'aa2bcdd8ee', [b'', b'aa34', b'aa23678', b'aa24568ee'])
178 testfilefixup(case4, b'aaaaaa', case4) 178 testfilefixup(case4, b'aaaaaa', case4)
179 testfilefixup(case4, b'aa258b', [b'', b'aa34', b'aa2378', b'aa258b']) 179 testfilefixup(case4, b'aa258b', [b'', b'aa34', b'aa2378', b'aa258b'])
180 testfilefixup(case4, b'25bb', [b'', b'34', b'23678', b'25689']) 180 testfilefixup(case4, b'25bb', [b'', b'34', b'23678', b'25689'])
181 testfilefixup(case4, b'27', [b'', b'34', b'23678', b'245689']) 181 testfilefixup(case4, b'27', [b'', b'34', b'23678', b'245689'])
182 testfilefixup(case4, b'28', [b'', b'34', b'2378', b'28']) 182 testfilefixup(case4, b'28', [b'', b'34', b'2378', b'28'])
183 testfilefixup(case4, b'', [b'', b'34', b'37', b'']) 183 testfilefixup(case4, b'', [b'', b'34', b'37', b''])
184 184
185 # input case 5: replace a small chunk which is near a deleted line 185 # input case 5: replace a small chunk which is near a deleted line
186 case5 = buildcontents([ 186 case5 = buildcontents([(b'12', [1, 2]), (b'3', [1]), (b'4', [1, 2]),])
187 (b'12', [1, 2]),
188 (b'3', [1]),
189 (b'4', [1, 2]),
190 ])
191 187
192 testfilefixup(case5, b'1cd4', [b'', b'1cd34', b'1cd4']) 188 testfilefixup(case5, b'1cd4', [b'', b'1cd34', b'1cd4'])
193 189
194 # input case 6: base "changeset" is immutable 190 # input case 6: base "changeset" is immutable
195 case6 = [b'1357', b'0125678'] 191 case6 = [b'1357', b'0125678']