Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | """ |
2 | Common tests shared by test_str, test_unicode, test_userstring and test_string. | |
3 | """ | |
4 | ||
5 | import unittest, string, sys | |
6 | from test import test_support | |
7 | from UserList import UserList | |
8 | ||
9 | class Sequence: | |
10 | def __init__(self, seq='wxyz'): self.seq = seq | |
11 | def __len__(self): return len(self.seq) | |
12 | def __getitem__(self, i): return self.seq[i] | |
13 | ||
14 | class BadSeq1(Sequence): | |
15 | def __init__(self): self.seq = [7, 'hello', 123L] | |
16 | ||
17 | class BadSeq2(Sequence): | |
18 | def __init__(self): self.seq = ['a', 'b', 'c'] | |
19 | def __len__(self): return 8 | |
20 | ||
21 | class CommonTest(unittest.TestCase): | |
22 | # This testcase contains test that can be used in all | |
23 | # stringlike classes. Currently this is str, unicode | |
24 | # UserString and the string module. | |
25 | ||
26 | # The type to be tested | |
27 | # Change in subclasses to change the behaviour of fixtesttype() | |
28 | type2test = None | |
29 | ||
30 | # All tests pass their arguments to the testing methods | |
31 | # as str objects. fixtesttype() can be used to propagate | |
32 | # these arguments to the appropriate type | |
33 | def fixtype(self, obj): | |
34 | if isinstance(obj, str): | |
35 | return self.__class__.type2test(obj) | |
36 | elif isinstance(obj, list): | |
37 | return [self.fixtype(x) for x in obj] | |
38 | elif isinstance(obj, tuple): | |
39 | return tuple([self.fixtype(x) for x in obj]) | |
40 | elif isinstance(obj, dict): | |
41 | return dict([ | |
42 | (self.fixtype(key), self.fixtype(value)) | |
43 | for (key, value) in obj.iteritems() | |
44 | ]) | |
45 | else: | |
46 | return obj | |
47 | ||
48 | # check that object.method(*args) returns result | |
49 | def checkequal(self, result, object, methodname, *args): | |
50 | result = self.fixtype(result) | |
51 | object = self.fixtype(object) | |
52 | args = self.fixtype(args) | |
53 | realresult = getattr(object, methodname)(*args) | |
54 | self.assertEqual( | |
55 | result, | |
56 | realresult | |
57 | ) | |
58 | # if the original is returned make sure that | |
59 | # this doesn't happen with subclasses | |
60 | if object == realresult: | |
61 | class subtype(self.__class__.type2test): | |
62 | pass | |
63 | object = subtype(object) | |
64 | realresult = getattr(object, methodname)(*args) | |
65 | self.assert_(object is not realresult) | |
66 | ||
67 | # check that object.method(*args) raises exc | |
68 | def checkraises(self, exc, object, methodname, *args): | |
69 | object = self.fixtype(object) | |
70 | args = self.fixtype(args) | |
71 | self.assertRaises( | |
72 | exc, | |
73 | getattr(object, methodname), | |
74 | *args | |
75 | ) | |
76 | ||
77 | # call object.method(*args) without any checks | |
78 | def checkcall(self, object, methodname, *args): | |
79 | object = self.fixtype(object) | |
80 | args = self.fixtype(args) | |
81 | getattr(object, methodname)(*args) | |
82 | ||
83 | def test_hash(self): | |
84 | # SF bug 1054139: += optimization was not invalidating cached hash value | |
85 | a = self.type2test('DNSSEC') | |
86 | b = self.type2test('') | |
87 | for c in a: | |
88 | b += c | |
89 | hash(b) | |
90 | self.assertEqual(hash(a), hash(b)) | |
91 | ||
92 | def test_capitalize(self): | |
93 | self.checkequal(' hello ', ' hello ', 'capitalize') | |
94 | self.checkequal('Hello ', 'Hello ','capitalize') | |
95 | self.checkequal('Hello ', 'hello ','capitalize') | |
96 | self.checkequal('Aaaa', 'aaaa', 'capitalize') | |
97 | self.checkequal('Aaaa', 'AaAa', 'capitalize') | |
98 | ||
99 | self.checkraises(TypeError, 'hello', 'capitalize', 42) | |
100 | ||
101 | def test_count(self): | |
102 | self.checkequal(3, 'aaa', 'count', 'a') | |
103 | self.checkequal(0, 'aaa', 'count', 'b') | |
104 | self.checkequal(3, 'aaa', 'count', 'a') | |
105 | self.checkequal(0, 'aaa', 'count', 'b') | |
106 | self.checkequal(3, 'aaa', 'count', 'a') | |
107 | self.checkequal(0, 'aaa', 'count', 'b') | |
108 | self.checkequal(0, 'aaa', 'count', 'b') | |
109 | self.checkequal(1, 'aaa', 'count', 'a', -1) | |
110 | self.checkequal(3, 'aaa', 'count', 'a', -10) | |
111 | self.checkequal(2, 'aaa', 'count', 'a', 0, -1) | |
112 | self.checkequal(0, 'aaa', 'count', 'a', 0, -10) | |
113 | ||
114 | self.checkraises(TypeError, 'hello', 'count') | |
115 | self.checkraises(TypeError, 'hello', 'count', 42) | |
116 | ||
117 | def test_find(self): | |
118 | self.checkequal(0, 'abcdefghiabc', 'find', 'abc') | |
119 | self.checkequal(9, 'abcdefghiabc', 'find', 'abc', 1) | |
120 | self.checkequal(-1, 'abcdefghiabc', 'find', 'def', 4) | |
121 | ||
122 | self.checkraises(TypeError, 'hello', 'find') | |
123 | self.checkraises(TypeError, 'hello', 'find', 42) | |
124 | ||
125 | def test_rfind(self): | |
126 | self.checkequal(9, 'abcdefghiabc', 'rfind', 'abc') | |
127 | self.checkequal(12, 'abcdefghiabc', 'rfind', '') | |
128 | self.checkequal(0, 'abcdefghiabc', 'rfind', 'abcd') | |
129 | self.checkequal(-1, 'abcdefghiabc', 'rfind', 'abcz') | |
130 | ||
131 | self.checkraises(TypeError, 'hello', 'rfind') | |
132 | self.checkraises(TypeError, 'hello', 'rfind', 42) | |
133 | ||
134 | def test_index(self): | |
135 | self.checkequal(0, 'abcdefghiabc', 'index', '') | |
136 | self.checkequal(3, 'abcdefghiabc', 'index', 'def') | |
137 | self.checkequal(0, 'abcdefghiabc', 'index', 'abc') | |
138 | self.checkequal(9, 'abcdefghiabc', 'index', 'abc', 1) | |
139 | ||
140 | self.checkraises(ValueError, 'abcdefghiabc', 'index', 'hib') | |
141 | self.checkraises(ValueError, 'abcdefghiab', 'index', 'abc', 1) | |
142 | self.checkraises(ValueError, 'abcdefghi', 'index', 'ghi', 8) | |
143 | self.checkraises(ValueError, 'abcdefghi', 'index', 'ghi', -1) | |
144 | ||
145 | self.checkraises(TypeError, 'hello', 'index') | |
146 | self.checkraises(TypeError, 'hello', 'index', 42) | |
147 | ||
148 | def test_rindex(self): | |
149 | self.checkequal(12, 'abcdefghiabc', 'rindex', '') | |
150 | self.checkequal(3, 'abcdefghiabc', 'rindex', 'def') | |
151 | self.checkequal(9, 'abcdefghiabc', 'rindex', 'abc') | |
152 | self.checkequal(0, 'abcdefghiabc', 'rindex', 'abc', 0, -1) | |
153 | ||
154 | self.checkraises(ValueError, 'abcdefghiabc', 'rindex', 'hib') | |
155 | self.checkraises(ValueError, 'defghiabc', 'rindex', 'def', 1) | |
156 | self.checkraises(ValueError, 'defghiabc', 'rindex', 'abc', 0, -1) | |
157 | self.checkraises(ValueError, 'abcdefghi', 'rindex', 'ghi', 0, 8) | |
158 | self.checkraises(ValueError, 'abcdefghi', 'rindex', 'ghi', 0, -1) | |
159 | ||
160 | self.checkraises(TypeError, 'hello', 'rindex') | |
161 | self.checkraises(TypeError, 'hello', 'rindex', 42) | |
162 | ||
163 | def test_lower(self): | |
164 | self.checkequal('hello', 'HeLLo', 'lower') | |
165 | self.checkequal('hello', 'hello', 'lower') | |
166 | self.checkraises(TypeError, 'hello', 'lower', 42) | |
167 | ||
168 | def test_upper(self): | |
169 | self.checkequal('HELLO', 'HeLLo', 'upper') | |
170 | self.checkequal('HELLO', 'HELLO', 'upper') | |
171 | self.checkraises(TypeError, 'hello', 'upper', 42) | |
172 | ||
173 | def test_expandtabs(self): | |
174 | self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs') | |
175 | self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 8) | |
176 | self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 4) | |
177 | self.checkequal('abc\r\nab def\ng hi', 'abc\r\nab\tdef\ng\thi', 'expandtabs', 4) | |
178 | self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs') | |
179 | self.checkequal('abc\rab def\ng hi', 'abc\rab\tdef\ng\thi', 'expandtabs', 8) | |
180 | self.checkequal('abc\r\nab\r\ndef\ng\r\nhi', 'abc\r\nab\r\ndef\ng\r\nhi', 'expandtabs', 4) | |
181 | ||
182 | self.checkraises(TypeError, 'hello', 'expandtabs', 42, 42) | |
183 | ||
184 | def test_split(self): | |
185 | self.checkequal(['this', 'is', 'the', 'split', 'function'], | |
186 | 'this is the split function', 'split') | |
187 | ||
188 | # by whitespace | |
189 | self.checkequal(['a', 'b', 'c', 'd'], 'a b c d ', 'split') | |
190 | self.checkequal(['a', 'b c d'], 'a b c d', 'split', None, 1) | |
191 | self.checkequal(['a', 'b', 'c d'], 'a b c d', 'split', None, 2) | |
192 | self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'split', None, 3) | |
193 | self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'split', None, 4) | |
194 | self.checkequal(['a b c d'], 'a b c d', 'split', None, 0) | |
195 | self.checkequal(['a', 'b', 'c d'], 'a b c d', 'split', None, 2) | |
196 | ||
197 | # by a char | |
198 | self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|') | |
199 | self.checkequal(['a', 'b|c|d'], 'a|b|c|d', 'split', '|', 1) | |
200 | self.checkequal(['a', 'b', 'c|d'], 'a|b|c|d', 'split', '|', 2) | |
201 | self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|', 3) | |
202 | self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'split', '|', 4) | |
203 | self.checkequal(['a|b|c|d'], 'a|b|c|d', 'split', '|', 0) | |
204 | self.checkequal(['a', '', 'b||c||d'], 'a||b||c||d', 'split', '|', 2) | |
205 | self.checkequal(['endcase ', ''], 'endcase |', 'split', '|') | |
206 | self.checkequal(['a', '', 'b\x00c\x00d'], 'a\x00\x00b\x00c\x00d', 'split', '\x00', 2) | |
207 | ||
208 | # by string | |
209 | self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//') | |
210 | self.checkequal(['a', 'b//c//d'], 'a//b//c//d', 'split', '//', 1) | |
211 | self.checkequal(['a', 'b', 'c//d'], 'a//b//c//d', 'split', '//', 2) | |
212 | self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//', 3) | |
213 | self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//', 4) | |
214 | self.checkequal(['a//b//c//d'], 'a//b//c//d', 'split', '//', 0) | |
215 | self.checkequal(['a', '', 'b////c////d'], 'a////b////c////d', 'split', '//', 2) | |
216 | self.checkequal(['endcase ', ''], 'endcase test', 'split', 'test') | |
217 | ||
218 | # mixed use of str and unicode | |
219 | self.checkequal([u'a', u'b', u'c d'], 'a b c d', 'split', u' ', 2) | |
220 | ||
221 | # argument type | |
222 | self.checkraises(TypeError, 'hello', 'split', 42, 42, 42) | |
223 | ||
224 | def test_rsplit(self): | |
225 | self.checkequal(['this', 'is', 'the', 'rsplit', 'function'], | |
226 | 'this is the rsplit function', 'rsplit') | |
227 | ||
228 | # by whitespace | |
229 | self.checkequal(['a', 'b', 'c', 'd'], 'a b c d ', 'rsplit') | |
230 | self.checkequal(['a b c', 'd'], 'a b c d', 'rsplit', None, 1) | |
231 | self.checkequal(['a b', 'c', 'd'], 'a b c d', 'rsplit', None, 2) | |
232 | self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', None, 3) | |
233 | self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', None, 4) | |
234 | self.checkequal(['a b c d'], 'a b c d', 'rsplit', None, 0) | |
235 | self.checkequal(['a b', 'c', 'd'], 'a b c d', 'rsplit', None, 2) | |
236 | ||
237 | # by a char | |
238 | self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|') | |
239 | self.checkequal(['a|b|c', 'd'], 'a|b|c|d', 'rsplit', '|', 1) | |
240 | self.checkequal(['a|b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|', 2) | |
241 | self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|', 3) | |
242 | self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|', 4) | |
243 | self.checkequal(['a|b|c|d'], 'a|b|c|d', 'rsplit', '|', 0) | |
244 | self.checkequal(['a||b||c', '', 'd'], 'a||b||c||d', 'rsplit', '|', 2) | |
245 | self.checkequal(['', ' begincase'], '| begincase', 'rsplit', '|') | |
246 | self.checkequal(['a\x00\x00b', 'c', 'd'], 'a\x00\x00b\x00c\x00d', 'rsplit', '\x00', 2) | |
247 | ||
248 | # by string | |
249 | self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//') | |
250 | self.checkequal(['a//b//c', 'd'], 'a//b//c//d', 'rsplit', '//', 1) | |
251 | self.checkequal(['a//b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//', 2) | |
252 | self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//', 3) | |
253 | self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//', 4) | |
254 | self.checkequal(['a//b//c//d'], 'a//b//c//d', 'rsplit', '//', 0) | |
255 | self.checkequal(['a////b////c', '', 'd'], 'a////b////c////d', 'rsplit', '//', 2) | |
256 | self.checkequal(['', ' begincase'], 'test begincase', 'rsplit', 'test') | |
257 | ||
258 | # mixed use of str and unicode | |
259 | self.checkequal([u'a b', u'c', u'd'], 'a b c d', 'rsplit', u' ', 2) | |
260 | ||
261 | # argument type | |
262 | self.checkraises(TypeError, 'hello', 'rsplit', 42, 42, 42) | |
263 | ||
264 | def test_strip(self): | |
265 | self.checkequal('hello', ' hello ', 'strip') | |
266 | self.checkequal('hello ', ' hello ', 'lstrip') | |
267 | self.checkequal(' hello', ' hello ', 'rstrip') | |
268 | self.checkequal('hello', 'hello', 'strip') | |
269 | ||
270 | # strip/lstrip/rstrip with None arg | |
271 | self.checkequal('hello', ' hello ', 'strip', None) | |
272 | self.checkequal('hello ', ' hello ', 'lstrip', None) | |
273 | self.checkequal(' hello', ' hello ', 'rstrip', None) | |
274 | self.checkequal('hello', 'hello', 'strip', None) | |
275 | ||
276 | # strip/lstrip/rstrip with str arg | |
277 | self.checkequal('hello', 'xyzzyhelloxyzzy', 'strip', 'xyz') | |
278 | self.checkequal('helloxyzzy', 'xyzzyhelloxyzzy', 'lstrip', 'xyz') | |
279 | self.checkequal('xyzzyhello', 'xyzzyhelloxyzzy', 'rstrip', 'xyz') | |
280 | self.checkequal('hello', 'hello', 'strip', 'xyz') | |
281 | ||
282 | # strip/lstrip/rstrip with unicode arg | |
283 | if test_support.have_unicode: | |
284 | self.checkequal(unicode('hello', 'ascii'), 'xyzzyhelloxyzzy', | |
285 | 'strip', unicode('xyz', 'ascii')) | |
286 | self.checkequal(unicode('helloxyzzy', 'ascii'), 'xyzzyhelloxyzzy', | |
287 | 'lstrip', unicode('xyz', 'ascii')) | |
288 | self.checkequal(unicode('xyzzyhello', 'ascii'), 'xyzzyhelloxyzzy', | |
289 | 'rstrip', unicode('xyz', 'ascii')) | |
290 | self.checkequal(unicode('hello', 'ascii'), 'hello', | |
291 | 'strip', unicode('xyz', 'ascii')) | |
292 | ||
293 | self.checkraises(TypeError, 'hello', 'strip', 42, 42) | |
294 | self.checkraises(TypeError, 'hello', 'lstrip', 42, 42) | |
295 | self.checkraises(TypeError, 'hello', 'rstrip', 42, 42) | |
296 | ||
297 | def test_ljust(self): | |
298 | self.checkequal('abc ', 'abc', 'ljust', 10) | |
299 | self.checkequal('abc ', 'abc', 'ljust', 6) | |
300 | self.checkequal('abc', 'abc', 'ljust', 3) | |
301 | self.checkequal('abc', 'abc', 'ljust', 2) | |
302 | self.checkequal('abc*******', 'abc', 'ljust', 10, '*') | |
303 | self.checkraises(TypeError, 'abc', 'ljust') | |
304 | ||
305 | def test_rjust(self): | |
306 | self.checkequal(' abc', 'abc', 'rjust', 10) | |
307 | self.checkequal(' abc', 'abc', 'rjust', 6) | |
308 | self.checkequal('abc', 'abc', 'rjust', 3) | |
309 | self.checkequal('abc', 'abc', 'rjust', 2) | |
310 | self.checkequal('*******abc', 'abc', 'rjust', 10, '*') | |
311 | self.checkraises(TypeError, 'abc', 'rjust') | |
312 | ||
313 | def test_center(self): | |
314 | self.checkequal(' abc ', 'abc', 'center', 10) | |
315 | self.checkequal(' abc ', 'abc', 'center', 6) | |
316 | self.checkequal('abc', 'abc', 'center', 3) | |
317 | self.checkequal('abc', 'abc', 'center', 2) | |
318 | self.checkequal('***abc****', 'abc', 'center', 10, '*') | |
319 | self.checkraises(TypeError, 'abc', 'center') | |
320 | ||
321 | def test_swapcase(self): | |
322 | self.checkequal('hEllO CoMPuTErS', 'HeLLo cOmpUteRs', 'swapcase') | |
323 | ||
324 | self.checkraises(TypeError, 'hello', 'swapcase', 42) | |
325 | ||
326 | def test_replace(self): | |
327 | self.checkequal('one@two!three!', 'one!two!three!', 'replace', '!', '@', 1) | |
328 | self.checkequal('onetwothree', 'one!two!three!', 'replace', '!', '') | |
329 | self.checkequal('one@two@three!', 'one!two!three!', 'replace', '!', '@', 2) | |
330 | self.checkequal('one@two@three@', 'one!two!three!', 'replace', '!', '@', 3) | |
331 | self.checkequal('one@two@three@', 'one!two!three!', 'replace', '!', '@', 4) | |
332 | self.checkequal('one!two!three!', 'one!two!three!', 'replace', '!', '@', 0) | |
333 | self.checkequal('one@two@three@', 'one!two!three!', 'replace', '!', '@') | |
334 | self.checkequal('one!two!three!', 'one!two!three!', 'replace', 'x', '@') | |
335 | self.checkequal('one!two!three!', 'one!two!three!', 'replace', 'x', '@', 2) | |
336 | self.checkequal('-a-b-c-', 'abc', 'replace', '', '-') | |
337 | self.checkequal('-a-b-c', 'abc', 'replace', '', '-', 3) | |
338 | self.checkequal('abc', 'abc', 'replace', '', '-', 0) | |
339 | self.checkequal('', '', 'replace', '', '') | |
340 | self.checkequal('abc', 'abc', 'replace', 'ab', '--', 0) | |
341 | self.checkequal('abc', 'abc', 'replace', 'xy', '--') | |
342 | # Next three for SF bug 422088: [OSF1 alpha] string.replace(); died with | |
343 | # MemoryError due to empty result (platform malloc issue when requesting | |
344 | # 0 bytes). | |
345 | self.checkequal('', '123', 'replace', '123', '') | |
346 | self.checkequal('', '123123', 'replace', '123', '') | |
347 | self.checkequal('x', '123x123', 'replace', '123', '') | |
348 | ||
349 | self.checkraises(TypeError, 'hello', 'replace') | |
350 | self.checkraises(TypeError, 'hello', 'replace', 42) | |
351 | self.checkraises(TypeError, 'hello', 'replace', 42, 'h') | |
352 | self.checkraises(TypeError, 'hello', 'replace', 'h', 42) | |
353 | ||
354 | def test_zfill(self): | |
355 | self.checkequal('123', '123', 'zfill', 2) | |
356 | self.checkequal('123', '123', 'zfill', 3) | |
357 | self.checkequal('0123', '123', 'zfill', 4) | |
358 | self.checkequal('+123', '+123', 'zfill', 3) | |
359 | self.checkequal('+123', '+123', 'zfill', 4) | |
360 | self.checkequal('+0123', '+123', 'zfill', 5) | |
361 | self.checkequal('-123', '-123', 'zfill', 3) | |
362 | self.checkequal('-123', '-123', 'zfill', 4) | |
363 | self.checkequal('-0123', '-123', 'zfill', 5) | |
364 | self.checkequal('000', '', 'zfill', 3) | |
365 | self.checkequal('34', '34', 'zfill', 1) | |
366 | self.checkequal('0034', '34', 'zfill', 4) | |
367 | ||
368 | self.checkraises(TypeError, '123', 'zfill') | |
369 | ||
370 | class MixinStrUnicodeUserStringTest: | |
371 | # additional tests that only work for | |
372 | # stringlike objects, i.e. str, unicode, UserString | |
373 | # (but not the string module) | |
374 | ||
375 | def test_islower(self): | |
376 | self.checkequal(False, '', 'islower') | |
377 | self.checkequal(True, 'a', 'islower') | |
378 | self.checkequal(False, 'A', 'islower') | |
379 | self.checkequal(False, '\n', 'islower') | |
380 | self.checkequal(True, 'abc', 'islower') | |
381 | self.checkequal(False, 'aBc', 'islower') | |
382 | self.checkequal(True, 'abc\n', 'islower') | |
383 | self.checkraises(TypeError, 'abc', 'islower', 42) | |
384 | ||
385 | def test_isupper(self): | |
386 | self.checkequal(False, '', 'isupper') | |
387 | self.checkequal(False, 'a', 'isupper') | |
388 | self.checkequal(True, 'A', 'isupper') | |
389 | self.checkequal(False, '\n', 'isupper') | |
390 | self.checkequal(True, 'ABC', 'isupper') | |
391 | self.checkequal(False, 'AbC', 'isupper') | |
392 | self.checkequal(True, 'ABC\n', 'isupper') | |
393 | self.checkraises(TypeError, 'abc', 'isupper', 42) | |
394 | ||
395 | def test_istitle(self): | |
396 | self.checkequal(False, '', 'istitle') | |
397 | self.checkequal(False, 'a', 'istitle') | |
398 | self.checkequal(True, 'A', 'istitle') | |
399 | self.checkequal(False, '\n', 'istitle') | |
400 | self.checkequal(True, 'A Titlecased Line', 'istitle') | |
401 | self.checkequal(True, 'A\nTitlecased Line', 'istitle') | |
402 | self.checkequal(True, 'A Titlecased, Line', 'istitle') | |
403 | self.checkequal(False, 'Not a capitalized String', 'istitle') | |
404 | self.checkequal(False, 'Not\ta Titlecase String', 'istitle') | |
405 | self.checkequal(False, 'Not--a Titlecase String', 'istitle') | |
406 | self.checkequal(False, 'NOT', 'istitle') | |
407 | self.checkraises(TypeError, 'abc', 'istitle', 42) | |
408 | ||
409 | def test_isspace(self): | |
410 | self.checkequal(False, '', 'isspace') | |
411 | self.checkequal(False, 'a', 'isspace') | |
412 | self.checkequal(True, ' ', 'isspace') | |
413 | self.checkequal(True, '\t', 'isspace') | |
414 | self.checkequal(True, '\r', 'isspace') | |
415 | self.checkequal(True, '\n', 'isspace') | |
416 | self.checkequal(True, ' \t\r\n', 'isspace') | |
417 | self.checkequal(False, ' \t\r\na', 'isspace') | |
418 | self.checkraises(TypeError, 'abc', 'isspace', 42) | |
419 | ||
420 | def test_isalpha(self): | |
421 | self.checkequal(False, '', 'isalpha') | |
422 | self.checkequal(True, 'a', 'isalpha') | |
423 | self.checkequal(True, 'A', 'isalpha') | |
424 | self.checkequal(False, '\n', 'isalpha') | |
425 | self.checkequal(True, 'abc', 'isalpha') | |
426 | self.checkequal(False, 'aBc123', 'isalpha') | |
427 | self.checkequal(False, 'abc\n', 'isalpha') | |
428 | self.checkraises(TypeError, 'abc', 'isalpha', 42) | |
429 | ||
430 | def test_isalnum(self): | |
431 | self.checkequal(False, '', 'isalnum') | |
432 | self.checkequal(True, 'a', 'isalnum') | |
433 | self.checkequal(True, 'A', 'isalnum') | |
434 | self.checkequal(False, '\n', 'isalnum') | |
435 | self.checkequal(True, '123abc456', 'isalnum') | |
436 | self.checkequal(True, 'a1b3c', 'isalnum') | |
437 | self.checkequal(False, 'aBc000 ', 'isalnum') | |
438 | self.checkequal(False, 'abc\n', 'isalnum') | |
439 | self.checkraises(TypeError, 'abc', 'isalnum', 42) | |
440 | ||
441 | def test_isdigit(self): | |
442 | self.checkequal(False, '', 'isdigit') | |
443 | self.checkequal(False, 'a', 'isdigit') | |
444 | self.checkequal(True, '0', 'isdigit') | |
445 | self.checkequal(True, '0123456789', 'isdigit') | |
446 | self.checkequal(False, '0123456789a', 'isdigit') | |
447 | ||
448 | self.checkraises(TypeError, 'abc', 'isdigit', 42) | |
449 | ||
450 | def test_title(self): | |
451 | self.checkequal(' Hello ', ' hello ', 'title') | |
452 | self.checkequal('Hello ', 'hello ', 'title') | |
453 | self.checkequal('Hello ', 'Hello ', 'title') | |
454 | self.checkequal('Format This As Title String', "fOrMaT thIs aS titLe String", 'title') | |
455 | self.checkequal('Format,This-As*Title;String', "fOrMaT,thIs-aS*titLe;String", 'title', ) | |
456 | self.checkequal('Getint', "getInt", 'title') | |
457 | self.checkraises(TypeError, 'hello', 'title', 42) | |
458 | ||
459 | def test_splitlines(self): | |
460 | self.checkequal(['abc', 'def', '', 'ghi'], "abc\ndef\n\rghi", 'splitlines') | |
461 | self.checkequal(['abc', 'def', '', 'ghi'], "abc\ndef\n\r\nghi", 'splitlines') | |
462 | self.checkequal(['abc', 'def', 'ghi'], "abc\ndef\r\nghi", 'splitlines') | |
463 | self.checkequal(['abc', 'def', 'ghi'], "abc\ndef\r\nghi\n", 'splitlines') | |
464 | self.checkequal(['abc', 'def', 'ghi', ''], "abc\ndef\r\nghi\n\r", 'splitlines') | |
465 | self.checkequal(['', 'abc', 'def', 'ghi', ''], "\nabc\ndef\r\nghi\n\r", 'splitlines') | |
466 | self.checkequal(['\n', 'abc\n', 'def\r\n', 'ghi\n', '\r'], "\nabc\ndef\r\nghi\n\r", 'splitlines', 1) | |
467 | ||
468 | self.checkraises(TypeError, 'abc', 'splitlines', 42, 42) | |
469 | ||
470 | def test_startswith(self): | |
471 | self.checkequal(True, 'hello', 'startswith', 'he') | |
472 | self.checkequal(True, 'hello', 'startswith', 'hello') | |
473 | self.checkequal(False, 'hello', 'startswith', 'hello world') | |
474 | self.checkequal(True, 'hello', 'startswith', '') | |
475 | self.checkequal(False, 'hello', 'startswith', 'ello') | |
476 | self.checkequal(True, 'hello', 'startswith', 'ello', 1) | |
477 | self.checkequal(True, 'hello', 'startswith', 'o', 4) | |
478 | self.checkequal(False, 'hello', 'startswith', 'o', 5) | |
479 | self.checkequal(True, 'hello', 'startswith', '', 5) | |
480 | self.checkequal(False, 'hello', 'startswith', 'lo', 6) | |
481 | self.checkequal(True, 'helloworld', 'startswith', 'lowo', 3) | |
482 | self.checkequal(True, 'helloworld', 'startswith', 'lowo', 3, 7) | |
483 | self.checkequal(False, 'helloworld', 'startswith', 'lowo', 3, 6) | |
484 | ||
485 | # test negative indices | |
486 | self.checkequal(True, 'hello', 'startswith', 'he', 0, -1) | |
487 | self.checkequal(True, 'hello', 'startswith', 'he', -53, -1) | |
488 | self.checkequal(False, 'hello', 'startswith', 'hello', 0, -1) | |
489 | self.checkequal(False, 'hello', 'startswith', 'hello world', -1, -10) | |
490 | self.checkequal(False, 'hello', 'startswith', 'ello', -5) | |
491 | self.checkequal(True, 'hello', 'startswith', 'ello', -4) | |
492 | self.checkequal(False, 'hello', 'startswith', 'o', -2) | |
493 | self.checkequal(True, 'hello', 'startswith', 'o', -1) | |
494 | self.checkequal(True, 'hello', 'startswith', '', -3, -3) | |
495 | self.checkequal(False, 'hello', 'startswith', 'lo', -9) | |
496 | ||
497 | self.checkraises(TypeError, 'hello', 'startswith') | |
498 | self.checkraises(TypeError, 'hello', 'startswith', 42) | |
499 | ||
500 | def test_endswith(self): | |
501 | self.checkequal(True, 'hello', 'endswith', 'lo') | |
502 | self.checkequal(False, 'hello', 'endswith', 'he') | |
503 | self.checkequal(True, 'hello', 'endswith', '') | |
504 | self.checkequal(False, 'hello', 'endswith', 'hello world') | |
505 | self.checkequal(False, 'helloworld', 'endswith', 'worl') | |
506 | self.checkequal(True, 'helloworld', 'endswith', 'worl', 3, 9) | |
507 | self.checkequal(True, 'helloworld', 'endswith', 'world', 3, 12) | |
508 | self.checkequal(True, 'helloworld', 'endswith', 'lowo', 1, 7) | |
509 | self.checkequal(True, 'helloworld', 'endswith', 'lowo', 2, 7) | |
510 | self.checkequal(True, 'helloworld', 'endswith', 'lowo', 3, 7) | |
511 | self.checkequal(False, 'helloworld', 'endswith', 'lowo', 4, 7) | |
512 | self.checkequal(False, 'helloworld', 'endswith', 'lowo', 3, 8) | |
513 | self.checkequal(False, 'ab', 'endswith', 'ab', 0, 1) | |
514 | self.checkequal(False, 'ab', 'endswith', 'ab', 0, 0) | |
515 | ||
516 | # test negative indices | |
517 | self.checkequal(True, 'hello', 'endswith', 'lo', -2) | |
518 | self.checkequal(False, 'hello', 'endswith', 'he', -2) | |
519 | self.checkequal(True, 'hello', 'endswith', '', -3, -3) | |
520 | self.checkequal(False, 'hello', 'endswith', 'hello world', -10, -2) | |
521 | self.checkequal(False, 'helloworld', 'endswith', 'worl', -6) | |
522 | self.checkequal(True, 'helloworld', 'endswith', 'worl', -5, -1) | |
523 | self.checkequal(True, 'helloworld', 'endswith', 'worl', -5, 9) | |
524 | self.checkequal(True, 'helloworld', 'endswith', 'world', -7, 12) | |
525 | self.checkequal(True, 'helloworld', 'endswith', 'lowo', -99, -3) | |
526 | self.checkequal(True, 'helloworld', 'endswith', 'lowo', -8, -3) | |
527 | self.checkequal(True, 'helloworld', 'endswith', 'lowo', -7, -3) | |
528 | self.checkequal(False, 'helloworld', 'endswith', 'lowo', 3, -4) | |
529 | self.checkequal(False, 'helloworld', 'endswith', 'lowo', -8, -2) | |
530 | ||
531 | self.checkraises(TypeError, 'hello', 'endswith') | |
532 | self.checkraises(TypeError, 'hello', 'endswith', 42) | |
533 | ||
534 | def test___contains__(self): | |
535 | self.checkequal(True, '', '__contains__', '') # vereq('' in '', True) | |
536 | self.checkequal(True, 'abc', '__contains__', '') # vereq('' in 'abc', True) | |
537 | self.checkequal(False, 'abc', '__contains__', '\0') # vereq('\0' in 'abc', False) | |
538 | self.checkequal(True, '\0abc', '__contains__', '\0') # vereq('\0' in '\0abc', True) | |
539 | self.checkequal(True, 'abc\0', '__contains__', '\0') # vereq('\0' in 'abc\0', True) | |
540 | self.checkequal(True, '\0abc', '__contains__', 'a') # vereq('a' in '\0abc', True) | |
541 | self.checkequal(True, 'asdf', '__contains__', 'asdf') # vereq('asdf' in 'asdf', True) | |
542 | self.checkequal(False, 'asd', '__contains__', 'asdf') # vereq('asdf' in 'asd', False) | |
543 | self.checkequal(False, '', '__contains__', 'asdf') # vereq('asdf' in '', False) | |
544 | ||
545 | def test_subscript(self): | |
546 | self.checkequal(u'a', 'abc', '__getitem__', 0) | |
547 | self.checkequal(u'c', 'abc', '__getitem__', -1) | |
548 | self.checkequal(u'a', 'abc', '__getitem__', 0L) | |
549 | self.checkequal(u'abc', 'abc', '__getitem__', slice(0, 3)) | |
550 | self.checkequal(u'abc', 'abc', '__getitem__', slice(0, 1000)) | |
551 | self.checkequal(u'a', 'abc', '__getitem__', slice(0, 1)) | |
552 | self.checkequal(u'', 'abc', '__getitem__', slice(0, 0)) | |
553 | # FIXME What about negative indizes? This is handled differently by [] and __getitem__(slice) | |
554 | ||
555 | self.checkraises(TypeError, 'abc', '__getitem__', 'def') | |
556 | ||
557 | def test_slice(self): | |
558 | self.checkequal('abc', 'abc', '__getslice__', 0, 1000) | |
559 | self.checkequal('abc', 'abc', '__getslice__', 0, 3) | |
560 | self.checkequal('ab', 'abc', '__getslice__', 0, 2) | |
561 | self.checkequal('bc', 'abc', '__getslice__', 1, 3) | |
562 | self.checkequal('b', 'abc', '__getslice__', 1, 2) | |
563 | self.checkequal('', 'abc', '__getslice__', 2, 2) | |
564 | self.checkequal('', 'abc', '__getslice__', 1000, 1000) | |
565 | self.checkequal('', 'abc', '__getslice__', 2000, 1000) | |
566 | self.checkequal('', 'abc', '__getslice__', 2, 1) | |
567 | # FIXME What about negative indizes? This is handled differently by [] and __getslice__ | |
568 | ||
569 | self.checkraises(TypeError, 'abc', '__getslice__', 'def') | |
570 | ||
571 | def test_mul(self): | |
572 | self.checkequal('', 'abc', '__mul__', -1) | |
573 | self.checkequal('', 'abc', '__mul__', 0) | |
574 | self.checkequal('abc', 'abc', '__mul__', 1) | |
575 | self.checkequal('abcabcabc', 'abc', '__mul__', 3) | |
576 | self.checkraises(TypeError, 'abc', '__mul__') | |
577 | self.checkraises(TypeError, 'abc', '__mul__', '') | |
578 | self.checkraises(OverflowError, 10000*'abc', '__mul__', 2000000000) | |
579 | ||
580 | def test_join(self): | |
581 | # join now works with any sequence type | |
582 | # moved here, because the argument order is | |
583 | # different in string.join (see the test in | |
584 | # test.test_string.StringTest.test_join) | |
585 | self.checkequal('a b c d', ' ', 'join', ['a', 'b', 'c', 'd']) | |
586 | self.checkequal('abcd', '', 'join', ('a', 'b', 'c', 'd')) | |
587 | self.checkequal('w x y z', ' ', 'join', Sequence()) | |
588 | self.checkequal('abc', 'a', 'join', ('abc',)) | |
589 | self.checkequal('z', 'a', 'join', UserList(['z'])) | |
590 | if test_support.have_unicode: | |
591 | self.checkequal(unicode('a.b.c'), unicode('.'), 'join', ['a', 'b', 'c']) | |
592 | self.checkequal(unicode('a.b.c'), '.', 'join', [unicode('a'), 'b', 'c']) | |
593 | self.checkequal(unicode('a.b.c'), '.', 'join', ['a', unicode('b'), 'c']) | |
594 | self.checkequal(unicode('a.b.c'), '.', 'join', ['a', 'b', unicode('c')]) | |
595 | self.checkraises(TypeError, '.', 'join', ['a', unicode('b'), 3]) | |
596 | for i in [5, 25, 125]: | |
597 | self.checkequal(((('a' * i) + '-') * i)[:-1], '-', 'join', | |
598 | ['a' * i] * i) | |
599 | self.checkequal(((('a' * i) + '-') * i)[:-1], '-', 'join', | |
600 | ('a' * i,) * i) | |
601 | ||
602 | self.checkraises(TypeError, ' ', 'join', BadSeq1()) | |
603 | self.checkequal('a b c', ' ', 'join', BadSeq2()) | |
604 | ||
605 | self.checkraises(TypeError, ' ', 'join') | |
606 | self.checkraises(TypeError, ' ', 'join', 7) | |
607 | self.checkraises(TypeError, ' ', 'join', Sequence([7, 'hello', 123L])) | |
608 | ||
609 | def test_formatting(self): | |
610 | self.checkequal('+hello+', '+%s+', '__mod__', 'hello') | |
611 | self.checkequal('+10+', '+%d+', '__mod__', 10) | |
612 | self.checkequal('a', "%c", '__mod__', "a") | |
613 | self.checkequal('a', "%c", '__mod__', "a") | |
614 | self.checkequal('"', "%c", '__mod__', 34) | |
615 | self.checkequal('$', "%c", '__mod__', 36) | |
616 | self.checkequal('10', "%d", '__mod__', 10) | |
617 | self.checkequal('\x7f', "%c", '__mod__', 0x7f) | |
618 | ||
619 | for ordinal in (-100, 0x200000): | |
620 | # unicode raises ValueError, str raises OverflowError | |
621 | self.checkraises((ValueError, OverflowError), '%c', '__mod__', ordinal) | |
622 | ||
623 | self.checkequal(' 42', '%3ld', '__mod__', 42) | |
624 | self.checkequal('0042.00', '%07.2f', '__mod__', 42) | |
625 | self.checkequal('0042.00', '%07.2F', '__mod__', 42) | |
626 | ||
627 | self.checkraises(TypeError, 'abc', '__mod__') | |
628 | self.checkraises(TypeError, '%(foo)s', '__mod__', 42) | |
629 | self.checkraises(TypeError, '%s%s', '__mod__', (42,)) | |
630 | self.checkraises(TypeError, '%c', '__mod__', (None,)) | |
631 | self.checkraises(ValueError, '%(foo', '__mod__', {}) | |
632 | self.checkraises(TypeError, '%(foo)s %(bar)s', '__mod__', ('foo', 42)) | |
633 | ||
634 | # argument names with properly nested brackets are supported | |
635 | self.checkequal('bar', '%((foo))s', '__mod__', {'(foo)': 'bar'}) | |
636 | ||
637 | # 100 is a magic number in PyUnicode_Format, this forces a resize | |
638 | self.checkequal(103*'a'+'x', '%sx', '__mod__', 103*'a') | |
639 | ||
640 | self.checkraises(TypeError, '%*s', '__mod__', ('foo', 'bar')) | |
641 | self.checkraises(TypeError, '%10.*f', '__mod__', ('foo', 42.)) | |
642 | self.checkraises(ValueError, '%10', '__mod__', (42,)) | |
643 | ||
644 | def test_floatformatting(self): | |
645 | # float formatting | |
646 | for prec in xrange(100): | |
647 | format = '%%.%if' % prec | |
648 | value = 0.01 | |
649 | for x in xrange(60): | |
650 | value = value * 3.141592655 / 3.0 * 10.0 | |
651 | # The formatfloat() code in stringobject.c and | |
652 | # unicodeobject.c uses a 120 byte buffer and switches from | |
653 | # 'f' formatting to 'g' at precision 50, so we expect | |
654 | # OverflowErrors for the ranges x < 50 and prec >= 67. | |
655 | if x < 50 and prec >= 67: | |
656 | self.checkraises(OverflowError, format, "__mod__", value) | |
657 | else: | |
658 | self.checkcall(format, "__mod__", value) | |
659 | ||
660 | ||
661 | class MixinStrStringUserStringTest: | |
662 | # Additional tests for 8bit strings, i.e. str, UserString and | |
663 | # the string module | |
664 | ||
665 | def test_maketrans(self): | |
666 | self.assertEqual( | |
667 | ''.join(map(chr, xrange(256))).replace('abc', 'xyz'), | |
668 | string.maketrans('abc', 'xyz') | |
669 | ) | |
670 | self.assertRaises(ValueError, string.maketrans, 'abc', 'xyzw') | |
671 | ||
672 | def test_translate(self): | |
673 | table = string.maketrans('abc', 'xyz') | |
674 | self.checkequal('xyzxyz', 'xyzabcdef', 'translate', table, 'def') | |
675 | ||
676 | table = string.maketrans('a', 'A') | |
677 | self.checkequal('Abc', 'abc', 'translate', table) | |
678 | self.checkequal('xyz', 'xyz', 'translate', table) | |
679 | self.checkequal('yz', 'xyz', 'translate', table, 'x') | |
680 | self.checkraises(ValueError, 'xyz', 'translate', 'too short', 'strip') | |
681 | self.checkraises(ValueError, 'xyz', 'translate', 'too short') | |
682 | ||
683 | ||
684 | class MixinStrUserStringTest: | |
685 | # Additional tests that only work with | |
686 | # 8bit compatible object, i.e. str and UserString | |
687 | ||
688 | def test_encoding_decoding(self): | |
689 | codecs = [('rot13', 'uryyb jbeyq'), | |
690 | ('base64', 'aGVsbG8gd29ybGQ=\n'), | |
691 | ('hex', '68656c6c6f20776f726c64'), | |
692 | ('uu', 'begin 666 <data>\n+:&5L;&\\@=V]R;&0 \n \nend\n')] | |
693 | for encoding, data in codecs: | |
694 | self.checkequal(data, 'hello world', 'encode', encoding) | |
695 | self.checkequal('hello world', data, 'decode', encoding) | |
696 | # zlib is optional, so we make the test optional too... | |
697 | try: | |
698 | import zlib | |
699 | except ImportError: | |
700 | pass | |
701 | else: | |
702 | data = 'x\x9c\xcbH\xcd\xc9\xc9W(\xcf/\xcaI\x01\x00\x1a\x0b\x04]' | |
703 | self.checkequal(data, 'hello world', 'encode', 'zlib') | |
704 | self.checkequal('hello world', data, 'decode', 'zlib') | |
705 | ||
706 | self.checkraises(TypeError, 'xyz', 'decode', 42) | |
707 | self.checkraises(TypeError, 'xyz', 'encode', 42) | |
708 | ||
709 | ||
710 | class MixinStrUnicodeTest: | |
711 | # Additional tests that only work with str and unicode. | |
712 | ||
713 | def test_bug1001011(self): | |
714 | # Make sure join returns a NEW object for single item sequences | |
715 | # involving a subclass. | |
716 | # Make sure that it is of the appropriate type. | |
717 | # Check the optimisation still occurs for standard objects. | |
718 | t = self.type2test | |
719 | class subclass(t): | |
720 | pass | |
721 | s1 = subclass("abcd") | |
722 | s2 = t().join([s1]) | |
723 | self.assert_(s1 is not s2) | |
724 | self.assert_(type(s2) is t) | |
725 | ||
726 | s1 = t("abcd") | |
727 | s2 = t().join([s1]) | |
728 | self.assert_(s1 is s2) | |
729 | ||
730 | # Should also test mixed-type join. | |
731 | if t is unicode: | |
732 | s1 = subclass("abcd") | |
733 | s2 = "".join([s1]) | |
734 | self.assert_(s1 is not s2) | |
735 | self.assert_(type(s2) is t) | |
736 | ||
737 | s1 = t("abcd") | |
738 | s2 = "".join([s1]) | |
739 | self.assert_(s1 is s2) | |
740 | ||
741 | elif t is str: | |
742 | s1 = subclass("abcd") | |
743 | s2 = u"".join([s1]) | |
744 | self.assert_(s1 is not s2) | |
745 | self.assert_(type(s2) is unicode) # promotes! | |
746 | ||
747 | s1 = t("abcd") | |
748 | s2 = u"".join([s1]) | |
749 | self.assert_(s1 is not s2) | |
750 | self.assert_(type(s2) is unicode) # promotes! | |
751 | ||
752 | else: | |
753 | self.fail("unexpected type for MixinStrUnicodeTest %r" % t) |