blob: be959353fd899b1d33cde631dcbc1ea03e2c2f3a [file] [log] [blame]
Guido van Rossum4dfe8a12006-04-22 23:28:04 +00001"""Unit tests for the bytes type."""
2
Guido van Rossumd624f182006-04-24 13:47:05 +00003import os
4import re
Guido van Rossum4dfe8a12006-04-22 23:28:04 +00005import sys
Guido van Rossumd624f182006-04-24 13:47:05 +00006import tempfile
Guido van Rossum4dfe8a12006-04-22 23:28:04 +00007import unittest
8import test.test_support
9
10
11class BytesTest(unittest.TestCase):
12
13 def test_basics(self):
14 b = bytes()
15 self.assertEqual(type(b), bytes)
16 self.assertEqual(b.__class__, bytes)
17
18 def test_empty_sequence(self):
19 b = bytes()
20 self.assertEqual(len(b), 0)
21 self.assertRaises(IndexError, lambda: b[0])
22 self.assertRaises(IndexError, lambda: b[1])
23 self.assertRaises(IndexError, lambda: b[sys.maxint])
24 self.assertRaises(IndexError, lambda: b[sys.maxint+1])
25 self.assertRaises(IndexError, lambda: b[10**100])
26 self.assertRaises(IndexError, lambda: b[-1])
27 self.assertRaises(IndexError, lambda: b[-2])
28 self.assertRaises(IndexError, lambda: b[-sys.maxint])
29 self.assertRaises(IndexError, lambda: b[-sys.maxint-1])
30 self.assertRaises(IndexError, lambda: b[-sys.maxint-2])
31 self.assertRaises(IndexError, lambda: b[-10**100])
32
33 def test_from_list(self):
34 ints = list(range(256))
35 b = bytes(i for i in ints)
36 self.assertEqual(len(b), 256)
37 self.assertEqual(list(b), ints)
38
39 def test_from_index(self):
40 class C:
41 def __init__(self, i=0):
42 self.i = i
43 def __index__(self):
44 return self.i
45 b = bytes([C(), C(1), C(254), C(255)])
46 self.assertEqual(list(b), [0, 1, 254, 255])
Guido van Rossume06b6b82006-04-23 07:43:54 +000047 self.assertRaises(ValueError, bytes, [C(-1)])
48 self.assertRaises(ValueError, bytes, [C(256)])
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000049
50 def test_constructor_type_errors(self):
Guido van Rossumd624f182006-04-24 13:47:05 +000051 self.assertRaises(TypeError, bytes, 0.0)
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000052 class C:
53 pass
Guido van Rossume06b6b82006-04-23 07:43:54 +000054 self.assertRaises(TypeError, bytes, ["0"])
55 self.assertRaises(TypeError, bytes, [0.0])
56 self.assertRaises(TypeError, bytes, [None])
57 self.assertRaises(TypeError, bytes, [C()])
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000058
59 def test_constructor_value_errors(self):
Guido van Rossume06b6b82006-04-23 07:43:54 +000060 self.assertRaises(ValueError, bytes, [-1])
61 self.assertRaises(ValueError, bytes, [-sys.maxint])
62 self.assertRaises(ValueError, bytes, [-sys.maxint-1])
Thomas Woutersd204a712006-08-22 13:41:17 +000063 self.assertRaises(ValueError, bytes, [-sys.maxint-2])
64 self.assertRaises(ValueError, bytes, [-10**100])
Guido van Rossume06b6b82006-04-23 07:43:54 +000065 self.assertRaises(ValueError, bytes, [256])
66 self.assertRaises(ValueError, bytes, [257])
67 self.assertRaises(ValueError, bytes, [sys.maxint])
Thomas Woutersd204a712006-08-22 13:41:17 +000068 self.assertRaises(ValueError, bytes, [sys.maxint+1])
69 self.assertRaises(ValueError, bytes, [10**100])
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000070
71 def test_repr(self):
72 self.assertEqual(repr(bytes()), "bytes()")
73 self.assertEqual(repr(bytes([0])), "bytes([0x00])")
74 self.assertEqual(repr(bytes([0, 1, 254, 255])), "bytes([0x00, 0x01, 0xfe, 0xff])")
75
76 def test_compare(self):
77 b1 = bytes([1, 2, 3])
78 b2 = bytes([1, 2, 3])
79 b3 = bytes([1, 3])
80
81 self.failUnless(b1 == b2)
82 self.failUnless(b2 != b3)
83 self.failUnless(b1 <= b2)
84 self.failUnless(b1 <= b3)
85 self.failUnless(b1 < b3)
86 self.failUnless(b1 >= b2)
87 self.failUnless(b3 >= b2)
88 self.failUnless(b3 > b2)
89
90 self.failIf(b1 != b2)
91 self.failIf(b2 == b3)
92 self.failIf(b1 > b2)
93 self.failIf(b1 > b3)
94 self.failIf(b1 >= b3)
95 self.failIf(b1 < b2)
96 self.failIf(b3 < b2)
97 self.failIf(b3 <= b2)
98
99 def test_nohash(self):
100 self.assertRaises(TypeError, hash, bytes())
101
102 def test_doc(self):
103 self.failUnless(bytes.__doc__ != None)
104 self.failUnless(bytes.__doc__.startswith("bytes("))
105
Guido van Rossumd624f182006-04-24 13:47:05 +0000106 def test_buffer_api(self):
107 short_sample = "Hello world\n"
108 sample = short_sample + "x"*(20 - len(short_sample))
109 tfn = tempfile.mktemp()
110 try:
111 # Prepare
112 with open(tfn, "wb") as f:
113 f.write(short_sample)
114 # Test readinto
115 with open(tfn, "rb") as f:
116 b = bytes([ord('x')]*20)
117 n = f.readinto(b)
118 self.assertEqual(n, len(short_sample))
119 self.assertEqual(list(b), map(ord, sample))
120 # Test writing in binary mode
121 with open(tfn, "wb") as f:
122 f.write(b)
123 with open(tfn, "rb") as f:
124 self.assertEqual(f.read(), sample)
125 # Test writing in text mode
126 with open(tfn, "w") as f:
127 f.write(b)
128 with open(tfn, "r") as f:
129 self.assertEqual(f.read(), sample)
130 # Can't use readinto in text mode
131 with open(tfn, "r") as f:
132 self.assertRaises(TypeError, f.readinto, b)
133 finally:
134 try:
135 os.remove(tfn)
136 except os.error:
137 pass
138
139 def test_reversed(self):
140 input = map(ord, "Hello")
141 b = bytes(input)
142 output = list(reversed(b))
143 input.reverse()
144 self.assertEqual(output, input)
145
146 def test_getslice(self):
147 def by(s):
148 return bytes(map(ord, s))
149 b = by("Hello, world")
150
151 self.assertEqual(b[:5], by("Hello"))
152 self.assertEqual(b[1:5], by("ello"))
153 self.assertEqual(b[5:7], by(", "))
154 self.assertEqual(b[7:], by("world"))
155 self.assertEqual(b[7:12], by("world"))
156 self.assertEqual(b[7:100], by("world"))
157
158 self.assertEqual(b[:-7], by("Hello"))
159 self.assertEqual(b[-11:-7], by("ello"))
160 self.assertEqual(b[-7:-5], by(", "))
161 self.assertEqual(b[-5:], by("world"))
162 self.assertEqual(b[-5:12], by("world"))
163 self.assertEqual(b[-5:100], by("world"))
164 self.assertEqual(b[-100:5], by("Hello"))
165
Thomas Wouters376446d2006-12-19 08:30:14 +0000166 def test_extended_getslice(self):
167 # Test extended slicing by comparing with list slicing.
168 L = list(range(255))
169 b = bytes(L)
170 indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
171 for start in indices:
172 for stop in indices:
173 # Skip step 0 (invalid)
174 for step in indices[1:]:
175 self.assertEqual(b[start:stop:step], bytes(L[start:stop:step]))
176
Guido van Rossumd624f182006-04-24 13:47:05 +0000177 def test_regexps(self):
178 def by(s):
179 return bytes(map(ord, s))
180 b = by("Hello, world")
181 self.assertEqual(re.findall(r"\w+", b), [by("Hello"), by("world")])
182
183 def test_setitem(self):
184 b = bytes([1, 2, 3])
185 b[1] = 100
186 self.assertEqual(b, bytes([1, 100, 3]))
187 b[-1] = 200
188 self.assertEqual(b, bytes([1, 100, 200]))
189 class C:
190 def __init__(self, i=0):
191 self.i = i
192 def __index__(self):
193 return self.i
194 b[0] = C(10)
195 self.assertEqual(b, bytes([10, 100, 200]))
196 try:
197 b[3] = 0
198 self.fail("Didn't raise IndexError")
199 except IndexError:
200 pass
201 try:
202 b[-10] = 0
203 self.fail("Didn't raise IndexError")
204 except IndexError:
205 pass
206 try:
207 b[0] = 256
208 self.fail("Didn't raise ValueError")
209 except ValueError:
210 pass
211 try:
212 b[0] = C(-1)
213 self.fail("Didn't raise ValueError")
214 except ValueError:
215 pass
216 try:
217 b[0] = None
218 self.fail("Didn't raise TypeError")
219 except TypeError:
220 pass
221
222 def test_delitem(self):
223 b = bytes(range(10))
224 del b[0]
225 self.assertEqual(b, bytes(range(1, 10)))
226 del b[-1]
227 self.assertEqual(b, bytes(range(1, 9)))
228 del b[4]
229 self.assertEqual(b, bytes([1, 2, 3, 4, 6, 7, 8]))
230
231 def test_setslice(self):
232 b = bytes(range(10))
233 self.assertEqual(list(b), list(range(10)))
234
235 b[0:5] = bytes([1, 1, 1, 1, 1])
236 self.assertEqual(b, bytes([1, 1, 1, 1, 1, 5, 6, 7, 8, 9]))
237
238 del b[0:-5]
239 self.assertEqual(b, bytes([5, 6, 7, 8, 9]))
240
241 b[0:0] = bytes([0, 1, 2, 3, 4])
242 self.assertEqual(b, bytes(range(10)))
243
244 b[-7:-3] = bytes([100, 101])
245 self.assertEqual(b, bytes([0, 1, 2, 100, 101, 7, 8, 9]))
246
247 b[3:5] = [3, 4, 5, 6]
248 self.assertEqual(b, bytes(range(10)))
Thomas Wouters9a6e62b2006-08-23 23:20:29 +0000249
250 b[3:0] = [42, 42, 42]
251 self.assertEqual(b, bytes([0, 1, 2, 42, 42, 42, 3, 4, 5, 6, 7, 8, 9]))
Guido van Rossumd624f182006-04-24 13:47:05 +0000252
Thomas Wouters376446d2006-12-19 08:30:14 +0000253 def test_extended_set_del_slice(self):
254 indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
255 for start in indices:
256 for stop in indices:
257 # Skip invalid step 0
258 for step in indices[1:]:
259 L = list(range(255))
260 b = bytes(L)
261 # Make sure we have a slice of exactly the right length,
262 # but with different data.
263 data = L[start:stop:step]
264 data.reverse()
265 L[start:stop:step] = data
266 b[start:stop:step] = data
267 self.assertEquals(b, bytes(L))
268
269 del L[start:stop:step]
270 del b[start:stop:step]
271 self.assertEquals(b, bytes(L))
272
Guido van Rossumd624f182006-04-24 13:47:05 +0000273 def test_setslice_trap(self):
274 # This test verifies that we correctly handle assigning self
275 # to a slice of self (the old Lambert Meertens trap).
276 b = bytes(range(256))
277 b[8:] = b
278 self.assertEqual(b, bytes(list(range(8)) + list(range(256))))
279
280 def test_encoding(self):
281 sample = u"Hello world\n\u1234\u5678\u9abc\udef0"
282 for enc in ("utf8", "utf16"):
283 b = bytes(sample, enc)
284 self.assertEqual(b, bytes(map(ord, sample.encode(enc))))
285 self.assertRaises(UnicodeEncodeError, bytes, sample, "latin1")
286 b = bytes(sample, "latin1", "ignore")
287 self.assertEqual(b, bytes(sample[:-4]))
288
289 def test_decode(self):
290 sample = u"Hello world\n\u1234\u5678\u9abc\def0\def0"
291 for enc in ("utf8", "utf16"):
292 b = bytes(sample, enc)
293 self.assertEqual(b.decode(enc), sample)
294 sample = u"Hello world\n\x80\x81\xfe\xff"
295 b = bytes(sample, "latin1")
296 self.assertRaises(UnicodeDecodeError, b.decode, "utf8")
297 self.assertEqual(b.decode("utf8", "ignore"), "Hello world\n")
298
299 def test_from_buffer(self):
300 sample = "Hello world\n\x80\x81\xfe\xff"
301 buf = buffer(sample)
302 b = bytes(buf)
303 self.assertEqual(b, bytes(map(ord, sample)))
304
305 def test_to_str(self):
306 sample = "Hello world\n\x80\x81\xfe\xff"
307 b = bytes(sample)
308 self.assertEqual(str(b), sample)
309
310 def test_from_int(self):
311 b = bytes(0)
312 self.assertEqual(b, bytes())
313 b = bytes(10)
314 self.assertEqual(b, bytes([0]*10))
315 b = bytes(10000)
316 self.assertEqual(b, bytes([0]*10000))
317
318 def test_concat(self):
319 b1 = bytes("abc")
320 b2 = bytes("def")
321 self.assertEqual(b1 + b2, bytes("abcdef"))
322 self.assertRaises(TypeError, lambda: b1 + "def")
323 self.assertRaises(TypeError, lambda: "abc" + b2)
324
325 def test_repeat(self):
326 b = bytes("abc")
327 self.assertEqual(b * 3, bytes("abcabcabc"))
328 self.assertEqual(b * 0, bytes())
329 self.assertEqual(b * -1, bytes())
330 self.assertRaises(TypeError, lambda: b * 3.14)
331 self.assertRaises(TypeError, lambda: 3.14 * b)
332 self.assertRaises(MemoryError, lambda: b * sys.maxint)
Guido van Rossum13e57212006-04-27 22:54:26 +0000333
334 def test_repeat_1char(self):
Guido van Rossumd624f182006-04-24 13:47:05 +0000335 self.assertEqual(bytes('x')*100, bytes('x'*100))
336
Guido van Rossum13e57212006-04-27 22:54:26 +0000337 def test_iconcat(self):
338 b = bytes("abc")
339 b1 = b
340 b += bytes("def")
341 self.assertEqual(b, bytes("abcdef"))
342 self.assertEqual(b, b1)
343 self.failUnless(b is b1)
344
345 def test_irepeat(self):
346 b = bytes("abc")
347 b1 = b
348 b *= 3
349 self.assertEqual(b, bytes("abcabcabc"))
350 self.assertEqual(b, b1)
351 self.failUnless(b is b1)
352
353 def test_irepeat_1char(self):
354 b = bytes("x")
355 b1 = b
356 b *= 100
357 self.assertEqual(b, bytes("x"*100))
358 self.assertEqual(b, b1)
359 self.failUnless(b is b1)
360
361 def test_contains(self):
362 b = bytes("abc")
363 self.failUnless(ord('a') in b)
364 self.failUnless(long(ord('a')) in b)
365 self.failIf(200 in b)
366 self.failIf(200L in b)
367 self.assertRaises(ValueError, lambda: 300 in b)
368 self.assertRaises(ValueError, lambda: -1 in b)
369 self.assertRaises(TypeError, lambda: None in b)
370 self.assertRaises(TypeError, lambda: float(ord('a')) in b)
371 self.assertRaises(TypeError, lambda: "a" in b)
372 self.failUnless(bytes("") in b)
373 self.failUnless(bytes("a") in b)
374 self.failUnless(bytes("b") in b)
375 self.failUnless(bytes("c") in b)
376 self.failUnless(bytes("ab") in b)
377 self.failUnless(bytes("bc") in b)
378 self.failUnless(bytes("abc") in b)
379 self.failIf(bytes("ac") in b)
380 self.failIf(bytes("d") in b)
381 self.failIf(bytes("dab") in b)
382 self.failIf(bytes("abd") in b)
383
Guido van Rossum20188312006-05-05 15:15:40 +0000384 def test_alloc(self):
385 b = bytes()
386 alloc = b.__alloc__()
387 self.assert_(alloc >= 0)
388 seq = [alloc]
389 for i in range(100):
390 b += bytes("x")
391 alloc = b.__alloc__()
392 self.assert_(alloc >= len(b))
393 if alloc not in seq:
394 seq.append(alloc)
Guido van Rossum08e8b7a2006-05-26 19:16:09 +0000395 #print seq
Guido van Rossum20188312006-05-05 15:15:40 +0000396
397 def test_join(self):
398 self.assertEqual(bytes.join([]), bytes())
399 self.assertEqual(bytes.join([bytes()]), bytes())
400 for part in [("abc",), ("a", "bc"), ("ab", "c"), ("a", "b", "c")]:
401 lst = map(bytes, part)
402 self.assertEqual(bytes.join(lst), bytes("abc"))
403 self.assertEqual(bytes.join(tuple(lst)), bytes("abc"))
404 self.assertEqual(bytes.join(iter(lst)), bytes("abc"))
405 # XXX more...
406
407
Guido van Rossumd624f182006-04-24 13:47:05 +0000408 # Optimizations:
Guido van Rossume06b6b82006-04-23 07:43:54 +0000409 # __iter__? (optimization)
Guido van Rossumd624f182006-04-24 13:47:05 +0000410 # __reversed__? (optimization)
411
412 # XXX Some list methods?
413 # extended slicing
414 # extended slice assignment
415 # extend (same as b[len(b):] = src)
416 # reverse (in-place)
417 # remove
418 # pop
419 # NOT sort!
420 # With int arg:
Guido van Rossumd624f182006-04-24 13:47:05 +0000421 # index
422 # count
423 # append
424 # insert
425
426 # XXX Some string methods? (Those that don't use character properties)
427 # startswith
428 # endswidth
429 # find, rfind
Guido van Rossumd624f182006-04-24 13:47:05 +0000430 # index, rindex (bytes arg)
431 # join
432 # replace
433 # translate
434 # split, rsplit
435 # lstrip, rstrip, strip??
436
437 # XXX pickle and marshal support?
Guido van Rossume06b6b82006-04-23 07:43:54 +0000438
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000439
440def test_main():
Thomas Wouters5f6f27d2006-04-23 00:19:58 +0000441 test.test_support.run_unittest(BytesTest)
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000442
443
444if __name__ == "__main__":
Guido van Rossumd624f182006-04-24 13:47:05 +0000445 test_main()
446 ##unittest.main()