mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 23:07:18 +03:00
tests: make test-manifest.py portable to Python 3
Lots of b prefixes here, and https://bugs.python.org/issue29714 means that this test is still very broken on Python 3.6 and 3.6.1, but 3.6.2 should things (based on testing using tip of the 3.6 branch from git). #cleanup-only
This commit is contained in:
parent
47e0320f8b
commit
c64072ee5b
@ -10,84 +10,84 @@ from mercurial import (
|
||||
match as matchmod,
|
||||
)
|
||||
|
||||
EMTPY_MANIFEST = ''
|
||||
EMTPY_MANIFEST_V2 = '\0\n'
|
||||
EMTPY_MANIFEST = b''
|
||||
EMTPY_MANIFEST_V2 = b'\0\n'
|
||||
|
||||
HASH_1 = '1' * 40
|
||||
HASH_1 = b'1' * 40
|
||||
BIN_HASH_1 = binascii.unhexlify(HASH_1)
|
||||
HASH_2 = 'f' * 40
|
||||
HASH_2 = b'f' * 40
|
||||
BIN_HASH_2 = binascii.unhexlify(HASH_2)
|
||||
HASH_3 = '1234567890abcdef0987654321deadbeef0fcafe'
|
||||
HASH_3 = b'1234567890abcdef0987654321deadbeef0fcafe'
|
||||
BIN_HASH_3 = binascii.unhexlify(HASH_3)
|
||||
A_SHORT_MANIFEST = (
|
||||
'bar/baz/qux.py\0%(hash2)s%(flag2)s\n'
|
||||
'foo\0%(hash1)s%(flag1)s\n'
|
||||
) % {'hash1': HASH_1,
|
||||
'flag1': '',
|
||||
'hash2': HASH_2,
|
||||
'flag2': 'l',
|
||||
b'bar/baz/qux.py\0%(hash2)s%(flag2)s\n'
|
||||
b'foo\0%(hash1)s%(flag1)s\n'
|
||||
) % {b'hash1': HASH_1,
|
||||
b'flag1': b'',
|
||||
b'hash2': HASH_2,
|
||||
b'flag2': b'l',
|
||||
}
|
||||
|
||||
# Same data as A_SHORT_MANIFEST
|
||||
A_SHORT_MANIFEST_V2 = (
|
||||
'\0\n'
|
||||
'\x00bar/baz/qux.py\0%(flag2)s\n%(hash2)s\n'
|
||||
'\x00foo\0%(flag1)s\n%(hash1)s\n'
|
||||
) % {'hash1': BIN_HASH_1,
|
||||
'flag1': '',
|
||||
'hash2': BIN_HASH_2,
|
||||
'flag2': 'l',
|
||||
b'\0\n'
|
||||
b'\x00bar/baz/qux.py\0%(flag2)s\n%(hash2)s\n'
|
||||
b'\x00foo\0%(flag1)s\n%(hash1)s\n'
|
||||
) % {b'hash1': BIN_HASH_1,
|
||||
b'flag1': b'',
|
||||
b'hash2': BIN_HASH_2,
|
||||
b'flag2': b'l',
|
||||
}
|
||||
|
||||
# Same data as A_SHORT_MANIFEST
|
||||
A_METADATA_MANIFEST = (
|
||||
'\0foo\0bar\n'
|
||||
'\x00bar/baz/qux.py\0%(flag2)s\0foo\0bar\n%(hash2)s\n' # flag and metadata
|
||||
'\x00foo\0%(flag1)s\0foo\n%(hash1)s\n' # no flag, but metadata
|
||||
) % {'hash1': BIN_HASH_1,
|
||||
'flag1': '',
|
||||
'hash2': BIN_HASH_2,
|
||||
'flag2': 'l',
|
||||
b'\0foo\0bar\n'
|
||||
b'\x00bar/baz/qux.py\0%(flag2)s\0foo\0bar\n%(hash2)s\n' # flag and metadata
|
||||
b'\x00foo\0%(flag1)s\0foo\n%(hash1)s\n' # no flag, but metadata
|
||||
) % {b'hash1': BIN_HASH_1,
|
||||
b'flag1': b'',
|
||||
b'hash2': BIN_HASH_2,
|
||||
b'flag2': b'l',
|
||||
}
|
||||
|
||||
A_STEM_COMPRESSED_MANIFEST = (
|
||||
'\0\n'
|
||||
'\x00bar/baz/qux.py\0%(flag2)s\n%(hash2)s\n'
|
||||
'\x04qux/foo.py\0%(flag1)s\n%(hash1)s\n' # simple case of 4 stem chars
|
||||
'\x0az.py\0%(flag1)s\n%(hash1)s\n' # tricky newline = 10 stem characters
|
||||
'\x00%(verylongdir)sx/x\0\n%(hash1)s\n'
|
||||
'\xffx/y\0\n%(hash2)s\n' # more than 255 stem chars
|
||||
) % {'hash1': BIN_HASH_1,
|
||||
'flag1': '',
|
||||
'hash2': BIN_HASH_2,
|
||||
'flag2': 'l',
|
||||
'verylongdir': 255 * 'x',
|
||||
b'\0\n'
|
||||
b'\x00bar/baz/qux.py\0%(flag2)s\n%(hash2)s\n'
|
||||
b'\x04qux/foo.py\0%(flag1)s\n%(hash1)s\n' # simple case of 4 stem chars
|
||||
b'\x0az.py\0%(flag1)s\n%(hash1)s\n' # tricky newline = 10 stem characters
|
||||
b'\x00%(verylongdir)sx/x\0\n%(hash1)s\n'
|
||||
b'\xffx/y\0\n%(hash2)s\n' # more than 255 stem chars
|
||||
) % {b'hash1': BIN_HASH_1,
|
||||
b'flag1': b'',
|
||||
b'hash2': BIN_HASH_2,
|
||||
b'flag2': b'l',
|
||||
b'verylongdir': 255 * b'x',
|
||||
}
|
||||
|
||||
A_DEEPER_MANIFEST = (
|
||||
'a/b/c/bar.py\0%(hash3)s%(flag1)s\n'
|
||||
'a/b/c/bar.txt\0%(hash1)s%(flag1)s\n'
|
||||
'a/b/c/foo.py\0%(hash3)s%(flag1)s\n'
|
||||
'a/b/c/foo.txt\0%(hash2)s%(flag2)s\n'
|
||||
'a/b/d/baz.py\0%(hash3)s%(flag1)s\n'
|
||||
'a/b/d/qux.py\0%(hash1)s%(flag2)s\n'
|
||||
'a/b/d/ten.txt\0%(hash3)s%(flag2)s\n'
|
||||
'a/b/dog.py\0%(hash3)s%(flag1)s\n'
|
||||
'a/b/fish.py\0%(hash2)s%(flag1)s\n'
|
||||
'a/c/london.py\0%(hash3)s%(flag2)s\n'
|
||||
'a/c/paper.txt\0%(hash2)s%(flag2)s\n'
|
||||
'a/c/paris.py\0%(hash2)s%(flag1)s\n'
|
||||
'a/d/apple.py\0%(hash3)s%(flag1)s\n'
|
||||
'a/d/pizza.py\0%(hash3)s%(flag2)s\n'
|
||||
'a/green.py\0%(hash1)s%(flag2)s\n'
|
||||
'a/purple.py\0%(hash2)s%(flag1)s\n'
|
||||
'app.py\0%(hash3)s%(flag1)s\n'
|
||||
'readme.txt\0%(hash2)s%(flag1)s\n'
|
||||
) % {'hash1': HASH_1,
|
||||
'flag1': '',
|
||||
'hash2': HASH_2,
|
||||
'flag2': 'l',
|
||||
'hash3': HASH_3,
|
||||
b'a/b/c/bar.py\0%(hash3)s%(flag1)s\n'
|
||||
b'a/b/c/bar.txt\0%(hash1)s%(flag1)s\n'
|
||||
b'a/b/c/foo.py\0%(hash3)s%(flag1)s\n'
|
||||
b'a/b/c/foo.txt\0%(hash2)s%(flag2)s\n'
|
||||
b'a/b/d/baz.py\0%(hash3)s%(flag1)s\n'
|
||||
b'a/b/d/qux.py\0%(hash1)s%(flag2)s\n'
|
||||
b'a/b/d/ten.txt\0%(hash3)s%(flag2)s\n'
|
||||
b'a/b/dog.py\0%(hash3)s%(flag1)s\n'
|
||||
b'a/b/fish.py\0%(hash2)s%(flag1)s\n'
|
||||
b'a/c/london.py\0%(hash3)s%(flag2)s\n'
|
||||
b'a/c/paper.txt\0%(hash2)s%(flag2)s\n'
|
||||
b'a/c/paris.py\0%(hash2)s%(flag1)s\n'
|
||||
b'a/d/apple.py\0%(hash3)s%(flag1)s\n'
|
||||
b'a/d/pizza.py\0%(hash3)s%(flag2)s\n'
|
||||
b'a/green.py\0%(hash1)s%(flag2)s\n'
|
||||
b'a/purple.py\0%(hash2)s%(flag1)s\n'
|
||||
b'app.py\0%(hash3)s%(flag1)s\n'
|
||||
b'readme.txt\0%(hash2)s%(flag1)s\n'
|
||||
) % {b'hash1': HASH_1,
|
||||
b'flag1': b'',
|
||||
b'hash2': HASH_2,
|
||||
b'flag2': b'l',
|
||||
b'hash3': HASH_3,
|
||||
}
|
||||
|
||||
HUGE_MANIFEST_ENTRIES = 200001
|
||||
@ -96,11 +96,11 @@ izip = getattr(itertools, 'izip', zip)
|
||||
if 'xrange' not in globals():
|
||||
xrange = range
|
||||
|
||||
A_HUGE_MANIFEST = ''.join(sorted(
|
||||
'file%d\0%s%s\n' % (i, h, f) for i, h, f in
|
||||
A_HUGE_MANIFEST = b''.join(sorted(
|
||||
b'file%d\0%s%s\n' % (i, h, f) for i, h, f in
|
||||
izip(xrange(200001),
|
||||
itertools.cycle((HASH_1, HASH_2)),
|
||||
itertools.cycle(('', 'x', 'l')))))
|
||||
itertools.cycle((b'', b'x', b'l')))))
|
||||
|
||||
class basemanifesttests(object):
|
||||
def parsemanifest(self, text):
|
||||
@ -118,13 +118,13 @@ class basemanifesttests(object):
|
||||
|
||||
def testManifest(self):
|
||||
m = self.parsemanifest(A_SHORT_MANIFEST)
|
||||
self.assertEqual(['bar/baz/qux.py', 'foo'], list(m))
|
||||
self.assertEqual(BIN_HASH_2, m['bar/baz/qux.py'])
|
||||
self.assertEqual('l', m.flags('bar/baz/qux.py'))
|
||||
self.assertEqual(BIN_HASH_1, m['foo'])
|
||||
self.assertEqual('', m.flags('foo'))
|
||||
self.assertEqual([b'bar/baz/qux.py', b'foo'], list(m))
|
||||
self.assertEqual(BIN_HASH_2, m[b'bar/baz/qux.py'])
|
||||
self.assertEqual(b'l', m.flags(b'bar/baz/qux.py'))
|
||||
self.assertEqual(BIN_HASH_1, m[b'foo'])
|
||||
self.assertEqual(b'', m.flags(b'foo'))
|
||||
with self.assertRaises(KeyError):
|
||||
m['wat']
|
||||
m[b'wat']
|
||||
|
||||
def testParseManifestV2(self):
|
||||
m1 = self.parsemanifest(A_SHORT_MANIFEST)
|
||||
@ -139,11 +139,11 @@ class basemanifesttests(object):
|
||||
|
||||
def testParseManifestStemCompression(self):
|
||||
m = self.parsemanifest(A_STEM_COMPRESSED_MANIFEST)
|
||||
self.assertIn('bar/baz/qux.py', m)
|
||||
self.assertIn('bar/qux/foo.py', m)
|
||||
self.assertIn('bar/qux/foz.py', m)
|
||||
self.assertIn(256 * 'x' + '/x', m)
|
||||
self.assertIn(256 * 'x' + '/y', m)
|
||||
self.assertIn(b'bar/baz/qux.py', m)
|
||||
self.assertIn(b'bar/qux/foo.py', m)
|
||||
self.assertIn(b'bar/qux/foz.py', m)
|
||||
self.assertIn(256 * b'x' + b'/x', m)
|
||||
self.assertIn(256 * b'x' + b'/y', m)
|
||||
self.assertEqual(A_STEM_COMPRESSED_MANIFEST, m.text(usemanifestv2=True))
|
||||
|
||||
def testTextV2(self):
|
||||
@ -155,38 +155,38 @@ class basemanifesttests(object):
|
||||
want = BIN_HASH_1
|
||||
|
||||
m = self.parsemanifest(EMTPY_MANIFEST)
|
||||
m['a'] = want
|
||||
self.assertIn('a', m)
|
||||
self.assertEqual(want, m['a'])
|
||||
self.assertEqual('a\0' + HASH_1 + '\n', m.text())
|
||||
m[b'a'] = want
|
||||
self.assertIn(b'a', m)
|
||||
self.assertEqual(want, m[b'a'])
|
||||
self.assertEqual(b'a\0' + HASH_1 + b'\n', m.text())
|
||||
|
||||
m = self.parsemanifest(A_SHORT_MANIFEST)
|
||||
m['a'] = want
|
||||
self.assertEqual(want, m['a'])
|
||||
self.assertEqual('a\0' + HASH_1 + '\n' + A_SHORT_MANIFEST,
|
||||
m[b'a'] = want
|
||||
self.assertEqual(want, m[b'a'])
|
||||
self.assertEqual(b'a\0' + HASH_1 + b'\n' + A_SHORT_MANIFEST,
|
||||
m.text())
|
||||
|
||||
def testSetFlag(self):
|
||||
want = 'x'
|
||||
want = b'x'
|
||||
|
||||
m = self.parsemanifest(EMTPY_MANIFEST)
|
||||
# first add a file; a file-less flag makes no sense
|
||||
m['a'] = BIN_HASH_1
|
||||
m.setflag('a', want)
|
||||
self.assertEqual(want, m.flags('a'))
|
||||
self.assertEqual('a\0' + HASH_1 + want + '\n', m.text())
|
||||
m[b'a'] = BIN_HASH_1
|
||||
m.setflag(b'a', want)
|
||||
self.assertEqual(want, m.flags(b'a'))
|
||||
self.assertEqual(b'a\0' + HASH_1 + want + b'\n', m.text())
|
||||
|
||||
m = self.parsemanifest(A_SHORT_MANIFEST)
|
||||
# first add a file; a file-less flag makes no sense
|
||||
m['a'] = BIN_HASH_1
|
||||
m.setflag('a', want)
|
||||
self.assertEqual(want, m.flags('a'))
|
||||
self.assertEqual('a\0' + HASH_1 + want + '\n' + A_SHORT_MANIFEST,
|
||||
m[b'a'] = BIN_HASH_1
|
||||
m.setflag(b'a', want)
|
||||
self.assertEqual(want, m.flags(b'a'))
|
||||
self.assertEqual(b'a\0' + HASH_1 + want + b'\n' + A_SHORT_MANIFEST,
|
||||
m.text())
|
||||
|
||||
def testCopy(self):
|
||||
m = self.parsemanifest(A_SHORT_MANIFEST)
|
||||
m['a'] = BIN_HASH_1
|
||||
m[b'a'] = BIN_HASH_1
|
||||
m2 = m.copy()
|
||||
del m
|
||||
del m2 # make sure we don't double free() anything
|
||||
@ -195,60 +195,60 @@ class basemanifesttests(object):
|
||||
unhex = binascii.unhexlify
|
||||
h1, h2 = unhex(HASH_1), unhex(HASH_2)
|
||||
m = self.parsemanifest(A_SHORT_MANIFEST)
|
||||
m['alpha'] = h1
|
||||
m['beta'] = h2
|
||||
del m['foo']
|
||||
want = 'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % (
|
||||
m[b'alpha'] = h1
|
||||
m[b'beta'] = h2
|
||||
del m[b'foo']
|
||||
want = b'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % (
|
||||
HASH_1, HASH_2, HASH_2)
|
||||
self.assertEqual(want, m.text())
|
||||
self.assertEqual(3, len(m))
|
||||
self.assertEqual(['alpha', 'bar/baz/qux.py', 'beta'], list(m))
|
||||
self.assertEqual(h1, m['alpha'])
|
||||
self.assertEqual(h2, m['bar/baz/qux.py'])
|
||||
self.assertEqual(h2, m['beta'])
|
||||
self.assertEqual('', m.flags('alpha'))
|
||||
self.assertEqual('l', m.flags('bar/baz/qux.py'))
|
||||
self.assertEqual('', m.flags('beta'))
|
||||
self.assertEqual([b'alpha', b'bar/baz/qux.py', b'beta'], list(m))
|
||||
self.assertEqual(h1, m[b'alpha'])
|
||||
self.assertEqual(h2, m[b'bar/baz/qux.py'])
|
||||
self.assertEqual(h2, m[b'beta'])
|
||||
self.assertEqual(b'', m.flags(b'alpha'))
|
||||
self.assertEqual(b'l', m.flags(b'bar/baz/qux.py'))
|
||||
self.assertEqual(b'', m.flags(b'beta'))
|
||||
with self.assertRaises(KeyError):
|
||||
m['foo']
|
||||
m[b'foo']
|
||||
|
||||
def testSetGetNodeSuffix(self):
|
||||
clean = self.parsemanifest(A_SHORT_MANIFEST)
|
||||
m = self.parsemanifest(A_SHORT_MANIFEST)
|
||||
h = m['foo']
|
||||
f = m.flags('foo')
|
||||
want = h + 'a'
|
||||
h = m[b'foo']
|
||||
f = m.flags(b'foo')
|
||||
want = h + b'a'
|
||||
# Merge code wants to set 21-byte fake hashes at times
|
||||
m['foo'] = want
|
||||
self.assertEqual(want, m['foo'])
|
||||
self.assertEqual([('bar/baz/qux.py', BIN_HASH_2),
|
||||
('foo', BIN_HASH_1 + 'a')],
|
||||
m[b'foo'] = want
|
||||
self.assertEqual(want, m[b'foo'])
|
||||
self.assertEqual([(b'bar/baz/qux.py', BIN_HASH_2),
|
||||
(b'foo', BIN_HASH_1 + b'a')],
|
||||
list(m.iteritems()))
|
||||
# Sometimes it even tries a 22-byte fake hash, but we can
|
||||
# return 21 and it'll work out
|
||||
m['foo'] = want + '+'
|
||||
self.assertEqual(want, m['foo'])
|
||||
m[b'foo'] = want + b'+'
|
||||
self.assertEqual(want, m[b'foo'])
|
||||
# make sure the suffix survives a copy
|
||||
match = matchmod.match('', '', ['re:foo'])
|
||||
match = matchmod.match(b'', b'', [b're:foo'])
|
||||
m2 = m.matches(match)
|
||||
self.assertEqual(want, m2['foo'])
|
||||
self.assertEqual(want, m2[b'foo'])
|
||||
self.assertEqual(1, len(m2))
|
||||
m2 = m.copy()
|
||||
self.assertEqual(want, m2['foo'])
|
||||
self.assertEqual(want, m2[b'foo'])
|
||||
# suffix with iteration
|
||||
self.assertEqual([('bar/baz/qux.py', BIN_HASH_2),
|
||||
('foo', want)],
|
||||
self.assertEqual([(b'bar/baz/qux.py', BIN_HASH_2),
|
||||
(b'foo', want)],
|
||||
list(m.iteritems()))
|
||||
|
||||
# shows up in diff
|
||||
self.assertEqual({'foo': ((want, f), (h, ''))}, m.diff(clean))
|
||||
self.assertEqual({'foo': ((h, ''), (want, f))}, clean.diff(m))
|
||||
self.assertEqual({b'foo': ((want, f), (h, b''))}, m.diff(clean))
|
||||
self.assertEqual({b'foo': ((h, b''), (want, f))}, clean.diff(m))
|
||||
|
||||
def testMatchException(self):
|
||||
m = self.parsemanifest(A_SHORT_MANIFEST)
|
||||
match = matchmod.match('', '', ['re:.*'])
|
||||
match = matchmod.match(b'', b'', [b're:.*'])
|
||||
def filt(path):
|
||||
if path == 'foo':
|
||||
if path == b'foo':
|
||||
assert False
|
||||
return True
|
||||
match.matchfn = filt
|
||||
@ -257,73 +257,73 @@ class basemanifesttests(object):
|
||||
|
||||
def testRemoveItem(self):
|
||||
m = self.parsemanifest(A_SHORT_MANIFEST)
|
||||
del m['foo']
|
||||
del m[b'foo']
|
||||
with self.assertRaises(KeyError):
|
||||
m['foo']
|
||||
m[b'foo']
|
||||
self.assertEqual(1, len(m))
|
||||
self.assertEqual(1, len(list(m)))
|
||||
# now restore and make sure everything works right
|
||||
m['foo'] = 'a' * 20
|
||||
m[b'foo'] = b'a' * 20
|
||||
self.assertEqual(2, len(m))
|
||||
self.assertEqual(2, len(list(m)))
|
||||
|
||||
def testManifestDiff(self):
|
||||
MISSING = (None, '')
|
||||
addl = 'z-only-in-left\0' + HASH_1 + '\n'
|
||||
addr = 'z-only-in-right\0' + HASH_2 + 'x\n'
|
||||
MISSING = (None, b'')
|
||||
addl = b'z-only-in-left\0' + HASH_1 + b'\n'
|
||||
addr = b'z-only-in-right\0' + HASH_2 + b'x\n'
|
||||
left = self.parsemanifest(
|
||||
A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl)
|
||||
A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + b'x') + addl)
|
||||
right = self.parsemanifest(A_SHORT_MANIFEST + addr)
|
||||
want = {
|
||||
'foo': ((BIN_HASH_3, 'x'),
|
||||
(BIN_HASH_1, '')),
|
||||
'z-only-in-left': ((BIN_HASH_1, ''), MISSING),
|
||||
'z-only-in-right': (MISSING, (BIN_HASH_2, 'x')),
|
||||
b'foo': ((BIN_HASH_3, b'x'),
|
||||
(BIN_HASH_1, b'')),
|
||||
b'z-only-in-left': ((BIN_HASH_1, b''), MISSING),
|
||||
b'z-only-in-right': (MISSING, (BIN_HASH_2, b'x')),
|
||||
}
|
||||
self.assertEqual(want, left.diff(right))
|
||||
|
||||
want = {
|
||||
'bar/baz/qux.py': (MISSING, (BIN_HASH_2, 'l')),
|
||||
'foo': (MISSING, (BIN_HASH_3, 'x')),
|
||||
'z-only-in-left': (MISSING, (BIN_HASH_1, '')),
|
||||
b'bar/baz/qux.py': (MISSING, (BIN_HASH_2, b'l')),
|
||||
b'foo': (MISSING, (BIN_HASH_3, b'x')),
|
||||
b'z-only-in-left': (MISSING, (BIN_HASH_1, b'')),
|
||||
}
|
||||
self.assertEqual(want, self.parsemanifest(EMTPY_MANIFEST).diff(left))
|
||||
|
||||
want = {
|
||||
'bar/baz/qux.py': ((BIN_HASH_2, 'l'), MISSING),
|
||||
'foo': ((BIN_HASH_3, 'x'), MISSING),
|
||||
'z-only-in-left': ((BIN_HASH_1, ''), MISSING),
|
||||
b'bar/baz/qux.py': ((BIN_HASH_2, b'l'), MISSING),
|
||||
b'foo': ((BIN_HASH_3, b'x'), MISSING),
|
||||
b'z-only-in-left': ((BIN_HASH_1, b''), MISSING),
|
||||
}
|
||||
self.assertEqual(want, left.diff(self.parsemanifest(EMTPY_MANIFEST)))
|
||||
copy = right.copy()
|
||||
del copy['z-only-in-right']
|
||||
del right['foo']
|
||||
del copy[b'z-only-in-right']
|
||||
del right[b'foo']
|
||||
want = {
|
||||
'foo': (MISSING, (BIN_HASH_1, '')),
|
||||
'z-only-in-right': ((BIN_HASH_2, 'x'), MISSING),
|
||||
b'foo': (MISSING, (BIN_HASH_1, b'')),
|
||||
b'z-only-in-right': ((BIN_HASH_2, b'x'), MISSING),
|
||||
}
|
||||
self.assertEqual(want, right.diff(copy))
|
||||
|
||||
short = self.parsemanifest(A_SHORT_MANIFEST)
|
||||
pruned = short.copy()
|
||||
del pruned['foo']
|
||||
del pruned[b'foo']
|
||||
want = {
|
||||
'foo': ((BIN_HASH_1, ''), MISSING),
|
||||
b'foo': ((BIN_HASH_1, b''), MISSING),
|
||||
}
|
||||
self.assertEqual(want, short.diff(pruned))
|
||||
want = {
|
||||
'foo': (MISSING, (BIN_HASH_1, '')),
|
||||
b'foo': (MISSING, (BIN_HASH_1, b'')),
|
||||
}
|
||||
self.assertEqual(want, pruned.diff(short))
|
||||
want = {
|
||||
'bar/baz/qux.py': None,
|
||||
'foo': (MISSING, (BIN_HASH_1, '')),
|
||||
b'bar/baz/qux.py': None,
|
||||
b'foo': (MISSING, (BIN_HASH_1, b'')),
|
||||
}
|
||||
self.assertEqual(want, pruned.diff(short, clean=True))
|
||||
|
||||
def testReversedLines(self):
|
||||
backwards = ''.join(
|
||||
l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l)
|
||||
backwards = b''.join(
|
||||
l + b'\n' for l in reversed(A_SHORT_MANIFEST.split(b'\n')) if l)
|
||||
try:
|
||||
self.parsemanifest(backwards)
|
||||
self.fail('Should have raised ValueError')
|
||||
@ -332,14 +332,14 @@ class basemanifesttests(object):
|
||||
|
||||
def testNoTerminalNewline(self):
|
||||
try:
|
||||
self.parsemanifest(A_SHORT_MANIFEST + 'wat')
|
||||
self.parsemanifest(A_SHORT_MANIFEST + b'wat')
|
||||
self.fail('Should have raised ValueError')
|
||||
except ValueError as v:
|
||||
self.assertIn('Manifest did not end in a newline.', str(v))
|
||||
|
||||
def testNoNewLineAtAll(self):
|
||||
try:
|
||||
self.parsemanifest('wat')
|
||||
self.parsemanifest(b'wat')
|
||||
self.fail('Should have raised ValueError')
|
||||
except ValueError as v:
|
||||
self.assertIn('Manifest did not end in a newline.', str(v))
|
||||
@ -355,13 +355,13 @@ class basemanifesttests(object):
|
||||
the resulting manifest.'''
|
||||
m = self.parsemanifest(A_HUGE_MANIFEST)
|
||||
|
||||
match = matchmod.match('/', '',
|
||||
['file1', 'file200', 'file300'], exact=True)
|
||||
match = matchmod.match(b'/', b'',
|
||||
[b'file1', b'file200', b'file300'], exact=True)
|
||||
m2 = m.matches(match)
|
||||
|
||||
w = ('file1\0%sx\n'
|
||||
'file200\0%sl\n'
|
||||
'file300\0%s\n') % (HASH_2, HASH_1, HASH_1)
|
||||
w = (b'file1\0%sx\n'
|
||||
b'file200\0%sl\n'
|
||||
b'file300\0%s\n') % (HASH_2, HASH_1, HASH_1)
|
||||
self.assertEqual(w, m2.text())
|
||||
|
||||
def testMatchesNonexistentFile(self):
|
||||
@ -370,13 +370,14 @@ class basemanifesttests(object):
|
||||
'''
|
||||
m = self.parsemanifest(A_DEEPER_MANIFEST)
|
||||
|
||||
match = matchmod.match('/', '',
|
||||
['a/b/c/bar.txt', 'a/b/d/qux.py', 'readme.txt', 'nonexistent'],
|
||||
match = matchmod.match(b'/', b'',
|
||||
[b'a/b/c/bar.txt', b'a/b/d/qux.py',
|
||||
b'readme.txt', b'nonexistent'],
|
||||
exact=True)
|
||||
m2 = m.matches(match)
|
||||
|
||||
self.assertEqual(
|
||||
['a/b/c/bar.txt', 'a/b/d/qux.py', 'readme.txt'],
|
||||
[b'a/b/c/bar.txt', b'a/b/d/qux.py', b'readme.txt'],
|
||||
m2.keys())
|
||||
|
||||
def testMatchesNonexistentDirectory(self):
|
||||
@ -384,7 +385,7 @@ class basemanifesttests(object):
|
||||
actually exist.'''
|
||||
m = self.parsemanifest(A_DEEPER_MANIFEST)
|
||||
|
||||
match = matchmod.match('/', '', ['a/f'], default='relpath')
|
||||
match = matchmod.match(b'/', b'', [b'a/f'], default=b'relpath')
|
||||
m2 = m.matches(match)
|
||||
|
||||
self.assertEqual([], m2.keys())
|
||||
@ -395,7 +396,7 @@ class basemanifesttests(object):
|
||||
m = self.parsemanifest(A_HUGE_MANIFEST)
|
||||
|
||||
flist = m.keys()[80:300]
|
||||
match = matchmod.match('/', '', flist, exact=True)
|
||||
match = matchmod.match(b'/', b'', flist, exact=True)
|
||||
m2 = m.matches(match)
|
||||
|
||||
self.assertEqual(flist, m2.keys())
|
||||
@ -404,7 +405,7 @@ class basemanifesttests(object):
|
||||
'''Tests matches() for what should be a full match.'''
|
||||
m = self.parsemanifest(A_DEEPER_MANIFEST)
|
||||
|
||||
match = matchmod.match('/', '', [''])
|
||||
match = matchmod.match(b'/', b'', [b''])
|
||||
m2 = m.matches(match)
|
||||
|
||||
self.assertEqual(m.keys(), m2.keys())
|
||||
@ -414,13 +415,14 @@ class basemanifesttests(object):
|
||||
match against all files within said directory.'''
|
||||
m = self.parsemanifest(A_DEEPER_MANIFEST)
|
||||
|
||||
match = matchmod.match('/', '', ['a/b'], default='relpath')
|
||||
match = matchmod.match(b'/', b'', [b'a/b'], default=b'relpath')
|
||||
m2 = m.matches(match)
|
||||
|
||||
self.assertEqual([
|
||||
'a/b/c/bar.py', 'a/b/c/bar.txt', 'a/b/c/foo.py', 'a/b/c/foo.txt',
|
||||
'a/b/d/baz.py', 'a/b/d/qux.py', 'a/b/d/ten.txt', 'a/b/dog.py',
|
||||
'a/b/fish.py'], m2.keys())
|
||||
b'a/b/c/bar.py', b'a/b/c/bar.txt', b'a/b/c/foo.py',
|
||||
b'a/b/c/foo.txt',
|
||||
b'a/b/d/baz.py', b'a/b/d/qux.py', b'a/b/d/ten.txt', b'a/b/dog.py',
|
||||
b'a/b/fish.py'], m2.keys())
|
||||
|
||||
def testMatchesExactPath(self):
|
||||
'''Tests matches() on an exact match on a directory, which should
|
||||
@ -428,7 +430,7 @@ class basemanifesttests(object):
|
||||
against a directory.'''
|
||||
m = self.parsemanifest(A_DEEPER_MANIFEST)
|
||||
|
||||
match = matchmod.match('/', '', ['a/b'], exact=True)
|
||||
match = matchmod.match(b'/', b'', [b'a/b'], exact=True)
|
||||
m2 = m.matches(match)
|
||||
|
||||
self.assertEqual([], m2.keys())
|
||||
@ -438,24 +440,24 @@ class basemanifesttests(object):
|
||||
when not in the root directory.'''
|
||||
m = self.parsemanifest(A_DEEPER_MANIFEST)
|
||||
|
||||
match = matchmod.match('/', 'a/b', ['.'], default='relpath')
|
||||
match = matchmod.match(b'/', b'a/b', [b'.'], default=b'relpath')
|
||||
m2 = m.matches(match)
|
||||
|
||||
self.assertEqual([
|
||||
'a/b/c/bar.py', 'a/b/c/bar.txt', 'a/b/c/foo.py', 'a/b/c/foo.txt',
|
||||
'a/b/d/baz.py', 'a/b/d/qux.py', 'a/b/d/ten.txt', 'a/b/dog.py',
|
||||
'a/b/fish.py'], m2.keys())
|
||||
b'a/b/c/bar.py', b'a/b/c/bar.txt', b'a/b/c/foo.py',
|
||||
b'a/b/c/foo.txt', b'a/b/d/baz.py', b'a/b/d/qux.py',
|
||||
b'a/b/d/ten.txt', b'a/b/dog.py', b'a/b/fish.py'], m2.keys())
|
||||
|
||||
def testMatchesWithPattern(self):
|
||||
'''Tests matches() for files matching a pattern that reside
|
||||
deeper than the specified directory.'''
|
||||
m = self.parsemanifest(A_DEEPER_MANIFEST)
|
||||
|
||||
match = matchmod.match('/', '', ['a/b/*/*.txt'])
|
||||
match = matchmod.match(b'/', b'', [b'a/b/*/*.txt'])
|
||||
m2 = m.matches(match)
|
||||
|
||||
self.assertEqual(
|
||||
['a/b/c/bar.txt', 'a/b/c/foo.txt', 'a/b/d/ten.txt'],
|
||||
[b'a/b/c/bar.txt', b'a/b/c/foo.txt', b'a/b/d/ten.txt'],
|
||||
m2.keys())
|
||||
|
||||
class testmanifestdict(unittest.TestCase, basemanifesttests):
|
||||
@ -464,21 +466,22 @@ class testmanifestdict(unittest.TestCase, basemanifesttests):
|
||||
|
||||
class testtreemanifest(unittest.TestCase, basemanifesttests):
|
||||
def parsemanifest(self, text):
|
||||
return manifestmod.treemanifest('', text)
|
||||
return manifestmod.treemanifest(b'', text)
|
||||
|
||||
def testWalkSubtrees(self):
|
||||
m = self.parsemanifest(A_DEEPER_MANIFEST)
|
||||
|
||||
dirs = [s._dir for s in m.walksubtrees()]
|
||||
self.assertEqual(
|
||||
sorted(['', 'a/', 'a/c/', 'a/d/', 'a/b/', 'a/b/c/', 'a/b/d/']),
|
||||
sorted([
|
||||
b'', b'a/', b'a/c/', b'a/d/', b'a/b/', b'a/b/c/', b'a/b/d/']),
|
||||
sorted(dirs)
|
||||
)
|
||||
|
||||
match = matchmod.match('/', '', ['path:a/b/'])
|
||||
match = matchmod.match(b'/', b'', [b'path:a/b/'])
|
||||
dirs = [s._dir for s in m.walksubtrees(matcher=match)]
|
||||
self.assertEqual(
|
||||
sorted(['a/b/', 'a/b/c/', 'a/b/d/']),
|
||||
sorted([b'a/b/', b'a/b/c/', b'a/b/d/']),
|
||||
sorted(dirs)
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user