blob: cf5cd5ad4d53a57f96fad2e95cc7bc3504255163 [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])
63 self.assertRaises(ValueError, bytes, [-sys.maxint-2])
64 self.assertRaises(ValueError, bytes, [-10**100])
65 self.assertRaises(ValueError, bytes, [256])
66 self.assertRaises(ValueError, bytes, [257])
67 self.assertRaises(ValueError, bytes, [sys.maxint])
68 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
166 def test_regexps(self):
167 def by(s):
168 return bytes(map(ord, s))
169 b = by("Hello, world")
170 self.assertEqual(re.findall(r"\w+", b), [by("Hello"), by("world")])
171
172 def test_setitem(self):
173 b = bytes([1, 2, 3])
174 b[1] = 100
175 self.assertEqual(b, bytes([1, 100, 3]))
176 b[-1] = 200
177 self.assertEqual(b, bytes([1, 100, 200]))
178 class C:
179 def __init__(self, i=0):
180 self.i = i
181 def __index__(self):
182 return self.i
183 b[0] = C(10)
184 self.assertEqual(b, bytes([10, 100, 200]))
185 try:
186 b[3] = 0
187 self.fail("Didn't raise IndexError")
188 except IndexError:
189 pass
190 try:
191 b[-10] = 0
192 self.fail("Didn't raise IndexError")
193 except IndexError:
194 pass
195 try:
196 b[0] = 256
197 self.fail("Didn't raise ValueError")
198 except ValueError:
199 pass
200 try:
201 b[0] = C(-1)
202 self.fail("Didn't raise ValueError")
203 except ValueError:
204 pass
205 try:
206 b[0] = None
207 self.fail("Didn't raise TypeError")
208 except TypeError:
209 pass
210
211 def test_delitem(self):
212 b = bytes(range(10))
213 del b[0]
214 self.assertEqual(b, bytes(range(1, 10)))
215 del b[-1]
216 self.assertEqual(b, bytes(range(1, 9)))
217 del b[4]
218 self.assertEqual(b, bytes([1, 2, 3, 4, 6, 7, 8]))
219
220 def test_setslice(self):
221 b = bytes(range(10))
222 self.assertEqual(list(b), list(range(10)))
223
224 b[0:5] = bytes([1, 1, 1, 1, 1])
225 self.assertEqual(b, bytes([1, 1, 1, 1, 1, 5, 6, 7, 8, 9]))
226
227 del b[0:-5]
228 self.assertEqual(b, bytes([5, 6, 7, 8, 9]))
229
230 b[0:0] = bytes([0, 1, 2, 3, 4])
231 self.assertEqual(b, bytes(range(10)))
232
233 b[-7:-3] = bytes([100, 101])
234 self.assertEqual(b, bytes([0, 1, 2, 100, 101, 7, 8, 9]))
235
236 b[3:5] = [3, 4, 5, 6]
237 self.assertEqual(b, bytes(range(10)))
238
239 def test_setslice_trap(self):
240 # This test verifies that we correctly handle assigning self
241 # to a slice of self (the old Lambert Meertens trap).
242 b = bytes(range(256))
243 b[8:] = b
244 self.assertEqual(b, bytes(list(range(8)) + list(range(256))))
245
246 def test_encoding(self):
247 sample = u"Hello world\n\u1234\u5678\u9abc\udef0"
248 for enc in ("utf8", "utf16"):
249 b = bytes(sample, enc)
250 self.assertEqual(b, bytes(map(ord, sample.encode(enc))))
251 self.assertRaises(UnicodeEncodeError, bytes, sample, "latin1")
252 b = bytes(sample, "latin1", "ignore")
253 self.assertEqual(b, bytes(sample[:-4]))
254
255 def test_decode(self):
256 sample = u"Hello world\n\u1234\u5678\u9abc\def0\def0"
257 for enc in ("utf8", "utf16"):
258 b = bytes(sample, enc)
259 self.assertEqual(b.decode(enc), sample)
260 sample = u"Hello world\n\x80\x81\xfe\xff"
261 b = bytes(sample, "latin1")
262 self.assertRaises(UnicodeDecodeError, b.decode, "utf8")
263 self.assertEqual(b.decode("utf8", "ignore"), "Hello world\n")
264
265 def test_from_buffer(self):
266 sample = "Hello world\n\x80\x81\xfe\xff"
267 buf = buffer(sample)
268 b = bytes(buf)
269 self.assertEqual(b, bytes(map(ord, sample)))
270
271 def test_to_str(self):
272 sample = "Hello world\n\x80\x81\xfe\xff"
273 b = bytes(sample)
274 self.assertEqual(str(b), sample)
275
276 def test_from_int(self):
277 b = bytes(0)
278 self.assertEqual(b, bytes())
279 b = bytes(10)
280 self.assertEqual(b, bytes([0]*10))
281 b = bytes(10000)
282 self.assertEqual(b, bytes([0]*10000))
283
284 def test_concat(self):
285 b1 = bytes("abc")
286 b2 = bytes("def")
287 self.assertEqual(b1 + b2, bytes("abcdef"))
288 self.assertRaises(TypeError, lambda: b1 + "def")
289 self.assertRaises(TypeError, lambda: "abc" + b2)
290
291 def test_repeat(self):
292 b = bytes("abc")
293 self.assertEqual(b * 3, bytes("abcabcabc"))
294 self.assertEqual(b * 0, bytes())
295 self.assertEqual(b * -1, bytes())
296 self.assertRaises(TypeError, lambda: b * 3.14)
297 self.assertRaises(TypeError, lambda: 3.14 * b)
298 self.assertRaises(MemoryError, lambda: b * sys.maxint)
299 self.assertEqual(bytes('x')*100, bytes('x'*100))
300
301 # Optimizations:
Guido van Rossume06b6b82006-04-23 07:43:54 +0000302 # __iter__? (optimization)
Guido van Rossumd624f182006-04-24 13:47:05 +0000303 # __reversed__? (optimization)
304
305 # XXX Some list methods?
306 # extended slicing
307 # extended slice assignment
308 # extend (same as b[len(b):] = src)
309 # reverse (in-place)
310 # remove
311 # pop
312 # NOT sort!
313 # With int arg:
314 # __contains__
315 # index
316 # count
317 # append
318 # insert
319
320 # XXX Some string methods? (Those that don't use character properties)
321 # startswith
322 # endswidth
323 # find, rfind
324 # __contains__ (bytes arg)
325 # index, rindex (bytes arg)
326 # join
327 # replace
328 # translate
329 # split, rsplit
330 # lstrip, rstrip, strip??
331
332 # XXX pickle and marshal support?
Guido van Rossume06b6b82006-04-23 07:43:54 +0000333
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000334
335def test_main():
Thomas Wouters5f6f27d2006-04-23 00:19:58 +0000336 test.test_support.run_unittest(BytesTest)
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000337
338
339if __name__ == "__main__":
Guido van Rossumd624f182006-04-24 13:47:05 +0000340 test_main()
341 ##unittest.main()