blob: c86f5cfae8d49ed2b60a592dcd6249ebe60bdcdc [file] [log] [blame]
Greg Ward3dc94e12002-08-22 18:37:50 +00001#
Greg Ward61864102004-06-03 01:59:41 +00002# Test suite for the textwrap module.
Greg Ward3dc94e12002-08-22 18:37:50 +00003#
4# Original tests written by Greg Ward <gward@python.net>.
5# Converted to PyUnit by Peter Hansen <peter@engcorp.com>.
6# Currently maintained by Greg Ward.
7#
8# $Id$
9#
10
Greg Ward90c0b072002-08-22 18:11:10 +000011import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000012from test import support
Greg Ward90c0b072002-08-22 18:11:10 +000013
Nick Coghlan4fae8cd2012-06-11 23:07:51 +100014from textwrap import TextWrapper, wrap, fill, dedent, indent
Greg Ward90c0b072002-08-22 18:11:10 +000015
16
Greg Ward13c53c62002-08-22 18:57:26 +000017class BaseTestCase(unittest.TestCase):
Greg Ward90c0b072002-08-22 18:11:10 +000018 '''Parent class with utility methods for textwrap tests.'''
19
20 def show(self, textin):
21 if isinstance(textin, list):
22 result = []
23 for i in range(len(textin)):
24 result.append(" %d: %r" % (i, textin[i]))
R David Murray1585b702012-09-08 13:13:25 -040025 result = "\n".join(result) if result else " no lines"
Guido van Rossum3172c5d2007-10-16 18:12:55 +000026 elif isinstance(textin, str):
Greg Ward90c0b072002-08-22 18:11:10 +000027 result = " %s\n" % repr(textin)
28 return result
29
30
31 def check(self, result, expect):
Ezio Melottib3aedd42010-11-20 19:04:17 +000032 self.assertEqual(result, expect,
Greg Ward9ad15a32002-08-22 19:47:27 +000033 'expected:\n%s\nbut got:\n%s' % (
34 self.show(expect), self.show(result)))
Greg Ward90c0b072002-08-22 18:11:10 +000035
Guido van Rossumeb287a22002-10-02 15:47:32 +000036 def check_wrap(self, text, width, expect, **kwargs):
37 result = wrap(text, width, **kwargs)
Greg Wardee413842002-08-22 18:55:38 +000038 self.check(result, expect)
39
Greg Wardd1a72a02002-10-31 16:11:18 +000040 def check_split(self, text, expect):
41 result = self.wrapper._split(text)
Ezio Melottib3aedd42010-11-20 19:04:17 +000042 self.assertEqual(result, expect,
43 "\nexpected %r\n"
44 "but got %r" % (expect, result))
Greg Ward715debd2002-08-22 21:16:25 +000045
Greg Ward90c0b072002-08-22 18:11:10 +000046
Greg Ward13c53c62002-08-22 18:57:26 +000047class WrapTestCase(BaseTestCase):
Greg Ward90c0b072002-08-22 18:11:10 +000048
Greg Ward90c0b072002-08-22 18:11:10 +000049 def setUp(self):
Greg Wardf0ba7642004-05-13 01:53:10 +000050 self.wrapper = TextWrapper(width=45)
Greg Ward90c0b072002-08-22 18:11:10 +000051
Greg Wardf6765782002-08-22 18:35:49 +000052 def test_simple(self):
Guido van Rossum327af772002-08-22 20:13:47 +000053 # Simple case: just words, spaces, and a bit of punctuation
Greg Ward90c0b072002-08-22 18:11:10 +000054
Greg Wardee413842002-08-22 18:55:38 +000055 text = "Hello there, how are you this fine day? I'm glad to hear it!"
Greg Ward90c0b072002-08-22 18:11:10 +000056
Greg Wardee413842002-08-22 18:55:38 +000057 self.check_wrap(text, 12,
58 ["Hello there,",
59 "how are you",
60 "this fine",
61 "day? I'm",
62 "glad to hear",
63 "it!"])
64 self.check_wrap(text, 42,
65 ["Hello there, how are you this fine day?",
66 "I'm glad to hear it!"])
67 self.check_wrap(text, 80, [text])
Greg Ward90c0b072002-08-22 18:11:10 +000068
R David Murray1585b702012-09-08 13:13:25 -040069 def test_empty_string(self):
70 # Check that wrapping the empty string returns an empty list.
71 self.check_wrap("", 6, [])
72 self.check_wrap("", 6, [], drop_whitespace=False)
73
74 def test_empty_string_with_initial_indent(self):
75 # Check that the empty string is not indented.
76 self.check_wrap("", 6, [], initial_indent="++")
77 self.check_wrap("", 6, [], initial_indent="++", drop_whitespace=False)
Greg Ward90c0b072002-08-22 18:11:10 +000078
Greg Wardf6765782002-08-22 18:35:49 +000079 def test_whitespace(self):
Guido van Rossum327af772002-08-22 20:13:47 +000080 # Whitespace munging and end-of-sentence detection
Greg Ward90c0b072002-08-22 18:11:10 +000081
Greg Wardee413842002-08-22 18:55:38 +000082 text = """\
Greg Ward90c0b072002-08-22 18:11:10 +000083This is a paragraph that already has
84line breaks. But some of its lines are much longer than the others,
85so it needs to be wrapped.
86Some lines are \ttabbed too.
87What a mess!
88"""
89
Greg Wardee413842002-08-22 18:55:38 +000090 expect = ["This is a paragraph that already has line",
91 "breaks. But some of its lines are much",
92 "longer than the others, so it needs to be",
93 "wrapped. Some lines are tabbed too. What a",
94 "mess!"]
Greg Ward90c0b072002-08-22 18:11:10 +000095
Greg Wardf0ba7642004-05-13 01:53:10 +000096 wrapper = TextWrapper(45, fix_sentence_endings=True)
97 result = wrapper.wrap(text)
Greg Ward90c0b072002-08-22 18:11:10 +000098 self.check(result, expect)
99
Greg Wardf0ba7642004-05-13 01:53:10 +0000100 result = wrapper.fill(text)
Greg Ward90c0b072002-08-22 18:11:10 +0000101 self.check(result, '\n'.join(expect))
102
Hynek Schlawackd5272592012-05-19 13:33:11 +0200103 text = "\tTest\tdefault\t\ttabsize."
104 expect = [" Test default tabsize."]
105 self.check_wrap(text, 80, expect)
106
107 text = "\tTest\tcustom\t\ttabsize."
108 expect = [" Test custom tabsize."]
109 self.check_wrap(text, 80, expect, tabsize=4)
110
Greg Wardf0ba7642004-05-13 01:53:10 +0000111 def test_fix_sentence_endings(self):
112 wrapper = TextWrapper(60, fix_sentence_endings=True)
Greg Ward90c0b072002-08-22 18:11:10 +0000113
Greg Wardf0ba7642004-05-13 01:53:10 +0000114 # SF #847346: ensure that fix_sentence_endings=True does the
115 # right thing even on input short enough that it doesn't need to
116 # be wrapped.
117 text = "A short line. Note the single space."
118 expect = ["A short line. Note the single space."]
119 self.check(wrapper.wrap(text), expect)
120
121 # Test some of the hairy end cases that _fix_sentence_endings()
122 # is supposed to handle (the easy stuff is tested in
123 # test_whitespace() above).
124 text = "Well, Doctor? What do you think?"
125 expect = ["Well, Doctor? What do you think?"]
126 self.check(wrapper.wrap(text), expect)
127
128 text = "Well, Doctor?\nWhat do you think?"
129 self.check(wrapper.wrap(text), expect)
130
131 text = 'I say, chaps! Anyone for "tennis?"\nHmmph!'
132 expect = ['I say, chaps! Anyone for "tennis?" Hmmph!']
133 self.check(wrapper.wrap(text), expect)
134
135 wrapper.width = 20
136 expect = ['I say, chaps!', 'Anyone for "tennis?"', 'Hmmph!']
137 self.check(wrapper.wrap(text), expect)
138
139 text = 'And she said, "Go to hell!"\nCan you believe that?'
140 expect = ['And she said, "Go to',
141 'hell!" Can you',
142 'believe that?']
143 self.check(wrapper.wrap(text), expect)
144
145 wrapper.width = 60
146 expect = ['And she said, "Go to hell!" Can you believe that?']
147 self.check(wrapper.wrap(text), expect)
Tim Peters27f88362004-07-08 04:22:35 +0000148
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000149 text = 'File stdio.h is nice.'
150 expect = ['File stdio.h is nice.']
151 self.check(wrapper.wrap(text), expect)
152
Greg Wardf6765782002-08-22 18:35:49 +0000153 def test_wrap_short(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000154 # Wrapping to make short lines longer
Greg Ward90c0b072002-08-22 18:11:10 +0000155
Greg Wardee413842002-08-22 18:55:38 +0000156 text = "This is a\nshort paragraph."
Greg Ward90c0b072002-08-22 18:11:10 +0000157
Greg Wardee413842002-08-22 18:55:38 +0000158 self.check_wrap(text, 20, ["This is a short",
159 "paragraph."])
160 self.check_wrap(text, 40, ["This is a short paragraph."])
Greg Ward90c0b072002-08-22 18:11:10 +0000161
162
Guido van Rossumeb287a22002-10-02 15:47:32 +0000163 def test_wrap_short_1line(self):
164 # Test endcases
165
166 text = "This is a short line."
167
168 self.check_wrap(text, 30, ["This is a short line."])
169 self.check_wrap(text, 30, ["(1) This is a short line."],
170 initial_indent="(1) ")
171
172
Greg Wardf6765782002-08-22 18:35:49 +0000173 def test_hyphenated(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000174 # Test breaking hyphenated words
Greg Ward90c0b072002-08-22 18:11:10 +0000175
Greg Wardee413842002-08-22 18:55:38 +0000176 text = ("this-is-a-useful-feature-for-"
177 "reformatting-posts-from-tim-peters'ly")
Greg Ward90c0b072002-08-22 18:11:10 +0000178
Greg Wardee413842002-08-22 18:55:38 +0000179 self.check_wrap(text, 40,
180 ["this-is-a-useful-feature-for-",
181 "reformatting-posts-from-tim-peters'ly"])
182 self.check_wrap(text, 41,
183 ["this-is-a-useful-feature-for-",
184 "reformatting-posts-from-tim-peters'ly"])
185 self.check_wrap(text, 42,
186 ["this-is-a-useful-feature-for-reformatting-",
187 "posts-from-tim-peters'ly"])
Greg Ward90c0b072002-08-22 18:11:10 +0000188
Greg Ward40407942005-03-05 02:53:17 +0000189 def test_hyphenated_numbers(self):
190 # Test that hyphenated numbers (eg. dates) are not broken like words.
191 text = ("Python 1.0.0 was released on 1994-01-26. Python 1.0.1 was\n"
192 "released on 1994-02-15.")
193
194 self.check_wrap(text, 30, ['Python 1.0.0 was released on',
195 '1994-01-26. Python 1.0.1 was',
196 'released on 1994-02-15.'])
197 self.check_wrap(text, 40, ['Python 1.0.0 was released on 1994-01-26.',
198 'Python 1.0.1 was released on 1994-02-15.'])
199
200 text = "I do all my shopping at 7-11."
201 self.check_wrap(text, 25, ["I do all my shopping at",
202 "7-11."])
203 self.check_wrap(text, 27, ["I do all my shopping at",
204 "7-11."])
205 self.check_wrap(text, 29, ["I do all my shopping at 7-11."])
206
Greg Ward9ad15a32002-08-22 19:47:27 +0000207 def test_em_dash(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000208 # Test text with em-dashes
Greg Ward9ad15a32002-08-22 19:47:27 +0000209 text = "Em-dashes should be written -- thus."
210 self.check_wrap(text, 25,
211 ["Em-dashes should be",
212 "written -- thus."])
213
214 # Probe the boundaries of the properly written em-dash,
215 # ie. " -- ".
216 self.check_wrap(text, 29,
217 ["Em-dashes should be written",
218 "-- thus."])
219 expect = ["Em-dashes should be written --",
220 "thus."]
221 self.check_wrap(text, 30, expect)
222 self.check_wrap(text, 35, expect)
223 self.check_wrap(text, 36,
224 ["Em-dashes should be written -- thus."])
Guido van Rossum327af772002-08-22 20:13:47 +0000225
Greg Ward9ad15a32002-08-22 19:47:27 +0000226 # The improperly written em-dash is handled too, because
227 # it's adjacent to non-whitespace on both sides.
228 text = "You can also do--this or even---this."
229 expect = ["You can also do",
230 "--this or even",
231 "---this."]
232 self.check_wrap(text, 15, expect)
233 self.check_wrap(text, 16, expect)
234 expect = ["You can also do--",
235 "this or even---",
236 "this."]
237 self.check_wrap(text, 17, expect)
238 self.check_wrap(text, 19, expect)
239 expect = ["You can also do--this or even",
240 "---this."]
241 self.check_wrap(text, 29, expect)
242 self.check_wrap(text, 31, expect)
243 expect = ["You can also do--this or even---",
244 "this."]
245 self.check_wrap(text, 32, expect)
246 self.check_wrap(text, 35, expect)
247
248 # All of the above behaviour could be deduced by probing the
249 # _split() method.
250 text = "Here's an -- em-dash and--here's another---and another!"
Greg Ward9ad15a32002-08-22 19:47:27 +0000251 expect = ["Here's", " ", "an", " ", "--", " ", "em-", "dash", " ",
252 "and", "--", "here's", " ", "another", "---",
253 "and", " ", "another!"]
Greg Wardd1a72a02002-10-31 16:11:18 +0000254 self.check_split(text, expect)
Greg Ward90c0b072002-08-22 18:11:10 +0000255
Greg Wardc6edb372002-08-22 21:27:05 +0000256 text = "and then--bam!--he was gone"
257 expect = ["and", " ", "then", "--", "bam!", "--",
258 "he", " ", "was", " ", "gone"]
Greg Wardd1a72a02002-10-31 16:11:18 +0000259 self.check_split(text, expect)
Greg Wardc6edb372002-08-22 21:27:05 +0000260
261
Greg Ward34f995b2002-08-22 21:10:07 +0000262 def test_unix_options (self):
263 # Test that Unix-style command-line options are wrapped correctly.
264 # Both Optik (OptionParser) and Docutils rely on this behaviour!
265
266 text = "You should use the -n option, or --dry-run in its long form."
267 self.check_wrap(text, 20,
268 ["You should use the",
269 "-n option, or --dry-",
270 "run in its long",
271 "form."])
272 self.check_wrap(text, 21,
273 ["You should use the -n",
274 "option, or --dry-run",
275 "in its long form."])
276 expect = ["You should use the -n option, or",
277 "--dry-run in its long form."]
278 self.check_wrap(text, 32, expect)
279 self.check_wrap(text, 34, expect)
280 self.check_wrap(text, 35, expect)
281 self.check_wrap(text, 38, expect)
282 expect = ["You should use the -n option, or --dry-",
283 "run in its long form."]
284 self.check_wrap(text, 39, expect)
285 self.check_wrap(text, 41, expect)
286 expect = ["You should use the -n option, or --dry-run",
287 "in its long form."]
288 self.check_wrap(text, 42, expect)
289
Greg Ward24a1c9c2002-08-22 21:12:54 +0000290 # Again, all of the above can be deduced from _split().
291 text = "the -n option, or --dry-run or --dryrun"
Greg Ward24a1c9c2002-08-22 21:12:54 +0000292 expect = ["the", " ", "-n", " ", "option,", " ", "or", " ",
293 "--dry-", "run", " ", "or", " ", "--dryrun"]
Greg Wardd1a72a02002-10-31 16:11:18 +0000294 self.check_split(text, expect)
295
296 def test_funky_hyphens (self):
297 # Screwy edge cases cooked up by David Goodger. All reported
298 # in SF bug #596434.
299 self.check_split("what the--hey!", ["what", " ", "the", "--", "hey!"])
300 self.check_split("what the--", ["what", " ", "the--"])
301 self.check_split("what the--.", ["what", " ", "the--."])
302 self.check_split("--text--.", ["--text--."])
303
Greg Wardcc55cb92003-05-07 01:19:22 +0000304 # When I first read bug #596434, this is what I thought David
305 # was talking about. I was wrong; these have always worked
306 # fine. The real problem is tested in test_funky_parens()
307 # below...
Greg Wardd1a72a02002-10-31 16:11:18 +0000308 self.check_split("--option", ["--option"])
309 self.check_split("--option-opt", ["--option-", "opt"])
Greg Wardcc55cb92003-05-07 01:19:22 +0000310 self.check_split("foo --option-opt bar",
311 ["foo", " ", "--option-", "opt", " ", "bar"])
312
Greg Ward61864102004-06-03 01:59:41 +0000313 def test_punct_hyphens(self):
314 # Oh bother, SF #965425 found another problem with hyphens --
315 # hyphenated words in single quotes weren't handled correctly.
316 # In fact, the bug is that *any* punctuation around a hyphenated
317 # word was handled incorrectly, except for a leading "--", which
318 # was special-cased for Optik and Docutils. So test a variety
319 # of styles of punctuation around a hyphenated word.
320 # (Actually this is based on an Optik bug report, #813077).
321 self.check_split("the 'wibble-wobble' widget",
322 ['the', ' ', "'wibble-", "wobble'", ' ', 'widget'])
323 self.check_split('the "wibble-wobble" widget',
324 ['the', ' ', '"wibble-', 'wobble"', ' ', 'widget'])
325 self.check_split("the (wibble-wobble) widget",
326 ['the', ' ', "(wibble-", "wobble)", ' ', 'widget'])
327 self.check_split("the ['wibble-wobble'] widget",
328 ['the', ' ', "['wibble-", "wobble']", ' ', 'widget'])
329
Greg Wardcc55cb92003-05-07 01:19:22 +0000330 def test_funky_parens (self):
331 # Second part of SF bug #596434: long option strings inside
332 # parentheses.
333 self.check_split("foo (--option) bar",
334 ["foo", " ", "(--option)", " ", "bar"])
335
336 # Related stuff -- make sure parens work in simpler contexts.
337 self.check_split("foo (bar) baz",
338 ["foo", " ", "(bar)", " ", "baz"])
339 self.check_split("blah (ding dong), wubba",
340 ["blah", " ", "(ding", " ", "dong),",
341 " ", "wubba"])
Greg Ward24a1c9c2002-08-22 21:12:54 +0000342
R David Murray1585b702012-09-08 13:13:25 -0400343 def test_drop_whitespace_false(self):
344 # Check that drop_whitespace=False preserves whitespace.
345 # SF patch #1581073
346 text = " This is a sentence with much whitespace."
347 self.check_wrap(text, 10,
348 [" This is a", " ", "sentence ",
349 "with ", "much white", "space."],
350 drop_whitespace=False)
351
352 def test_drop_whitespace_false_whitespace_only(self):
353 # Check that drop_whitespace=False preserves a whitespace-only string.
354 self.check_wrap(" ", 6, [" "], drop_whitespace=False)
355
356 def test_drop_whitespace_false_whitespace_only_with_indent(self):
357 # Check that a whitespace-only string gets indented (when
358 # drop_whitespace is False).
359 self.check_wrap(" ", 6, [" "], drop_whitespace=False,
360 initial_indent=" ")
361
362 def test_drop_whitespace_whitespace_only(self):
363 # Check drop_whitespace on a whitespace-only string.
364 self.check_wrap(" ", 6, [])
365
366 def test_drop_whitespace_leading_whitespace(self):
367 # Check that drop_whitespace does not drop leading whitespace (if
368 # followed by non-whitespace).
Greg Ward24cbbcb2002-12-09 16:27:15 +0000369 # SF bug #622849 reported inconsistent handling of leading
370 # whitespace; let's test that a bit, shall we?
371 text = " This is a sentence with leading whitespace."
372 self.check_wrap(text, 50,
373 [" This is a sentence with leading whitespace."])
374 self.check_wrap(text, 30,
375 [" This is a sentence with", "leading whitespace."])
376
R David Murray1585b702012-09-08 13:13:25 -0400377 def test_drop_whitespace_whitespace_line(self):
378 # Check that drop_whitespace skips the whole line if a non-leading
379 # line consists only of whitespace.
380 text = "abcd efgh"
381 # Include the result for drop_whitespace=False for comparison.
382 self.check_wrap(text, 6, ["abcd", " ", "efgh"],
Guido van Rossumd8faa362007-04-27 19:54:29 +0000383 drop_whitespace=False)
R David Murray1585b702012-09-08 13:13:25 -0400384 self.check_wrap(text, 6, ["abcd", "efgh"])
385
386 def test_drop_whitespace_whitespace_only_with_indent(self):
387 # Check that initial_indent is not applied to a whitespace-only
388 # string. This checks a special case of the fact that dropping
389 # whitespace occurs before indenting.
390 self.check_wrap(" ", 6, [], initial_indent="++")
391
392 def test_drop_whitespace_whitespace_indent(self):
393 # Check that drop_whitespace does not drop whitespace indents.
394 # This checks a special case of the fact that dropping whitespace
395 # occurs before indenting.
396 self.check_wrap("abcd efgh", 6, [" abcd", " efgh"],
397 initial_indent=" ", subsequent_indent=" ")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000398
Greg Ward90c0b072002-08-22 18:11:10 +0000399 def test_split(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000400 # Ensure that the standard _split() method works as advertised
401 # in the comments
Greg Ward90c0b072002-08-22 18:11:10 +0000402
Greg Wardee413842002-08-22 18:55:38 +0000403 text = "Hello there -- you goof-ball, use the -b option!"
Greg Ward90c0b072002-08-22 18:11:10 +0000404
Greg Wardee413842002-08-22 18:55:38 +0000405 result = self.wrapper._split(text)
Greg Ward90c0b072002-08-22 18:11:10 +0000406 self.check(result,
407 ["Hello", " ", "there", " ", "--", " ", "you", " ", "goof-",
408 "ball,", " ", "use", " ", "the", " ", "-b", " ", "option!"])
409
Alexandre Vassalotti5f8ced22008-05-16 00:03:33 +0000410 def test_break_on_hyphens(self):
411 # Ensure that the break_on_hyphens attributes work
412 text = "yaba daba-doo"
413 self.check_wrap(text, 10, ["yaba daba-", "doo"],
414 break_on_hyphens=True)
415 self.check_wrap(text, 10, ["yaba", "daba-doo"],
416 break_on_hyphens=False)
417
Greg Ward49128572003-05-07 00:54:42 +0000418 def test_bad_width(self):
419 # Ensure that width <= 0 is caught.
420 text = "Whatever, it doesn't matter."
421 self.assertRaises(ValueError, wrap, text, 0)
422 self.assertRaises(ValueError, wrap, text, -1)
423
Antoine Pitrou7c59bc62008-12-13 23:20:54 +0000424 def test_no_split_at_umlaut(self):
425 text = "Die Empf\xe4nger-Auswahl"
426 self.check_wrap(text, 13, ["Die", "Empf\xe4nger-", "Auswahl"])
427
428 def test_umlaut_followed_by_dash(self):
429 text = "aa \xe4\xe4-\xe4\xe4"
430 self.check_wrap(text, 7, ["aa \xe4\xe4-", "\xe4\xe4"])
431
Greg Ward90c0b072002-08-22 18:11:10 +0000432
Greg Wardfd030e42002-08-22 19:02:37 +0000433class LongWordTestCase (BaseTestCase):
434 def setUp(self):
435 self.wrapper = TextWrapper()
Greg Ward24cbbcb2002-12-09 16:27:15 +0000436 self.text = '''\
Greg Ward90c0b072002-08-22 18:11:10 +0000437Did you say "supercalifragilisticexpialidocious?"
438How *do* you spell that odd word, anyways?
439'''
Greg Wardfd030e42002-08-22 19:02:37 +0000440
441 def test_break_long(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000442 # Wrap text with long words and lots of punctuation
Greg Wardfd030e42002-08-22 19:02:37 +0000443
444 self.check_wrap(self.text, 30,
Greg Wardee413842002-08-22 18:55:38 +0000445 ['Did you say "supercalifragilis',
446 'ticexpialidocious?" How *do*',
447 'you spell that odd word,',
448 'anyways?'])
Greg Wardfd030e42002-08-22 19:02:37 +0000449 self.check_wrap(self.text, 50,
Greg Wardee413842002-08-22 18:55:38 +0000450 ['Did you say "supercalifragilisticexpialidocious?"',
451 'How *do* you spell that odd word, anyways?'])
Greg Ward90c0b072002-08-22 18:11:10 +0000452
Raymond Hettingerc11dbcd2003-08-30 14:43:55 +0000453 # SF bug 797650. Prevent an infinite loop by making sure that at
454 # least one character gets split off on every pass.
455 self.check_wrap('-'*10+'hello', 10,
456 ['----------',
457 ' h',
458 ' e',
459 ' l',
460 ' l',
461 ' o'],
462 subsequent_indent = ' '*15)
Greg Ward90c0b072002-08-22 18:11:10 +0000463
Georg Brandlfceab5a2008-01-19 20:08:23 +0000464 # bug 1146. Prevent a long word to be wrongly wrapped when the
465 # preceding word is exactly one character shorter than the width
466 self.check_wrap(self.text, 12,
467 ['Did you say ',
468 '"supercalifr',
469 'agilisticexp',
470 'ialidocious?',
471 '" How *do*',
472 'you spell',
473 'that odd',
474 'word,',
475 'anyways?'])
476
Guido van Rossum327af772002-08-22 20:13:47 +0000477 def test_nobreak_long(self):
478 # Test with break_long_words disabled
Greg Ward90c0b072002-08-22 18:11:10 +0000479 self.wrapper.break_long_words = 0
480 self.wrapper.width = 30
Greg Wardee413842002-08-22 18:55:38 +0000481 expect = ['Did you say',
482 '"supercalifragilisticexpialidocious?"',
483 'How *do* you spell that odd',
484 'word, anyways?'
Guido van Rossum327af772002-08-22 20:13:47 +0000485 ]
Greg Wardfd030e42002-08-22 19:02:37 +0000486 result = self.wrapper.wrap(self.text)
Greg Ward90c0b072002-08-22 18:11:10 +0000487 self.check(result, expect)
488
489 # Same thing with kwargs passed to standalone wrap() function.
Greg Wardfd030e42002-08-22 19:02:37 +0000490 result = wrap(self.text, width=30, break_long_words=0)
Greg Ward90c0b072002-08-22 18:11:10 +0000491 self.check(result, expect)
492
493
Greg Ward13c53c62002-08-22 18:57:26 +0000494class IndentTestCases(BaseTestCase):
Greg Ward90c0b072002-08-22 18:11:10 +0000495
496 # called before each test method
497 def setUp(self):
Greg Wardf69d3c92002-08-22 19:06:45 +0000498 self.text = '''\
Greg Ward90c0b072002-08-22 18:11:10 +0000499This paragraph will be filled, first without any indentation,
500and then with some (including a hanging indent).'''
501
502
Greg Wardf6765782002-08-22 18:35:49 +0000503 def test_fill(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000504 # Test the fill() method
Greg Ward90c0b072002-08-22 18:11:10 +0000505
506 expect = '''\
507This paragraph will be filled, first
508without any indentation, and then with
509some (including a hanging indent).'''
510
Greg Wardf69d3c92002-08-22 19:06:45 +0000511 result = fill(self.text, 40)
Greg Ward90c0b072002-08-22 18:11:10 +0000512 self.check(result, expect)
513
514
Greg Wardf6765782002-08-22 18:35:49 +0000515 def test_initial_indent(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000516 # Test initial_indent parameter
Greg Ward90c0b072002-08-22 18:11:10 +0000517
Greg Wardf69d3c92002-08-22 19:06:45 +0000518 expect = [" This paragraph will be filled,",
519 "first without any indentation, and then",
520 "with some (including a hanging indent)."]
521 result = wrap(self.text, 40, initial_indent=" ")
Greg Ward90c0b072002-08-22 18:11:10 +0000522 self.check(result, expect)
523
Greg Wardf69d3c92002-08-22 19:06:45 +0000524 expect = "\n".join(expect)
525 result = fill(self.text, 40, initial_indent=" ")
Greg Ward90c0b072002-08-22 18:11:10 +0000526 self.check(result, expect)
527
528
Greg Wardf6765782002-08-22 18:35:49 +0000529 def test_subsequent_indent(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000530 # Test subsequent_indent parameter
Greg Ward90c0b072002-08-22 18:11:10 +0000531
532 expect = '''\
533 * This paragraph will be filled, first
534 without any indentation, and then
535 with some (including a hanging
536 indent).'''
537
Greg Wardf69d3c92002-08-22 19:06:45 +0000538 result = fill(self.text, 40,
539 initial_indent=" * ", subsequent_indent=" ")
Greg Ward90c0b072002-08-22 18:11:10 +0000540 self.check(result, expect)
541
542
Greg Ward9e082f42003-05-08 01:58:26 +0000543# Despite the similar names, DedentTestCase is *not* the inverse
544# of IndentTestCase!
545class DedentTestCase(unittest.TestCase):
546
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000547 def assertUnchanged(self, text):
548 """assert that dedent() has no effect on 'text'"""
Ezio Melottib3aedd42010-11-20 19:04:17 +0000549 self.assertEqual(text, dedent(text))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000550
Greg Ward9e082f42003-05-08 01:58:26 +0000551 def test_dedent_nomargin(self):
552 # No lines indented.
553 text = "Hello there.\nHow are you?\nOh good, I'm glad."
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000554 self.assertUnchanged(text)
Greg Ward9e082f42003-05-08 01:58:26 +0000555
556 # Similar, with a blank line.
557 text = "Hello there.\n\nBoo!"
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000558 self.assertUnchanged(text)
Greg Ward9e082f42003-05-08 01:58:26 +0000559
560 # Some lines indented, but overall margin is still zero.
561 text = "Hello there.\n This is indented."
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000562 self.assertUnchanged(text)
Greg Ward9e082f42003-05-08 01:58:26 +0000563
564 # Again, add a blank line.
565 text = "Hello there.\n\n Boo!\n"
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000566 self.assertUnchanged(text)
Greg Ward9e082f42003-05-08 01:58:26 +0000567
568 def test_dedent_even(self):
569 # All lines indented by two spaces.
570 text = " Hello there.\n How are ya?\n Oh good."
571 expect = "Hello there.\nHow are ya?\nOh good."
Ezio Melottib3aedd42010-11-20 19:04:17 +0000572 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000573
574 # Same, with blank lines.
575 text = " Hello there.\n\n How are ya?\n Oh good.\n"
576 expect = "Hello there.\n\nHow are ya?\nOh good.\n"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000577 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000578
579 # Now indent one of the blank lines.
580 text = " Hello there.\n \n How are ya?\n Oh good.\n"
581 expect = "Hello there.\n\nHow are ya?\nOh good.\n"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000582 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000583
584 def test_dedent_uneven(self):
585 # Lines indented unevenly.
586 text = '''\
587 def foo():
588 while 1:
589 return foo
590 '''
591 expect = '''\
592def foo():
593 while 1:
594 return foo
595'''
Ezio Melottib3aedd42010-11-20 19:04:17 +0000596 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000597
598 # Uneven indentation with a blank line.
599 text = " Foo\n Bar\n\n Baz\n"
600 expect = "Foo\n Bar\n\n Baz\n"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000601 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000602
603 # Uneven indentation with a whitespace-only line.
604 text = " Foo\n Bar\n \n Baz\n"
605 expect = "Foo\n Bar\n\n Baz\n"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000606 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000607
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000608 # dedent() should not mangle internal tabs
609 def test_dedent_preserve_internal_tabs(self):
610 text = " hello\tthere\n how are\tyou?"
611 expect = "hello\tthere\nhow are\tyou?"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000612 self.assertEqual(expect, dedent(text))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000613
614 # make sure that it preserves tabs when it's not making any
615 # changes at all
Ezio Melottib3aedd42010-11-20 19:04:17 +0000616 self.assertEqual(expect, dedent(expect))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000617
618 # dedent() should not mangle tabs in the margin (i.e.
619 # tabs and spaces both count as margin, but are *not*
620 # considered equivalent)
621 def test_dedent_preserve_margin_tabs(self):
622 text = " hello there\n\thow are you?"
623 self.assertUnchanged(text)
624
625 # same effect even if we have 8 spaces
626 text = " hello there\n\thow are you?"
627 self.assertUnchanged(text)
628
629 # dedent() only removes whitespace that can be uniformly removed!
630 text = "\thello there\n\thow are you?"
631 expect = "hello there\nhow are you?"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000632 self.assertEqual(expect, dedent(text))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000633
634 text = " \thello there\n \thow are you?"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000635 self.assertEqual(expect, dedent(text))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000636
637 text = " \t hello there\n \t how are you?"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000638 self.assertEqual(expect, dedent(text))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000639
640 text = " \thello there\n \t how are you?"
641 expect = "hello there\n how are you?"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000642 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000643
644
Nick Coghlan4fae8cd2012-06-11 23:07:51 +1000645# Test textwrap.indent
646class IndentTestCase(unittest.TestCase):
647 # The examples used for tests. If any of these change, the expected
648 # results in the various test cases must also be updated.
649 # The roundtrip cases are separate, because textwrap.dedent doesn't
650 # handle Windows line endings
651 ROUNDTRIP_CASES = (
652 # Basic test case
653 "Hi.\nThis is a test.\nTesting.",
654 # Include a blank line
655 "Hi.\nThis is a test.\n\nTesting.",
656 # Include leading and trailing blank lines
657 "\nHi.\nThis is a test.\nTesting.\n",
658 )
659 CASES = ROUNDTRIP_CASES + (
660 # Use Windows line endings
661 "Hi.\r\nThis is a test.\r\nTesting.\r\n",
662 # Pathological case
663 "\nHi.\r\nThis is a test.\n\r\nTesting.\r\n\n",
664 )
665
666 def test_indent_nomargin_default(self):
667 # indent should do nothing if 'prefix' is empty.
668 for text in self.CASES:
669 self.assertEqual(indent(text, ''), text)
670
671 def test_indent_nomargin_explicit_default(self):
672 # The same as test_indent_nomargin, but explicitly requesting
673 # the default behaviour by passing None as the predicate
674 for text in self.CASES:
675 self.assertEqual(indent(text, '', None), text)
676
677 def test_indent_nomargin_all_lines(self):
678 # The same as test_indent_nomargin, but using the optional
679 # predicate argument
680 predicate = lambda line: True
681 for text in self.CASES:
682 self.assertEqual(indent(text, '', predicate), text)
683
684 def test_indent_no_lines(self):
685 # Explicitly skip indenting any lines
686 predicate = lambda line: False
687 for text in self.CASES:
688 self.assertEqual(indent(text, ' ', predicate), text)
689
690 def test_roundtrip_spaces(self):
691 # A whitespace prefix should roundtrip with dedent
692 for text in self.ROUNDTRIP_CASES:
693 self.assertEqual(dedent(indent(text, ' ')), text)
694
695 def test_roundtrip_tabs(self):
696 # A whitespace prefix should roundtrip with dedent
697 for text in self.ROUNDTRIP_CASES:
698 self.assertEqual(dedent(indent(text, '\t\t')), text)
699
700 def test_roundtrip_mixed(self):
701 # A whitespace prefix should roundtrip with dedent
702 for text in self.ROUNDTRIP_CASES:
703 self.assertEqual(dedent(indent(text, ' \t \t ')), text)
704
705 def test_indent_default(self):
706 # Test default indenting of lines that are not whitespace only
707 prefix = ' '
708 expected = (
709 # Basic test case
710 " Hi.\n This is a test.\n Testing.",
711 # Include a blank line
712 " Hi.\n This is a test.\n\n Testing.",
713 # Include leading and trailing blank lines
714 "\n Hi.\n This is a test.\n Testing.\n",
715 # Use Windows line endings
716 " Hi.\r\n This is a test.\r\n Testing.\r\n",
717 # Pathological case
718 "\n Hi.\r\n This is a test.\n\r\n Testing.\r\n\n",
719 )
720 for text, expect in zip(self.CASES, expected):
721 self.assertEqual(indent(text, prefix), expect)
722
723 def test_indent_explicit_default(self):
724 # Test default indenting of lines that are not whitespace only
725 prefix = ' '
726 expected = (
727 # Basic test case
728 " Hi.\n This is a test.\n Testing.",
729 # Include a blank line
730 " Hi.\n This is a test.\n\n Testing.",
731 # Include leading and trailing blank lines
732 "\n Hi.\n This is a test.\n Testing.\n",
733 # Use Windows line endings
734 " Hi.\r\n This is a test.\r\n Testing.\r\n",
735 # Pathological case
736 "\n Hi.\r\n This is a test.\n\r\n Testing.\r\n\n",
737 )
738 for text, expect in zip(self.CASES, expected):
739 self.assertEqual(indent(text, prefix, None), expect)
740
741 def test_indent_all_lines(self):
742 # Add 'prefix' to all lines, including whitespace-only ones.
743 prefix = ' '
744 expected = (
745 # Basic test case
746 " Hi.\n This is a test.\n Testing.",
747 # Include a blank line
748 " Hi.\n This is a test.\n \n Testing.",
749 # Include leading and trailing blank lines
750 " \n Hi.\n This is a test.\n Testing.\n",
751 # Use Windows line endings
752 " Hi.\r\n This is a test.\r\n Testing.\r\n",
753 # Pathological case
754 " \n Hi.\r\n This is a test.\n \r\n Testing.\r\n \n",
755 )
756 predicate = lambda line: True
757 for text, expect in zip(self.CASES, expected):
758 self.assertEqual(indent(text, prefix, predicate), expect)
759
760 def test_indent_empty_lines(self):
761 # Add 'prefix' solely to whitespace-only lines.
762 prefix = ' '
763 expected = (
764 # Basic test case
765 "Hi.\nThis is a test.\nTesting.",
766 # Include a blank line
767 "Hi.\nThis is a test.\n \nTesting.",
768 # Include leading and trailing blank lines
769 " \nHi.\nThis is a test.\nTesting.\n",
770 # Use Windows line endings
771 "Hi.\r\nThis is a test.\r\nTesting.\r\n",
772 # Pathological case
773 " \nHi.\r\nThis is a test.\n \r\nTesting.\r\n \n",
774 )
775 predicate = lambda line: not line.strip()
776 for text, expect in zip(self.CASES, expected):
777 self.assertEqual(indent(text, prefix, predicate), expect)
778
779
Greg Wardf6765782002-08-22 18:35:49 +0000780def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000781 support.run_unittest(WrapTestCase,
Greg Ward9e082f42003-05-08 01:58:26 +0000782 LongWordTestCase,
783 IndentTestCases,
Nick Coghlan4fae8cd2012-06-11 23:07:51 +1000784 DedentTestCase,
785 IndentTestCase)
Greg Wardf6765782002-08-22 18:35:49 +0000786
Greg Ward90c0b072002-08-22 18:11:10 +0000787if __name__ == '__main__':
Greg Wardf6765782002-08-22 18:35:49 +0000788 test_main()