##// END OF EJS Templates
test-manifest.py: don't test .text() with present node suffix...
Martin von Zweigbergk -
r24468:016b71ea default
parent child Browse files
Show More
@@ -1,263 +1,262
1 import binascii
1 import binascii
2 import unittest
2 import unittest
3 import itertools
3 import itertools
4
4
5 import silenttestrunner
5 import silenttestrunner
6
6
7 from mercurial import manifest as manifestmod
7 from mercurial import manifest as manifestmod
8 from mercurial import match as matchmod
8 from mercurial import match as matchmod
9
9
10 HASH_1 = '1' * 40
10 HASH_1 = '1' * 40
11 HASH_2 = 'f' * 40
11 HASH_2 = 'f' * 40
12 HASH_3 = '1234567890abcdef0987654321deadbeef0fcafe'
12 HASH_3 = '1234567890abcdef0987654321deadbeef0fcafe'
13 A_SHORT_MANIFEST = (
13 A_SHORT_MANIFEST = (
14 'bar/baz/qux.py\0%(hash2)s%(flag2)s\n'
14 'bar/baz/qux.py\0%(hash2)s%(flag2)s\n'
15 'foo\0%(hash1)s%(flag1)s\n'
15 'foo\0%(hash1)s%(flag1)s\n'
16 ) % {'hash1': HASH_1,
16 ) % {'hash1': HASH_1,
17 'flag1': '',
17 'flag1': '',
18 'hash2': HASH_2,
18 'hash2': HASH_2,
19 'flag2': 'l',
19 'flag2': 'l',
20 }
20 }
21
21
22 HUGE_MANIFEST_ENTRIES = 200001
22 HUGE_MANIFEST_ENTRIES = 200001
23
23
24 A_HUGE_MANIFEST = ''.join(sorted(
24 A_HUGE_MANIFEST = ''.join(sorted(
25 'file%d\0%s%s\n' % (i, h, f) for i, h, f in
25 'file%d\0%s%s\n' % (i, h, f) for i, h, f in
26 itertools.izip(xrange(200001),
26 itertools.izip(xrange(200001),
27 itertools.cycle((HASH_1, HASH_2)),
27 itertools.cycle((HASH_1, HASH_2)),
28 itertools.cycle(('', 'x', 'l')))))
28 itertools.cycle(('', 'x', 'l')))))
29
29
30 def parsemanifest(text):
30 def parsemanifest(text):
31 return manifestmod.manifestdict(text)
31 return manifestmod.manifestdict(text)
32
32
33 class testmanifest(unittest.TestCase):
33 class testmanifest(unittest.TestCase):
34
34
35 def assertIn(self, thing, container, msg=None):
35 def assertIn(self, thing, container, msg=None):
36 # assertIn new in 2.7, use it if available, otherwise polyfill
36 # assertIn new in 2.7, use it if available, otherwise polyfill
37 sup = getattr(unittest.TestCase, 'assertIn', False)
37 sup = getattr(unittest.TestCase, 'assertIn', False)
38 if sup:
38 if sup:
39 return sup(self, thing, container, msg=msg)
39 return sup(self, thing, container, msg=msg)
40 if not msg:
40 if not msg:
41 msg = 'Expected %r in %r' % (thing, container)
41 msg = 'Expected %r in %r' % (thing, container)
42 self.assert_(thing in container, msg)
42 self.assert_(thing in container, msg)
43
43
44 def testEmptyManifest(self):
44 def testEmptyManifest(self):
45 m = parsemanifest('')
45 m = parsemanifest('')
46 self.assertEqual(0, len(m))
46 self.assertEqual(0, len(m))
47 self.assertEqual([], list(m))
47 self.assertEqual([], list(m))
48
48
49 def testManifest(self):
49 def testManifest(self):
50 m = parsemanifest(A_SHORT_MANIFEST)
50 m = parsemanifest(A_SHORT_MANIFEST)
51 self.assertEqual(['bar/baz/qux.py', 'foo'], list(m))
51 self.assertEqual(['bar/baz/qux.py', 'foo'], list(m))
52 self.assertEqual(binascii.unhexlify(HASH_2), m['bar/baz/qux.py'])
52 self.assertEqual(binascii.unhexlify(HASH_2), m['bar/baz/qux.py'])
53 self.assertEqual('l', m.flags('bar/baz/qux.py'))
53 self.assertEqual('l', m.flags('bar/baz/qux.py'))
54 self.assertEqual(binascii.unhexlify(HASH_1), m['foo'])
54 self.assertEqual(binascii.unhexlify(HASH_1), m['foo'])
55 self.assertEqual('', m.flags('foo'))
55 self.assertEqual('', m.flags('foo'))
56 self.assertRaises(KeyError, lambda : m['wat'])
56 self.assertRaises(KeyError, lambda : m['wat'])
57
57
58 def testSetItem(self):
58 def testSetItem(self):
59 want = binascii.unhexlify(HASH_1)
59 want = binascii.unhexlify(HASH_1)
60
60
61 m = parsemanifest('')
61 m = parsemanifest('')
62 m['a'] = want
62 m['a'] = want
63 self.assertIn('a', m)
63 self.assertIn('a', m)
64 self.assertEqual(want, m['a'])
64 self.assertEqual(want, m['a'])
65 self.assertEqual('a\0' + HASH_1 + '\n', m.text())
65 self.assertEqual('a\0' + HASH_1 + '\n', m.text())
66
66
67 m = parsemanifest(A_SHORT_MANIFEST)
67 m = parsemanifest(A_SHORT_MANIFEST)
68 m['a'] = want
68 m['a'] = want
69 self.assertEqual(want, m['a'])
69 self.assertEqual(want, m['a'])
70 self.assertEqual('a\0' + HASH_1 + '\n' + A_SHORT_MANIFEST,
70 self.assertEqual('a\0' + HASH_1 + '\n' + A_SHORT_MANIFEST,
71 m.text())
71 m.text())
72
72
73 def testSetFlag(self):
73 def testSetFlag(self):
74 want = 'x'
74 want = 'x'
75
75
76 m = parsemanifest('')
76 m = parsemanifest('')
77 # first add a file; a file-less flag makes no sense
77 # first add a file; a file-less flag makes no sense
78 m['a'] = binascii.unhexlify(HASH_1)
78 m['a'] = binascii.unhexlify(HASH_1)
79 m.setflag('a', want)
79 m.setflag('a', want)
80 self.assertEqual(want, m.flags('a'))
80 self.assertEqual(want, m.flags('a'))
81 self.assertEqual('a\0' + HASH_1 + want + '\n', m.text())
81 self.assertEqual('a\0' + HASH_1 + want + '\n', m.text())
82
82
83 m = parsemanifest(A_SHORT_MANIFEST)
83 m = parsemanifest(A_SHORT_MANIFEST)
84 # first add a file; a file-less flag makes no sense
84 # first add a file; a file-less flag makes no sense
85 m['a'] = binascii.unhexlify(HASH_1)
85 m['a'] = binascii.unhexlify(HASH_1)
86 m.setflag('a', want)
86 m.setflag('a', want)
87 self.assertEqual(want, m.flags('a'))
87 self.assertEqual(want, m.flags('a'))
88 self.assertEqual('a\0' + HASH_1 + want + '\n' + A_SHORT_MANIFEST,
88 self.assertEqual('a\0' + HASH_1 + want + '\n' + A_SHORT_MANIFEST,
89 m.text())
89 m.text())
90
90
91 def testCopy(self):
91 def testCopy(self):
92 m = parsemanifest(A_SHORT_MANIFEST)
92 m = parsemanifest(A_SHORT_MANIFEST)
93 m['a'] = binascii.unhexlify(HASH_1)
93 m['a'] = binascii.unhexlify(HASH_1)
94 m2 = m.copy()
94 m2 = m.copy()
95 del m
95 del m
96 del m2 # make sure we don't double free() anything
96 del m2 # make sure we don't double free() anything
97
97
98 def testCompaction(self):
98 def testCompaction(self):
99 unhex = binascii.unhexlify
99 unhex = binascii.unhexlify
100 h1, h2 = unhex(HASH_1), unhex(HASH_2)
100 h1, h2 = unhex(HASH_1), unhex(HASH_2)
101 m = parsemanifest(A_SHORT_MANIFEST)
101 m = parsemanifest(A_SHORT_MANIFEST)
102 m['alpha'] = h1
102 m['alpha'] = h1
103 m['beta'] = h2
103 m['beta'] = h2
104 del m['foo']
104 del m['foo']
105 want = 'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % (
105 want = 'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % (
106 HASH_1, HASH_2, HASH_2)
106 HASH_1, HASH_2, HASH_2)
107 self.assertEqual(want, m.text())
107 self.assertEqual(want, m.text())
108 self.assertEqual(3, len(m))
108 self.assertEqual(3, len(m))
109 self.assertEqual(['alpha', 'bar/baz/qux.py', 'beta'], list(m))
109 self.assertEqual(['alpha', 'bar/baz/qux.py', 'beta'], list(m))
110 self.assertEqual(h1, m['alpha'])
110 self.assertEqual(h1, m['alpha'])
111 self.assertEqual(h2, m['bar/baz/qux.py'])
111 self.assertEqual(h2, m['bar/baz/qux.py'])
112 self.assertEqual(h2, m['beta'])
112 self.assertEqual(h2, m['beta'])
113 self.assertEqual('', m.flags('alpha'))
113 self.assertEqual('', m.flags('alpha'))
114 self.assertEqual('l', m.flags('bar/baz/qux.py'))
114 self.assertEqual('l', m.flags('bar/baz/qux.py'))
115 self.assertEqual('', m.flags('beta'))
115 self.assertEqual('', m.flags('beta'))
116 self.assertRaises(KeyError, lambda : m['foo'])
116 self.assertRaises(KeyError, lambda : m['foo'])
117
117
118 def testSetGetNodeSuffix(self):
118 def testSetGetNodeSuffix(self):
119 clean = parsemanifest(A_SHORT_MANIFEST)
119 clean = parsemanifest(A_SHORT_MANIFEST)
120 m = parsemanifest(A_SHORT_MANIFEST)
120 m = parsemanifest(A_SHORT_MANIFEST)
121 h = m['foo']
121 h = m['foo']
122 f = m.flags('foo')
122 f = m.flags('foo')
123 want = h + 'a'
123 want = h + 'a'
124 # Merge code wants to set 21-byte fake hashes at times
124 # Merge code wants to set 21-byte fake hashes at times
125 m['foo'] = want
125 m['foo'] = want
126 self.assertEqual(want, m['foo'])
126 self.assertEqual(want, m['foo'])
127 self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2)),
127 self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2)),
128 ('foo', binascii.unhexlify(HASH_1) + 'a')],
128 ('foo', binascii.unhexlify(HASH_1) + 'a')],
129 list(m.iteritems()))
129 list(m.iteritems()))
130 # Sometimes it even tries a 22-byte fake hash, but we can
130 # Sometimes it even tries a 22-byte fake hash, but we can
131 # return 21 and it'll work out
131 # return 21 and it'll work out
132 m['foo'] = want + '+'
132 m['foo'] = want + '+'
133 self.assertEqual(want, m['foo'])
133 self.assertEqual(want, m['foo'])
134 # make sure the suffix survives a copy
134 # make sure the suffix survives a copy
135 match = matchmod.match('', '', ['re:foo'])
135 match = matchmod.match('', '', ['re:foo'])
136 m2 = m.matches(match)
136 m2 = m.matches(match)
137 self.assertEqual(want, m2['foo'])
137 self.assertEqual(want, m2['foo'])
138 self.assertEqual(1, len(m2))
138 self.assertEqual(1, len(m2))
139 self.assertEqual(('foo\0%s\n' % HASH_1), m2.text())
140 m2 = m.copy()
139 m2 = m.copy()
141 self.assertEqual(want, m2['foo'])
140 self.assertEqual(want, m2['foo'])
142 # suffix with iteration
141 # suffix with iteration
143 self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2)),
142 self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2)),
144 ('foo', want)],
143 ('foo', want)],
145 list(m.iteritems()))
144 list(m.iteritems()))
146
145
147 # shows up in diff
146 # shows up in diff
148 self.assertEqual({'foo': ((want, f), (h, ''))}, m.diff(clean))
147 self.assertEqual({'foo': ((want, f), (h, ''))}, m.diff(clean))
149 self.assertEqual({'foo': ((h, ''), (want, f))}, clean.diff(m))
148 self.assertEqual({'foo': ((h, ''), (want, f))}, clean.diff(m))
150
149
151 def testMatchException(self):
150 def testMatchException(self):
152 m = parsemanifest(A_SHORT_MANIFEST)
151 m = parsemanifest(A_SHORT_MANIFEST)
153 match = matchmod.match('', '', ['re:.*'])
152 match = matchmod.match('', '', ['re:.*'])
154 def filt(path):
153 def filt(path):
155 if path == 'foo':
154 if path == 'foo':
156 assert False
155 assert False
157 return True
156 return True
158 match.matchfn = filt
157 match.matchfn = filt
159 self.assertRaises(AssertionError, m.matches, match)
158 self.assertRaises(AssertionError, m.matches, match)
160
159
161 def testRemoveItem(self):
160 def testRemoveItem(self):
162 m = parsemanifest(A_SHORT_MANIFEST)
161 m = parsemanifest(A_SHORT_MANIFEST)
163 del m['foo']
162 del m['foo']
164 self.assertRaises(KeyError, lambda : m['foo'])
163 self.assertRaises(KeyError, lambda : m['foo'])
165 self.assertEqual(1, len(m))
164 self.assertEqual(1, len(m))
166 self.assertEqual(1, len(list(m)))
165 self.assertEqual(1, len(list(m)))
167 # now restore and make sure everything works right
166 # now restore and make sure everything works right
168 m['foo'] = 'a' * 20
167 m['foo'] = 'a' * 20
169 self.assertEqual(2, len(m))
168 self.assertEqual(2, len(m))
170 self.assertEqual(2, len(list(m)))
169 self.assertEqual(2, len(list(m)))
171
170
172 def testManifestDiff(self):
171 def testManifestDiff(self):
173 MISSING = (None, '')
172 MISSING = (None, '')
174 addl = 'z-only-in-left\0' + HASH_1 + '\n'
173 addl = 'z-only-in-left\0' + HASH_1 + '\n'
175 addr = 'z-only-in-right\0' + HASH_2 + 'x\n'
174 addr = 'z-only-in-right\0' + HASH_2 + 'x\n'
176 left = parsemanifest(
175 left = parsemanifest(
177 A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl)
176 A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl)
178 right = parsemanifest(A_SHORT_MANIFEST + addr)
177 right = parsemanifest(A_SHORT_MANIFEST + addr)
179 want = {
178 want = {
180 'foo': ((binascii.unhexlify(HASH_3), 'x'),
179 'foo': ((binascii.unhexlify(HASH_3), 'x'),
181 (binascii.unhexlify(HASH_1), '')),
180 (binascii.unhexlify(HASH_1), '')),
182 'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING),
181 'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING),
183 'z-only-in-right': (MISSING, (binascii.unhexlify(HASH_2), 'x')),
182 'z-only-in-right': (MISSING, (binascii.unhexlify(HASH_2), 'x')),
184 }
183 }
185 self.assertEqual(want, left.diff(right))
184 self.assertEqual(want, left.diff(right))
186
185
187 want = {
186 want = {
188 'bar/baz/qux.py': (MISSING, (binascii.unhexlify(HASH_2), 'l')),
187 'bar/baz/qux.py': (MISSING, (binascii.unhexlify(HASH_2), 'l')),
189 'foo': (MISSING, (binascii.unhexlify(HASH_3), 'x')),
188 'foo': (MISSING, (binascii.unhexlify(HASH_3), 'x')),
190 'z-only-in-left': (MISSING, (binascii.unhexlify(HASH_1), '')),
189 'z-only-in-left': (MISSING, (binascii.unhexlify(HASH_1), '')),
191 }
190 }
192 self.assertEqual(want, parsemanifest('').diff(left))
191 self.assertEqual(want, parsemanifest('').diff(left))
193
192
194 want = {
193 want = {
195 'bar/baz/qux.py': ((binascii.unhexlify(HASH_2), 'l'), MISSING),
194 'bar/baz/qux.py': ((binascii.unhexlify(HASH_2), 'l'), MISSING),
196 'foo': ((binascii.unhexlify(HASH_3), 'x'), MISSING),
195 'foo': ((binascii.unhexlify(HASH_3), 'x'), MISSING),
197 'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING),
196 'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING),
198 }
197 }
199 self.assertEqual(want, left.diff(parsemanifest('')))
198 self.assertEqual(want, left.diff(parsemanifest('')))
200 copy = right.copy()
199 copy = right.copy()
201 del copy['z-only-in-right']
200 del copy['z-only-in-right']
202 del right['foo']
201 del right['foo']
203 want = {
202 want = {
204 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
203 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
205 'z-only-in-right': ((binascii.unhexlify(HASH_2), 'x'), MISSING),
204 'z-only-in-right': ((binascii.unhexlify(HASH_2), 'x'), MISSING),
206 }
205 }
207 self.assertEqual(want, right.diff(copy))
206 self.assertEqual(want, right.diff(copy))
208
207
209 short = parsemanifest(A_SHORT_MANIFEST)
208 short = parsemanifest(A_SHORT_MANIFEST)
210 pruned = short.copy()
209 pruned = short.copy()
211 del pruned['foo']
210 del pruned['foo']
212 want = {
211 want = {
213 'foo': ((binascii.unhexlify(HASH_1), ''), MISSING),
212 'foo': ((binascii.unhexlify(HASH_1), ''), MISSING),
214 }
213 }
215 self.assertEqual(want, short.diff(pruned))
214 self.assertEqual(want, short.diff(pruned))
216 want = {
215 want = {
217 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
216 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
218 }
217 }
219 self.assertEqual(want, pruned.diff(short))
218 self.assertEqual(want, pruned.diff(short))
220 want = {
219 want = {
221 'bar/baz/qux.py': None,
220 'bar/baz/qux.py': None,
222 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
221 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
223 }
222 }
224 self.assertEqual(want, pruned.diff(short, True))
223 self.assertEqual(want, pruned.diff(short, True))
225
224
226 def testReversedLines(self):
225 def testReversedLines(self):
227 backwards = ''.join(
226 backwards = ''.join(
228 l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l)
227 l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l)
229 try:
228 try:
230 parsemanifest(backwards)
229 parsemanifest(backwards)
231 self.fail('Should have raised ValueError')
230 self.fail('Should have raised ValueError')
232 except ValueError, v:
231 except ValueError, v:
233 self.assertIn('Manifest lines not in sorted order.', str(v))
232 self.assertIn('Manifest lines not in sorted order.', str(v))
234
233
235 def testNoTerminalNewline(self):
234 def testNoTerminalNewline(self):
236 try:
235 try:
237 parsemanifest(A_SHORT_MANIFEST + 'wat')
236 parsemanifest(A_SHORT_MANIFEST + 'wat')
238 self.fail('Should have raised ValueError')
237 self.fail('Should have raised ValueError')
239 except ValueError, v:
238 except ValueError, v:
240 self.assertIn('Manifest did not end in a newline.', str(v))
239 self.assertIn('Manifest did not end in a newline.', str(v))
241
240
242 def testNoNewLineAtAll(self):
241 def testNoNewLineAtAll(self):
243 try:
242 try:
244 parsemanifest('wat')
243 parsemanifest('wat')
245 self.fail('Should have raised ValueError')
244 self.fail('Should have raised ValueError')
246 except ValueError, v:
245 except ValueError, v:
247 self.assertIn('Manifest did not end in a newline.', str(v))
246 self.assertIn('Manifest did not end in a newline.', str(v))
248
247
249 def testHugeManifest(self):
248 def testHugeManifest(self):
250 m = parsemanifest(A_HUGE_MANIFEST)
249 m = parsemanifest(A_HUGE_MANIFEST)
251 self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m))
250 self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m))
252 self.assertEqual(len(m), len(list(m)))
251 self.assertEqual(len(m), len(list(m)))
253
252
254 def testIntersectFiles(self):
253 def testIntersectFiles(self):
255 m = parsemanifest(A_HUGE_MANIFEST)
254 m = parsemanifest(A_HUGE_MANIFEST)
256 m2 = m.intersectfiles(['file1', 'file200', 'file300'])
255 m2 = m.intersectfiles(['file1', 'file200', 'file300'])
257 w = ('file1\0%sx\n'
256 w = ('file1\0%sx\n'
258 'file200\0%sl\n'
257 'file200\0%sl\n'
259 'file300\0%s\n') % (HASH_2, HASH_1, HASH_1)
258 'file300\0%s\n') % (HASH_2, HASH_1, HASH_1)
260 self.assertEqual(w, m2.text())
259 self.assertEqual(w, m2.text())
261
260
262 if __name__ == '__main__':
261 if __name__ == '__main__':
263 silenttestrunner.main(__name__)
262 silenttestrunner.main(__name__)
General Comments 0
You need to be logged in to leave comments. Login now