Show More
@@ -9,53 +9,119 b' from i18n import _' | |||||
9 | import mdiff, parsers, error, revlog, util |
|
9 | import mdiff, parsers, error, revlog, util | |
10 | import array, struct |
|
10 | import array, struct | |
11 |
|
11 | |||
12 | # Pure Python fallback |
|
12 | ||
13 | def _parsemanifest(mfdict, fdict, lines): |
|
13 | class _lazymanifest(dict): | |
14 | bin = revlog.bin |
|
14 | """This is the pure implementation of lazymanifest. | |
15 | for l in lines.splitlines(): |
|
15 | ||
16 | f, n = l.split('\0') |
|
16 | It has not been optimized *at all* and is not lazy. | |
17 | if len(n) > 40: |
|
17 | """ | |
18 | fdict[f] = n[40:] |
|
|||
19 | mfdict[f] = bin(n[:40]) |
|
|||
20 | else: |
|
|||
21 | mfdict[f] = bin(n) |
|
|||
22 |
|
18 | |||
23 | def _parse(lines, mfdict, flags): |
|
19 | def __init__(self, data): | |
24 | try: |
|
20 | # This init method does a little bit of excessive-looking | |
25 | parsers.parse_manifest(mfdict, flags, lines) |
|
21 | # precondition checking. This is so that the behavior of this | |
26 | except AttributeError: |
|
22 | # class exactly matches its C counterpart to try and help | |
27 | _parsemanifest(mfdict, flags, lines) |
|
23 | # prevent surprise breakage for anyone that develops against | |
28 | return mfdict |
|
24 | # the pure version. | |
29 |
|
25 | if data and data[-1] != '\n': | ||
30 | class manifestdict(dict): |
|
26 | raise ValueError('Manifest did not end in a newline.') | |
31 |
|
|
27 | dict.__init__(self) | |
32 | self._flags = {} |
|
28 | prev = None | |
33 | _parse(data, self, self._flags) |
|
29 | for l in data.splitlines(): | |
|
30 | if prev is not None and prev > l: | |||
|
31 | raise ValueError('Manifest lines not in sorted order.') | |||
|
32 | prev = l | |||
|
33 | f, n = l.split('\0') | |||
|
34 | if len(n) > 40: | |||
|
35 | self[f] = revlog.bin(n[:40]), n[40:] | |||
|
36 | else: | |||
|
37 | self[f] = revlog.bin(n), '' | |||
34 |
|
38 | |||
35 | def __setitem__(self, k, v): |
|
39 | def __setitem__(self, k, v): | |
36 | assert v is not None |
|
40 | node, flag = v | |
37 | dict.__setitem__(self, k, v) |
|
41 | assert node is not None | |
38 | def flags(self, f): |
|
42 | if len(node) > 21: | |
39 | return self._flags.get(f, "") |
|
43 | node = node[:21] # match c implementation behavior | |
40 | def setflag(self, f, flags): |
|
44 | dict.__setitem__(self, k, (node, flag)) | |
41 | """Set the flags (symlink, executable) for path f.""" |
|
45 | ||
42 | self._flags[f] = flags |
|
46 | def __iter__(self): | |
|
47 | return ((f, e[0], e[1]) for f, e in sorted(self.iteritems())) | |||
|
48 | ||||
43 | def copy(self): |
|
49 | def copy(self): | |
44 |
c |
|
50 | c = _lazymanifest('') | |
45 | dict.__init__(copy, self) |
|
51 | c.update(self) | |
46 | copy._flags = dict.copy(self._flags) |
|
52 | return c | |
47 | return copy |
|
53 | ||
|
54 | def diff(self, m2, clean=False): | |||
|
55 | '''Finds changes between the current manifest and m2.''' | |||
|
56 | diff = {} | |||
|
57 | ||||
|
58 | for fn, e1 in self.iteritems(): | |||
|
59 | if fn not in m2: | |||
|
60 | diff[fn] = e1, (None, '') | |||
|
61 | else: | |||
|
62 | e2 = m2[fn] | |||
|
63 | if e1 != e2: | |||
|
64 | diff[fn] = e1, e2 | |||
|
65 | elif clean: | |||
|
66 | diff[fn] = None | |||
|
67 | ||||
|
68 | for fn, e2 in m2.iteritems(): | |||
|
69 | if fn not in self: | |||
|
70 | diff[fn] = (None, ''), e2 | |||
|
71 | ||||
|
72 | return diff | |||
|
73 | ||||
|
74 | def filtercopy(self, filterfn): | |||
|
75 | c = _lazymanifest('') | |||
|
76 | for f, n, fl in self: | |||
|
77 | if filterfn(f): | |||
|
78 | c[f] = n, fl | |||
|
79 | return c | |||
|
80 | ||||
|
81 | def text(self): | |||
|
82 | """Get the full data of this manifest as a bytestring.""" | |||
|
83 | fl = sorted(self) | |||
|
84 | ||||
|
85 | _hex = revlog.hex | |||
|
86 | # if this is changed to support newlines in filenames, | |||
|
87 | # be sure to check the templates/ dir again (especially *-raw.tmpl) | |||
|
88 | return ''.join("%s\0%s%s\n" % ( | |||
|
89 | f, _hex(n[:20]), flag) for f, n, flag in fl) | |||
|
90 | ||||
|
91 | class manifestdict(object): | |||
|
92 | def __init__(self, data=''): | |||
|
93 | self._lm = _lazymanifest(data) | |||
|
94 | ||||
|
95 | def __getitem__(self, key): | |||
|
96 | return self._lm[key][0] | |||
|
97 | ||||
|
98 | def __len__(self): | |||
|
99 | return len(self._lm) | |||
|
100 | ||||
|
101 | def __setitem__(self, key, node): | |||
|
102 | self._lm[key] = node, self.flags(key, '') | |||
|
103 | ||||
|
104 | def __contains__(self, key): | |||
|
105 | return key in self._lm | |||
|
106 | ||||
|
107 | def __delitem__(self, key): | |||
|
108 | del self._lm[key] | |||
|
109 | ||||
|
110 | def keys(self): | |||
|
111 | return [x[0] for x in self._lm] | |||
|
112 | ||||
|
113 | def iterkeys(self): | |||
|
114 | return iter(self.keys()) | |||
|
115 | ||||
48 | def intersectfiles(self, files): |
|
116 | def intersectfiles(self, files): | |
49 |
'''make a new manifes |
|
117 | '''make a new lazymanifest with the intersection of self with files | |
50 |
|
118 | |||
51 | The algorithm assumes that files is much smaller than self.''' |
|
119 | The algorithm assumes that files is much smaller than self.''' | |
52 | ret = manifestdict() |
|
120 | ret = manifestdict() | |
|
121 | lm = self._lm | |||
53 | for fn in files: |
|
122 | for fn in files: | |
54 |
if fn in |
|
123 | if fn in lm: | |
55 | ret[fn] = self[fn] |
|
124 | ret._lm[fn] = self._lm[fn] | |
56 | flags = self._flags.get(fn, None) |
|
|||
57 | if flags: |
|
|||
58 | ret._flags[fn] = flags |
|
|||
59 | return ret |
|
125 | return ret | |
60 |
|
126 | |||
61 | def filesnotin(self, m2): |
|
127 | def filesnotin(self, m2): | |
@@ -74,11 +140,9 b' class manifestdict(dict):' | |||||
74 | (not match.anypats() and util.all(fn in self for fn in files))): |
|
140 | (not match.anypats() and util.all(fn in self for fn in files))): | |
75 | return self.intersectfiles(files) |
|
141 | return self.intersectfiles(files) | |
76 |
|
142 | |||
77 |
m = |
|
143 | lm = manifestdict('') | |
78 | for fn in m.keys(): |
|
144 | lm._lm = self._lm.filtercopy(match) | |
79 | if not match(fn): |
|
145 | return lm | |
80 | del m[fn] |
|
|||
81 | return m |
|
|||
82 |
|
146 | |||
83 | def diff(self, m2, clean=False): |
|
147 | def diff(self, m2, clean=False): | |
84 | '''Finds changes between the current manifest and m2. |
|
148 | '''Finds changes between the current manifest and m2. | |
@@ -95,35 +159,36 b' class manifestdict(dict):' | |||||
95 | the nodeid will be None and the flags will be the empty |
|
159 | the nodeid will be None and the flags will be the empty | |
96 | string. |
|
160 | string. | |
97 | ''' |
|
161 | ''' | |
98 | diff = {} |
|
162 | return self._lm.diff(m2._lm, clean) | |
|
163 | ||||
|
164 | def setflag(self, key, flag): | |||
|
165 | self._lm[key] = self[key], flag | |||
|
166 | ||||
|
167 | def get(self, key, default=None): | |||
|
168 | try: | |||
|
169 | return self._lm[key][0] | |||
|
170 | except KeyError: | |||
|
171 | return default | |||
99 |
|
172 | |||
100 | for fn, n1 in self.iteritems(): |
|
173 | def flags(self, key, default=''): | |
101 | fl1 = self._flags.get(fn, '') |
|
174 | try: | |
102 | n2 = m2.get(fn, None) |
|
175 | return self._lm[key][1] | |
103 | fl2 = m2._flags.get(fn, '') |
|
176 | except KeyError: | |
104 | if n2 is None: |
|
177 | return default | |
105 | fl2 = '' |
|
|||
106 | if n1 != n2 or fl1 != fl2: |
|
|||
107 | diff[fn] = ((n1, fl1), (n2, fl2)) |
|
|||
108 | elif clean: |
|
|||
109 | diff[fn] = None |
|
|||
110 |
|
178 | |||
111 | for fn, n2 in m2.iteritems(): |
|
179 | def __iter__(self): | |
112 | if fn not in self: |
|
180 | return (x[0] for x in self._lm) | |
113 | fl2 = m2._flags.get(fn, '') |
|
|||
114 | diff[fn] = ((None, ''), (n2, fl2)) |
|
|||
115 |
|
181 | |||
116 | return diff |
|
182 | def copy(self): | |
|
183 | c = manifestdict('') | |||
|
184 | c._lm = self._lm.copy() | |||
|
185 | return c | |||
|
186 | ||||
|
187 | def iteritems(self): | |||
|
188 | return (x[:2] for x in self._lm) | |||
117 |
|
189 | |||
118 | def text(self): |
|
190 | def text(self): | |
119 | """Get the full data of this manifest as a bytestring.""" |
|
191 | return self._lm.text() | |
120 | fl = sorted(self) |
|
|||
121 | _checkforbidden(fl) |
|
|||
122 |
|
||||
123 | hex, flags = revlog.hex, self.flags |
|
|||
124 | # if this is changed to support newlines in filenames, |
|
|||
125 | # be sure to check the templates/ dir again (especially *-raw.tmpl) |
|
|||
126 | return ''.join("%s\0%s%s\n" % (f, hex(self[f]), flags(f)) for f in fl) |
|
|||
127 |
|
192 | |||
128 | def fastdelta(self, base, changes): |
|
193 | def fastdelta(self, base, changes): | |
129 | """Given a base manifest text as an array.array and a list of changes |
|
194 | """Given a base manifest text as an array.array and a list of changes | |
@@ -143,7 +208,8 b' class manifestdict(dict):' | |||||
143 | # bs will either be the index of the item or the insert point |
|
208 | # bs will either be the index of the item or the insert point | |
144 | start, end = _msearch(addbuf, f, start) |
|
209 | start, end = _msearch(addbuf, f, start) | |
145 | if not todelete: |
|
210 | if not todelete: | |
146 | l = "%s\0%s%s\n" % (f, revlog.hex(self[f]), self.flags(f)) |
|
211 | h, fl = self._lm[f] | |
|
212 | l = "%s\0%s%s\n" % (f, revlog.hex(h), fl) | |||
147 | else: |
|
213 | else: | |
148 | if start == end: |
|
214 | if start == end: | |
149 | # item we want to delete was not found, error out |
|
215 | # item we want to delete was not found, error out | |
@@ -280,12 +346,10 b' class manifest(revlog.revlog):' | |||||
280 | m = self._mancache[node][0] |
|
346 | m = self._mancache[node][0] | |
281 | return m.get(f), m.flags(f) |
|
347 | return m.get(f), m.flags(f) | |
282 | text = self.revision(node) |
|
348 | text = self.revision(node) | |
283 | start, end = _msearch(text, f) |
|
349 | try: | |
284 | if start == end: |
|
350 | return manifestdict(text)._lm[f] | |
|
351 | except KeyError: | |||
285 | return None, None |
|
352 | return None, None | |
286 | l = text[start:end] |
|
|||
287 | f, n = l.split('\0') |
|
|||
288 | return revlog.bin(n[:40]), n[40:-1] |
|
|||
289 |
|
353 | |||
290 | def add(self, m, transaction, link, p1, p2, added, removed): |
|
354 | def add(self, m, transaction, link, p1, p2, added, removed): | |
291 | if p1 in self._mancache: |
|
355 | if p1 in self._mancache: |
@@ -4,7 +4,7 b' import itertools' | |||||
4 |
|
4 | |||
5 | import silenttestrunner |
|
5 | import silenttestrunner | |
6 |
|
6 | |||
7 |
from mercurial import |
|
7 | from mercurial import manifest as manifestmod | |
8 |
|
8 | |||
9 | HASH_1 = '1' * 40 |
|
9 | HASH_1 = '1' * 40 | |
10 | HASH_2 = 'f' * 40 |
|
10 | HASH_2 = 'f' * 40 | |
@@ -38,12 +38,12 b' class testmanifest(unittest.TestCase):' | |||||
38 | self.assert_(thing in container, msg) |
|
38 | self.assert_(thing in container, msg) | |
39 |
|
39 | |||
40 | def testEmptyManifest(self): |
|
40 | def testEmptyManifest(self): | |
41 |
m = |
|
41 | m = manifestmod._lazymanifest('') | |
42 | self.assertEqual(0, len(m)) |
|
42 | self.assertEqual(0, len(m)) | |
43 | self.assertEqual([], list(m)) |
|
43 | self.assertEqual([], list(m)) | |
44 |
|
44 | |||
45 | def testManifest(self): |
|
45 | def testManifest(self): | |
46 |
m = |
|
46 | m = manifestmod._lazymanifest(A_SHORT_MANIFEST) | |
47 | want = [ |
|
47 | want = [ | |
48 | ('bar/baz/qux.py', binascii.unhexlify(HASH_2), 'l'), |
|
48 | ('bar/baz/qux.py', binascii.unhexlify(HASH_2), 'l'), | |
49 | ('foo', binascii.unhexlify(HASH_1), ''), |
|
49 | ('foo', binascii.unhexlify(HASH_1), ''), | |
@@ -58,13 +58,13 b' class testmanifest(unittest.TestCase):' | |||||
58 | def testSetItem(self): |
|
58 | def testSetItem(self): | |
59 | want = binascii.unhexlify(HASH_1), '' |
|
59 | want = binascii.unhexlify(HASH_1), '' | |
60 |
|
60 | |||
61 |
m = |
|
61 | m = manifestmod._lazymanifest('') | |
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 = |
|
67 | m = manifestmod._lazymanifest(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, | |
@@ -76,7 +76,7 b' class testmanifest(unittest.TestCase):' | |||||
76 | def testCompaction(self): |
|
76 | def testCompaction(self): | |
77 | unhex = binascii.unhexlify |
|
77 | unhex = binascii.unhexlify | |
78 | h1, h2 = unhex(HASH_1), unhex(HASH_2) |
|
78 | h1, h2 = unhex(HASH_1), unhex(HASH_2) | |
79 |
m = |
|
79 | m = manifestmod._lazymanifest(A_SHORT_MANIFEST) | |
80 | m['alpha'] = h1, '' |
|
80 | m['alpha'] = h1, '' | |
81 | m['beta'] = h2, '' |
|
81 | m['beta'] = h2, '' | |
82 | del m['foo'] |
|
82 | del m['foo'] | |
@@ -91,8 +91,8 b' class testmanifest(unittest.TestCase):' | |||||
91 | self.assertEqual(w, list(m)) |
|
91 | self.assertEqual(w, list(m)) | |
92 |
|
92 | |||
93 | def testSetGetNodeSuffix(self): |
|
93 | def testSetGetNodeSuffix(self): | |
94 |
clean = |
|
94 | clean = manifestmod._lazymanifest(A_SHORT_MANIFEST) | |
95 |
m = |
|
95 | m = manifestmod._lazymanifest(A_SHORT_MANIFEST) | |
96 | h, f = m['foo'] |
|
96 | h, f = m['foo'] | |
97 | want = h + 'a', f |
|
97 | want = h + 'a', f | |
98 | # Merge code wants to set 21-byte fake hashes at times |
|
98 | # Merge code wants to set 21-byte fake hashes at times | |
@@ -120,7 +120,7 b' class testmanifest(unittest.TestCase):' | |||||
120 | self.assertEqual({'foo': ((h, ''), want)}, clean.diff(m)) |
|
120 | self.assertEqual({'foo': ((h, ''), want)}, clean.diff(m)) | |
121 |
|
121 | |||
122 | def testFilterCopyException(self): |
|
122 | def testFilterCopyException(self): | |
123 |
m = |
|
123 | m = manifestmod._lazymanifest(A_SHORT_MANIFEST) | |
124 | def filt(path): |
|
124 | def filt(path): | |
125 | if path == 'foo': |
|
125 | if path == 'foo': | |
126 | assert False |
|
126 | assert False | |
@@ -128,7 +128,7 b' class testmanifest(unittest.TestCase):' | |||||
128 | self.assertRaises(AssertionError, m.filtercopy, filt) |
|
128 | self.assertRaises(AssertionError, m.filtercopy, filt) | |
129 |
|
129 | |||
130 | def testRemoveItem(self): |
|
130 | def testRemoveItem(self): | |
131 |
m = |
|
131 | m = manifestmod._lazymanifest(A_SHORT_MANIFEST) | |
132 | del m['foo'] |
|
132 | del m['foo'] | |
133 | self.assertRaises(KeyError, lambda : m['foo']) |
|
133 | self.assertRaises(KeyError, lambda : m['foo']) | |
134 | self.assertEqual(1, len(m)) |
|
134 | self.assertEqual(1, len(m)) | |
@@ -138,9 +138,9 b' class testmanifest(unittest.TestCase):' | |||||
138 | MISSING = (None, '') |
|
138 | MISSING = (None, '') | |
139 | addl = 'z-only-in-left\0' + HASH_1 + '\n' |
|
139 | addl = 'z-only-in-left\0' + HASH_1 + '\n' | |
140 | addr = 'z-only-in-right\0' + HASH_2 + 'x\n' |
|
140 | addr = 'z-only-in-right\0' + HASH_2 + 'x\n' | |
141 |
left = |
|
141 | left = manifestmod._lazymanifest( | |
142 | A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl) |
|
142 | A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl) | |
143 |
right = |
|
143 | right = manifestmod._lazymanifest(A_SHORT_MANIFEST + addr) | |
144 | want = { |
|
144 | want = { | |
145 | 'foo': ((binascii.unhexlify(HASH_3), 'x'), |
|
145 | 'foo': ((binascii.unhexlify(HASH_3), 'x'), | |
146 | (binascii.unhexlify(HASH_1), '')), |
|
146 | (binascii.unhexlify(HASH_1), '')), | |
@@ -154,14 +154,14 b' class testmanifest(unittest.TestCase):' | |||||
154 | 'foo': (MISSING, (binascii.unhexlify(HASH_3), 'x')), |
|
154 | 'foo': (MISSING, (binascii.unhexlify(HASH_3), 'x')), | |
155 | 'z-only-in-left': (MISSING, (binascii.unhexlify(HASH_1), '')), |
|
155 | 'z-only-in-left': (MISSING, (binascii.unhexlify(HASH_1), '')), | |
156 | } |
|
156 | } | |
157 |
self.assertEqual(want, |
|
157 | self.assertEqual(want, manifestmod._lazymanifest('').diff(left)) | |
158 |
|
158 | |||
159 | want = { |
|
159 | want = { | |
160 | 'bar/baz/qux.py': ((binascii.unhexlify(HASH_2), 'l'), MISSING), |
|
160 | 'bar/baz/qux.py': ((binascii.unhexlify(HASH_2), 'l'), MISSING), | |
161 | 'foo': ((binascii.unhexlify(HASH_3), 'x'), MISSING), |
|
161 | 'foo': ((binascii.unhexlify(HASH_3), 'x'), MISSING), | |
162 | 'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING), |
|
162 | 'z-only-in-left': ((binascii.unhexlify(HASH_1), ''), MISSING), | |
163 | } |
|
163 | } | |
164 |
self.assertEqual(want, left.diff( |
|
164 | self.assertEqual(want, left.diff(manifestmod._lazymanifest(''))) | |
165 | copy = right.copy() |
|
165 | copy = right.copy() | |
166 | del copy['z-only-in-right'] |
|
166 | del copy['z-only-in-right'] | |
167 | del right['foo'] |
|
167 | del right['foo'] | |
@@ -171,7 +171,7 b' class testmanifest(unittest.TestCase):' | |||||
171 | } |
|
171 | } | |
172 | self.assertEqual(want, right.diff(copy)) |
|
172 | self.assertEqual(want, right.diff(copy)) | |
173 |
|
173 | |||
174 |
short = |
|
174 | short = manifestmod._lazymanifest(A_SHORT_MANIFEST) | |
175 | pruned = short.copy() |
|
175 | pruned = short.copy() | |
176 | del pruned['foo'] |
|
176 | del pruned['foo'] | |
177 | want = { |
|
177 | want = { | |
@@ -192,30 +192,37 b' class testmanifest(unittest.TestCase):' | |||||
192 | backwards = ''.join( |
|
192 | backwards = ''.join( | |
193 | l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l) |
|
193 | l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l) | |
194 | try: |
|
194 | try: | |
195 |
|
|
195 | manifestmod._lazymanifest(backwards) | |
196 | self.fail('Should have raised ValueError') |
|
196 | self.fail('Should have raised ValueError') | |
197 | except ValueError, v: |
|
197 | except ValueError, v: | |
198 | self.assertIn('Manifest lines not in sorted order.', str(v)) |
|
198 | self.assertIn('Manifest lines not in sorted order.', str(v)) | |
199 |
|
199 | |||
200 | def testNoTerminalNewline(self): |
|
200 | def testNoTerminalNewline(self): | |
201 | try: |
|
201 | try: | |
202 |
|
|
202 | manifestmod._lazymanifest(A_SHORT_MANIFEST + 'wat') | |
203 | self.fail('Should have raised ValueError') |
|
203 | self.fail('Should have raised ValueError') | |
204 | except ValueError, v: |
|
204 | except ValueError, v: | |
205 | self.assertIn('Manifest did not end in a newline.', str(v)) |
|
205 | self.assertIn('Manifest did not end in a newline.', str(v)) | |
206 |
|
206 | |||
207 | def testNoNewLineAtAll(self): |
|
207 | def testNoNewLineAtAll(self): | |
208 | try: |
|
208 | try: | |
209 |
|
|
209 | manifestmod._lazymanifest('wat') | |
210 | self.fail('Should have raised ValueError') |
|
210 | self.fail('Should have raised ValueError') | |
211 | except ValueError, v: |
|
211 | except ValueError, v: | |
212 | self.assertIn('Manifest did not end in a newline.', str(v)) |
|
212 | self.assertIn('Manifest did not end in a newline.', str(v)) | |
213 |
|
213 | |||
214 | def testHugeManifest(self): |
|
214 | def testHugeManifest(self): | |
215 |
m = |
|
215 | m = manifestmod._lazymanifest(A_HUGE_MANIFEST) | |
216 | self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m)) |
|
216 | self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m)) | |
217 | self.assertEqual(len(m), len(list(m))) |
|
217 | self.assertEqual(len(m), len(list(m))) | |
218 |
|
218 | |||
|
219 | def testIntersectFiles(self): | |||
|
220 | m = manifestmod.manifestdict(A_HUGE_MANIFEST) | |||
|
221 | m2 = m.intersectfiles(['file1', 'file200', 'file300']) | |||
|
222 | w = ('file1\0%sx\n' | |||
|
223 | 'file200\0%sl\n' | |||
|
224 | 'file300\0%s\n') % (HASH_2, HASH_1, HASH_1) | |||
|
225 | self.assertEqual(w, m2.text()) | |||
219 |
|
226 | |||
220 | if __name__ == '__main__': |
|
227 | if __name__ == '__main__': | |
221 | silenttestrunner.main(__name__) |
|
228 | silenttestrunner.main(__name__) |
General Comments 0
You need to be logged in to leave comments.
Login now