blob: b344f9a6ba33c97a998b4d9bce72cdef8816aa74 [file] [log] [blame]
Barry Warsaw04f357c2002-07-23 19:04:11 +00001from test import test_support
2import unittest
Marc-André Lemburga37171d2001-06-19 20:09:28 +00003import codecs
Walter Dörwalda47d1c02005-08-30 10:23:14 +00004import sys, StringIO
Marc-André Lemburga37171d2001-06-19 20:09:28 +00005
Walter Dörwald69652032004-09-07 20:24:22 +00006class Queue(object):
7 """
8 queue: write bytes at one end, read bytes from the other end
9 """
10 def __init__(self):
11 self._buffer = ""
12
13 def write(self, chars):
14 self._buffer += chars
15
16 def read(self, size=-1):
17 if size<0:
18 s = self._buffer
19 self._buffer = ""
20 return s
21 else:
22 s = self._buffer[:size]
23 self._buffer = self._buffer[size:]
24 return s
25
Walter Dörwalde57d7b12004-12-21 22:24:00 +000026class ReadTest(unittest.TestCase):
27 def check_partial(self, input, partialresults):
Walter Dörwald69652032004-09-07 20:24:22 +000028 # get a StreamReader for the encoding and feed the bytestring version
29 # of input to the reader byte by byte. Read every available from
30 # the StreamReader and check that the results equal the appropriate
31 # entries from partialresults.
32 q = Queue()
Walter Dörwalde57d7b12004-12-21 22:24:00 +000033 r = codecs.getreader(self.encoding)(q)
Walter Dörwald69652032004-09-07 20:24:22 +000034 result = u""
Walter Dörwalde57d7b12004-12-21 22:24:00 +000035 for (c, partialresult) in zip(input.encode(self.encoding), partialresults):
Walter Dörwald69652032004-09-07 20:24:22 +000036 q.write(c)
37 result += r.read()
38 self.assertEqual(result, partialresult)
39 # check that there's nothing left in the buffers
40 self.assertEqual(r.read(), u"")
41 self.assertEqual(r.bytebuffer, "")
42 self.assertEqual(r.charbuffer, u"")
43
Walter Dörwalde57d7b12004-12-21 22:24:00 +000044 def test_readline(self):
45 def getreader(input):
46 stream = StringIO.StringIO(input.encode(self.encoding))
47 return codecs.getreader(self.encoding)(stream)
48
49 def readalllines(input, keepends=True):
50 reader = getreader(input)
51 lines = []
52 while True:
53 line = reader.readline(keepends=keepends)
54 if not line:
55 break
56 lines.append(line)
57 return "".join(lines)
58
59 s = u"foo\nbar\r\nbaz\rspam\u2028eggs"
60 self.assertEqual(readalllines(s, True), s)
61 self.assertEqual(readalllines(s, False), u"foobarbazspameggs")
62
63 # Test long lines (multiple calls to read() in readline())
64 vw = []
65 vwo = []
66 for (i, lineend) in enumerate(u"\n \r\n \r \u2028".split()):
67 vw.append((i*200)*u"\3042" + lineend)
68 vwo.append((i*200)*u"\3042")
69 self.assertEqual(readalllines("".join(vw), True), "".join(vw))
70 self.assertEqual(readalllines("".join(vw), False),"".join(vwo))
71
72 # Test lines where the first read might end with \r, so the
73 # reader has to look ahead whether this is a lone \r or a \r\n
74 for size in xrange(80):
75 for lineend in u"\n \r\n \r \u2028".split():
Walter Dörwald7a6dc132005-04-04 21:38:47 +000076 s = 10*(size*u"a" + lineend + u"xxx\n")
77 reader = getreader(s)
78 for i in xrange(10):
79 self.assertEqual(
80 reader.readline(keepends=True),
81 size*u"a" + lineend,
82 )
83 reader = getreader(s)
84 for i in xrange(10):
85 self.assertEqual(
86 reader.readline(keepends=False),
87 size*u"a",
88 )
89
90 def test_bug1175396(self):
91 s = [
92 '<%!--===================================================\r\n',
93 ' BLOG index page: show recent articles,\r\n',
94 ' today\'s articles, or articles of a specific date.\r\n',
95 '========================================================--%>\r\n',
96 '<%@inputencoding="ISO-8859-1"%>\r\n',
97 '<%@pagetemplate=TEMPLATE.y%>\r\n',
98 '<%@import=import frog.util, frog%>\r\n',
99 '<%@import=import frog.objects%>\r\n',
100 '<%@import=from frog.storageerrors import StorageError%>\r\n',
101 '<%\r\n',
102 '\r\n',
103 'import logging\r\n',
104 'log=logging.getLogger("Snakelets.logger")\r\n',
105 '\r\n',
106 '\r\n',
107 'user=self.SessionCtx.user\r\n',
108 'storageEngine=self.SessionCtx.storageEngine\r\n',
109 '\r\n',
110 '\r\n',
111 'def readArticlesFromDate(date, count=None):\r\n',
112 ' entryids=storageEngine.listBlogEntries(date)\r\n',
113 ' entryids.reverse() # descending\r\n',
114 ' if count:\r\n',
115 ' entryids=entryids[:count]\r\n',
116 ' try:\r\n',
117 ' return [ frog.objects.BlogEntry.load(storageEngine, date, Id) for Id in entryids ]\r\n',
118 ' except StorageError,x:\r\n',
119 ' log.error("Error loading articles: "+str(x))\r\n',
120 ' self.abort("cannot load articles")\r\n',
121 '\r\n',
122 'showdate=None\r\n',
123 '\r\n',
124 'arg=self.Request.getArg()\r\n',
125 'if arg=="today":\r\n',
126 ' #-------------------- TODAY\'S ARTICLES\r\n',
127 ' self.write("<h2>Today\'s articles</h2>")\r\n',
128 ' showdate = frog.util.isodatestr() \r\n',
129 ' entries = readArticlesFromDate(showdate)\r\n',
130 'elif arg=="active":\r\n',
131 ' #-------------------- ACTIVE ARTICLES redirect\r\n',
132 ' self.Yredirect("active.y")\r\n',
133 'elif arg=="login":\r\n',
134 ' #-------------------- LOGIN PAGE redirect\r\n',
135 ' self.Yredirect("login.y")\r\n',
136 'elif arg=="date":\r\n',
137 ' #-------------------- ARTICLES OF A SPECIFIC DATE\r\n',
138 ' showdate = self.Request.getParameter("date")\r\n',
139 ' self.write("<h2>Articles written on %s</h2>"% frog.util.mediumdatestr(showdate))\r\n',
140 ' entries = readArticlesFromDate(showdate)\r\n',
141 'else:\r\n',
142 ' #-------------------- RECENT ARTICLES\r\n',
143 ' self.write("<h2>Recent articles</h2>")\r\n',
144 ' dates=storageEngine.listBlogEntryDates()\r\n',
145 ' if dates:\r\n',
146 ' entries=[]\r\n',
147 ' SHOWAMOUNT=10\r\n',
148 ' for showdate in dates:\r\n',
149 ' entries.extend( readArticlesFromDate(showdate, SHOWAMOUNT-len(entries)) )\r\n',
150 ' if len(entries)>=SHOWAMOUNT:\r\n',
151 ' break\r\n',
152 ' \r\n',
153 ]
154 stream = StringIO.StringIO("".join(s).encode(self.encoding))
155 reader = codecs.getreader(self.encoding)(stream)
156 for (i, line) in enumerate(reader):
157 self.assertEqual(line, s[i])
Walter Dörwalde57d7b12004-12-21 22:24:00 +0000158
159 def test_readlinequeue(self):
160 q = Queue()
161 writer = codecs.getwriter(self.encoding)(q)
162 reader = codecs.getreader(self.encoding)(q)
163
164 # No lineends
165 writer.write(u"foo\r")
166 self.assertEqual(reader.readline(keepends=False), u"foo")
167 writer.write(u"\nbar\r")
Walter Dörwald43148c82005-04-21 21:45:36 +0000168 self.assertEqual(reader.readline(keepends=False), u"")
Walter Dörwalde57d7b12004-12-21 22:24:00 +0000169 self.assertEqual(reader.readline(keepends=False), u"bar")
170 writer.write(u"baz")
171 self.assertEqual(reader.readline(keepends=False), u"baz")
172 self.assertEqual(reader.readline(keepends=False), u"")
173
174 # Lineends
175 writer.write(u"foo\r")
176 self.assertEqual(reader.readline(keepends=True), u"foo\r")
177 writer.write(u"\nbar\r")
Walter Dörwald43148c82005-04-21 21:45:36 +0000178 self.assertEqual(reader.readline(keepends=True), u"\n")
Walter Dörwalde57d7b12004-12-21 22:24:00 +0000179 self.assertEqual(reader.readline(keepends=True), u"bar\r")
180 writer.write(u"baz")
181 self.assertEqual(reader.readline(keepends=True), u"baz")
182 self.assertEqual(reader.readline(keepends=True), u"")
183 writer.write(u"foo\r\n")
184 self.assertEqual(reader.readline(keepends=True), u"foo\r\n")
185
Walter Dörwald9fa09462005-01-10 12:01:39 +0000186 def test_bug1098990_a(self):
187 s1 = u"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\r\n"
188 s2 = u"offending line: ladfj askldfj klasdj fskla dfzaskdj fasklfj laskd fjasklfzzzzaa%whereisthis!!!\r\n"
189 s3 = u"next line.\r\n"
190
191 s = (s1+s2+s3).encode(self.encoding)
192 stream = StringIO.StringIO(s)
193 reader = codecs.getreader(self.encoding)(stream)
194 self.assertEqual(reader.readline(), s1)
195 self.assertEqual(reader.readline(), s2)
196 self.assertEqual(reader.readline(), s3)
197 self.assertEqual(reader.readline(), u"")
198
199 def test_bug1098990_b(self):
200 s1 = u"aaaaaaaaaaaaaaaaaaaaaaaa\r\n"
201 s2 = u"bbbbbbbbbbbbbbbbbbbbbbbb\r\n"
202 s3 = u"stillokay:bbbbxx\r\n"
203 s4 = u"broken!!!!badbad\r\n"
204 s5 = u"againokay.\r\n"
205
206 s = (s1+s2+s3+s4+s5).encode(self.encoding)
207 stream = StringIO.StringIO(s)
208 reader = codecs.getreader(self.encoding)(stream)
209 self.assertEqual(reader.readline(), s1)
210 self.assertEqual(reader.readline(), s2)
211 self.assertEqual(reader.readline(), s3)
212 self.assertEqual(reader.readline(), s4)
213 self.assertEqual(reader.readline(), s5)
214 self.assertEqual(reader.readline(), u"")
215
Walter Dörwalde57d7b12004-12-21 22:24:00 +0000216class UTF16Test(ReadTest):
217 encoding = "utf-16"
Marc-André Lemburga37171d2001-06-19 20:09:28 +0000218
219 spamle = '\xff\xfes\x00p\x00a\x00m\x00s\x00p\x00a\x00m\x00'
220 spambe = '\xfe\xff\x00s\x00p\x00a\x00m\x00s\x00p\x00a\x00m'
221
222 def test_only_one_bom(self):
Walter Dörwalde57d7b12004-12-21 22:24:00 +0000223 _,_,reader,writer = codecs.lookup(self.encoding)
Marc-André Lemburga37171d2001-06-19 20:09:28 +0000224 # encode some stream
225 s = StringIO.StringIO()
226 f = writer(s)
227 f.write(u"spam")
228 f.write(u"spam")
229 d = s.getvalue()
230 # check whether there is exactly one BOM in it
231 self.assert_(d == self.spamle or d == self.spambe)
232 # try to read it back
233 s = StringIO.StringIO(d)
234 f = reader(s)
235 self.assertEquals(f.read(), u"spamspam")
236
Walter Dörwald1f1d2522005-02-04 14:15:34 +0000237 def test_badbom(self):
238 s = StringIO.StringIO("\xff\xff")
Walter Dörwalda9620d12005-02-08 10:10:01 +0000239 f = codecs.getreader(self.encoding)(s)
Walter Dörwald1f1d2522005-02-04 14:15:34 +0000240 self.assertRaises(UnicodeError, f.read)
241
242 s = StringIO.StringIO("\xff\xff\xff\xff")
Walter Dörwalda9620d12005-02-08 10:10:01 +0000243 f = codecs.getreader(self.encoding)(s)
Walter Dörwald1f1d2522005-02-04 14:15:34 +0000244 self.assertRaises(UnicodeError, f.read)
245
Walter Dörwald69652032004-09-07 20:24:22 +0000246 def test_partial(self):
247 self.check_partial(
Walter Dörwald69652032004-09-07 20:24:22 +0000248 u"\x00\xff\u0100\uffff",
249 [
250 u"", # first byte of BOM read
251 u"", # second byte of BOM read => byteorder known
252 u"",
253 u"\x00",
254 u"\x00",
255 u"\x00\xff",
256 u"\x00\xff",
257 u"\x00\xff\u0100",
258 u"\x00\xff\u0100",
259 u"\x00\xff\u0100\uffff",
260 ]
261 )
262
Walter Dörwalde22d3392005-11-17 08:52:34 +0000263 def test_errors(self):
264 self.assertRaises(UnicodeDecodeError, codecs.utf_16_decode, "\xff", "strict", True)
265
Walter Dörwalde57d7b12004-12-21 22:24:00 +0000266class UTF16LETest(ReadTest):
267 encoding = "utf-16-le"
Walter Dörwald69652032004-09-07 20:24:22 +0000268
269 def test_partial(self):
270 self.check_partial(
Walter Dörwald69652032004-09-07 20:24:22 +0000271 u"\x00\xff\u0100\uffff",
272 [
273 u"",
274 u"\x00",
275 u"\x00",
276 u"\x00\xff",
277 u"\x00\xff",
278 u"\x00\xff\u0100",
279 u"\x00\xff\u0100",
280 u"\x00\xff\u0100\uffff",
281 ]
282 )
283
Walter Dörwalde22d3392005-11-17 08:52:34 +0000284 def test_errors(self):
285 self.assertRaises(UnicodeDecodeError, codecs.utf_16_le_decode, "\xff", "strict", True)
286
Walter Dörwalde57d7b12004-12-21 22:24:00 +0000287class UTF16BETest(ReadTest):
288 encoding = "utf-16-be"
Walter Dörwald69652032004-09-07 20:24:22 +0000289
290 def test_partial(self):
291 self.check_partial(
Walter Dörwald69652032004-09-07 20:24:22 +0000292 u"\x00\xff\u0100\uffff",
293 [
294 u"",
295 u"\x00",
296 u"\x00",
297 u"\x00\xff",
298 u"\x00\xff",
299 u"\x00\xff\u0100",
300 u"\x00\xff\u0100",
301 u"\x00\xff\u0100\uffff",
302 ]
303 )
304
Walter Dörwalde22d3392005-11-17 08:52:34 +0000305 def test_errors(self):
306 self.assertRaises(UnicodeDecodeError, codecs.utf_16_be_decode, "\xff", "strict", True)
307
Walter Dörwalde57d7b12004-12-21 22:24:00 +0000308class UTF8Test(ReadTest):
309 encoding = "utf-8"
Walter Dörwald69652032004-09-07 20:24:22 +0000310
311 def test_partial(self):
312 self.check_partial(
Walter Dörwald69652032004-09-07 20:24:22 +0000313 u"\x00\xff\u07ff\u0800\uffff",
314 [
315 u"\x00",
316 u"\x00",
317 u"\x00\xff",
318 u"\x00\xff",
319 u"\x00\xff\u07ff",
320 u"\x00\xff\u07ff",
321 u"\x00\xff\u07ff",
322 u"\x00\xff\u07ff\u0800",
323 u"\x00\xff\u07ff\u0800",
324 u"\x00\xff\u07ff\u0800",
325 u"\x00\xff\u07ff\u0800\uffff",
326 ]
327 )
328
Walter Dörwalde22d3392005-11-17 08:52:34 +0000329class UTF7Test(ReadTest):
330 encoding = "utf-7"
331
332 # No test_partial() yet, because UTF-7 doesn't support it.
333
334class UTF16ExTest(unittest.TestCase):
335
336 def test_errors(self):
337 self.assertRaises(UnicodeDecodeError, codecs.utf_16_ex_decode, "\xff", "strict", 0, True)
338
339 def test_bad_args(self):
340 self.assertRaises(TypeError, codecs.utf_16_ex_decode)
341
342class ReadBufferTest(unittest.TestCase):
343
344 def test_array(self):
345 import array
346 self.assertEqual(
347 codecs.readbuffer_encode(array.array("c", "spam")),
348 ("spam", 4)
349 )
350
351 def test_empty(self):
352 self.assertEqual(codecs.readbuffer_encode(""), ("", 0))
353
354 def test_bad_args(self):
355 self.assertRaises(TypeError, codecs.readbuffer_encode)
356 self.assertRaises(TypeError, codecs.readbuffer_encode, 42)
357
358class CharBufferTest(unittest.TestCase):
359
360 def test_string(self):
361 self.assertEqual(codecs.charbuffer_encode("spam"), ("spam", 4))
362
363 def test_empty(self):
364 self.assertEqual(codecs.charbuffer_encode(""), ("", 0))
365
366 def test_bad_args(self):
367 self.assertRaises(TypeError, codecs.charbuffer_encode)
368 self.assertRaises(TypeError, codecs.charbuffer_encode, 42)
369
Walter Dörwald8709a422002-09-03 13:53:40 +0000370class EscapeDecodeTest(unittest.TestCase):
Walter Dörwalde22d3392005-11-17 08:52:34 +0000371 def test_empty(self):
Walter Dörwald8709a422002-09-03 13:53:40 +0000372 self.assertEquals(codecs.escape_decode(""), ("", 0))
373
Marc-André Lemburg29273c82003-02-04 19:35:03 +0000374class RecodingTest(unittest.TestCase):
375 def test_recoding(self):
376 f = StringIO.StringIO()
377 f2 = codecs.EncodedFile(f, "unicode_internal", "utf-8")
378 f2.write(u"a")
379 f2.close()
380 # Python used to crash on this at exit because of a refcount
381 # bug in _codecsmodule.c
Fred Drake2e2be372001-09-20 21:33:42 +0000382
Martin v. Löwis2548c732003-04-18 10:39:54 +0000383# From RFC 3492
384punycode_testcases = [
385 # A Arabic (Egyptian):
386 (u"\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644"
387 u"\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F",
388 "egbpdaj6bu4bxfgehfvwxn"),
389 # B Chinese (simplified):
390 (u"\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587",
391 "ihqwcrb4cv8a8dqg056pqjye"),
392 # C Chinese (traditional):
393 (u"\u4ED6\u5011\u7232\u4EC0\u9EBD\u4E0D\u8AAA\u4E2D\u6587",
394 "ihqwctvzc91f659drss3x8bo0yb"),
395 # D Czech: Pro<ccaron>prost<ecaron>nemluv<iacute><ccaron>esky
396 (u"\u0050\u0072\u006F\u010D\u0070\u0072\u006F\u0073\u0074"
397 u"\u011B\u006E\u0065\u006D\u006C\u0075\u0076\u00ED\u010D"
398 u"\u0065\u0073\u006B\u0079",
399 "Proprostnemluvesky-uyb24dma41a"),
400 # E Hebrew:
401 (u"\u05DC\u05DE\u05D4\u05D4\u05DD\u05E4\u05E9\u05D5\u05D8"
402 u"\u05DC\u05D0\u05DE\u05D3\u05D1\u05E8\u05D9\u05DD\u05E2"
403 u"\u05D1\u05E8\u05D9\u05EA",
404 "4dbcagdahymbxekheh6e0a7fei0b"),
405 # F Hindi (Devanagari):
406 (u"\u092F\u0939\u0932\u094B\u0917\u0939\u093F\u0928\u094D"
407 u"\u0926\u0940\u0915\u094D\u092F\u094B\u0902\u0928\u0939"
408 u"\u0940\u0902\u092C\u094B\u0932\u0938\u0915\u0924\u0947"
409 u"\u0939\u0948\u0902",
410 "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd"),
411
412 #(G) Japanese (kanji and hiragana):
413 (u"\u306A\u305C\u307F\u3093\u306A\u65E5\u672C\u8A9E\u3092"
414 u"\u8A71\u3057\u3066\u304F\u308C\u306A\u3044\u306E\u304B",
415 "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa"),
416
417 # (H) Korean (Hangul syllables):
418 (u"\uC138\uACC4\uC758\uBAA8\uB4E0\uC0AC\uB78C\uB4E4\uC774"
419 u"\uD55C\uAD6D\uC5B4\uB97C\uC774\uD574\uD55C\uB2E4\uBA74"
420 u"\uC5BC\uB9C8\uB098\uC88B\uC744\uAE4C",
421 "989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5j"
422 "psd879ccm6fea98c"),
423
424 # (I) Russian (Cyrillic):
425 (u"\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E"
426 u"\u043D\u0438\u043D\u0435\u0433\u043E\u0432\u043E\u0440"
427 u"\u044F\u0442\u043F\u043E\u0440\u0443\u0441\u0441\u043A"
428 u"\u0438",
429 "b1abfaaepdrnnbgefbaDotcwatmq2g4l"),
430
431 # (J) Spanish: Porqu<eacute>nopuedensimplementehablarenEspa<ntilde>ol
432 (u"\u0050\u006F\u0072\u0071\u0075\u00E9\u006E\u006F\u0070"
433 u"\u0075\u0065\u0064\u0065\u006E\u0073\u0069\u006D\u0070"
434 u"\u006C\u0065\u006D\u0065\u006E\u0074\u0065\u0068\u0061"
435 u"\u0062\u006C\u0061\u0072\u0065\u006E\u0045\u0073\u0070"
436 u"\u0061\u00F1\u006F\u006C",
437 "PorqunopuedensimplementehablarenEspaol-fmd56a"),
438
439 # (K) Vietnamese:
440 # T<adotbelow>isaoh<odotbelow>kh<ocirc>ngth<ecirchookabove>ch\
441 # <ihookabove>n<oacute>iti<ecircacute>ngVi<ecircdotbelow>t
442 (u"\u0054\u1EA1\u0069\u0073\u0061\u006F\u0068\u1ECD\u006B"
443 u"\u0068\u00F4\u006E\u0067\u0074\u0068\u1EC3\u0063\u0068"
444 u"\u1EC9\u006E\u00F3\u0069\u0074\u0069\u1EBF\u006E\u0067"
445 u"\u0056\u0069\u1EC7\u0074",
446 "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g"),
447
Martin v. Löwis2548c732003-04-18 10:39:54 +0000448 #(L) 3<nen>B<gumi><kinpachi><sensei>
449 (u"\u0033\u5E74\u0042\u7D44\u91D1\u516B\u5148\u751F",
450 "3B-ww4c5e180e575a65lsy2b"),
Tim Peters0eadaac2003-04-24 16:02:54 +0000451
Martin v. Löwis2548c732003-04-18 10:39:54 +0000452 # (M) <amuro><namie>-with-SUPER-MONKEYS
453 (u"\u5B89\u5BA4\u5948\u7F8E\u6075\u002D\u0077\u0069\u0074"
454 u"\u0068\u002D\u0053\u0055\u0050\u0045\u0052\u002D\u004D"
455 u"\u004F\u004E\u004B\u0045\u0059\u0053",
456 "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n"),
457
458 # (N) Hello-Another-Way-<sorezore><no><basho>
459 (u"\u0048\u0065\u006C\u006C\u006F\u002D\u0041\u006E\u006F"
460 u"\u0074\u0068\u0065\u0072\u002D\u0057\u0061\u0079\u002D"
461 u"\u305D\u308C\u305E\u308C\u306E\u5834\u6240",
462 "Hello-Another-Way--fc4qua05auwb3674vfr0b"),
463
464 # (O) <hitotsu><yane><no><shita>2
465 (u"\u3072\u3068\u3064\u5C4B\u6839\u306E\u4E0B\u0032",
466 "2-u9tlzr9756bt3uc0v"),
467
468 # (P) Maji<de>Koi<suru>5<byou><mae>
469 (u"\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059"
470 u"\u308B\u0035\u79D2\u524D",
471 "MajiKoi5-783gue6qz075azm5e"),
472
473 # (Q) <pafii>de<runba>
474 (u"\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0",
475 "de-jg4avhby1noc0d"),
476
477 # (R) <sono><supiido><de>
478 (u"\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067",
479 "d9juau41awczczp"),
480
481 # (S) -> $1.00 <-
482 (u"\u002D\u003E\u0020\u0024\u0031\u002E\u0030\u0030\u0020"
483 u"\u003C\u002D",
484 "-> $1.00 <--")
485 ]
486
487for i in punycode_testcases:
488 if len(i)!=2:
489 print repr(i)
490
491class PunycodeTest(unittest.TestCase):
492 def test_encode(self):
493 for uni, puny in punycode_testcases:
494 # Need to convert both strings to lower case, since
495 # some of the extended encodings use upper case, but our
496 # code produces only lower case. Converting just puny to
497 # lower is also insufficient, since some of the input characters
498 # are upper case.
499 self.assertEquals(uni.encode("punycode").lower(), puny.lower())
500
501 def test_decode(self):
502 for uni, puny in punycode_testcases:
503 self.assertEquals(uni, puny.decode("punycode"))
504
Walter Dörwalda47d1c02005-08-30 10:23:14 +0000505class UnicodeInternalTest(unittest.TestCase):
506 def test_bug1251300(self):
507 # Decoding with unicode_internal used to not correctly handle "code
508 # points" above 0x10ffff on UCS-4 builds.
509 if sys.maxunicode > 0xffff:
510 ok = [
511 ("\x00\x10\xff\xff", u"\U0010ffff"),
512 ("\x00\x00\x01\x01", u"\U00000101"),
513 ("", u""),
514 ]
515 not_ok = [
516 "\x7f\xff\xff\xff",
517 "\x80\x00\x00\x00",
518 "\x81\x00\x00\x00",
519 "\x00",
520 "\x00\x00\x00\x00\x00",
521 ]
522 for internal, uni in ok:
523 if sys.byteorder == "little":
524 internal = "".join(reversed(internal))
525 self.assertEquals(uni, internal.decode("unicode_internal"))
526 for internal in not_ok:
527 if sys.byteorder == "little":
528 internal = "".join(reversed(internal))
529 self.assertRaises(UnicodeDecodeError, internal.decode,
530 "unicode_internal")
531
532 def test_decode_error_attributes(self):
533 if sys.maxunicode > 0xffff:
534 try:
535 "\x00\x00\x00\x00\x00\x11\x11\x00".decode("unicode_internal")
536 except UnicodeDecodeError, ex:
537 self.assertEquals("unicode_internal", ex.encoding)
538 self.assertEquals("\x00\x00\x00\x00\x00\x11\x11\x00", ex.object)
539 self.assertEquals(4, ex.start)
540 self.assertEquals(8, ex.end)
541 else:
542 self.fail()
543
544 def test_decode_callback(self):
545 if sys.maxunicode > 0xffff:
546 codecs.register_error("UnicodeInternalTest", codecs.ignore_errors)
547 decoder = codecs.getdecoder("unicode_internal")
548 ab = u"ab".encode("unicode_internal")
549 ignored = decoder("%s\x22\x22\x22\x22%s" % (ab[:4], ab[4:]),
550 "UnicodeInternalTest")
551 self.assertEquals((u"ab", 12), ignored)
552
Martin v. Löwis2548c732003-04-18 10:39:54 +0000553# From http://www.gnu.org/software/libidn/draft-josefsson-idn-test-vectors.html
554nameprep_tests = [
555 # 3.1 Map to nothing.
556 ('foo\xc2\xad\xcd\x8f\xe1\xa0\x86\xe1\xa0\x8bbar'
557 '\xe2\x80\x8b\xe2\x81\xa0baz\xef\xb8\x80\xef\xb8\x88\xef'
558 '\xb8\x8f\xef\xbb\xbf',
559 'foobarbaz'),
560 # 3.2 Case folding ASCII U+0043 U+0041 U+0046 U+0045.
561 ('CAFE',
562 'cafe'),
563 # 3.3 Case folding 8bit U+00DF (german sharp s).
564 # The original test case is bogus; it says \xc3\xdf
565 ('\xc3\x9f',
566 'ss'),
567 # 3.4 Case folding U+0130 (turkish capital I with dot).
568 ('\xc4\xb0',
569 'i\xcc\x87'),
570 # 3.5 Case folding multibyte U+0143 U+037A.
571 ('\xc5\x83\xcd\xba',
572 '\xc5\x84 \xce\xb9'),
573 # 3.6 Case folding U+2121 U+33C6 U+1D7BB.
574 # XXX: skip this as it fails in UCS-2 mode
575 #('\xe2\x84\xa1\xe3\x8f\x86\xf0\x9d\x9e\xbb',
576 # 'telc\xe2\x88\x95kg\xcf\x83'),
577 (None, None),
578 # 3.7 Normalization of U+006a U+030c U+00A0 U+00AA.
579 ('j\xcc\x8c\xc2\xa0\xc2\xaa',
580 '\xc7\xb0 a'),
581 # 3.8 Case folding U+1FB7 and normalization.
582 ('\xe1\xbe\xb7',
583 '\xe1\xbe\xb6\xce\xb9'),
584 # 3.9 Self-reverting case folding U+01F0 and normalization.
585 # The original test case is bogus, it says `\xc7\xf0'
586 ('\xc7\xb0',
587 '\xc7\xb0'),
588 # 3.10 Self-reverting case folding U+0390 and normalization.
589 ('\xce\x90',
590 '\xce\x90'),
591 # 3.11 Self-reverting case folding U+03B0 and normalization.
592 ('\xce\xb0',
593 '\xce\xb0'),
594 # 3.12 Self-reverting case folding U+1E96 and normalization.
595 ('\xe1\xba\x96',
596 '\xe1\xba\x96'),
597 # 3.13 Self-reverting case folding U+1F56 and normalization.
598 ('\xe1\xbd\x96',
599 '\xe1\xbd\x96'),
600 # 3.14 ASCII space character U+0020.
601 (' ',
602 ' '),
603 # 3.15 Non-ASCII 8bit space character U+00A0.
604 ('\xc2\xa0',
605 ' '),
606 # 3.16 Non-ASCII multibyte space character U+1680.
607 ('\xe1\x9a\x80',
608 None),
609 # 3.17 Non-ASCII multibyte space character U+2000.
610 ('\xe2\x80\x80',
611 ' '),
612 # 3.18 Zero Width Space U+200b.
613 ('\xe2\x80\x8b',
614 ''),
615 # 3.19 Non-ASCII multibyte space character U+3000.
616 ('\xe3\x80\x80',
617 ' '),
618 # 3.20 ASCII control characters U+0010 U+007F.
619 ('\x10\x7f',
620 '\x10\x7f'),
621 # 3.21 Non-ASCII 8bit control character U+0085.
622 ('\xc2\x85',
623 None),
624 # 3.22 Non-ASCII multibyte control character U+180E.
625 ('\xe1\xa0\x8e',
626 None),
627 # 3.23 Zero Width No-Break Space U+FEFF.
628 ('\xef\xbb\xbf',
629 ''),
630 # 3.24 Non-ASCII control character U+1D175.
631 ('\xf0\x9d\x85\xb5',
632 None),
633 # 3.25 Plane 0 private use character U+F123.
634 ('\xef\x84\xa3',
635 None),
636 # 3.26 Plane 15 private use character U+F1234.
637 ('\xf3\xb1\x88\xb4',
638 None),
639 # 3.27 Plane 16 private use character U+10F234.
640 ('\xf4\x8f\x88\xb4',
641 None),
642 # 3.28 Non-character code point U+8FFFE.
643 ('\xf2\x8f\xbf\xbe',
644 None),
645 # 3.29 Non-character code point U+10FFFF.
646 ('\xf4\x8f\xbf\xbf',
647 None),
648 # 3.30 Surrogate code U+DF42.
649 ('\xed\xbd\x82',
650 None),
651 # 3.31 Non-plain text character U+FFFD.
652 ('\xef\xbf\xbd',
653 None),
654 # 3.32 Ideographic description character U+2FF5.
655 ('\xe2\xbf\xb5',
656 None),
657 # 3.33 Display property character U+0341.
Tim Peters0eadaac2003-04-24 16:02:54 +0000658 ('\xcd\x81',
Martin v. Löwis2548c732003-04-18 10:39:54 +0000659 '\xcc\x81'),
660 # 3.34 Left-to-right mark U+200E.
661 ('\xe2\x80\x8e',
662 None),
663 # 3.35 Deprecated U+202A.
664 ('\xe2\x80\xaa',
665 None),
666 # 3.36 Language tagging character U+E0001.
667 ('\xf3\xa0\x80\x81',
668 None),
669 # 3.37 Language tagging character U+E0042.
670 ('\xf3\xa0\x81\x82',
671 None),
672 # 3.38 Bidi: RandALCat character U+05BE and LCat characters.
673 ('foo\xd6\xbebar',
674 None),
675 # 3.39 Bidi: RandALCat character U+FD50 and LCat characters.
676 ('foo\xef\xb5\x90bar',
677 None),
678 # 3.40 Bidi: RandALCat character U+FB38 and LCat characters.
679 ('foo\xef\xb9\xb6bar',
680 'foo \xd9\x8ebar'),
681 # 3.41 Bidi: RandALCat without trailing RandALCat U+0627 U+0031.
682 ('\xd8\xa71',
683 None),
684 # 3.42 Bidi: RandALCat character U+0627 U+0031 U+0628.
685 ('\xd8\xa71\xd8\xa8',
686 '\xd8\xa71\xd8\xa8'),
687 # 3.43 Unassigned code point U+E0002.
Martin v. Löwisb5c4b7b2003-04-18 20:21:00 +0000688 # Skip this test as we allow unassigned
689 #('\xf3\xa0\x80\x82',
690 # None),
691 (None, None),
Martin v. Löwis2548c732003-04-18 10:39:54 +0000692 # 3.44 Larger test (shrinking).
693 # Original test case reads \xc3\xdf
694 ('X\xc2\xad\xc3\x9f\xc4\xb0\xe2\x84\xa1j\xcc\x8c\xc2\xa0\xc2'
695 '\xaa\xce\xb0\xe2\x80\x80',
696 'xssi\xcc\x87tel\xc7\xb0 a\xce\xb0 '),
697 # 3.45 Larger test (expanding).
698 # Original test case reads \xc3\x9f
699 ('X\xc3\x9f\xe3\x8c\x96\xc4\xb0\xe2\x84\xa1\xe2\x92\x9f\xe3\x8c'
700 '\x80',
701 'xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3'
702 '\x83\x88\xe3\x83\xabi\xcc\x87tel\x28d\x29\xe3\x82'
703 '\xa2\xe3\x83\x91\xe3\x83\xbc\xe3\x83\x88')
704 ]
705
706
707class NameprepTest(unittest.TestCase):
708 def test_nameprep(self):
709 from encodings.idna import nameprep
710 for pos, (orig, prepped) in enumerate(nameprep_tests):
711 if orig is None:
712 # Skipped
713 continue
714 # The Unicode strings are given in UTF-8
715 orig = unicode(orig, "utf-8")
716 if prepped is None:
717 # Input contains prohibited characters
718 self.assertRaises(UnicodeError, nameprep, orig)
719 else:
720 prepped = unicode(prepped, "utf-8")
721 try:
722 self.assertEquals(nameprep(orig), prepped)
723 except Exception,e:
724 raise test_support.TestFailed("Test 3.%d: %s" % (pos+1, str(e)))
725
Martin v. Löwisa1dde132004-03-24 16:48:24 +0000726class CodecTest(unittest.TestCase):
727 def test_builtin(self):
728 self.assertEquals(unicode("python.org", "idna"), u"python.org")
729
Martin v. Löwis8b595142005-08-25 11:03:38 +0000730 def test_stream(self):
731 import StringIO
732 r = codecs.getreader("idna")(StringIO.StringIO("abc"))
733 r.read(3)
734 self.assertEquals(r.read(), u"")
735
Marc-André Lemburg3f419742004-07-10 12:06:10 +0000736class CodecsModuleTest(unittest.TestCase):
737
738 def test_decode(self):
739 self.assertEquals(codecs.decode('\xe4\xf6\xfc', 'latin-1'),
740 u'\xe4\xf6\xfc')
Walter Dörwald063e1e82004-10-28 13:04:26 +0000741 self.assertRaises(TypeError, codecs.decode)
742 self.assertEquals(codecs.decode('abc'), u'abc')
743 self.assertRaises(UnicodeDecodeError, codecs.decode, '\xff', 'ascii')
744
Marc-André Lemburg3f419742004-07-10 12:06:10 +0000745 def test_encode(self):
746 self.assertEquals(codecs.encode(u'\xe4\xf6\xfc', 'latin-1'),
747 '\xe4\xf6\xfc')
Walter Dörwald063e1e82004-10-28 13:04:26 +0000748 self.assertRaises(TypeError, codecs.encode)
Walter Dörwald690402f2005-11-17 18:51:34 +0000749 self.assertRaises(LookupError, codecs.encode, "foo", "__spam__")
Walter Dörwald063e1e82004-10-28 13:04:26 +0000750 self.assertEquals(codecs.encode(u'abc'), 'abc')
751 self.assertRaises(UnicodeEncodeError, codecs.encode, u'\xffff', 'ascii')
752
753 def test_register(self):
754 self.assertRaises(TypeError, codecs.register)
Walter Dörwald690402f2005-11-17 18:51:34 +0000755 self.assertRaises(TypeError, codecs.register, 42)
Walter Dörwald063e1e82004-10-28 13:04:26 +0000756
757 def test_lookup(self):
758 self.assertRaises(TypeError, codecs.lookup)
759 self.assertRaises(LookupError, codecs.lookup, "__spam__")
Walter Dörwald690402f2005-11-17 18:51:34 +0000760 self.assertRaises(LookupError, codecs.lookup, " ")
761
762 def test_getencoder(self):
763 self.assertRaises(TypeError, codecs.getencoder)
764 self.assertRaises(LookupError, codecs.getencoder, "__spam__")
765
766 def test_getdecoder(self):
767 self.assertRaises(TypeError, codecs.getdecoder)
768 self.assertRaises(LookupError, codecs.getdecoder, "__spam__")
769
770 def test_getreader(self):
771 self.assertRaises(TypeError, codecs.getreader)
772 self.assertRaises(LookupError, codecs.getreader, "__spam__")
773
774 def test_getwriter(self):
775 self.assertRaises(TypeError, codecs.getwriter)
776 self.assertRaises(LookupError, codecs.getwriter, "__spam__")
Marc-André Lemburg3f419742004-07-10 12:06:10 +0000777
Hye-Shik Changaf5c7cf2004-10-17 23:51:21 +0000778class StreamReaderTest(unittest.TestCase):
779
780 def setUp(self):
781 self.reader = codecs.getreader('utf-8')
782 self.stream = StringIO.StringIO('\xed\x95\x9c\n\xea\xb8\x80')
783
784 def test_readlines(self):
785 f = self.reader(self.stream)
786 self.assertEquals(f.readlines(), [u'\ud55c\n', u'\uae00'])
787
Walter Dörwaldc9878e12005-07-20 22:15:39 +0000788class Str2StrTest(unittest.TestCase):
789
790 def test_read(self):
791 sin = "\x80".encode("base64_codec")
792 reader = codecs.getreader("base64_codec")(StringIO.StringIO(sin))
793 sout = reader.read()
794 self.assertEqual(sout, "\x80")
795 self.assert_(isinstance(sout, str))
796
797 def test_readline(self):
798 sin = "\x80".encode("base64_codec")
799 reader = codecs.getreader("base64_codec")(StringIO.StringIO(sin))
800 sout = reader.readline()
801 self.assertEqual(sout, "\x80")
802 self.assert_(isinstance(sout, str))
803
Walter Dörwaldee1d2472004-12-29 16:04:38 +0000804all_unicode_encodings = [
805 "ascii",
806 "base64_codec",
807 "big5",
808 "big5hkscs",
809 "charmap",
810 "cp037",
811 "cp1006",
812 "cp1026",
813 "cp1140",
814 "cp1250",
815 "cp1251",
816 "cp1252",
817 "cp1253",
818 "cp1254",
819 "cp1255",
820 "cp1256",
821 "cp1257",
822 "cp1258",
823 "cp424",
824 "cp437",
825 "cp500",
826 "cp737",
827 "cp775",
828 "cp850",
829 "cp852",
830 "cp855",
831 "cp856",
832 "cp857",
833 "cp860",
834 "cp861",
835 "cp862",
836 "cp863",
837 "cp864",
838 "cp865",
839 "cp866",
840 "cp869",
841 "cp874",
842 "cp875",
843 "cp932",
844 "cp949",
845 "cp950",
846 "euc_jis_2004",
847 "euc_jisx0213",
848 "euc_jp",
849 "euc_kr",
850 "gb18030",
851 "gb2312",
852 "gbk",
853 "hex_codec",
854 "hp_roman8",
855 "hz",
856 "idna",
857 "iso2022_jp",
858 "iso2022_jp_1",
859 "iso2022_jp_2",
860 "iso2022_jp_2004",
861 "iso2022_jp_3",
862 "iso2022_jp_ext",
863 "iso2022_kr",
864 "iso8859_1",
865 "iso8859_10",
866 "iso8859_11",
867 "iso8859_13",
868 "iso8859_14",
869 "iso8859_15",
870 "iso8859_16",
871 "iso8859_2",
872 "iso8859_3",
873 "iso8859_4",
874 "iso8859_5",
875 "iso8859_6",
876 "iso8859_7",
877 "iso8859_8",
878 "iso8859_9",
879 "johab",
880 "koi8_r",
881 "koi8_u",
882 "latin_1",
883 "mac_cyrillic",
884 "mac_greek",
885 "mac_iceland",
886 "mac_latin2",
887 "mac_roman",
888 "mac_turkish",
889 "palmos",
890 "ptcp154",
891 "punycode",
892 "raw_unicode_escape",
893 "rot_13",
894 "shift_jis",
895 "shift_jis_2004",
896 "shift_jisx0213",
897 "tis_620",
898 "unicode_escape",
899 "unicode_internal",
900 "utf_16",
901 "utf_16_be",
902 "utf_16_le",
903 "utf_7",
904 "utf_8",
905]
906
907if hasattr(codecs, "mbcs_encode"):
908 all_unicode_encodings.append("mbcs")
909
910# The following encodings work only with str, not unicode
911all_string_encodings = [
912 "quopri_codec",
913 "string_escape",
914 "uu_codec",
915]
916
917# The following encoding is not tested, because it's not supposed
918# to work:
919# "undefined"
920
921# The following encodings don't work in stateful mode
922broken_unicode_with_streams = [
923 "base64_codec",
924 "hex_codec",
925 "punycode",
926 "unicode_internal"
927]
928
929try:
930 import bz2
931except ImportError:
932 pass
933else:
934 all_unicode_encodings.append("bz2_codec")
935 broken_unicode_with_streams.append("bz2_codec")
936
937try:
938 import zlib
939except ImportError:
940 pass
941else:
942 all_unicode_encodings.append("zlib_codec")
943 broken_unicode_with_streams.append("zlib_codec")
944
945class BasicUnicodeTest(unittest.TestCase):
946 def test_basics(self):
947 s = u"abc123" # all codecs should be able to encode these
948 for encoding in all_unicode_encodings:
949 (bytes, size) = codecs.getencoder(encoding)(s)
950 if encoding != "unicode_internal":
951 self.assertEqual(size, len(s), "%r != %r (encoding=%r)" % (size, len(s), encoding))
952 (chars, size) = codecs.getdecoder(encoding)(bytes)
953 self.assertEqual(chars, s, "%r != %r (encoding=%r)" % (chars, s, encoding))
954
955 if encoding not in broken_unicode_with_streams:
956 # check stream reader/writer
957 q = Queue()
958 writer = codecs.getwriter(encoding)(q)
959 encodedresult = ""
960 for c in s:
961 writer.write(c)
962 encodedresult += q.read()
963 q = Queue()
964 reader = codecs.getreader(encoding)(q)
965 decodedresult = u""
966 for c in encodedresult:
967 q.write(c)
968 decodedresult += reader.read()
969 self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
970
Walter Dörwald729c31f2005-03-14 19:06:30 +0000971 def test_seek(self):
972 # all codecs should be able to encode these
973 s = u"%s\n%s\n" % (100*u"abc123", 100*u"def456")
974 for encoding in all_unicode_encodings:
975 if encoding == "idna": # FIXME: See SF bug #1163178
976 continue
977 if encoding in broken_unicode_with_streams:
978 continue
979 reader = codecs.getreader(encoding)(StringIO.StringIO(s.encode(encoding)))
980 for t in xrange(5):
981 # Test that calling seek resets the internal codec state and buffers
982 reader.seek(0, 0)
983 line = reader.readline()
984 self.assertEqual(s[:len(line)], line)
985
Walter Dörwalde22d3392005-11-17 08:52:34 +0000986 def test_bad_decode_args(self):
987 for encoding in all_unicode_encodings:
988 decoder = codecs.getdecoder(encoding)
989 self.assertRaises(TypeError, decoder)
990 if encoding not in ("idna", "punycode"):
991 self.assertRaises(TypeError, decoder, 42)
992
993 def test_bad_encode_args(self):
994 for encoding in all_unicode_encodings:
995 encoder = codecs.getencoder(encoding)
996 self.assertRaises(TypeError, encoder)
997
Walter Dörwaldee1d2472004-12-29 16:04:38 +0000998class BasicStrTest(unittest.TestCase):
999 def test_basics(self):
1000 s = "abc123"
1001 for encoding in all_string_encodings:
1002 (bytes, size) = codecs.getencoder(encoding)(s)
1003 self.assertEqual(size, len(s))
1004 (chars, size) = codecs.getdecoder(encoding)(bytes)
1005 self.assertEqual(chars, s, "%r != %r (encoding=%r)" % (chars, s, encoding))
1006
Walter Dörwaldd1c1e102005-10-06 20:29:57 +00001007class CharmapTest(unittest.TestCase):
1008 def test_decode_with_string_map(self):
1009 self.assertEquals(
1010 codecs.charmap_decode("\x00\x01\x02", "strict", u"abc"),
1011 (u"abc", 3)
1012 )
1013
1014 self.assertEquals(
1015 codecs.charmap_decode("\x00\x01\x02", "replace", u"ab"),
1016 (u"ab\ufffd", 3)
1017 )
1018
1019 self.assertEquals(
1020 codecs.charmap_decode("\x00\x01\x02", "replace", u"ab\ufffe"),
1021 (u"ab\ufffd", 3)
1022 )
1023
1024 self.assertEquals(
1025 codecs.charmap_decode("\x00\x01\x02", "ignore", u"ab"),
1026 (u"ab", 3)
1027 )
1028
1029 self.assertEquals(
1030 codecs.charmap_decode("\x00\x01\x02", "ignore", u"ab\ufffe"),
1031 (u"ab", 3)
1032 )
1033
1034 allbytes = "".join(chr(i) for i in xrange(256))
1035 self.assertEquals(
1036 codecs.charmap_decode(allbytes, "ignore", u""),
1037 (u"", len(allbytes))
1038 )
1039
1040
Fred Drake2e2be372001-09-20 21:33:42 +00001041def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +00001042 test_support.run_unittest(
1043 UTF16Test,
Walter Dörwald69652032004-09-07 20:24:22 +00001044 UTF16LETest,
1045 UTF16BETest,
1046 UTF8Test,
Walter Dörwalde22d3392005-11-17 08:52:34 +00001047 UTF7Test,
1048 UTF16ExTest,
1049 ReadBufferTest,
1050 CharBufferTest,
Walter Dörwald21d3a322003-05-01 17:45:56 +00001051 EscapeDecodeTest,
1052 RecodingTest,
1053 PunycodeTest,
Walter Dörwalda47d1c02005-08-30 10:23:14 +00001054 UnicodeInternalTest,
Martin v. Löwisa1dde132004-03-24 16:48:24 +00001055 NameprepTest,
Marc-André Lemburg3f419742004-07-10 12:06:10 +00001056 CodecTest,
Hye-Shik Changaf5c7cf2004-10-17 23:51:21 +00001057 CodecsModuleTest,
Walter Dörwaldee1d2472004-12-29 16:04:38 +00001058 StreamReaderTest,
Walter Dörwaldc9878e12005-07-20 22:15:39 +00001059 Str2StrTest,
Walter Dörwaldee1d2472004-12-29 16:04:38 +00001060 BasicUnicodeTest,
Walter Dörwaldd1c1e102005-10-06 20:29:57 +00001061 BasicStrTest,
1062 CharmapTest
Walter Dörwald21d3a322003-05-01 17:45:56 +00001063 )
Fred Drake2e2be372001-09-20 21:33:42 +00001064
1065
1066if __name__ == "__main__":
1067 test_main()