##// END OF EJS Templates
test-manifest: extract constants for binary hashes...
Martin von Zweigbergk -
r24570:487245cb default
parent child Browse files
Show More
@@ -1,391 +1,394 b''
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 EMTPY_MANIFEST = ''
10 EMTPY_MANIFEST = ''
11
11
12 HASH_1 = '1' * 40
12 HASH_1 = '1' * 40
13 BIN_HASH_1 = binascii.unhexlify(HASH_1)
13 HASH_2 = 'f' * 40
14 HASH_2 = 'f' * 40
15 BIN_HASH_2 = binascii.unhexlify(HASH_2)
14 HASH_3 = '1234567890abcdef0987654321deadbeef0fcafe'
16 HASH_3 = '1234567890abcdef0987654321deadbeef0fcafe'
17 BIN_HASH_3 = binascii.unhexlify(HASH_3)
15 A_SHORT_MANIFEST = (
18 A_SHORT_MANIFEST = (
16 'bar/baz/qux.py\0%(hash2)s%(flag2)s\n'
19 'bar/baz/qux.py\0%(hash2)s%(flag2)s\n'
17 'foo\0%(hash1)s%(flag1)s\n'
20 'foo\0%(hash1)s%(flag1)s\n'
18 ) % {'hash1': HASH_1,
21 ) % {'hash1': HASH_1,
19 'flag1': '',
22 'flag1': '',
20 'hash2': HASH_2,
23 'hash2': HASH_2,
21 'flag2': 'l',
24 'flag2': 'l',
22 }
25 }
23
26
24 A_DEEPER_MANIFEST = (
27 A_DEEPER_MANIFEST = (
25 'a/b/c/bar.py\0%(hash3)s%(flag1)s\n'
28 'a/b/c/bar.py\0%(hash3)s%(flag1)s\n'
26 'a/b/c/bar.txt\0%(hash1)s%(flag1)s\n'
29 'a/b/c/bar.txt\0%(hash1)s%(flag1)s\n'
27 'a/b/c/foo.py\0%(hash3)s%(flag1)s\n'
30 'a/b/c/foo.py\0%(hash3)s%(flag1)s\n'
28 'a/b/c/foo.txt\0%(hash2)s%(flag2)s\n'
31 'a/b/c/foo.txt\0%(hash2)s%(flag2)s\n'
29 'a/b/d/baz.py\0%(hash3)s%(flag1)s\n'
32 'a/b/d/baz.py\0%(hash3)s%(flag1)s\n'
30 'a/b/d/qux.py\0%(hash1)s%(flag2)s\n'
33 'a/b/d/qux.py\0%(hash1)s%(flag2)s\n'
31 'a/b/d/ten.txt\0%(hash3)s%(flag2)s\n'
34 'a/b/d/ten.txt\0%(hash3)s%(flag2)s\n'
32 'a/b/dog.py\0%(hash3)s%(flag1)s\n'
35 'a/b/dog.py\0%(hash3)s%(flag1)s\n'
33 'a/b/fish.py\0%(hash2)s%(flag1)s\n'
36 'a/b/fish.py\0%(hash2)s%(flag1)s\n'
34 'a/c/london.py\0%(hash3)s%(flag2)s\n'
37 'a/c/london.py\0%(hash3)s%(flag2)s\n'
35 'a/c/paper.txt\0%(hash2)s%(flag2)s\n'
38 'a/c/paper.txt\0%(hash2)s%(flag2)s\n'
36 'a/c/paris.py\0%(hash2)s%(flag1)s\n'
39 'a/c/paris.py\0%(hash2)s%(flag1)s\n'
37 'a/d/apple.py\0%(hash3)s%(flag1)s\n'
40 'a/d/apple.py\0%(hash3)s%(flag1)s\n'
38 'a/d/pizza.py\0%(hash3)s%(flag2)s\n'
41 'a/d/pizza.py\0%(hash3)s%(flag2)s\n'
39 'a/green.py\0%(hash1)s%(flag2)s\n'
42 'a/green.py\0%(hash1)s%(flag2)s\n'
40 'a/purple.py\0%(hash2)s%(flag1)s\n'
43 'a/purple.py\0%(hash2)s%(flag1)s\n'
41 'app.py\0%(hash3)s%(flag1)s\n'
44 'app.py\0%(hash3)s%(flag1)s\n'
42 'readme.txt\0%(hash2)s%(flag1)s\n'
45 'readme.txt\0%(hash2)s%(flag1)s\n'
43 ) % {'hash1': HASH_1,
46 ) % {'hash1': HASH_1,
44 'flag1': '',
47 'flag1': '',
45 'hash2': HASH_2,
48 'hash2': HASH_2,
46 'flag2': 'l',
49 'flag2': 'l',
47 'hash3': HASH_3,
50 'hash3': HASH_3,
48 }
51 }
49
52
50 HUGE_MANIFEST_ENTRIES = 200001
53 HUGE_MANIFEST_ENTRIES = 200001
51
54
52 A_HUGE_MANIFEST = ''.join(sorted(
55 A_HUGE_MANIFEST = ''.join(sorted(
53 'file%d\0%s%s\n' % (i, h, f) for i, h, f in
56 'file%d\0%s%s\n' % (i, h, f) for i, h, f in
54 itertools.izip(xrange(200001),
57 itertools.izip(xrange(200001),
55 itertools.cycle((HASH_1, HASH_2)),
58 itertools.cycle((HASH_1, HASH_2)),
56 itertools.cycle(('', 'x', 'l')))))
59 itertools.cycle(('', 'x', 'l')))))
57
60
58 def parsemanifest(text):
61 def parsemanifest(text):
59 return manifestmod.manifestdict(text)
62 return manifestmod.manifestdict(text)
60
63
61 class testmanifest(unittest.TestCase):
64 class testmanifest(unittest.TestCase):
62
65
63 def assertIn(self, thing, container, msg=None):
66 def assertIn(self, thing, container, msg=None):
64 # assertIn new in 2.7, use it if available, otherwise polyfill
67 # assertIn new in 2.7, use it if available, otherwise polyfill
65 sup = getattr(unittest.TestCase, 'assertIn', False)
68 sup = getattr(unittest.TestCase, 'assertIn', False)
66 if sup:
69 if sup:
67 return sup(self, thing, container, msg=msg)
70 return sup(self, thing, container, msg=msg)
68 if not msg:
71 if not msg:
69 msg = 'Expected %r in %r' % (thing, container)
72 msg = 'Expected %r in %r' % (thing, container)
70 self.assert_(thing in container, msg)
73 self.assert_(thing in container, msg)
71
74
72 def testEmptyManifest(self):
75 def testEmptyManifest(self):
73 m = parsemanifest(EMTPY_MANIFEST)
76 m = parsemanifest(EMTPY_MANIFEST)
74 self.assertEqual(0, len(m))
77 self.assertEqual(0, len(m))
75 self.assertEqual([], list(m))
78 self.assertEqual([], list(m))
76
79
77 def testManifest(self):
80 def testManifest(self):
78 m = parsemanifest(A_SHORT_MANIFEST)
81 m = parsemanifest(A_SHORT_MANIFEST)
79 self.assertEqual(['bar/baz/qux.py', 'foo'], list(m))
82 self.assertEqual(['bar/baz/qux.py', 'foo'], list(m))
80 self.assertEqual(binascii.unhexlify(HASH_2), m['bar/baz/qux.py'])
83 self.assertEqual(BIN_HASH_2, m['bar/baz/qux.py'])
81 self.assertEqual('l', m.flags('bar/baz/qux.py'))
84 self.assertEqual('l', m.flags('bar/baz/qux.py'))
82 self.assertEqual(binascii.unhexlify(HASH_1), m['foo'])
85 self.assertEqual(BIN_HASH_1, m['foo'])
83 self.assertEqual('', m.flags('foo'))
86 self.assertEqual('', m.flags('foo'))
84 self.assertRaises(KeyError, lambda : m['wat'])
87 self.assertRaises(KeyError, lambda : m['wat'])
85
88
86 def testSetItem(self):
89 def testSetItem(self):
87 want = binascii.unhexlify(HASH_1)
90 want = BIN_HASH_1
88
91
89 m = parsemanifest(EMTPY_MANIFEST)
92 m = parsemanifest(EMTPY_MANIFEST)
90 m['a'] = want
93 m['a'] = want
91 self.assertIn('a', m)
94 self.assertIn('a', m)
92 self.assertEqual(want, m['a'])
95 self.assertEqual(want, m['a'])
93 self.assertEqual('a\0' + HASH_1 + '\n', m.text())
96 self.assertEqual('a\0' + HASH_1 + '\n', m.text())
94
97
95 m = parsemanifest(A_SHORT_MANIFEST)
98 m = parsemanifest(A_SHORT_MANIFEST)
96 m['a'] = want
99 m['a'] = want
97 self.assertEqual(want, m['a'])
100 self.assertEqual(want, m['a'])
98 self.assertEqual('a\0' + HASH_1 + '\n' + A_SHORT_MANIFEST,
101 self.assertEqual('a\0' + HASH_1 + '\n' + A_SHORT_MANIFEST,
99 m.text())
102 m.text())
100
103
101 def testSetFlag(self):
104 def testSetFlag(self):
102 want = 'x'
105 want = 'x'
103
106
104 m = parsemanifest(EMTPY_MANIFEST)
107 m = parsemanifest(EMTPY_MANIFEST)
105 # first add a file; a file-less flag makes no sense
108 # first add a file; a file-less flag makes no sense
106 m['a'] = binascii.unhexlify(HASH_1)
109 m['a'] = BIN_HASH_1
107 m.setflag('a', want)
110 m.setflag('a', want)
108 self.assertEqual(want, m.flags('a'))
111 self.assertEqual(want, m.flags('a'))
109 self.assertEqual('a\0' + HASH_1 + want + '\n', m.text())
112 self.assertEqual('a\0' + HASH_1 + want + '\n', m.text())
110
113
111 m = parsemanifest(A_SHORT_MANIFEST)
114 m = parsemanifest(A_SHORT_MANIFEST)
112 # first add a file; a file-less flag makes no sense
115 # first add a file; a file-less flag makes no sense
113 m['a'] = binascii.unhexlify(HASH_1)
116 m['a'] = BIN_HASH_1
114 m.setflag('a', want)
117 m.setflag('a', want)
115 self.assertEqual(want, m.flags('a'))
118 self.assertEqual(want, m.flags('a'))
116 self.assertEqual('a\0' + HASH_1 + want + '\n' + A_SHORT_MANIFEST,
119 self.assertEqual('a\0' + HASH_1 + want + '\n' + A_SHORT_MANIFEST,
117 m.text())
120 m.text())
118
121
119 def testCopy(self):
122 def testCopy(self):
120 m = parsemanifest(A_SHORT_MANIFEST)
123 m = parsemanifest(A_SHORT_MANIFEST)
121 m['a'] = binascii.unhexlify(HASH_1)
124 m['a'] = BIN_HASH_1
122 m2 = m.copy()
125 m2 = m.copy()
123 del m
126 del m
124 del m2 # make sure we don't double free() anything
127 del m2 # make sure we don't double free() anything
125
128
126 def testCompaction(self):
129 def testCompaction(self):
127 unhex = binascii.unhexlify
130 unhex = binascii.unhexlify
128 h1, h2 = unhex(HASH_1), unhex(HASH_2)
131 h1, h2 = unhex(HASH_1), unhex(HASH_2)
129 m = parsemanifest(A_SHORT_MANIFEST)
132 m = parsemanifest(A_SHORT_MANIFEST)
130 m['alpha'] = h1
133 m['alpha'] = h1
131 m['beta'] = h2
134 m['beta'] = h2
132 del m['foo']
135 del m['foo']
133 want = 'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % (
136 want = 'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % (
134 HASH_1, HASH_2, HASH_2)
137 HASH_1, HASH_2, HASH_2)
135 self.assertEqual(want, m.text())
138 self.assertEqual(want, m.text())
136 self.assertEqual(3, len(m))
139 self.assertEqual(3, len(m))
137 self.assertEqual(['alpha', 'bar/baz/qux.py', 'beta'], list(m))
140 self.assertEqual(['alpha', 'bar/baz/qux.py', 'beta'], list(m))
138 self.assertEqual(h1, m['alpha'])
141 self.assertEqual(h1, m['alpha'])
139 self.assertEqual(h2, m['bar/baz/qux.py'])
142 self.assertEqual(h2, m['bar/baz/qux.py'])
140 self.assertEqual(h2, m['beta'])
143 self.assertEqual(h2, m['beta'])
141 self.assertEqual('', m.flags('alpha'))
144 self.assertEqual('', m.flags('alpha'))
142 self.assertEqual('l', m.flags('bar/baz/qux.py'))
145 self.assertEqual('l', m.flags('bar/baz/qux.py'))
143 self.assertEqual('', m.flags('beta'))
146 self.assertEqual('', m.flags('beta'))
144 self.assertRaises(KeyError, lambda : m['foo'])
147 self.assertRaises(KeyError, lambda : m['foo'])
145
148
146 def testSetGetNodeSuffix(self):
149 def testSetGetNodeSuffix(self):
147 clean = parsemanifest(A_SHORT_MANIFEST)
150 clean = parsemanifest(A_SHORT_MANIFEST)
148 m = parsemanifest(A_SHORT_MANIFEST)
151 m = parsemanifest(A_SHORT_MANIFEST)
149 h = m['foo']
152 h = m['foo']
150 f = m.flags('foo')
153 f = m.flags('foo')
151 want = h + 'a'
154 want = h + 'a'
152 # Merge code wants to set 21-byte fake hashes at times
155 # Merge code wants to set 21-byte fake hashes at times
153 m['foo'] = want
156 m['foo'] = want
154 self.assertEqual(want, m['foo'])
157 self.assertEqual(want, m['foo'])
155 self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2)),
158 self.assertEqual([('bar/baz/qux.py', BIN_HASH_2),
156 ('foo', binascii.unhexlify(HASH_1) + 'a')],
159 ('foo', BIN_HASH_1 + 'a')],
157 list(m.iteritems()))
160 list(m.iteritems()))
158 # Sometimes it even tries a 22-byte fake hash, but we can
161 # Sometimes it even tries a 22-byte fake hash, but we can
159 # return 21 and it'll work out
162 # return 21 and it'll work out
160 m['foo'] = want + '+'
163 m['foo'] = want + '+'
161 self.assertEqual(want, m['foo'])
164 self.assertEqual(want, m['foo'])
162 # make sure the suffix survives a copy
165 # make sure the suffix survives a copy
163 match = matchmod.match('', '', ['re:foo'])
166 match = matchmod.match('', '', ['re:foo'])
164 m2 = m.matches(match)
167 m2 = m.matches(match)
165 self.assertEqual(want, m2['foo'])
168 self.assertEqual(want, m2['foo'])
166 self.assertEqual(1, len(m2))
169 self.assertEqual(1, len(m2))
167 m2 = m.copy()
170 m2 = m.copy()
168 self.assertEqual(want, m2['foo'])
171 self.assertEqual(want, m2['foo'])
169 # suffix with iteration
172 # suffix with iteration
170 self.assertEqual([('bar/baz/qux.py', binascii.unhexlify(HASH_2)),
173 self.assertEqual([('bar/baz/qux.py', BIN_HASH_2),
171 ('foo', want)],
174 ('foo', want)],
172 list(m.iteritems()))
175 list(m.iteritems()))
173
176
174 # shows up in diff
177 # shows up in diff
175 self.assertEqual({'foo': ((want, f), (h, ''))}, m.diff(clean))
178 self.assertEqual({'foo': ((want, f), (h, ''))}, m.diff(clean))
176 self.assertEqual({'foo': ((h, ''), (want, f))}, clean.diff(m))
179 self.assertEqual({'foo': ((h, ''), (want, f))}, clean.diff(m))
177
180
178 def testMatchException(self):
181 def testMatchException(self):
179 m = parsemanifest(A_SHORT_MANIFEST)
182 m = parsemanifest(A_SHORT_MANIFEST)
180 match = matchmod.match('', '', ['re:.*'])
183 match = matchmod.match('', '', ['re:.*'])
181 def filt(path):
184 def filt(path):
182 if path == 'foo':
185 if path == 'foo':
183 assert False
186 assert False
184 return True
187 return True
185 match.matchfn = filt
188 match.matchfn = filt
186 self.assertRaises(AssertionError, m.matches, match)
189 self.assertRaises(AssertionError, m.matches, match)
187
190
188 def testRemoveItem(self):
191 def testRemoveItem(self):
189 m = parsemanifest(A_SHORT_MANIFEST)
192 m = parsemanifest(A_SHORT_MANIFEST)
190 del m['foo']
193 del m['foo']
191 self.assertRaises(KeyError, lambda : m['foo'])
194 self.assertRaises(KeyError, lambda : m['foo'])
192 self.assertEqual(1, len(m))
195 self.assertEqual(1, len(m))
193 self.assertEqual(1, len(list(m)))
196 self.assertEqual(1, len(list(m)))
194 # now restore and make sure everything works right
197 # now restore and make sure everything works right
195 m['foo'] = 'a' * 20
198 m['foo'] = 'a' * 20
196 self.assertEqual(2, len(m))
199 self.assertEqual(2, len(m))
197 self.assertEqual(2, len(list(m)))
200 self.assertEqual(2, len(list(m)))
198
201
199 def testManifestDiff(self):
202 def testManifestDiff(self):
200 MISSING = (None, '')
203 MISSING = (None, '')
201 addl = 'z-only-in-left\0' + HASH_1 + '\n'
204 addl = 'z-only-in-left\0' + HASH_1 + '\n'
202 addr = 'z-only-in-right\0' + HASH_2 + 'x\n'
205 addr = 'z-only-in-right\0' + HASH_2 + 'x\n'
203 left = parsemanifest(
206 left = parsemanifest(
204 A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl)
207 A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl)
205 right = parsemanifest(A_SHORT_MANIFEST + addr)
208 right = parsemanifest(A_SHORT_MANIFEST + addr)
206 want = {
209 want = {
207 'foo': ((binascii.unhexlify(HASH_3), 'x'),
210 'foo': ((BIN_HASH_3, 'x'),
208 (binascii.unhexlify(HASH_1), '')),
211 (BIN_HASH_1, '')),
209 'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING),
212 'z-only-in-left': ((BIN_HASH_1, ''), MISSING),
210 'z-only-in-right': (MISSING, (binascii.unhexlify(HASH_2), 'x')),
213 'z-only-in-right': (MISSING, (BIN_HASH_2, 'x')),
211 }
214 }
212 self.assertEqual(want, left.diff(right))
215 self.assertEqual(want, left.diff(right))
213
216
214 want = {
217 want = {
215 'bar/baz/qux.py': (MISSING, (binascii.unhexlify(HASH_2), 'l')),
218 'bar/baz/qux.py': (MISSING, (BIN_HASH_2, 'l')),
216 'foo': (MISSING, (binascii.unhexlify(HASH_3), 'x')),
219 'foo': (MISSING, (BIN_HASH_3, 'x')),
217 'z-only-in-left': (MISSING, (binascii.unhexlify(HASH_1), '')),
220 'z-only-in-left': (MISSING, (BIN_HASH_1, '')),
218 }
221 }
219 self.assertEqual(want, parsemanifest(EMTPY_MANIFEST).diff(left))
222 self.assertEqual(want, parsemanifest(EMTPY_MANIFEST).diff(left))
220
223
221 want = {
224 want = {
222 'bar/baz/qux.py': ((binascii.unhexlify(HASH_2), 'l'), MISSING),
225 'bar/baz/qux.py': ((BIN_HASH_2, 'l'), MISSING),
223 'foo': ((binascii.unhexlify(HASH_3), 'x'), MISSING),
226 'foo': ((BIN_HASH_3, 'x'), MISSING),
224 'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING),
227 'z-only-in-left': ((BIN_HASH_1, ''), MISSING),
225 }
228 }
226 self.assertEqual(want, left.diff(parsemanifest(EMTPY_MANIFEST)))
229 self.assertEqual(want, left.diff(parsemanifest(EMTPY_MANIFEST)))
227 copy = right.copy()
230 copy = right.copy()
228 del copy['z-only-in-right']
231 del copy['z-only-in-right']
229 del right['foo']
232 del right['foo']
230 want = {
233 want = {
231 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
234 'foo': (MISSING, (BIN_HASH_1, '')),
232 'z-only-in-right': ((binascii.unhexlify(HASH_2), 'x'), MISSING),
235 'z-only-in-right': ((BIN_HASH_2, 'x'), MISSING),
233 }
236 }
234 self.assertEqual(want, right.diff(copy))
237 self.assertEqual(want, right.diff(copy))
235
238
236 short = parsemanifest(A_SHORT_MANIFEST)
239 short = parsemanifest(A_SHORT_MANIFEST)
237 pruned = short.copy()
240 pruned = short.copy()
238 del pruned['foo']
241 del pruned['foo']
239 want = {
242 want = {
240 'foo': ((binascii.unhexlify(HASH_1), ''), MISSING),
243 'foo': ((BIN_HASH_1, ''), MISSING),
241 }
244 }
242 self.assertEqual(want, short.diff(pruned))
245 self.assertEqual(want, short.diff(pruned))
243 want = {
246 want = {
244 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
247 'foo': (MISSING, (BIN_HASH_1, '')),
245 }
248 }
246 self.assertEqual(want, pruned.diff(short))
249 self.assertEqual(want, pruned.diff(short))
247 want = {
250 want = {
248 'bar/baz/qux.py': None,
251 'bar/baz/qux.py': None,
249 'foo': (MISSING, (binascii.unhexlify(HASH_1), '')),
252 'foo': (MISSING, (BIN_HASH_1, '')),
250 }
253 }
251 self.assertEqual(want, pruned.diff(short, True))
254 self.assertEqual(want, pruned.diff(short, True))
252
255
253 def testReversedLines(self):
256 def testReversedLines(self):
254 backwards = ''.join(
257 backwards = ''.join(
255 l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l)
258 l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l)
256 try:
259 try:
257 parsemanifest(backwards)
260 parsemanifest(backwards)
258 self.fail('Should have raised ValueError')
261 self.fail('Should have raised ValueError')
259 except ValueError, v:
262 except ValueError, v:
260 self.assertIn('Manifest lines not in sorted order.', str(v))
263 self.assertIn('Manifest lines not in sorted order.', str(v))
261
264
262 def testNoTerminalNewline(self):
265 def testNoTerminalNewline(self):
263 try:
266 try:
264 parsemanifest(A_SHORT_MANIFEST + 'wat')
267 parsemanifest(A_SHORT_MANIFEST + 'wat')
265 self.fail('Should have raised ValueError')
268 self.fail('Should have raised ValueError')
266 except ValueError, v:
269 except ValueError, v:
267 self.assertIn('Manifest did not end in a newline.', str(v))
270 self.assertIn('Manifest did not end in a newline.', str(v))
268
271
269 def testNoNewLineAtAll(self):
272 def testNoNewLineAtAll(self):
270 try:
273 try:
271 parsemanifest('wat')
274 parsemanifest('wat')
272 self.fail('Should have raised ValueError')
275 self.fail('Should have raised ValueError')
273 except ValueError, v:
276 except ValueError, v:
274 self.assertIn('Manifest did not end in a newline.', str(v))
277 self.assertIn('Manifest did not end in a newline.', str(v))
275
278
276 def testHugeManifest(self):
279 def testHugeManifest(self):
277 m = parsemanifest(A_HUGE_MANIFEST)
280 m = parsemanifest(A_HUGE_MANIFEST)
278 self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m))
281 self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m))
279 self.assertEqual(len(m), len(list(m)))
282 self.assertEqual(len(m), len(list(m)))
280
283
281 def testMatchesMetadata(self):
284 def testMatchesMetadata(self):
282 '''Tests matches() for a few specific files to make sure that both
285 '''Tests matches() for a few specific files to make sure that both
283 the set of files as well as their flags and nodeids are correct in
286 the set of files as well as their flags and nodeids are correct in
284 the resulting manifest.'''
287 the resulting manifest.'''
285 m = parsemanifest(A_HUGE_MANIFEST)
288 m = parsemanifest(A_HUGE_MANIFEST)
286
289
287 match = matchmod.match('/', '',
290 match = matchmod.match('/', '',
288 ['file1', 'file200', 'file300'], exact=True)
291 ['file1', 'file200', 'file300'], exact=True)
289 m2 = m.matches(match)
292 m2 = m.matches(match)
290
293
291 w = ('file1\0%sx\n'
294 w = ('file1\0%sx\n'
292 'file200\0%sl\n'
295 'file200\0%sl\n'
293 'file300\0%s\n') % (HASH_2, HASH_1, HASH_1)
296 'file300\0%s\n') % (HASH_2, HASH_1, HASH_1)
294 self.assertEqual(w, m2.text())
297 self.assertEqual(w, m2.text())
295
298
296 def testMatchesNonexistentFile(self):
299 def testMatchesNonexistentFile(self):
297 '''Tests matches() for a small set of specific files, including one
300 '''Tests matches() for a small set of specific files, including one
298 nonexistent file to make sure in only matches against existing files.
301 nonexistent file to make sure in only matches against existing files.
299 '''
302 '''
300 m = parsemanifest(A_DEEPER_MANIFEST)
303 m = parsemanifest(A_DEEPER_MANIFEST)
301
304
302 match = matchmod.match('/', '',
305 match = matchmod.match('/', '',
303 ['a/b/c/bar.txt', 'a/b/d/qux.py', 'readme.txt', 'nonexistent'],
306 ['a/b/c/bar.txt', 'a/b/d/qux.py', 'readme.txt', 'nonexistent'],
304 exact=True)
307 exact=True)
305 m2 = m.matches(match)
308 m2 = m.matches(match)
306
309
307 self.assertEqual(
310 self.assertEqual(
308 ['a/b/c/bar.txt', 'a/b/d/qux.py', 'readme.txt'],
311 ['a/b/c/bar.txt', 'a/b/d/qux.py', 'readme.txt'],
309 m2.keys())
312 m2.keys())
310
313
311 def testMatchesNonexistentDirectory(self):
314 def testMatchesNonexistentDirectory(self):
312 '''Tests matches() for a relpath match on a directory that doesn't
315 '''Tests matches() for a relpath match on a directory that doesn't
313 actually exist.'''
316 actually exist.'''
314 m = parsemanifest(A_DEEPER_MANIFEST)
317 m = parsemanifest(A_DEEPER_MANIFEST)
315
318
316 match = matchmod.match('/', '', ['a/f'], default='relpath')
319 match = matchmod.match('/', '', ['a/f'], default='relpath')
317 m2 = m.matches(match)
320 m2 = m.matches(match)
318
321
319 self.assertEqual([], m2.keys())
322 self.assertEqual([], m2.keys())
320
323
321 def testMatchesExactLarge(self):
324 def testMatchesExactLarge(self):
322 '''Tests matches() for files matching a large list of exact files.
325 '''Tests matches() for files matching a large list of exact files.
323 '''
326 '''
324 m = parsemanifest(A_HUGE_MANIFEST)
327 m = parsemanifest(A_HUGE_MANIFEST)
325
328
326 flist = m.keys()[80:300]
329 flist = m.keys()[80:300]
327 match = matchmod.match('/', '', flist, exact=True)
330 match = matchmod.match('/', '', flist, exact=True)
328 m2 = m.matches(match)
331 m2 = m.matches(match)
329
332
330 self.assertEqual(flist, m2.keys())
333 self.assertEqual(flist, m2.keys())
331
334
332 def testMatchesFull(self):
335 def testMatchesFull(self):
333 '''Tests matches() for what should be a full match.'''
336 '''Tests matches() for what should be a full match.'''
334 m = parsemanifest(A_DEEPER_MANIFEST)
337 m = parsemanifest(A_DEEPER_MANIFEST)
335
338
336 match = matchmod.match('/', '', [''])
339 match = matchmod.match('/', '', [''])
337 m2 = m.matches(match)
340 m2 = m.matches(match)
338
341
339 self.assertEqual(m.keys(), m2.keys())
342 self.assertEqual(m.keys(), m2.keys())
340
343
341 def testMatchesDirectory(self):
344 def testMatchesDirectory(self):
342 '''Tests matches() on a relpath match on a directory, which should
345 '''Tests matches() on a relpath match on a directory, which should
343 match against all files within said directory.'''
346 match against all files within said directory.'''
344 m = parsemanifest(A_DEEPER_MANIFEST)
347 m = parsemanifest(A_DEEPER_MANIFEST)
345
348
346 match = matchmod.match('/', '', ['a/b'], default='relpath')
349 match = matchmod.match('/', '', ['a/b'], default='relpath')
347 m2 = m.matches(match)
350 m2 = m.matches(match)
348
351
349 self.assertEqual([
352 self.assertEqual([
350 'a/b/c/bar.py', 'a/b/c/bar.txt', 'a/b/c/foo.py', 'a/b/c/foo.txt',
353 'a/b/c/bar.py', 'a/b/c/bar.txt', 'a/b/c/foo.py', 'a/b/c/foo.txt',
351 'a/b/d/baz.py', 'a/b/d/qux.py', 'a/b/d/ten.txt', 'a/b/dog.py',
354 'a/b/d/baz.py', 'a/b/d/qux.py', 'a/b/d/ten.txt', 'a/b/dog.py',
352 'a/b/fish.py'], m2.keys())
355 'a/b/fish.py'], m2.keys())
353
356
354 def testMatchesExactPath(self):
357 def testMatchesExactPath(self):
355 '''Tests matches() on an exact match on a directory, which should
358 '''Tests matches() on an exact match on a directory, which should
356 result in an empty manifest because you can't perform an exact match
359 result in an empty manifest because you can't perform an exact match
357 against a directory.'''
360 against a directory.'''
358 m = parsemanifest(A_DEEPER_MANIFEST)
361 m = parsemanifest(A_DEEPER_MANIFEST)
359
362
360 match = matchmod.match('/', '', ['a/b'], exact=True)
363 match = matchmod.match('/', '', ['a/b'], exact=True)
361 m2 = m.matches(match)
364 m2 = m.matches(match)
362
365
363 self.assertEqual([], m2.keys())
366 self.assertEqual([], m2.keys())
364
367
365 def testMatchesCwd(self):
368 def testMatchesCwd(self):
366 '''Tests matches() on a relpath match with the current directory ('.')
369 '''Tests matches() on a relpath match with the current directory ('.')
367 when not in the root directory.'''
370 when not in the root directory.'''
368 m = parsemanifest(A_DEEPER_MANIFEST)
371 m = parsemanifest(A_DEEPER_MANIFEST)
369
372
370 match = matchmod.match('/', 'a/b', ['.'], default='relpath')
373 match = matchmod.match('/', 'a/b', ['.'], default='relpath')
371 m2 = m.matches(match)
374 m2 = m.matches(match)
372
375
373 self.assertEqual([
376 self.assertEqual([
374 'a/b/c/bar.py', 'a/b/c/bar.txt', 'a/b/c/foo.py', 'a/b/c/foo.txt',
377 'a/b/c/bar.py', 'a/b/c/bar.txt', 'a/b/c/foo.py', 'a/b/c/foo.txt',
375 'a/b/d/baz.py', 'a/b/d/qux.py', 'a/b/d/ten.txt', 'a/b/dog.py',
378 'a/b/d/baz.py', 'a/b/d/qux.py', 'a/b/d/ten.txt', 'a/b/dog.py',
376 'a/b/fish.py'], m2.keys())
379 'a/b/fish.py'], m2.keys())
377
380
378 def testMatchesWithPattern(self):
381 def testMatchesWithPattern(self):
379 '''Tests matches() for files matching a pattern that reside
382 '''Tests matches() for files matching a pattern that reside
380 deeper than the specified directory.'''
383 deeper than the specified directory.'''
381 m = parsemanifest(A_DEEPER_MANIFEST)
384 m = parsemanifest(A_DEEPER_MANIFEST)
382
385
383 match = matchmod.match('/', '', ['a/b/*/*.txt'])
386 match = matchmod.match('/', '', ['a/b/*/*.txt'])
384 m2 = m.matches(match)
387 m2 = m.matches(match)
385
388
386 self.assertEqual(
389 self.assertEqual(
387 ['a/b/c/bar.txt', 'a/b/c/foo.txt', 'a/b/d/ten.txt'],
390 ['a/b/c/bar.txt', 'a/b/c/foo.txt', 'a/b/d/ten.txt'],
388 m2.keys())
391 m2.keys())
389
392
390 if __name__ == '__main__':
393 if __name__ == '__main__':
391 silenttestrunner.main(__name__)
394 silenttestrunner.main(__name__)
General Comments 0
You need to be logged in to leave comments. Login now