##// END OF EJS Templates
tests-pure: fixing test-parseindex2...
Georges Racinet -
r44399:ac627ed8 default
parent child Browse files
Show More
@@ -1,280 +1,282 b''
1 """This unit test primarily tests parsers.parse_index2().
1 """This unit test primarily tests parsers.parse_index2().
2
2
3 It also checks certain aspects of the parsers module as a whole.
3 It also checks certain aspects of the parsers module as a whole.
4 """
4 """
5
5
6 from __future__ import absolute_import, print_function
6 from __future__ import absolute_import, print_function
7
7
8 import struct
8 import struct
9 import subprocess
9 import subprocess
10 import sys
10 import sys
11 import unittest
11 import unittest
12
12
13 from mercurial.node import (
13 from mercurial.node import (
14 nullid,
14 nullid,
15 nullrev,
15 nullrev,
16 )
16 )
17 from mercurial import (
17 from mercurial import (
18 node as nodemod,
18 node as nodemod,
19 policy,
19 policy,
20 pycompat,
20 pycompat,
21 )
21 )
22
22
23 parsers = policy.importmod('parsers')
23 parsers = policy.importmod('parsers')
24
24
25 # original python implementation
25 # original python implementation
26 def gettype(q):
26 def gettype(q):
27 return int(q & 0xFFFF)
27 return int(q & 0xFFFF)
28
28
29
29
30 def offset_type(offset, type):
30 def offset_type(offset, type):
31 return int(int(offset) << 16 | type)
31 return int(int(offset) << 16 | type)
32
32
33
33
34 indexformatng = ">Qiiiiii20s12x"
34 indexformatng = ">Qiiiiii20s12x"
35
35
36
36
37 def py_parseindex(data, inline):
37 def py_parseindex(data, inline):
38 s = 64
38 s = 64
39 cache = None
39 cache = None
40 index = []
40 index = []
41 nodemap = {nullid: nullrev}
41 nodemap = {nullid: nullrev}
42 n = off = 0
42 n = off = 0
43
43
44 l = len(data) - s
44 l = len(data) - s
45 append = index.append
45 append = index.append
46 if inline:
46 if inline:
47 cache = (0, data)
47 cache = (0, data)
48 while off <= l:
48 while off <= l:
49 e = struct.unpack(indexformatng, data[off : off + s])
49 e = struct.unpack(indexformatng, data[off : off + s])
50 nodemap[e[7]] = n
50 nodemap[e[7]] = n
51 append(e)
51 append(e)
52 n += 1
52 n += 1
53 if e[1] < 0:
53 if e[1] < 0:
54 break
54 break
55 off += e[1] + s
55 off += e[1] + s
56 else:
56 else:
57 while off <= l:
57 while off <= l:
58 e = struct.unpack(indexformatng, data[off : off + s])
58 e = struct.unpack(indexformatng, data[off : off + s])
59 nodemap[e[7]] = n
59 nodemap[e[7]] = n
60 append(e)
60 append(e)
61 n += 1
61 n += 1
62 off += s
62 off += s
63
63
64 e = list(index[0])
64 e = list(index[0])
65 type = gettype(e[0])
65 type = gettype(e[0])
66 e[0] = offset_type(0, type)
66 e[0] = offset_type(0, type)
67 index[0] = tuple(e)
67 index[0] = tuple(e)
68
68
69 return index, cache
69 return index, cache
70
70
71
71
72 data_inlined = (
72 data_inlined = (
73 b'\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x01\x8c'
73 b'\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x01\x8c'
74 b'\x00\x00\x04\x07\x00\x00\x00\x00\x00\x00\x15\x15\xff\xff\xff'
74 b'\x00\x00\x04\x07\x00\x00\x00\x00\x00\x00\x15\x15\xff\xff\xff'
75 b'\xff\xff\xff\xff\xff\xebG\x97\xb7\x1fB\x04\xcf\x13V\x81\tw\x1b'
75 b'\xff\xff\xff\xff\xff\xebG\x97\xb7\x1fB\x04\xcf\x13V\x81\tw\x1b'
76 b'w\xdduR\xda\xc6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
76 b'w\xdduR\xda\xc6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
77 b'x\x9c\x9d\x93?O\xc30\x10\xc5\xf7|\x8a\xdb\x9a\xa8m\x06\xd8*\x95'
77 b'x\x9c\x9d\x93?O\xc30\x10\xc5\xf7|\x8a\xdb\x9a\xa8m\x06\xd8*\x95'
78 b'\x81B\xa1\xa2\xa2R\xcb\x86Pd\x9a\x0b5$vd_\x04\xfd\xf6\x9c\xff@'
78 b'\x81B\xa1\xa2\xa2R\xcb\x86Pd\x9a\x0b5$vd_\x04\xfd\xf6\x9c\xff@'
79 b'\x11!\x0b\xd9\xec\xf7\xbbw\xe7gG6\xad6\x04\xdaN\xc0\x92\xa0$)'
79 b'\x11!\x0b\xd9\xec\xf7\xbbw\xe7gG6\xad6\x04\xdaN\xc0\x92\xa0$)'
80 b'\xb1\x82\xa2\xd1%\x16\xa4\x8b7\xa9\xca\xd4-\xb2Y\x02\xfc\xc9'
80 b'\xb1\x82\xa2\xd1%\x16\xa4\x8b7\xa9\xca\xd4-\xb2Y\x02\xfc\xc9'
81 b'\xcaS\xf9\xaeX\xed\xb6\xd77Q\x02\x83\xd4\x19\xf5--Y\xea\xe1W'
81 b'\xcaS\xf9\xaeX\xed\xb6\xd77Q\x02\x83\xd4\x19\xf5--Y\xea\xe1W'
82 b'\xab\xed\x10\xceR\x0f_\xdf\xdf\r\xe1,\xf5\xf0\xcb\xf5 \xceR\x0f'
82 b'\xab\xed\x10\xceR\x0f_\xdf\xdf\r\xe1,\xf5\xf0\xcb\xf5 \xceR\x0f'
83 b'_\xdc\x0e\x0e\xc3R\x0f_\xae\x96\x9b!\x9e\xa5\x1e\xbf\xdb,\x06'
83 b'_\xdc\x0e\x0e\xc3R\x0f_\xae\x96\x9b!\x9e\xa5\x1e\xbf\xdb,\x06'
84 b'\xc7q\x9a/\x88\x82\xc3B\xea\xb5\xb4TJ\x93\xb6\x82\x0e\xe16\xe6'
84 b'\xc7q\x9a/\x88\x82\xc3B\xea\xb5\xb4TJ\x93\xb6\x82\x0e\xe16\xe6'
85 b'KQ\xdb\xaf\xecG\xa3\xd1 \x01\xd3\x0b_^\xe8\xaa\xa0\xae\xad\xd1'
85 b'KQ\xdb\xaf\xecG\xa3\xd1 \x01\xd3\x0b_^\xe8\xaa\xa0\xae\xad\xd1'
86 b'&\xbef\x1bz\x08\xb0|\xc9Xz\x06\xf6Z\x91\x90J\xaa\x17\x90\xaa'
86 b'&\xbef\x1bz\x08\xb0|\xc9Xz\x06\xf6Z\x91\x90J\xaa\x17\x90\xaa'
87 b'\xd2\xa6\x11$5C\xcf\xba#\xa0\x03\x02*2\x92-\xfc\xb1\x94\xdf\xe2'
87 b'\xd2\xa6\x11$5C\xcf\xba#\xa0\x03\x02*2\x92-\xfc\xb1\x94\xdf\xe2'
88 b'\xae\xb8\'m\x8ey0^\x85\xd3\x82\xb4\xf0`:\x9c\x00\x8a\xfd\x01'
88 b'\xae\xb8\'m\x8ey0^\x85\xd3\x82\xb4\xf0`:\x9c\x00\x8a\xfd\x01'
89 b'\xb0\xc6\x86\x8b\xdd\xae\x80\xf3\xa9\x9fd\x16\n\x00R%\x1a\x06'
89 b'\xb0\xc6\x86\x8b\xdd\xae\x80\xf3\xa9\x9fd\x16\n\x00R%\x1a\x06'
90 b'\xe9\xd8b\x98\x1d\xf4\xf3+\x9bf\x01\xd8p\x1b\xf3.\xed\x9f^g\xc3'
90 b'\xe9\xd8b\x98\x1d\xf4\xf3+\x9bf\x01\xd8p\x1b\xf3.\xed\x9f^g\xc3'
91 b'^\xd9W81T\xdb\xd5\x04sx|\xf2\xeb\xd6`%?x\xed"\x831\xbf\xf3\xdc'
91 b'^\xd9W81T\xdb\xd5\x04sx|\xf2\xeb\xd6`%?x\xed"\x831\xbf\xf3\xdc'
92 b'b\xeb%gaY\xe1\xad\x9f\xb9f\'1w\xa9\xa5a\x83s\x82J\xb98\xbc4\x8b'
92 b'b\xeb%gaY\xe1\xad\x9f\xb9f\'1w\xa9\xa5a\x83s\x82J\xb98\xbc4\x8b'
93 b'\x83\x00\x9f$z\xb8#\xa5\xb1\xdf\x98\xd9\xec\x1b\x89O\xe3Ts\x9a4'
93 b'\x83\x00\x9f$z\xb8#\xa5\xb1\xdf\x98\xd9\xec\x1b\x89O\xe3Ts\x9a4'
94 b'\x17m\x8b\xfc\x8f\xa5\x95\x9a\xfc\xfa\xed,\xe5|\xa1\xfe\x15\xb9'
94 b'\x17m\x8b\xfc\x8f\xa5\x95\x9a\xfc\xfa\xed,\xe5|\xa1\xfe\x15\xb9'
95 b'\xbc\xb2\x93\x1f\xf2\x95\xff\xdf,\x1a\xc5\xe7\x17*\x93Oz:>\x0e'
95 b'\xbc\xb2\x93\x1f\xf2\x95\xff\xdf,\x1a\xc5\xe7\x17*\x93Oz:>\x0e'
96 )
96 )
97
97
98 data_non_inlined = (
98 data_non_inlined = (
99 b'\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01D\x19'
99 b'\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01D\x19'
100 b'\x00\x07e\x12\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff'
100 b'\x00\x07e\x12\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff'
101 b'\xff\xff\xff\xff\xd1\xf4\xbb\xb0\xbe\xfc\x13\xbd\x8c\xd3\x9d'
101 b'\xff\xff\xff\xff\xd1\xf4\xbb\xb0\xbe\xfc\x13\xbd\x8c\xd3\x9d'
102 b'\x0f\xcd\xd9;\x8c\x07\x8cJ/\x00\x00\x00\x00\x00\x00\x00\x00\x00'
102 b'\x0f\xcd\xd9;\x8c\x07\x8cJ/\x00\x00\x00\x00\x00\x00\x00\x00\x00'
103 b'\x00\x00\x00\x00\x00\x00\x01D\x19\x00\x00\x00\x00\x00\xdf\x00'
103 b'\x00\x00\x00\x00\x00\x00\x01D\x19\x00\x00\x00\x00\x00\xdf\x00'
104 b'\x00\x01q\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\xff'
104 b'\x00\x01q\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\xff'
105 b'\xff\xff\xff\xc1\x12\xb9\x04\x96\xa4Z1t\x91\xdfsJ\x90\xf0\x9bh'
105 b'\xff\xff\xff\xc1\x12\xb9\x04\x96\xa4Z1t\x91\xdfsJ\x90\xf0\x9bh'
106 b'\x07l&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
106 b'\x07l&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
107 b'\x00\x01D\xf8\x00\x00\x00\x00\x01\x1b\x00\x00\x01\xb8\x00\x00'
107 b'\x00\x01D\xf8\x00\x00\x00\x00\x01\x1b\x00\x00\x01\xb8\x00\x00'
108 b'\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\x02\n'
108 b'\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\xff\xff\xff\xff\x02\n'
109 b'\x0e\xc6&\xa1\x92\xae6\x0b\x02i\xfe-\xe5\xbao\x05\xd1\xe7\x00'
109 b'\x0e\xc6&\xa1\x92\xae6\x0b\x02i\xfe-\xe5\xbao\x05\xd1\xe7\x00'
110 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01F'
110 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01F'
111 b'\x13\x00\x00\x00\x00\x01\xec\x00\x00\x03\x06\x00\x00\x00\x01'
111 b'\x13\x00\x00\x00\x00\x01\xec\x00\x00\x03\x06\x00\x00\x00\x01'
112 b'\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x12\xcb\xeby1'
112 b'\x00\x00\x00\x03\x00\x00\x00\x02\xff\xff\xff\xff\x12\xcb\xeby1'
113 b'\xb6\r\x98B\xcb\x07\xbd`\x8f\x92\xd9\xc4\x84\xbdK\x00\x00\x00'
113 b'\xb6\r\x98B\xcb\x07\xbd`\x8f\x92\xd9\xc4\x84\xbdK\x00\x00\x00'
114 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00'
114 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00'
115 )
115 )
116
116
117
117
118 def parse_index2(data, inline):
118 def parse_index2(data, inline):
119 index, chunkcache = parsers.parse_index2(data, inline)
119 index, chunkcache = parsers.parse_index2(data, inline)
120 return list(index), chunkcache
120 return list(index), chunkcache
121
121
122
122
123 def importparsers(hexversion):
123 def importparsers(hexversion):
124 """Import mercurial.parsers with the given sys.hexversion."""
124 """Import mercurial.parsers with the given sys.hexversion."""
125 # The file parsers.c inspects sys.hexversion to determine the version
125 # The file parsers.c inspects sys.hexversion to determine the version
126 # of the currently-running Python interpreter, so we monkey-patch
126 # of the currently-running Python interpreter, so we monkey-patch
127 # sys.hexversion to simulate using different versions.
127 # sys.hexversion to simulate using different versions.
128 code = (
128 code = (
129 "import sys; sys.hexversion=%s; "
129 "import sys; sys.hexversion=%s; "
130 "import mercurial.cext.parsers" % hexversion
130 "import mercurial.cext.parsers" % hexversion
131 )
131 )
132 cmd = "python -c \"%s\"" % code
132 cmd = "python -c \"%s\"" % code
133 # We need to do these tests inside a subprocess because parser.c's
133 # We need to do these tests inside a subprocess because parser.c's
134 # version-checking code happens inside the module init function, and
134 # version-checking code happens inside the module init function, and
135 # when using reload() to reimport an extension module, "The init function
135 # when using reload() to reimport an extension module, "The init function
136 # of extension modules is not called a second time"
136 # of extension modules is not called a second time"
137 # (from http://docs.python.org/2/library/functions.html?#reload).
137 # (from http://docs.python.org/2/library/functions.html?#reload).
138 p = subprocess.Popen(
138 p = subprocess.Popen(
139 cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
139 cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
140 )
140 )
141 return p.communicate() # returns stdout, stderr
141 return p.communicate() # returns stdout, stderr
142
142
143
143
144 def hexfailmsg(testnumber, hexversion, stdout, expected):
144 def hexfailmsg(testnumber, hexversion, stdout, expected):
145 try:
145 try:
146 hexstring = hex(hexversion)
146 hexstring = hex(hexversion)
147 except TypeError:
147 except TypeError:
148 hexstring = None
148 hexstring = None
149 return (
149 return (
150 "FAILED: version test #%s with Python %s and patched "
150 "FAILED: version test #%s with Python %s and patched "
151 "sys.hexversion %r (%r):\n Expected %s but got:\n-->'%s'\n"
151 "sys.hexversion %r (%r):\n Expected %s but got:\n-->'%s'\n"
152 % (
152 % (
153 testnumber,
153 testnumber,
154 sys.version_info,
154 sys.version_info,
155 hexversion,
155 hexversion,
156 hexstring,
156 hexstring,
157 expected,
157 expected,
158 stdout,
158 stdout,
159 )
159 )
160 )
160 )
161
161
162
162
163 def makehex(major, minor, micro):
163 def makehex(major, minor, micro):
164 return int("%x%02x%02x00" % (major, minor, micro), 16)
164 return int("%x%02x%02x00" % (major, minor, micro), 16)
165
165
166
166
167 class parseindex2tests(unittest.TestCase):
167 class parseindex2tests(unittest.TestCase):
168 def assertversionokay(self, testnumber, hexversion):
168 def assertversionokay(self, testnumber, hexversion):
169 stdout, stderr = importparsers(hexversion)
169 stdout, stderr = importparsers(hexversion)
170 self.assertFalse(
170 self.assertFalse(
171 stdout, hexfailmsg(testnumber, hexversion, stdout, 'no stdout')
171 stdout, hexfailmsg(testnumber, hexversion, stdout, 'no stdout')
172 )
172 )
173
173
174 def assertversionfail(self, testnumber, hexversion):
174 def assertversionfail(self, testnumber, hexversion):
175 stdout, stderr = importparsers(hexversion)
175 stdout, stderr = importparsers(hexversion)
176 # We include versionerrortext to distinguish from other ImportErrors.
176 # We include versionerrortext to distinguish from other ImportErrors.
177 errtext = b"ImportError: %s" % pycompat.sysbytes(
177 errtext = b"ImportError: %s" % pycompat.sysbytes(
178 parsers.versionerrortext
178 parsers.versionerrortext
179 )
179 )
180 self.assertIn(
180 self.assertIn(
181 errtext,
181 errtext,
182 stdout,
182 stdout,
183 hexfailmsg(
183 hexfailmsg(
184 testnumber,
184 testnumber,
185 hexversion,
185 hexversion,
186 stdout,
186 stdout,
187 expected="stdout to contain %r" % errtext,
187 expected="stdout to contain %r" % errtext,
188 ),
188 ),
189 )
189 )
190
190
191 def testversiondetection(self):
191 def testversiondetection(self):
192 """Check the version-detection logic when importing parsers."""
192 """Check the version-detection logic when importing parsers."""
193 # Only test the version-detection logic if it is present.
193 # Only test the version-detection logic if it is present.
194 try:
194 try:
195 parsers.versionerrortext
195 parsers.versionerrortext
196 except AttributeError:
196 except AttributeError:
197 return
197 return
198 info = sys.version_info
198 info = sys.version_info
199 major, minor, micro = info[0], info[1], info[2]
199 major, minor, micro = info[0], info[1], info[2]
200 # Test same major-minor versions.
200 # Test same major-minor versions.
201 self.assertversionokay(1, makehex(major, minor, micro))
201 self.assertversionokay(1, makehex(major, minor, micro))
202 self.assertversionokay(2, makehex(major, minor, micro + 1))
202 self.assertversionokay(2, makehex(major, minor, micro + 1))
203 # Test different major-minor versions.
203 # Test different major-minor versions.
204 self.assertversionfail(3, makehex(major + 1, minor, micro))
204 self.assertversionfail(3, makehex(major + 1, minor, micro))
205 self.assertversionfail(4, makehex(major, minor + 1, micro))
205 self.assertversionfail(4, makehex(major, minor + 1, micro))
206 self.assertversionfail(5, "'foo'")
206 self.assertversionfail(5, "'foo'")
207
207
208 def testbadargs(self):
208 def testbadargs(self):
209 # Check that parse_index2() raises TypeError on bad arguments.
209 # Check that parse_index2() raises TypeError on bad arguments.
210 with self.assertRaises(TypeError):
210 with self.assertRaises(TypeError):
211 parse_index2(0, True)
211 parse_index2(0, True)
212
212
213 def testparseindexfile(self):
213 def testparseindexfile(self):
214 # Check parsers.parse_index2() on an index file against the
214 # Check parsers.parse_index2() on an index file against the
215 # original Python implementation of parseindex, both with and
215 # original Python implementation of parseindex, both with and
216 # without inlined data.
216 # without inlined data.
217
217
218 want = py_parseindex(data_inlined, True)
218 want = py_parseindex(data_inlined, True)
219 got = parse_index2(data_inlined, True)
219 got = parse_index2(data_inlined, True)
220 self.assertEqual(want, got) # inline data
220 self.assertEqual(want, got) # inline data
221
221
222 want = py_parseindex(data_non_inlined, False)
222 want = py_parseindex(data_non_inlined, False)
223 got = parse_index2(data_non_inlined, False)
223 got = parse_index2(data_non_inlined, False)
224 self.assertEqual(want, got) # no inline data
224 self.assertEqual(want, got) # no inline data
225
225
226 ix = parsers.parse_index2(data_inlined, True)[0]
226 ix = parsers.parse_index2(data_inlined, True)[0]
227 for i, r in enumerate(ix):
227 for i, r in enumerate(ix):
228 if r[7] == nullid:
228 if r[7] == nullid:
229 i = -1
229 i = -1
230 try:
230 try:
231 self.assertEqual(
231 self.assertEqual(
232 ix[r[7]],
232 ix[r[7]],
233 i,
233 i,
234 'Reverse lookup inconsistent for %r' % nodemod.hex(r[7]),
234 'Reverse lookup inconsistent for %r' % nodemod.hex(r[7]),
235 )
235 )
236 except TypeError:
236 except TypeError:
237 # pure version doesn't support this
237 # pure version doesn't support this
238 break
238 break
239
239
240 def testminusone(self):
240 def testminusone(self):
241 want = (0, 0, 0, -1, -1, -1, -1, nullid)
241 want = (0, 0, 0, -1, -1, -1, -1, nullid)
242 index, junk = parsers.parse_index2(data_inlined, True)
242 index, junk = parsers.parse_index2(data_inlined, True)
243 got = index[-1]
243 got = index[-1]
244 self.assertEqual(want, got) # inline data
244 self.assertEqual(want, got) # inline data
245
245
246 index, junk = parsers.parse_index2(data_non_inlined, False)
246 index, junk = parsers.parse_index2(data_non_inlined, False)
247 got = index[-1]
247 got = index[-1]
248 self.assertEqual(want, got) # no inline data
248 self.assertEqual(want, got) # no inline data
249
249
250 def testdelitemwithoutnodetree(self):
250 def testdelitemwithoutnodetree(self):
251 index, _junk = parsers.parse_index2(data_non_inlined, False)
251 index, _junk = parsers.parse_index2(data_non_inlined, False)
252
252
253 def hexrev(rev):
253 def hexrev(rev):
254 if rev == nullrev:
254 if rev == nullrev:
255 return b'\xff\xff\xff\xff'
255 return b'\xff\xff\xff\xff'
256 else:
256 else:
257 return nodemod.bin('%08x' % rev)
257 return nodemod.bin('%08x' % rev)
258
258
259 def appendrev(p1, p2=nullrev):
259 def appendrev(p1, p2=nullrev):
260 # node won't matter for this test, let's just make sure
260 # node won't matter for this test, let's just make sure
261 # they don't collide. Other data don't matter either.
261 # they don't collide. Other data don't matter either.
262 node = hexrev(p1) + hexrev(p2) + b'.' * 12
262 node = hexrev(p1) + hexrev(p2) + b'.' * 12
263 index.append((0, 0, 12, 1, 34, p1, p2, node))
263 index.append((0, 0, 12, 1, 34, p1, p2, node))
264
264
265 appendrev(4)
265 appendrev(4)
266 appendrev(5)
266 appendrev(5)
267 appendrev(6)
267 appendrev(6)
268 self.assertEqual(len(index), 7)
268 self.assertEqual(len(index), 7)
269
269
270 del index[1:7]
270 del index[1:-1]
271
271
272 # assertions that failed before correction
272 # assertions that failed before correction
273 self.assertEqual(len(index), 1) # was 4
273 self.assertEqual(len(index), 1) # was 4
274 self.assertEqual(index.headrevs(), [0]) # gave ValueError
274 headrevs = getattr(index, 'headrevs', None)
275 if headrevs is not None: # not implemented in pure
276 self.assertEqual(index.headrevs(), [0]) # gave ValueError
275
277
276
278
277 if __name__ == '__main__':
279 if __name__ == '__main__':
278 import silenttestrunner
280 import silenttestrunner
279
281
280 silenttestrunner.main(__name__)
282 silenttestrunner.main(__name__)
General Comments 0
You need to be logged in to leave comments. Login now