1 #
2 # Test suite for the textwrap module.
3 #
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
11 import unittest
12
13 from textwrap import TextWrapper, wrap, fill, dedent, indent, shorten
14
15
16 class ESC[4;38;5;81mBaseTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
17 '''Parent class with utility methods for textwrap tests.'''
18
19 def show(self, textin):
20 if isinstance(textin, list):
21 result = []
22 for i in range(len(textin)):
23 result.append(" %d: %r" % (i, textin[i]))
24 result = "\n".join(result) if result else " no lines"
25 elif isinstance(textin, str):
26 result = " %s\n" % repr(textin)
27 return result
28
29
30 def check(self, result, expect):
31 self.assertEqual(result, expect,
32 'expected:\n%s\nbut got:\n%s' % (
33 self.show(expect), self.show(result)))
34
35 def check_wrap(self, text, width, expect, **kwargs):
36 result = wrap(text, width, **kwargs)
37 self.check(result, expect)
38
39 def check_split(self, text, expect):
40 result = self.wrapper._split(text)
41 self.assertEqual(result, expect,
42 "\nexpected %r\n"
43 "but got %r" % (expect, result))
44
45
46 class ESC[4;38;5;81mWrapTestCase(ESC[4;38;5;149mBaseTestCase):
47
48 def setUp(self):
49 self.wrapper = TextWrapper(width=45)
50
51 def test_simple(self):
52 # Simple case: just words, spaces, and a bit of punctuation
53
54 text = "Hello there, how are you this fine day? I'm glad to hear it!"
55
56 self.check_wrap(text, 12,
57 ["Hello there,",
58 "how are you",
59 "this fine",
60 "day? I'm",
61 "glad to hear",
62 "it!"])
63 self.check_wrap(text, 42,
64 ["Hello there, how are you this fine day?",
65 "I'm glad to hear it!"])
66 self.check_wrap(text, 80, [text])
67
68 def test_empty_string(self):
69 # Check that wrapping the empty string returns an empty list.
70 self.check_wrap("", 6, [])
71 self.check_wrap("", 6, [], drop_whitespace=False)
72
73 def test_empty_string_with_initial_indent(self):
74 # Check that the empty string is not indented.
75 self.check_wrap("", 6, [], initial_indent="++")
76 self.check_wrap("", 6, [], initial_indent="++", drop_whitespace=False)
77
78 def test_whitespace(self):
79 # Whitespace munging and end-of-sentence detection
80
81 text = """\
82 This is a paragraph that already has
83 line breaks. But some of its lines are much longer than the others,
84 so it needs to be wrapped.
85 Some lines are \ttabbed too.
86 What a mess!
87 """
88
89 expect = ["This is a paragraph that already has line",
90 "breaks. But some of its lines are much",
91 "longer than the others, so it needs to be",
92 "wrapped. Some lines are tabbed too. What a",
93 "mess!"]
94
95 wrapper = TextWrapper(45, fix_sentence_endings=True)
96 result = wrapper.wrap(text)
97 self.check(result, expect)
98
99 result = wrapper.fill(text)
100 self.check(result, '\n'.join(expect))
101
102 text = "\tTest\tdefault\t\ttabsize."
103 expect = [" Test default tabsize."]
104 self.check_wrap(text, 80, expect)
105
106 text = "\tTest\tcustom\t\ttabsize."
107 expect = [" Test custom tabsize."]
108 self.check_wrap(text, 80, expect, tabsize=4)
109
110 def test_fix_sentence_endings(self):
111 wrapper = TextWrapper(60, fix_sentence_endings=True)
112
113 # SF #847346: ensure that fix_sentence_endings=True does the
114 # right thing even on input short enough that it doesn't need to
115 # be wrapped.
116 text = "A short line. Note the single space."
117 expect = ["A short line. Note the single space."]
118 self.check(wrapper.wrap(text), expect)
119
120 # Test some of the hairy end cases that _fix_sentence_endings()
121 # is supposed to handle (the easy stuff is tested in
122 # test_whitespace() above).
123 text = "Well, Doctor? What do you think?"
124 expect = ["Well, Doctor? What do you think?"]
125 self.check(wrapper.wrap(text), expect)
126
127 text = "Well, Doctor?\nWhat do you think?"
128 self.check(wrapper.wrap(text), expect)
129
130 text = 'I say, chaps! Anyone for "tennis?"\nHmmph!'
131 expect = ['I say, chaps! Anyone for "tennis?" Hmmph!']
132 self.check(wrapper.wrap(text), expect)
133
134 wrapper.width = 20
135 expect = ['I say, chaps!', 'Anyone for "tennis?"', 'Hmmph!']
136 self.check(wrapper.wrap(text), expect)
137
138 text = 'And she said, "Go to hell!"\nCan you believe that?'
139 expect = ['And she said, "Go to',
140 'hell!" Can you',
141 'believe that?']
142 self.check(wrapper.wrap(text), expect)
143
144 wrapper.width = 60
145 expect = ['And she said, "Go to hell!" Can you believe that?']
146 self.check(wrapper.wrap(text), expect)
147
148 text = 'File stdio.h is nice.'
149 expect = ['File stdio.h is nice.']
150 self.check(wrapper.wrap(text), expect)
151
152 def test_wrap_short(self):
153 # Wrapping to make short lines longer
154
155 text = "This is a\nshort paragraph."
156
157 self.check_wrap(text, 20, ["This is a short",
158 "paragraph."])
159 self.check_wrap(text, 40, ["This is a short paragraph."])
160
161
162 def test_wrap_short_1line(self):
163 # Test endcases
164
165 text = "This is a short line."
166
167 self.check_wrap(text, 30, ["This is a short line."])
168 self.check_wrap(text, 30, ["(1) This is a short line."],
169 initial_indent="(1) ")
170
171
172 def test_hyphenated(self):
173 # Test breaking hyphenated words
174
175 text = ("this-is-a-useful-feature-for-"
176 "reformatting-posts-from-tim-peters'ly")
177
178 self.check_wrap(text, 40,
179 ["this-is-a-useful-feature-for-",
180 "reformatting-posts-from-tim-peters'ly"])
181 self.check_wrap(text, 41,
182 ["this-is-a-useful-feature-for-",
183 "reformatting-posts-from-tim-peters'ly"])
184 self.check_wrap(text, 42,
185 ["this-is-a-useful-feature-for-reformatting-",
186 "posts-from-tim-peters'ly"])
187 # The test tests current behavior but is not testing parts of the API.
188 expect = ("this-|is-|a-|useful-|feature-|for-|"
189 "reformatting-|posts-|from-|tim-|peters'ly").split('|')
190 self.check_wrap(text, 1, expect, break_long_words=False)
191 self.check_split(text, expect)
192
193 self.check_split('e-mail', ['e-mail'])
194 self.check_split('Jelly-O', ['Jelly-O'])
195 # The test tests current behavior but is not testing parts of the API.
196 self.check_split('half-a-crown', 'half-|a-|crown'.split('|'))
197
198 def test_hyphenated_numbers(self):
199 # Test that hyphenated numbers (eg. dates) are not broken like words.
200 text = ("Python 1.0.0 was released on 1994-01-26. Python 1.0.1 was\n"
201 "released on 1994-02-15.")
202
203 self.check_wrap(text, 30, ['Python 1.0.0 was released on',
204 '1994-01-26. Python 1.0.1 was',
205 'released on 1994-02-15.'])
206 self.check_wrap(text, 40, ['Python 1.0.0 was released on 1994-01-26.',
207 'Python 1.0.1 was released on 1994-02-15.'])
208 self.check_wrap(text, 1, text.split(), break_long_words=False)
209
210 text = "I do all my shopping at 7-11."
211 self.check_wrap(text, 25, ["I do all my shopping at",
212 "7-11."])
213 self.check_wrap(text, 27, ["I do all my shopping at",
214 "7-11."])
215 self.check_wrap(text, 29, ["I do all my shopping at 7-11."])
216 self.check_wrap(text, 1, text.split(), break_long_words=False)
217
218 def test_em_dash(self):
219 # Test text with em-dashes
220 text = "Em-dashes should be written -- thus."
221 self.check_wrap(text, 25,
222 ["Em-dashes should be",
223 "written -- thus."])
224
225 # Probe the boundaries of the properly written em-dash,
226 # ie. " -- ".
227 self.check_wrap(text, 29,
228 ["Em-dashes should be written",
229 "-- thus."])
230 expect = ["Em-dashes should be written --",
231 "thus."]
232 self.check_wrap(text, 30, expect)
233 self.check_wrap(text, 35, expect)
234 self.check_wrap(text, 36,
235 ["Em-dashes should be written -- thus."])
236
237 # The improperly written em-dash is handled too, because
238 # it's adjacent to non-whitespace on both sides.
239 text = "You can also do--this or even---this."
240 expect = ["You can also do",
241 "--this or even",
242 "---this."]
243 self.check_wrap(text, 15, expect)
244 self.check_wrap(text, 16, expect)
245 expect = ["You can also do--",
246 "this or even---",
247 "this."]
248 self.check_wrap(text, 17, expect)
249 self.check_wrap(text, 19, expect)
250 expect = ["You can also do--this or even",
251 "---this."]
252 self.check_wrap(text, 29, expect)
253 self.check_wrap(text, 31, expect)
254 expect = ["You can also do--this or even---",
255 "this."]
256 self.check_wrap(text, 32, expect)
257 self.check_wrap(text, 35, expect)
258
259 # All of the above behaviour could be deduced by probing the
260 # _split() method.
261 text = "Here's an -- em-dash and--here's another---and another!"
262 expect = ["Here's", " ", "an", " ", "--", " ", "em-", "dash", " ",
263 "and", "--", "here's", " ", "another", "---",
264 "and", " ", "another!"]
265 self.check_split(text, expect)
266
267 text = "and then--bam!--he was gone"
268 expect = ["and", " ", "then", "--", "bam!", "--",
269 "he", " ", "was", " ", "gone"]
270 self.check_split(text, expect)
271
272
273 def test_unix_options (self):
274 # Test that Unix-style command-line options are wrapped correctly.
275 # Both Optik (OptionParser) and Docutils rely on this behaviour!
276
277 text = "You should use the -n option, or --dry-run in its long form."
278 self.check_wrap(text, 20,
279 ["You should use the",
280 "-n option, or --dry-",
281 "run in its long",
282 "form."])
283 self.check_wrap(text, 21,
284 ["You should use the -n",
285 "option, or --dry-run",
286 "in its long form."])
287 expect = ["You should use the -n option, or",
288 "--dry-run in its long form."]
289 self.check_wrap(text, 32, expect)
290 self.check_wrap(text, 34, expect)
291 self.check_wrap(text, 35, expect)
292 self.check_wrap(text, 38, expect)
293 expect = ["You should use the -n option, or --dry-",
294 "run in its long form."]
295 self.check_wrap(text, 39, expect)
296 self.check_wrap(text, 41, expect)
297 expect = ["You should use the -n option, or --dry-run",
298 "in its long form."]
299 self.check_wrap(text, 42, expect)
300
301 # Again, all of the above can be deduced from _split().
302 text = "the -n option, or --dry-run or --dryrun"
303 expect = ["the", " ", "-n", " ", "option,", " ", "or", " ",
304 "--dry-", "run", " ", "or", " ", "--dryrun"]
305 self.check_split(text, expect)
306
307 def test_funky_hyphens (self):
308 # Screwy edge cases cooked up by David Goodger. All reported
309 # in SF bug #596434.
310 self.check_split("what the--hey!", ["what", " ", "the", "--", "hey!"])
311 self.check_split("what the--", ["what", " ", "the--"])
312 self.check_split("what the--.", ["what", " ", "the--."])
313 self.check_split("--text--.", ["--text--."])
314
315 # When I first read bug #596434, this is what I thought David
316 # was talking about. I was wrong; these have always worked
317 # fine. The real problem is tested in test_funky_parens()
318 # below...
319 self.check_split("--option", ["--option"])
320 self.check_split("--option-opt", ["--option-", "opt"])
321 self.check_split("foo --option-opt bar",
322 ["foo", " ", "--option-", "opt", " ", "bar"])
323
324 def test_punct_hyphens(self):
325 # Oh bother, SF #965425 found another problem with hyphens --
326 # hyphenated words in single quotes weren't handled correctly.
327 # In fact, the bug is that *any* punctuation around a hyphenated
328 # word was handled incorrectly, except for a leading "--", which
329 # was special-cased for Optik and Docutils. So test a variety
330 # of styles of punctuation around a hyphenated word.
331 # (Actually this is based on an Optik bug report, #813077).
332 self.check_split("the 'wibble-wobble' widget",
333 ['the', ' ', "'wibble-", "wobble'", ' ', 'widget'])
334 self.check_split('the "wibble-wobble" widget',
335 ['the', ' ', '"wibble-', 'wobble"', ' ', 'widget'])
336 self.check_split("the (wibble-wobble) widget",
337 ['the', ' ', "(wibble-", "wobble)", ' ', 'widget'])
338 self.check_split("the ['wibble-wobble'] widget",
339 ['the', ' ', "['wibble-", "wobble']", ' ', 'widget'])
340
341 # The test tests current behavior but is not testing parts of the API.
342 self.check_split("what-d'you-call-it.",
343 "what-d'you-|call-|it.".split('|'))
344
345 def test_funky_parens (self):
346 # Second part of SF bug #596434: long option strings inside
347 # parentheses.
348 self.check_split("foo (--option) bar",
349 ["foo", " ", "(--option)", " ", "bar"])
350
351 # Related stuff -- make sure parens work in simpler contexts.
352 self.check_split("foo (bar) baz",
353 ["foo", " ", "(bar)", " ", "baz"])
354 self.check_split("blah (ding dong), wubba",
355 ["blah", " ", "(ding", " ", "dong),",
356 " ", "wubba"])
357
358 def test_drop_whitespace_false(self):
359 # Check that drop_whitespace=False preserves whitespace.
360 # SF patch #1581073
361 text = " This is a sentence with much whitespace."
362 self.check_wrap(text, 10,
363 [" This is a", " ", "sentence ",
364 "with ", "much white", "space."],
365 drop_whitespace=False)
366
367 def test_drop_whitespace_false_whitespace_only(self):
368 # Check that drop_whitespace=False preserves a whitespace-only string.
369 self.check_wrap(" ", 6, [" "], drop_whitespace=False)
370
371 def test_drop_whitespace_false_whitespace_only_with_indent(self):
372 # Check that a whitespace-only string gets indented (when
373 # drop_whitespace is False).
374 self.check_wrap(" ", 6, [" "], drop_whitespace=False,
375 initial_indent=" ")
376
377 def test_drop_whitespace_whitespace_only(self):
378 # Check drop_whitespace on a whitespace-only string.
379 self.check_wrap(" ", 6, [])
380
381 def test_drop_whitespace_leading_whitespace(self):
382 # Check that drop_whitespace does not drop leading whitespace (if
383 # followed by non-whitespace).
384 # SF bug #622849 reported inconsistent handling of leading
385 # whitespace; let's test that a bit, shall we?
386 text = " This is a sentence with leading whitespace."
387 self.check_wrap(text, 50,
388 [" This is a sentence with leading whitespace."])
389 self.check_wrap(text, 30,
390 [" This is a sentence with", "leading whitespace."])
391
392 def test_drop_whitespace_whitespace_line(self):
393 # Check that drop_whitespace skips the whole line if a non-leading
394 # line consists only of whitespace.
395 text = "abcd efgh"
396 # Include the result for drop_whitespace=False for comparison.
397 self.check_wrap(text, 6, ["abcd", " ", "efgh"],
398 drop_whitespace=False)
399 self.check_wrap(text, 6, ["abcd", "efgh"])
400
401 def test_drop_whitespace_whitespace_only_with_indent(self):
402 # Check that initial_indent is not applied to a whitespace-only
403 # string. This checks a special case of the fact that dropping
404 # whitespace occurs before indenting.
405 self.check_wrap(" ", 6, [], initial_indent="++")
406
407 def test_drop_whitespace_whitespace_indent(self):
408 # Check that drop_whitespace does not drop whitespace indents.
409 # This checks a special case of the fact that dropping whitespace
410 # occurs before indenting.
411 self.check_wrap("abcd efgh", 6, [" abcd", " efgh"],
412 initial_indent=" ", subsequent_indent=" ")
413
414 def test_split(self):
415 # Ensure that the standard _split() method works as advertised
416 # in the comments
417
418 text = "Hello there -- you goof-ball, use the -b option!"
419
420 result = self.wrapper._split(text)
421 self.check(result,
422 ["Hello", " ", "there", " ", "--", " ", "you", " ", "goof-",
423 "ball,", " ", "use", " ", "the", " ", "-b", " ", "option!"])
424
425 def test_break_on_hyphens(self):
426 # Ensure that the break_on_hyphens attributes work
427 text = "yaba daba-doo"
428 self.check_wrap(text, 10, ["yaba daba-", "doo"],
429 break_on_hyphens=True)
430 self.check_wrap(text, 10, ["yaba", "daba-doo"],
431 break_on_hyphens=False)
432
433 def test_bad_width(self):
434 # Ensure that width <= 0 is caught.
435 text = "Whatever, it doesn't matter."
436 self.assertRaises(ValueError, wrap, text, 0)
437 self.assertRaises(ValueError, wrap, text, -1)
438
439 def test_no_split_at_umlaut(self):
440 text = "Die Empf\xe4nger-Auswahl"
441 self.check_wrap(text, 13, ["Die", "Empf\xe4nger-", "Auswahl"])
442
443 def test_umlaut_followed_by_dash(self):
444 text = "aa \xe4\xe4-\xe4\xe4"
445 self.check_wrap(text, 7, ["aa \xe4\xe4-", "\xe4\xe4"])
446
447 def test_non_breaking_space(self):
448 text = 'This is a sentence with non-breaking\N{NO-BREAK SPACE}space.'
449
450 self.check_wrap(text, 20,
451 ['This is a sentence',
452 'with non-',
453 'breaking\N{NO-BREAK SPACE}space.'],
454 break_on_hyphens=True)
455
456 self.check_wrap(text, 20,
457 ['This is a sentence',
458 'with',
459 'non-breaking\N{NO-BREAK SPACE}space.'],
460 break_on_hyphens=False)
461
462 def test_narrow_non_breaking_space(self):
463 text = ('This is a sentence with non-breaking'
464 '\N{NARROW NO-BREAK SPACE}space.')
465
466 self.check_wrap(text, 20,
467 ['This is a sentence',
468 'with non-',
469 'breaking\N{NARROW NO-BREAK SPACE}space.'],
470 break_on_hyphens=True)
471
472 self.check_wrap(text, 20,
473 ['This is a sentence',
474 'with',
475 'non-breaking\N{NARROW NO-BREAK SPACE}space.'],
476 break_on_hyphens=False)
477
478
479 class ESC[4;38;5;81mMaxLinesTestCase(ESC[4;38;5;149mBaseTestCase):
480 text = "Hello there, how are you this fine day? I'm glad to hear it!"
481
482 def test_simple(self):
483 self.check_wrap(self.text, 12,
484 ["Hello [...]"],
485 max_lines=0)
486 self.check_wrap(self.text, 12,
487 ["Hello [...]"],
488 max_lines=1)
489 self.check_wrap(self.text, 12,
490 ["Hello there,",
491 "how [...]"],
492 max_lines=2)
493 self.check_wrap(self.text, 13,
494 ["Hello there,",
495 "how are [...]"],
496 max_lines=2)
497 self.check_wrap(self.text, 80, [self.text], max_lines=1)
498 self.check_wrap(self.text, 12,
499 ["Hello there,",
500 "how are you",
501 "this fine",
502 "day? I'm",
503 "glad to hear",
504 "it!"],
505 max_lines=6)
506
507 def test_spaces(self):
508 # strip spaces before placeholder
509 self.check_wrap(self.text, 12,
510 ["Hello there,",
511 "how are you",
512 "this fine",
513 "day? [...]"],
514 max_lines=4)
515 # placeholder at the start of line
516 self.check_wrap(self.text, 6,
517 ["Hello",
518 "[...]"],
519 max_lines=2)
520 # final spaces
521 self.check_wrap(self.text + ' ' * 10, 12,
522 ["Hello there,",
523 "how are you",
524 "this fine",
525 "day? I'm",
526 "glad to hear",
527 "it!"],
528 max_lines=6)
529
530 def test_placeholder(self):
531 self.check_wrap(self.text, 12,
532 ["Hello..."],
533 max_lines=1,
534 placeholder='...')
535 self.check_wrap(self.text, 12,
536 ["Hello there,",
537 "how are..."],
538 max_lines=2,
539 placeholder='...')
540 # long placeholder and indentation
541 with self.assertRaises(ValueError):
542 wrap(self.text, 16, initial_indent=' ',
543 max_lines=1, placeholder=' [truncated]...')
544 with self.assertRaises(ValueError):
545 wrap(self.text, 16, subsequent_indent=' ',
546 max_lines=2, placeholder=' [truncated]...')
547 self.check_wrap(self.text, 16,
548 [" Hello there,",
549 " [truncated]..."],
550 max_lines=2,
551 initial_indent=' ',
552 subsequent_indent=' ',
553 placeholder=' [truncated]...')
554 self.check_wrap(self.text, 16,
555 [" [truncated]..."],
556 max_lines=1,
557 initial_indent=' ',
558 subsequent_indent=' ',
559 placeholder=' [truncated]...')
560 self.check_wrap(self.text, 80, [self.text], placeholder='.' * 1000)
561
562 def test_placeholder_backtrack(self):
563 # Test special case when max_lines insufficient, but what
564 # would be last wrapped line so long the placeholder cannot
565 # be added there without violence. So, textwrap backtracks,
566 # adding placeholder to the penultimate line.
567 text = 'Good grief Python features are advancing quickly!'
568 self.check_wrap(text, 12,
569 ['Good grief', 'Python*****'],
570 max_lines=3,
571 placeholder='*****')
572
573
574 class ESC[4;38;5;81mLongWordTestCase (ESC[4;38;5;149mBaseTestCase):
575 def setUp(self):
576 self.wrapper = TextWrapper()
577 self.text = '''\
578 Did you say "supercalifragilisticexpialidocious?"
579 How *do* you spell that odd word, anyways?
580 '''
581
582 def test_break_long(self):
583 # Wrap text with long words and lots of punctuation
584
585 self.check_wrap(self.text, 30,
586 ['Did you say "supercalifragilis',
587 'ticexpialidocious?" How *do*',
588 'you spell that odd word,',
589 'anyways?'])
590 self.check_wrap(self.text, 50,
591 ['Did you say "supercalifragilisticexpialidocious?"',
592 'How *do* you spell that odd word, anyways?'])
593
594 # SF bug 797650. Prevent an infinite loop by making sure that at
595 # least one character gets split off on every pass.
596 self.check_wrap('-'*10+'hello', 10,
597 ['----------',
598 ' h',
599 ' e',
600 ' l',
601 ' l',
602 ' o'],
603 subsequent_indent = ' '*15)
604
605 # bug 1146. Prevent a long word to be wrongly wrapped when the
606 # preceding word is exactly one character shorter than the width
607 self.check_wrap(self.text, 12,
608 ['Did you say ',
609 '"supercalifr',
610 'agilisticexp',
611 'ialidocious?',
612 '" How *do*',
613 'you spell',
614 'that odd',
615 'word,',
616 'anyways?'])
617
618 def test_nobreak_long(self):
619 # Test with break_long_words disabled
620 self.wrapper.break_long_words = 0
621 self.wrapper.width = 30
622 expect = ['Did you say',
623 '"supercalifragilisticexpialidocious?"',
624 'How *do* you spell that odd',
625 'word, anyways?'
626 ]
627 result = self.wrapper.wrap(self.text)
628 self.check(result, expect)
629
630 # Same thing with kwargs passed to standalone wrap() function.
631 result = wrap(self.text, width=30, break_long_words=0)
632 self.check(result, expect)
633
634 def test_max_lines_long(self):
635 self.check_wrap(self.text, 12,
636 ['Did you say ',
637 '"supercalifr',
638 'agilisticexp',
639 '[...]'],
640 max_lines=4)
641
642
643 class ESC[4;38;5;81mLongWordWithHyphensTestCase(ESC[4;38;5;149mBaseTestCase):
644 def setUp(self):
645 self.wrapper = TextWrapper()
646 self.text1 = '''\
647 We used enyzme 2-succinyl-6-hydroxy-2,4-cyclohexadiene-1-carboxylate synthase.
648 '''
649 self.text2 = '''\
650 1234567890-1234567890--this_is_a_very_long_option_indeed-good-bye"
651 '''
652
653 def test_break_long_words_on_hyphen(self):
654 expected = ['We used enyzme 2-succinyl-6-hydroxy-2,4-',
655 'cyclohexadiene-1-carboxylate synthase.']
656 self.check_wrap(self.text1, 50, expected)
657
658 expected = ['We used', 'enyzme 2-', 'succinyl-', '6-hydroxy-', '2,4-',
659 'cyclohexad', 'iene-1-', 'carboxylat', 'e', 'synthase.']
660 self.check_wrap(self.text1, 10, expected)
661
662 expected = ['1234567890', '-123456789', '0--this_is', '_a_very_lo',
663 'ng_option_', 'indeed-', 'good-bye"']
664 self.check_wrap(self.text2, 10, expected)
665
666 def test_break_long_words_not_on_hyphen(self):
667 expected = ['We used enyzme 2-succinyl-6-hydroxy-2,4-cyclohexad',
668 'iene-1-carboxylate synthase.']
669 self.check_wrap(self.text1, 50, expected, break_on_hyphens=False)
670
671 expected = ['We used', 'enyzme 2-s', 'uccinyl-6-', 'hydroxy-2,',
672 '4-cyclohex', 'adiene-1-c', 'arboxylate', 'synthase.']
673 self.check_wrap(self.text1, 10, expected, break_on_hyphens=False)
674
675 expected = ['1234567890', '-123456789', '0--this_is', '_a_very_lo',
676 'ng_option_', 'indeed-', 'good-bye"']
677 self.check_wrap(self.text2, 10, expected)
678
679 def test_break_on_hyphen_but_not_long_words(self):
680 expected = ['We used enyzme',
681 '2-succinyl-6-hydroxy-2,4-cyclohexadiene-1-carboxylate',
682 'synthase.']
683
684 self.check_wrap(self.text1, 50, expected, break_long_words=False)
685
686 expected = ['We used', 'enyzme',
687 '2-succinyl-6-hydroxy-2,4-cyclohexadiene-1-carboxylate',
688 'synthase.']
689 self.check_wrap(self.text1, 10, expected, break_long_words=False)
690
691 expected = ['1234567890', '-123456789', '0--this_is', '_a_very_lo',
692 'ng_option_', 'indeed-', 'good-bye"']
693 self.check_wrap(self.text2, 10, expected)
694
695
696 def test_do_not_break_long_words_or_on_hyphens(self):
697 expected = ['We used enyzme',
698 '2-succinyl-6-hydroxy-2,4-cyclohexadiene-1-carboxylate',
699 'synthase.']
700 self.check_wrap(self.text1, 50, expected,
701 break_long_words=False,
702 break_on_hyphens=False)
703
704 expected = ['We used', 'enyzme',
705 '2-succinyl-6-hydroxy-2,4-cyclohexadiene-1-carboxylate',
706 'synthase.']
707 self.check_wrap(self.text1, 10, expected,
708 break_long_words=False,
709 break_on_hyphens=False)
710
711 expected = ['1234567890', '-123456789', '0--this_is', '_a_very_lo',
712 'ng_option_', 'indeed-', 'good-bye"']
713 self.check_wrap(self.text2, 10, expected)
714
715 class ESC[4;38;5;81mIndentTestCases(ESC[4;38;5;149mBaseTestCase):
716
717 # called before each test method
718 def setUp(self):
719 self.text = '''\
720 This paragraph will be filled, first without any indentation,
721 and then with some (including a hanging indent).'''
722
723
724 def test_fill(self):
725 # Test the fill() method
726
727 expect = '''\
728 This paragraph will be filled, first
729 without any indentation, and then with
730 some (including a hanging indent).'''
731
732 result = fill(self.text, 40)
733 self.check(result, expect)
734
735
736 def test_initial_indent(self):
737 # Test initial_indent parameter
738
739 expect = [" This paragraph will be filled,",
740 "first without any indentation, and then",
741 "with some (including a hanging indent)."]
742 result = wrap(self.text, 40, initial_indent=" ")
743 self.check(result, expect)
744
745 expect = "\n".join(expect)
746 result = fill(self.text, 40, initial_indent=" ")
747 self.check(result, expect)
748
749
750 def test_subsequent_indent(self):
751 # Test subsequent_indent parameter
752
753 expect = '''\
754 * This paragraph will be filled, first
755 without any indentation, and then
756 with some (including a hanging
757 indent).'''
758
759 result = fill(self.text, 40,
760 initial_indent=" * ", subsequent_indent=" ")
761 self.check(result, expect)
762
763
764 # Despite the similar names, DedentTestCase is *not* the inverse
765 # of IndentTestCase!
766 class ESC[4;38;5;81mDedentTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
767
768 def assertUnchanged(self, text):
769 """assert that dedent() has no effect on 'text'"""
770 self.assertEqual(text, dedent(text))
771
772 def test_dedent_nomargin(self):
773 # No lines indented.
774 text = "Hello there.\nHow are you?\nOh good, I'm glad."
775 self.assertUnchanged(text)
776
777 # Similar, with a blank line.
778 text = "Hello there.\n\nBoo!"
779 self.assertUnchanged(text)
780
781 # Some lines indented, but overall margin is still zero.
782 text = "Hello there.\n This is indented."
783 self.assertUnchanged(text)
784
785 # Again, add a blank line.
786 text = "Hello there.\n\n Boo!\n"
787 self.assertUnchanged(text)
788
789 def test_dedent_even(self):
790 # All lines indented by two spaces.
791 text = " Hello there.\n How are ya?\n Oh good."
792 expect = "Hello there.\nHow are ya?\nOh good."
793 self.assertEqual(expect, dedent(text))
794
795 # Same, with blank lines.
796 text = " Hello there.\n\n How are ya?\n Oh good.\n"
797 expect = "Hello there.\n\nHow are ya?\nOh good.\n"
798 self.assertEqual(expect, dedent(text))
799
800 # Now indent one of the blank lines.
801 text = " Hello there.\n \n How are ya?\n Oh good.\n"
802 expect = "Hello there.\n\nHow are ya?\nOh good.\n"
803 self.assertEqual(expect, dedent(text))
804
805 def test_dedent_uneven(self):
806 # Lines indented unevenly.
807 text = '''\
808 def foo():
809 while 1:
810 return foo
811 '''
812 expect = '''\
813 def foo():
814 while 1:
815 return foo
816 '''
817 self.assertEqual(expect, dedent(text))
818
819 # Uneven indentation with a blank line.
820 text = " Foo\n Bar\n\n Baz\n"
821 expect = "Foo\n Bar\n\n Baz\n"
822 self.assertEqual(expect, dedent(text))
823
824 # Uneven indentation with a whitespace-only line.
825 text = " Foo\n Bar\n \n Baz\n"
826 expect = "Foo\n Bar\n\n Baz\n"
827 self.assertEqual(expect, dedent(text))
828
829 def test_dedent_declining(self):
830 # Uneven indentation with declining indent level.
831 text = " Foo\n Bar\n" # 5 spaces, then 4
832 expect = " Foo\nBar\n"
833 self.assertEqual(expect, dedent(text))
834
835 # Declining indent level with blank line.
836 text = " Foo\n\n Bar\n" # 5 spaces, blank, then 4
837 expect = " Foo\n\nBar\n"
838 self.assertEqual(expect, dedent(text))
839
840 # Declining indent level with whitespace only line.
841 text = " Foo\n \n Bar\n" # 5 spaces, then 4, then 4
842 expect = " Foo\n\nBar\n"
843 self.assertEqual(expect, dedent(text))
844
845 # dedent() should not mangle internal tabs
846 def test_dedent_preserve_internal_tabs(self):
847 text = " hello\tthere\n how are\tyou?"
848 expect = "hello\tthere\nhow are\tyou?"
849 self.assertEqual(expect, dedent(text))
850
851 # make sure that it preserves tabs when it's not making any
852 # changes at all
853 self.assertEqual(expect, dedent(expect))
854
855 # dedent() should not mangle tabs in the margin (i.e.
856 # tabs and spaces both count as margin, but are *not*
857 # considered equivalent)
858 def test_dedent_preserve_margin_tabs(self):
859 text = " hello there\n\thow are you?"
860 self.assertUnchanged(text)
861
862 # same effect even if we have 8 spaces
863 text = " hello there\n\thow are you?"
864 self.assertUnchanged(text)
865
866 # dedent() only removes whitespace that can be uniformly removed!
867 text = "\thello there\n\thow are you?"
868 expect = "hello there\nhow are you?"
869 self.assertEqual(expect, dedent(text))
870
871 text = " \thello there\n \thow are you?"
872 self.assertEqual(expect, dedent(text))
873
874 text = " \t hello there\n \t how are you?"
875 self.assertEqual(expect, dedent(text))
876
877 text = " \thello there\n \t how are you?"
878 expect = "hello there\n how are you?"
879 self.assertEqual(expect, dedent(text))
880
881 # test margin is smaller than smallest indent
882 text = " \thello there\n \thow are you?\n \tI'm fine, thanks"
883 expect = " \thello there\n \thow are you?\n\tI'm fine, thanks"
884 self.assertEqual(expect, dedent(text))
885
886
887 # Test textwrap.indent
888 class ESC[4;38;5;81mIndentTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
889 # The examples used for tests. If any of these change, the expected
890 # results in the various test cases must also be updated.
891 # The roundtrip cases are separate, because textwrap.dedent doesn't
892 # handle Windows line endings
893 ROUNDTRIP_CASES = (
894 # Basic test case
895 "Hi.\nThis is a test.\nTesting.",
896 # Include a blank line
897 "Hi.\nThis is a test.\n\nTesting.",
898 # Include leading and trailing blank lines
899 "\nHi.\nThis is a test.\nTesting.\n",
900 )
901 CASES = ROUNDTRIP_CASES + (
902 # Use Windows line endings
903 "Hi.\r\nThis is a test.\r\nTesting.\r\n",
904 # Pathological case
905 "\nHi.\r\nThis is a test.\n\r\nTesting.\r\n\n",
906 )
907
908 def test_indent_nomargin_default(self):
909 # indent should do nothing if 'prefix' is empty.
910 for text in self.CASES:
911 self.assertEqual(indent(text, ''), text)
912
913 def test_indent_nomargin_explicit_default(self):
914 # The same as test_indent_nomargin, but explicitly requesting
915 # the default behaviour by passing None as the predicate
916 for text in self.CASES:
917 self.assertEqual(indent(text, '', None), text)
918
919 def test_indent_nomargin_all_lines(self):
920 # The same as test_indent_nomargin, but using the optional
921 # predicate argument
922 predicate = lambda line: True
923 for text in self.CASES:
924 self.assertEqual(indent(text, '', predicate), text)
925
926 def test_indent_no_lines(self):
927 # Explicitly skip indenting any lines
928 predicate = lambda line: False
929 for text in self.CASES:
930 self.assertEqual(indent(text, ' ', predicate), text)
931
932 def test_roundtrip_spaces(self):
933 # A whitespace prefix should roundtrip with dedent
934 for text in self.ROUNDTRIP_CASES:
935 self.assertEqual(dedent(indent(text, ' ')), text)
936
937 def test_roundtrip_tabs(self):
938 # A whitespace prefix should roundtrip with dedent
939 for text in self.ROUNDTRIP_CASES:
940 self.assertEqual(dedent(indent(text, '\t\t')), text)
941
942 def test_roundtrip_mixed(self):
943 # A whitespace prefix should roundtrip with dedent
944 for text in self.ROUNDTRIP_CASES:
945 self.assertEqual(dedent(indent(text, ' \t \t ')), text)
946
947 def test_indent_default(self):
948 # Test default indenting of lines that are not whitespace only
949 prefix = ' '
950 expected = (
951 # Basic test case
952 " Hi.\n This is a test.\n Testing.",
953 # Include a blank line
954 " Hi.\n This is a test.\n\n Testing.",
955 # Include leading and trailing blank lines
956 "\n Hi.\n This is a test.\n Testing.\n",
957 # Use Windows line endings
958 " Hi.\r\n This is a test.\r\n Testing.\r\n",
959 # Pathological case
960 "\n Hi.\r\n This is a test.\n\r\n Testing.\r\n\n",
961 )
962 for text, expect in zip(self.CASES, expected):
963 self.assertEqual(indent(text, prefix), expect)
964
965 def test_indent_explicit_default(self):
966 # Test default indenting of lines that are not whitespace only
967 prefix = ' '
968 expected = (
969 # Basic test case
970 " Hi.\n This is a test.\n Testing.",
971 # Include a blank line
972 " Hi.\n This is a test.\n\n Testing.",
973 # Include leading and trailing blank lines
974 "\n Hi.\n This is a test.\n Testing.\n",
975 # Use Windows line endings
976 " Hi.\r\n This is a test.\r\n Testing.\r\n",
977 # Pathological case
978 "\n Hi.\r\n This is a test.\n\r\n Testing.\r\n\n",
979 )
980 for text, expect in zip(self.CASES, expected):
981 self.assertEqual(indent(text, prefix, None), expect)
982
983 def test_indent_all_lines(self):
984 # Add 'prefix' to all lines, including whitespace-only ones.
985 prefix = ' '
986 expected = (
987 # Basic test case
988 " Hi.\n This is a test.\n Testing.",
989 # Include a blank line
990 " Hi.\n This is a test.\n \n Testing.",
991 # Include leading and trailing blank lines
992 " \n Hi.\n This is a test.\n Testing.\n",
993 # Use Windows line endings
994 " Hi.\r\n This is a test.\r\n Testing.\r\n",
995 # Pathological case
996 " \n Hi.\r\n This is a test.\n \r\n Testing.\r\n \n",
997 )
998 predicate = lambda line: True
999 for text, expect in zip(self.CASES, expected):
1000 self.assertEqual(indent(text, prefix, predicate), expect)
1001
1002 def test_indent_empty_lines(self):
1003 # Add 'prefix' solely to whitespace-only lines.
1004 prefix = ' '
1005 expected = (
1006 # Basic test case
1007 "Hi.\nThis is a test.\nTesting.",
1008 # Include a blank line
1009 "Hi.\nThis is a test.\n \nTesting.",
1010 # Include leading and trailing blank lines
1011 " \nHi.\nThis is a test.\nTesting.\n",
1012 # Use Windows line endings
1013 "Hi.\r\nThis is a test.\r\nTesting.\r\n",
1014 # Pathological case
1015 " \nHi.\r\nThis is a test.\n \r\nTesting.\r\n \n",
1016 )
1017 predicate = lambda line: not line.strip()
1018 for text, expect in zip(self.CASES, expected):
1019 self.assertEqual(indent(text, prefix, predicate), expect)
1020
1021
1022 class ESC[4;38;5;81mShortenTestCase(ESC[4;38;5;149mBaseTestCase):
1023
1024 def check_shorten(self, text, width, expect, **kwargs):
1025 result = shorten(text, width, **kwargs)
1026 self.check(result, expect)
1027
1028 def test_simple(self):
1029 # Simple case: just words, spaces, and a bit of punctuation
1030 text = "Hello there, how are you this fine day? I'm glad to hear it!"
1031
1032 self.check_shorten(text, 18, "Hello there, [...]")
1033 self.check_shorten(text, len(text), text)
1034 self.check_shorten(text, len(text) - 1,
1035 "Hello there, how are you this fine day? "
1036 "I'm glad to [...]")
1037
1038 def test_placeholder(self):
1039 text = "Hello there, how are you this fine day? I'm glad to hear it!"
1040
1041 self.check_shorten(text, 17, "Hello there,$$", placeholder='$$')
1042 self.check_shorten(text, 18, "Hello there, how$$", placeholder='$$')
1043 self.check_shorten(text, 18, "Hello there, $$", placeholder=' $$')
1044 self.check_shorten(text, len(text), text, placeholder='$$')
1045 self.check_shorten(text, len(text) - 1,
1046 "Hello there, how are you this fine day? "
1047 "I'm glad to hear$$", placeholder='$$')
1048
1049 def test_empty_string(self):
1050 self.check_shorten("", 6, "")
1051
1052 def test_whitespace(self):
1053 # Whitespace collapsing
1054 text = """
1055 This is a paragraph that already has
1056 line breaks and \t tabs too."""
1057 self.check_shorten(text, 62,
1058 "This is a paragraph that already has line "
1059 "breaks and tabs too.")
1060 self.check_shorten(text, 61,
1061 "This is a paragraph that already has line "
1062 "breaks and [...]")
1063
1064 self.check_shorten("hello world! ", 12, "hello world!")
1065 self.check_shorten("hello world! ", 11, "hello [...]")
1066 # The leading space is trimmed from the placeholder
1067 # (it would be ugly otherwise).
1068 self.check_shorten("hello world! ", 10, "[...]")
1069
1070 def test_width_too_small_for_placeholder(self):
1071 shorten("x" * 20, width=8, placeholder="(......)")
1072 with self.assertRaises(ValueError):
1073 shorten("x" * 20, width=8, placeholder="(.......)")
1074
1075 def test_first_word_too_long_but_placeholder_fits(self):
1076 self.check_shorten("Helloo", 5, "[...]")
1077
1078
1079 if __name__ == '__main__':
1080 unittest.main()