comparison tests/test-manifest.py @ 24654:9d6db63ccf00

test-manifest: move parsemanifest() to be a testmanifest class method This refactoring lets testmanifest subclasses override this method to return different manifestdict implementations, such as treemanifest. It is useful for later commits where the testmanifest class is moved into a base class, and test cases that extend the base class can provide their own parsemanifest() implementation.
author Drew Gottlieb <drgott@google.com>
date Tue, 07 Apr 2015 15:16:19 -0700
parents 701d3554de0e
children 528ace39c85c
comparison
equal deleted inserted replaced
24653:83f6c4733ecc 24654:9d6db63ccf00
93 'file%d\0%s%s\n' % (i, h, f) for i, h, f in 93 'file%d\0%s%s\n' % (i, h, f) for i, h, f in
94 itertools.izip(xrange(200001), 94 itertools.izip(xrange(200001),
95 itertools.cycle((HASH_1, HASH_2)), 95 itertools.cycle((HASH_1, HASH_2)),
96 itertools.cycle(('', 'x', 'l'))))) 96 itertools.cycle(('', 'x', 'l')))))
97 97
98 def parsemanifest(text):
99 return manifestmod.manifestdict(text)
100
101 class testmanifest(unittest.TestCase): 98 class testmanifest(unittest.TestCase):
99 def parsemanifest(self, text):
100 return manifestmod.manifestdict(text)
102 101
103 def assertIn(self, thing, container, msg=None): 102 def assertIn(self, thing, container, msg=None):
104 # assertIn new in 2.7, use it if available, otherwise polyfill 103 # assertIn new in 2.7, use it if available, otherwise polyfill
105 sup = getattr(unittest.TestCase, 'assertIn', False) 104 sup = getattr(unittest.TestCase, 'assertIn', False)
106 if sup: 105 if sup:
108 if not msg: 107 if not msg:
109 msg = 'Expected %r in %r' % (thing, container) 108 msg = 'Expected %r in %r' % (thing, container)
110 self.assert_(thing in container, msg) 109 self.assert_(thing in container, msg)
111 110
112 def testEmptyManifest(self): 111 def testEmptyManifest(self):
113 m = parsemanifest(EMTPY_MANIFEST) 112 m = self.parsemanifest(EMTPY_MANIFEST)
114 self.assertEqual(0, len(m)) 113 self.assertEqual(0, len(m))
115 self.assertEqual([], list(m)) 114 self.assertEqual([], list(m))
116 115
117 def testEmptyManifestv2(self): 116 def testEmptyManifestv2(self):
118 m = parsemanifest(EMTPY_MANIFEST_V2) 117 m = self.parsemanifest(EMTPY_MANIFEST_V2)
119 self.assertEqual(0, len(m)) 118 self.assertEqual(0, len(m))
120 self.assertEqual([], list(m)) 119 self.assertEqual([], list(m))
121 120
122 def testManifest(self): 121 def testManifest(self):
123 m = parsemanifest(A_SHORT_MANIFEST) 122 m = self.parsemanifest(A_SHORT_MANIFEST)
124 self.assertEqual(['bar/baz/qux.py', 'foo'], list(m)) 123 self.assertEqual(['bar/baz/qux.py', 'foo'], list(m))
125 self.assertEqual(BIN_HASH_2, m['bar/baz/qux.py']) 124 self.assertEqual(BIN_HASH_2, m['bar/baz/qux.py'])
126 self.assertEqual('l', m.flags('bar/baz/qux.py')) 125 self.assertEqual('l', m.flags('bar/baz/qux.py'))
127 self.assertEqual(BIN_HASH_1, m['foo']) 126 self.assertEqual(BIN_HASH_1, m['foo'])
128 self.assertEqual('', m.flags('foo')) 127 self.assertEqual('', m.flags('foo'))
129 self.assertRaises(KeyError, lambda : m['wat']) 128 self.assertRaises(KeyError, lambda : m['wat'])
130 129
131 def testParseManifestV2(self): 130 def testParseManifestV2(self):
132 m1 = parsemanifest(A_SHORT_MANIFEST) 131 m1 = self.parsemanifest(A_SHORT_MANIFEST)
133 m2 = parsemanifest(A_SHORT_MANIFEST_V2) 132 m2 = self.parsemanifest(A_SHORT_MANIFEST_V2)
134 # Should have same content as A_SHORT_MANIFEST 133 # Should have same content as A_SHORT_MANIFEST
135 self.assertEqual(m1.text(), m2.text()) 134 self.assertEqual(m1.text(), m2.text())
136 135
137 def testParseManifestMetadata(self): 136 def testParseManifestMetadata(self):
138 # Metadata is for future-proofing and should be accepted but ignored 137 # Metadata is for future-proofing and should be accepted but ignored
139 m = parsemanifest(A_METADATA_MANIFEST) 138 m = self.parsemanifest(A_METADATA_MANIFEST)
140 self.assertEqual(A_SHORT_MANIFEST, m.text()) 139 self.assertEqual(A_SHORT_MANIFEST, m.text())
141 140
142 def testParseManifestStemCompression(self): 141 def testParseManifestStemCompression(self):
143 m = parsemanifest(A_STEM_COMPRESSED_MANIFEST) 142 m = self.parsemanifest(A_STEM_COMPRESSED_MANIFEST)
144 self.assertIn('bar/baz/qux.py', m) 143 self.assertIn('bar/baz/qux.py', m)
145 self.assertIn('bar/qux/foo.py', m) 144 self.assertIn('bar/qux/foo.py', m)
146 self.assertIn('bar/qux/foz.py', m) 145 self.assertIn('bar/qux/foz.py', m)
147 self.assertIn(256 * 'x' + '/x', m) 146 self.assertIn(256 * 'x' + '/x', m)
148 self.assertIn(256 * 'x' + '/y', m) 147 self.assertIn(256 * 'x' + '/y', m)
149 self.assertEqual(A_STEM_COMPRESSED_MANIFEST, m.text(usemanifestv2=True)) 148 self.assertEqual(A_STEM_COMPRESSED_MANIFEST, m.text(usemanifestv2=True))
150 149
151 def testTextV2(self): 150 def testTextV2(self):
152 m1 = parsemanifest(A_SHORT_MANIFEST) 151 m1 = self.parsemanifest(A_SHORT_MANIFEST)
153 v2text = m1.text(usemanifestv2=True) 152 v2text = m1.text(usemanifestv2=True)
154 self.assertEqual(A_SHORT_MANIFEST_V2, v2text) 153 self.assertEqual(A_SHORT_MANIFEST_V2, v2text)
155 154
156 def testSetItem(self): 155 def testSetItem(self):
157 want = BIN_HASH_1 156 want = BIN_HASH_1
158 157
159 m = parsemanifest(EMTPY_MANIFEST) 158 m = self.parsemanifest(EMTPY_MANIFEST)
160 m['a'] = want 159 m['a'] = want
161 self.assertIn('a', m) 160 self.assertIn('a', m)
162 self.assertEqual(want, m['a']) 161 self.assertEqual(want, m['a'])
163 self.assertEqual('a\0' + HASH_1 + '\n', m.text()) 162 self.assertEqual('a\0' + HASH_1 + '\n', m.text())
164 163
165 m = parsemanifest(A_SHORT_MANIFEST) 164 m = self.parsemanifest(A_SHORT_MANIFEST)
166 m['a'] = want 165 m['a'] = want
167 self.assertEqual(want, m['a']) 166 self.assertEqual(want, m['a'])
168 self.assertEqual('a\0' + HASH_1 + '\n' + A_SHORT_MANIFEST, 167 self.assertEqual('a\0' + HASH_1 + '\n' + A_SHORT_MANIFEST,
169 m.text()) 168 m.text())
170 169
171 def testSetFlag(self): 170 def testSetFlag(self):
172 want = 'x' 171 want = 'x'
173 172
174 m = parsemanifest(EMTPY_MANIFEST) 173 m = self.parsemanifest(EMTPY_MANIFEST)
175 # first add a file; a file-less flag makes no sense 174 # first add a file; a file-less flag makes no sense
176 m['a'] = BIN_HASH_1 175 m['a'] = BIN_HASH_1
177 m.setflag('a', want) 176 m.setflag('a', want)
178 self.assertEqual(want, m.flags('a')) 177 self.assertEqual(want, m.flags('a'))
179 self.assertEqual('a\0' + HASH_1 + want + '\n', m.text()) 178 self.assertEqual('a\0' + HASH_1 + want + '\n', m.text())
180 179
181 m = parsemanifest(A_SHORT_MANIFEST) 180 m = self.parsemanifest(A_SHORT_MANIFEST)
182 # first add a file; a file-less flag makes no sense 181 # first add a file; a file-less flag makes no sense
183 m['a'] = BIN_HASH_1 182 m['a'] = BIN_HASH_1
184 m.setflag('a', want) 183 m.setflag('a', want)
185 self.assertEqual(want, m.flags('a')) 184 self.assertEqual(want, m.flags('a'))
186 self.assertEqual('a\0' + HASH_1 + want + '\n' + A_SHORT_MANIFEST, 185 self.assertEqual('a\0' + HASH_1 + want + '\n' + A_SHORT_MANIFEST,
187 m.text()) 186 m.text())
188 187
189 def testCopy(self): 188 def testCopy(self):
190 m = parsemanifest(A_SHORT_MANIFEST) 189 m = self.parsemanifest(A_SHORT_MANIFEST)
191 m['a'] = BIN_HASH_1 190 m['a'] = BIN_HASH_1
192 m2 = m.copy() 191 m2 = m.copy()
193 del m 192 del m
194 del m2 # make sure we don't double free() anything 193 del m2 # make sure we don't double free() anything
195 194
196 def testCompaction(self): 195 def testCompaction(self):
197 unhex = binascii.unhexlify 196 unhex = binascii.unhexlify
198 h1, h2 = unhex(HASH_1), unhex(HASH_2) 197 h1, h2 = unhex(HASH_1), unhex(HASH_2)
199 m = parsemanifest(A_SHORT_MANIFEST) 198 m = self.parsemanifest(A_SHORT_MANIFEST)
200 m['alpha'] = h1 199 m['alpha'] = h1
201 m['beta'] = h2 200 m['beta'] = h2
202 del m['foo'] 201 del m['foo']
203 want = 'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % ( 202 want = 'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % (
204 HASH_1, HASH_2, HASH_2) 203 HASH_1, HASH_2, HASH_2)
212 self.assertEqual('l', m.flags('bar/baz/qux.py')) 211 self.assertEqual('l', m.flags('bar/baz/qux.py'))
213 self.assertEqual('', m.flags('beta')) 212 self.assertEqual('', m.flags('beta'))
214 self.assertRaises(KeyError, lambda : m['foo']) 213 self.assertRaises(KeyError, lambda : m['foo'])
215 214
216 def testSetGetNodeSuffix(self): 215 def testSetGetNodeSuffix(self):
217 clean = parsemanifest(A_SHORT_MANIFEST) 216 clean = self.parsemanifest(A_SHORT_MANIFEST)
218 m = parsemanifest(A_SHORT_MANIFEST) 217 m = self.parsemanifest(A_SHORT_MANIFEST)
219 h = m['foo'] 218 h = m['foo']
220 f = m.flags('foo') 219 f = m.flags('foo')
221 want = h + 'a' 220 want = h + 'a'
222 # Merge code wants to set 21-byte fake hashes at times 221 # Merge code wants to set 21-byte fake hashes at times
223 m['foo'] = want 222 m['foo'] = want
244 # shows up in diff 243 # shows up in diff
245 self.assertEqual({'foo': ((want, f), (h, ''))}, m.diff(clean)) 244 self.assertEqual({'foo': ((want, f), (h, ''))}, m.diff(clean))
246 self.assertEqual({'foo': ((h, ''), (want, f))}, clean.diff(m)) 245 self.assertEqual({'foo': ((h, ''), (want, f))}, clean.diff(m))
247 246
248 def testMatchException(self): 247 def testMatchException(self):
249 m = parsemanifest(A_SHORT_MANIFEST) 248 m = self.parsemanifest(A_SHORT_MANIFEST)
250 match = matchmod.match('', '', ['re:.*']) 249 match = matchmod.match('', '', ['re:.*'])
251 def filt(path): 250 def filt(path):
252 if path == 'foo': 251 if path == 'foo':
253 assert False 252 assert False
254 return True 253 return True
255 match.matchfn = filt 254 match.matchfn = filt
256 self.assertRaises(AssertionError, m.matches, match) 255 self.assertRaises(AssertionError, m.matches, match)
257 256
258 def testRemoveItem(self): 257 def testRemoveItem(self):
259 m = parsemanifest(A_SHORT_MANIFEST) 258 m = self.parsemanifest(A_SHORT_MANIFEST)
260 del m['foo'] 259 del m['foo']
261 self.assertRaises(KeyError, lambda : m['foo']) 260 self.assertRaises(KeyError, lambda : m['foo'])
262 self.assertEqual(1, len(m)) 261 self.assertEqual(1, len(m))
263 self.assertEqual(1, len(list(m))) 262 self.assertEqual(1, len(list(m)))
264 # now restore and make sure everything works right 263 # now restore and make sure everything works right
268 267
269 def testManifestDiff(self): 268 def testManifestDiff(self):
270 MISSING = (None, '') 269 MISSING = (None, '')
271 addl = 'z-only-in-left\0' + HASH_1 + '\n' 270 addl = 'z-only-in-left\0' + HASH_1 + '\n'
272 addr = 'z-only-in-right\0' + HASH_2 + 'x\n' 271 addr = 'z-only-in-right\0' + HASH_2 + 'x\n'
273 left = parsemanifest( 272 left = self.parsemanifest(
274 A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl) 273 A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl)
275 right = parsemanifest(A_SHORT_MANIFEST + addr) 274 right = self.parsemanifest(A_SHORT_MANIFEST + addr)
276 want = { 275 want = {
277 'foo': ((BIN_HASH_3, 'x'), 276 'foo': ((BIN_HASH_3, 'x'),
278 (BIN_HASH_1, '')), 277 (BIN_HASH_1, '')),
279 'z-only-in-left': ((BIN_HASH_1, ''), MISSING), 278 'z-only-in-left': ((BIN_HASH_1, ''), MISSING),
280 'z-only-in-right': (MISSING, (BIN_HASH_2, 'x')), 279 'z-only-in-right': (MISSING, (BIN_HASH_2, 'x')),
284 want = { 283 want = {
285 'bar/baz/qux.py': (MISSING, (BIN_HASH_2, 'l')), 284 'bar/baz/qux.py': (MISSING, (BIN_HASH_2, 'l')),
286 'foo': (MISSING, (BIN_HASH_3, 'x')), 285 'foo': (MISSING, (BIN_HASH_3, 'x')),
287 'z-only-in-left': (MISSING, (BIN_HASH_1, '')), 286 'z-only-in-left': (MISSING, (BIN_HASH_1, '')),
288 } 287 }
289 self.assertEqual(want, parsemanifest(EMTPY_MANIFEST).diff(left)) 288 self.assertEqual(want, self.parsemanifest(EMTPY_MANIFEST).diff(left))
290 289
291 want = { 290 want = {
292 'bar/baz/qux.py': ((BIN_HASH_2, 'l'), MISSING), 291 'bar/baz/qux.py': ((BIN_HASH_2, 'l'), MISSING),
293 'foo': ((BIN_HASH_3, 'x'), MISSING), 292 'foo': ((BIN_HASH_3, 'x'), MISSING),
294 'z-only-in-left': ((BIN_HASH_1, ''), MISSING), 293 'z-only-in-left': ((BIN_HASH_1, ''), MISSING),
295 } 294 }
296 self.assertEqual(want, left.diff(parsemanifest(EMTPY_MANIFEST))) 295 self.assertEqual(want, left.diff(self.parsemanifest(EMTPY_MANIFEST)))
297 copy = right.copy() 296 copy = right.copy()
298 del copy['z-only-in-right'] 297 del copy['z-only-in-right']
299 del right['foo'] 298 del right['foo']
300 want = { 299 want = {
301 'foo': (MISSING, (BIN_HASH_1, '')), 300 'foo': (MISSING, (BIN_HASH_1, '')),
302 'z-only-in-right': ((BIN_HASH_2, 'x'), MISSING), 301 'z-only-in-right': ((BIN_HASH_2, 'x'), MISSING),
303 } 302 }
304 self.assertEqual(want, right.diff(copy)) 303 self.assertEqual(want, right.diff(copy))
305 304
306 short = parsemanifest(A_SHORT_MANIFEST) 305 short = self.parsemanifest(A_SHORT_MANIFEST)
307 pruned = short.copy() 306 pruned = short.copy()
308 del pruned['foo'] 307 del pruned['foo']
309 want = { 308 want = {
310 'foo': ((BIN_HASH_1, ''), MISSING), 309 'foo': ((BIN_HASH_1, ''), MISSING),
311 } 310 }
322 321
323 def testReversedLines(self): 322 def testReversedLines(self):
324 backwards = ''.join( 323 backwards = ''.join(
325 l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l) 324 l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l)
326 try: 325 try:
327 parsemanifest(backwards) 326 self.parsemanifest(backwards)
328 self.fail('Should have raised ValueError') 327 self.fail('Should have raised ValueError')
329 except ValueError, v: 328 except ValueError, v:
330 self.assertIn('Manifest lines not in sorted order.', str(v)) 329 self.assertIn('Manifest lines not in sorted order.', str(v))
331 330
332 def testNoTerminalNewline(self): 331 def testNoTerminalNewline(self):
333 try: 332 try:
334 parsemanifest(A_SHORT_MANIFEST + 'wat') 333 self.parsemanifest(A_SHORT_MANIFEST + 'wat')
335 self.fail('Should have raised ValueError') 334 self.fail('Should have raised ValueError')
336 except ValueError, v: 335 except ValueError, v:
337 self.assertIn('Manifest did not end in a newline.', str(v)) 336 self.assertIn('Manifest did not end in a newline.', str(v))
338 337
339 def testNoNewLineAtAll(self): 338 def testNoNewLineAtAll(self):
340 try: 339 try:
341 parsemanifest('wat') 340 self.parsemanifest('wat')
342 self.fail('Should have raised ValueError') 341 self.fail('Should have raised ValueError')
343 except ValueError, v: 342 except ValueError, v:
344 self.assertIn('Manifest did not end in a newline.', str(v)) 343 self.assertIn('Manifest did not end in a newline.', str(v))
345 344
346 def testHugeManifest(self): 345 def testHugeManifest(self):
347 m = parsemanifest(A_HUGE_MANIFEST) 346 m = self.parsemanifest(A_HUGE_MANIFEST)
348 self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m)) 347 self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m))
349 self.assertEqual(len(m), len(list(m))) 348 self.assertEqual(len(m), len(list(m)))
350 349
351 def testMatchesMetadata(self): 350 def testMatchesMetadata(self):
352 '''Tests matches() for a few specific files to make sure that both 351 '''Tests matches() for a few specific files to make sure that both
353 the set of files as well as their flags and nodeids are correct in 352 the set of files as well as their flags and nodeids are correct in
354 the resulting manifest.''' 353 the resulting manifest.'''
355 m = parsemanifest(A_HUGE_MANIFEST) 354 m = self.parsemanifest(A_HUGE_MANIFEST)
356 355
357 match = matchmod.match('/', '', 356 match = matchmod.match('/', '',
358 ['file1', 'file200', 'file300'], exact=True) 357 ['file1', 'file200', 'file300'], exact=True)
359 m2 = m.matches(match) 358 m2 = m.matches(match)
360 359
365 364
366 def testMatchesNonexistentFile(self): 365 def testMatchesNonexistentFile(self):
367 '''Tests matches() for a small set of specific files, including one 366 '''Tests matches() for a small set of specific files, including one
368 nonexistent file to make sure in only matches against existing files. 367 nonexistent file to make sure in only matches against existing files.
369 ''' 368 '''
370 m = parsemanifest(A_DEEPER_MANIFEST) 369 m = self.parsemanifest(A_DEEPER_MANIFEST)
371 370
372 match = matchmod.match('/', '', 371 match = matchmod.match('/', '',
373 ['a/b/c/bar.txt', 'a/b/d/qux.py', 'readme.txt', 'nonexistent'], 372 ['a/b/c/bar.txt', 'a/b/d/qux.py', 'readme.txt', 'nonexistent'],
374 exact=True) 373 exact=True)
375 m2 = m.matches(match) 374 m2 = m.matches(match)
379 m2.keys()) 378 m2.keys())
380 379
381 def testMatchesNonexistentDirectory(self): 380 def testMatchesNonexistentDirectory(self):
382 '''Tests matches() for a relpath match on a directory that doesn't 381 '''Tests matches() for a relpath match on a directory that doesn't
383 actually exist.''' 382 actually exist.'''
384 m = parsemanifest(A_DEEPER_MANIFEST) 383 m = self.parsemanifest(A_DEEPER_MANIFEST)
385 384
386 match = matchmod.match('/', '', ['a/f'], default='relpath') 385 match = matchmod.match('/', '', ['a/f'], default='relpath')
387 m2 = m.matches(match) 386 m2 = m.matches(match)
388 387
389 self.assertEqual([], m2.keys()) 388 self.assertEqual([], m2.keys())
390 389
391 def testMatchesExactLarge(self): 390 def testMatchesExactLarge(self):
392 '''Tests matches() for files matching a large list of exact files. 391 '''Tests matches() for files matching a large list of exact files.
393 ''' 392 '''
394 m = parsemanifest(A_HUGE_MANIFEST) 393 m = self.parsemanifest(A_HUGE_MANIFEST)
395 394
396 flist = m.keys()[80:300] 395 flist = m.keys()[80:300]
397 match = matchmod.match('/', '', flist, exact=True) 396 match = matchmod.match('/', '', flist, exact=True)
398 m2 = m.matches(match) 397 m2 = m.matches(match)
399 398
400 self.assertEqual(flist, m2.keys()) 399 self.assertEqual(flist, m2.keys())
401 400
402 def testMatchesFull(self): 401 def testMatchesFull(self):
403 '''Tests matches() for what should be a full match.''' 402 '''Tests matches() for what should be a full match.'''
404 m = parsemanifest(A_DEEPER_MANIFEST) 403 m = self.parsemanifest(A_DEEPER_MANIFEST)
405 404
406 match = matchmod.match('/', '', ['']) 405 match = matchmod.match('/', '', [''])
407 m2 = m.matches(match) 406 m2 = m.matches(match)
408 407
409 self.assertEqual(m.keys(), m2.keys()) 408 self.assertEqual(m.keys(), m2.keys())
410 409
411 def testMatchesDirectory(self): 410 def testMatchesDirectory(self):
412 '''Tests matches() on a relpath match on a directory, which should 411 '''Tests matches() on a relpath match on a directory, which should
413 match against all files within said directory.''' 412 match against all files within said directory.'''
414 m = parsemanifest(A_DEEPER_MANIFEST) 413 m = self.parsemanifest(A_DEEPER_MANIFEST)
415 414
416 match = matchmod.match('/', '', ['a/b'], default='relpath') 415 match = matchmod.match('/', '', ['a/b'], default='relpath')
417 m2 = m.matches(match) 416 m2 = m.matches(match)
418 417
419 self.assertEqual([ 418 self.assertEqual([
423 422
424 def testMatchesExactPath(self): 423 def testMatchesExactPath(self):
425 '''Tests matches() on an exact match on a directory, which should 424 '''Tests matches() on an exact match on a directory, which should
426 result in an empty manifest because you can't perform an exact match 425 result in an empty manifest because you can't perform an exact match
427 against a directory.''' 426 against a directory.'''
428 m = parsemanifest(A_DEEPER_MANIFEST) 427 m = self.parsemanifest(A_DEEPER_MANIFEST)
429 428
430 match = matchmod.match('/', '', ['a/b'], exact=True) 429 match = matchmod.match('/', '', ['a/b'], exact=True)
431 m2 = m.matches(match) 430 m2 = m.matches(match)
432 431
433 self.assertEqual([], m2.keys()) 432 self.assertEqual([], m2.keys())
434 433
435 def testMatchesCwd(self): 434 def testMatchesCwd(self):
436 '''Tests matches() on a relpath match with the current directory ('.') 435 '''Tests matches() on a relpath match with the current directory ('.')
437 when not in the root directory.''' 436 when not in the root directory.'''
438 m = parsemanifest(A_DEEPER_MANIFEST) 437 m = self.parsemanifest(A_DEEPER_MANIFEST)
439 438
440 match = matchmod.match('/', 'a/b', ['.'], default='relpath') 439 match = matchmod.match('/', 'a/b', ['.'], default='relpath')
441 m2 = m.matches(match) 440 m2 = m.matches(match)
442 441
443 self.assertEqual([ 442 self.assertEqual([
446 'a/b/fish.py'], m2.keys()) 445 'a/b/fish.py'], m2.keys())
447 446
448 def testMatchesWithPattern(self): 447 def testMatchesWithPattern(self):
449 '''Tests matches() for files matching a pattern that reside 448 '''Tests matches() for files matching a pattern that reside
450 deeper than the specified directory.''' 449 deeper than the specified directory.'''
451 m = parsemanifest(A_DEEPER_MANIFEST) 450 m = self.parsemanifest(A_DEEPER_MANIFEST)
452 451
453 match = matchmod.match('/', '', ['a/b/*/*.txt']) 452 match = matchmod.match('/', '', ['a/b/*/*.txt'])
454 m2 = m.matches(match) 453 m2 = m.matches(match)
455 454
456 self.assertEqual( 455 self.assertEqual(