blob: ed97f70ba1fa40e829c3a8d1a6387ac631c6f1a7 [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
12
Antoine Pitrou389dec82013-08-12 22:39:09 +020013from textwrap import TextWrapper, wrap, fill, dedent, indent, shorten
Greg Ward90c0b072002-08-22 18:11:10 +000014
15
Greg Ward13c53c62002-08-22 18:57:26 +000016class BaseTestCase(unittest.TestCase):
Greg Ward90c0b072002-08-22 18:11:10 +000017 '''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]))
R David Murray1585b702012-09-08 13:13:25 -040024 result = "\n".join(result) if result else " no lines"
Guido van Rossum3172c5d2007-10-16 18:12:55 +000025 elif isinstance(textin, str):
Greg Ward90c0b072002-08-22 18:11:10 +000026 result = " %s\n" % repr(textin)
27 return result
28
29
30 def check(self, result, expect):
Ezio Melottib3aedd42010-11-20 19:04:17 +000031 self.assertEqual(result, expect,
Greg Ward9ad15a32002-08-22 19:47:27 +000032 'expected:\n%s\nbut got:\n%s' % (
33 self.show(expect), self.show(result)))
Greg Ward90c0b072002-08-22 18:11:10 +000034
Guido van Rossumeb287a22002-10-02 15:47:32 +000035 def check_wrap(self, text, width, expect, **kwargs):
36 result = wrap(text, width, **kwargs)
Greg Wardee413842002-08-22 18:55:38 +000037 self.check(result, expect)
38
Greg Wardd1a72a02002-10-31 16:11:18 +000039 def check_split(self, text, expect):
40 result = self.wrapper._split(text)
Ezio Melottib3aedd42010-11-20 19:04:17 +000041 self.assertEqual(result, expect,
42 "\nexpected %r\n"
43 "but got %r" % (expect, result))
Greg Ward715debd2002-08-22 21:16:25 +000044
Greg Ward90c0b072002-08-22 18:11:10 +000045
Greg Ward13c53c62002-08-22 18:57:26 +000046class WrapTestCase(BaseTestCase):
Greg Ward90c0b072002-08-22 18:11:10 +000047
Greg Ward90c0b072002-08-22 18:11:10 +000048 def setUp(self):
Greg Wardf0ba7642004-05-13 01:53:10 +000049 self.wrapper = TextWrapper(width=45)
Greg Ward90c0b072002-08-22 18:11:10 +000050
Greg Wardf6765782002-08-22 18:35:49 +000051 def test_simple(self):
Guido van Rossum327af772002-08-22 20:13:47 +000052 # Simple case: just words, spaces, and a bit of punctuation
Greg Ward90c0b072002-08-22 18:11:10 +000053
Greg Wardee413842002-08-22 18:55:38 +000054 text = "Hello there, how are you this fine day? I'm glad to hear it!"
Greg Ward90c0b072002-08-22 18:11:10 +000055
Greg Wardee413842002-08-22 18:55:38 +000056 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])
Greg Ward90c0b072002-08-22 18:11:10 +000067
R David Murray1585b702012-09-08 13:13:25 -040068 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)
Greg Ward90c0b072002-08-22 18:11:10 +000077
Greg Wardf6765782002-08-22 18:35:49 +000078 def test_whitespace(self):
Guido van Rossum327af772002-08-22 20:13:47 +000079 # Whitespace munging and end-of-sentence detection
Greg Ward90c0b072002-08-22 18:11:10 +000080
Greg Wardee413842002-08-22 18:55:38 +000081 text = """\
Greg Ward90c0b072002-08-22 18:11:10 +000082This is a paragraph that already has
83line breaks. But some of its lines are much longer than the others,
84so it needs to be wrapped.
85Some lines are \ttabbed too.
86What a mess!
87"""
88
Greg Wardee413842002-08-22 18:55:38 +000089 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!"]
Greg Ward90c0b072002-08-22 18:11:10 +000094
Greg Wardf0ba7642004-05-13 01:53:10 +000095 wrapper = TextWrapper(45, fix_sentence_endings=True)
96 result = wrapper.wrap(text)
Greg Ward90c0b072002-08-22 18:11:10 +000097 self.check(result, expect)
98
Greg Wardf0ba7642004-05-13 01:53:10 +000099 result = wrapper.fill(text)
Greg Ward90c0b072002-08-22 18:11:10 +0000100 self.check(result, '\n'.join(expect))
101
Hynek Schlawackd5272592012-05-19 13:33:11 +0200102 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
Greg Wardf0ba7642004-05-13 01:53:10 +0000110 def test_fix_sentence_endings(self):
111 wrapper = TextWrapper(60, fix_sentence_endings=True)
Greg Ward90c0b072002-08-22 18:11:10 +0000112
Greg Wardf0ba7642004-05-13 01:53:10 +0000113 # 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)
Tim Peters27f88362004-07-08 04:22:35 +0000147
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000148 text = 'File stdio.h is nice.'
149 expect = ['File stdio.h is nice.']
150 self.check(wrapper.wrap(text), expect)
151
Greg Wardf6765782002-08-22 18:35:49 +0000152 def test_wrap_short(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000153 # Wrapping to make short lines longer
Greg Ward90c0b072002-08-22 18:11:10 +0000154
Greg Wardee413842002-08-22 18:55:38 +0000155 text = "This is a\nshort paragraph."
Greg Ward90c0b072002-08-22 18:11:10 +0000156
Greg Wardee413842002-08-22 18:55:38 +0000157 self.check_wrap(text, 20, ["This is a short",
158 "paragraph."])
159 self.check_wrap(text, 40, ["This is a short paragraph."])
Greg Ward90c0b072002-08-22 18:11:10 +0000160
161
Guido van Rossumeb287a22002-10-02 15:47:32 +0000162 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
Greg Wardf6765782002-08-22 18:35:49 +0000172 def test_hyphenated(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000173 # Test breaking hyphenated words
Greg Ward90c0b072002-08-22 18:11:10 +0000174
Greg Wardee413842002-08-22 18:55:38 +0000175 text = ("this-is-a-useful-feature-for-"
176 "reformatting-posts-from-tim-peters'ly")
Greg Ward90c0b072002-08-22 18:11:10 +0000177
Greg Wardee413842002-08-22 18:55:38 +0000178 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"])
Serhiy Storchaka72bd3272015-03-24 18:32:27 +0200187 # 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('|'))
Greg Ward90c0b072002-08-22 18:11:10 +0000197
Greg Ward40407942005-03-05 02:53:17 +0000198 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.'])
Serhiy Storchaka72bd3272015-03-24 18:32:27 +0200208 self.check_wrap(text, 1, text.split(), break_long_words=False)
Greg Ward40407942005-03-05 02:53:17 +0000209
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."])
Serhiy Storchaka72bd3272015-03-24 18:32:27 +0200216 self.check_wrap(text, 1, text.split(), break_long_words=False)
Greg Ward40407942005-03-05 02:53:17 +0000217
Greg Ward9ad15a32002-08-22 19:47:27 +0000218 def test_em_dash(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000219 # Test text with em-dashes
Greg Ward9ad15a32002-08-22 19:47:27 +0000220 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."])
Guido van Rossum327af772002-08-22 20:13:47 +0000236
Greg Ward9ad15a32002-08-22 19:47:27 +0000237 # 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!"
Greg Ward9ad15a32002-08-22 19:47:27 +0000262 expect = ["Here's", " ", "an", " ", "--", " ", "em-", "dash", " ",
263 "and", "--", "here's", " ", "another", "---",
264 "and", " ", "another!"]
Greg Wardd1a72a02002-10-31 16:11:18 +0000265 self.check_split(text, expect)
Greg Ward90c0b072002-08-22 18:11:10 +0000266
Greg Wardc6edb372002-08-22 21:27:05 +0000267 text = "and then--bam!--he was gone"
268 expect = ["and", " ", "then", "--", "bam!", "--",
269 "he", " ", "was", " ", "gone"]
Greg Wardd1a72a02002-10-31 16:11:18 +0000270 self.check_split(text, expect)
Greg Wardc6edb372002-08-22 21:27:05 +0000271
272
Greg Ward34f995b2002-08-22 21:10:07 +0000273 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
Greg Ward24a1c9c2002-08-22 21:12:54 +0000301 # Again, all of the above can be deduced from _split().
302 text = "the -n option, or --dry-run or --dryrun"
Greg Ward24a1c9c2002-08-22 21:12:54 +0000303 expect = ["the", " ", "-n", " ", "option,", " ", "or", " ",
304 "--dry-", "run", " ", "or", " ", "--dryrun"]
Greg Wardd1a72a02002-10-31 16:11:18 +0000305 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
Greg Wardcc55cb92003-05-07 01:19:22 +0000315 # 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...
Greg Wardd1a72a02002-10-31 16:11:18 +0000319 self.check_split("--option", ["--option"])
320 self.check_split("--option-opt", ["--option-", "opt"])
Greg Wardcc55cb92003-05-07 01:19:22 +0000321 self.check_split("foo --option-opt bar",
322 ["foo", " ", "--option-", "opt", " ", "bar"])
323
Greg Ward61864102004-06-03 01:59:41 +0000324 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
Serhiy Storchaka72bd3272015-03-24 18:32:27 +0200341 # 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
Greg Wardcc55cb92003-05-07 01:19:22 +0000345 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"])
Greg Ward24a1c9c2002-08-22 21:12:54 +0000357
R David Murray1585b702012-09-08 13:13:25 -0400358 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).
Greg Ward24cbbcb2002-12-09 16:27:15 +0000384 # 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
R David Murray1585b702012-09-08 13:13:25 -0400392 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"],
Guido van Rossumd8faa362007-04-27 19:54:29 +0000398 drop_whitespace=False)
R David Murray1585b702012-09-08 13:13:25 -0400399 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=" ")
Guido van Rossumd8faa362007-04-27 19:54:29 +0000413
Greg Ward90c0b072002-08-22 18:11:10 +0000414 def test_split(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000415 # Ensure that the standard _split() method works as advertised
416 # in the comments
Greg Ward90c0b072002-08-22 18:11:10 +0000417
Greg Wardee413842002-08-22 18:55:38 +0000418 text = "Hello there -- you goof-ball, use the -b option!"
Greg Ward90c0b072002-08-22 18:11:10 +0000419
Greg Wardee413842002-08-22 18:55:38 +0000420 result = self.wrapper._split(text)
Greg Ward90c0b072002-08-22 18:11:10 +0000421 self.check(result,
422 ["Hello", " ", "there", " ", "--", " ", "you", " ", "goof-",
423 "ball,", " ", "use", " ", "the", " ", "-b", " ", "option!"])
424
Alexandre Vassalotti5f8ced22008-05-16 00:03:33 +0000425 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
Greg Ward49128572003-05-07 00:54:42 +0000433 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
Antoine Pitrou7c59bc62008-12-13 23:20:54 +0000439 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
Serhiy Storchakaf3ebc9f2016-10-25 14:44:54 +0300447 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
Greg Ward90c0b072002-08-22 18:11:10 +0000478
Serhiy Storchakaacc9f3f2013-10-15 21:22:54 +0300479class MaxLinesTestCase(BaseTestCase):
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
Jonathan Eunice5edf8272017-06-07 16:49:13 -0400562 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
Serhiy Storchakaacc9f3f2013-10-15 21:22:54 +0300573
Greg Wardfd030e42002-08-22 19:02:37 +0000574class LongWordTestCase (BaseTestCase):
575 def setUp(self):
576 self.wrapper = TextWrapper()
Greg Ward24cbbcb2002-12-09 16:27:15 +0000577 self.text = '''\
Greg Ward90c0b072002-08-22 18:11:10 +0000578Did you say "supercalifragilisticexpialidocious?"
579How *do* you spell that odd word, anyways?
580'''
Greg Wardfd030e42002-08-22 19:02:37 +0000581
582 def test_break_long(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000583 # Wrap text with long words and lots of punctuation
Greg Wardfd030e42002-08-22 19:02:37 +0000584
585 self.check_wrap(self.text, 30,
Greg Wardee413842002-08-22 18:55:38 +0000586 ['Did you say "supercalifragilis',
587 'ticexpialidocious?" How *do*',
588 'you spell that odd word,',
589 'anyways?'])
Greg Wardfd030e42002-08-22 19:02:37 +0000590 self.check_wrap(self.text, 50,
Greg Wardee413842002-08-22 18:55:38 +0000591 ['Did you say "supercalifragilisticexpialidocious?"',
592 'How *do* you spell that odd word, anyways?'])
Greg Ward90c0b072002-08-22 18:11:10 +0000593
Raymond Hettingerc11dbcd2003-08-30 14:43:55 +0000594 # 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)
Greg Ward90c0b072002-08-22 18:11:10 +0000604
Georg Brandlfceab5a2008-01-19 20:08:23 +0000605 # 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
Guido van Rossum327af772002-08-22 20:13:47 +0000618 def test_nobreak_long(self):
619 # Test with break_long_words disabled
Greg Ward90c0b072002-08-22 18:11:10 +0000620 self.wrapper.break_long_words = 0
621 self.wrapper.width = 30
Greg Wardee413842002-08-22 18:55:38 +0000622 expect = ['Did you say',
623 '"supercalifragilisticexpialidocious?"',
624 'How *do* you spell that odd',
625 'word, anyways?'
Guido van Rossum327af772002-08-22 20:13:47 +0000626 ]
Greg Wardfd030e42002-08-22 19:02:37 +0000627 result = self.wrapper.wrap(self.text)
Greg Ward90c0b072002-08-22 18:11:10 +0000628 self.check(result, expect)
629
630 # Same thing with kwargs passed to standalone wrap() function.
Greg Wardfd030e42002-08-22 19:02:37 +0000631 result = wrap(self.text, width=30, break_long_words=0)
Greg Ward90c0b072002-08-22 18:11:10 +0000632 self.check(result, expect)
633
Serhiy Storchakaacc9f3f2013-10-15 21:22:54 +0300634 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
Greg Ward90c0b072002-08-22 18:11:10 +0000642
Greg Ward13c53c62002-08-22 18:57:26 +0000643class IndentTestCases(BaseTestCase):
Greg Ward90c0b072002-08-22 18:11:10 +0000644
645 # called before each test method
646 def setUp(self):
Greg Wardf69d3c92002-08-22 19:06:45 +0000647 self.text = '''\
Greg Ward90c0b072002-08-22 18:11:10 +0000648This paragraph will be filled, first without any indentation,
649and then with some (including a hanging indent).'''
650
651
Greg Wardf6765782002-08-22 18:35:49 +0000652 def test_fill(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000653 # Test the fill() method
Greg Ward90c0b072002-08-22 18:11:10 +0000654
655 expect = '''\
656This paragraph will be filled, first
657without any indentation, and then with
658some (including a hanging indent).'''
659
Greg Wardf69d3c92002-08-22 19:06:45 +0000660 result = fill(self.text, 40)
Greg Ward90c0b072002-08-22 18:11:10 +0000661 self.check(result, expect)
662
663
Greg Wardf6765782002-08-22 18:35:49 +0000664 def test_initial_indent(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000665 # Test initial_indent parameter
Greg Ward90c0b072002-08-22 18:11:10 +0000666
Greg Wardf69d3c92002-08-22 19:06:45 +0000667 expect = [" This paragraph will be filled,",
668 "first without any indentation, and then",
669 "with some (including a hanging indent)."]
670 result = wrap(self.text, 40, initial_indent=" ")
Greg Ward90c0b072002-08-22 18:11:10 +0000671 self.check(result, expect)
672
Greg Wardf69d3c92002-08-22 19:06:45 +0000673 expect = "\n".join(expect)
674 result = fill(self.text, 40, initial_indent=" ")
Greg Ward90c0b072002-08-22 18:11:10 +0000675 self.check(result, expect)
676
677
Greg Wardf6765782002-08-22 18:35:49 +0000678 def test_subsequent_indent(self):
Guido van Rossum327af772002-08-22 20:13:47 +0000679 # Test subsequent_indent parameter
Greg Ward90c0b072002-08-22 18:11:10 +0000680
681 expect = '''\
682 * This paragraph will be filled, first
683 without any indentation, and then
684 with some (including a hanging
685 indent).'''
686
Greg Wardf69d3c92002-08-22 19:06:45 +0000687 result = fill(self.text, 40,
688 initial_indent=" * ", subsequent_indent=" ")
Greg Ward90c0b072002-08-22 18:11:10 +0000689 self.check(result, expect)
690
691
Greg Ward9e082f42003-05-08 01:58:26 +0000692# Despite the similar names, DedentTestCase is *not* the inverse
693# of IndentTestCase!
694class DedentTestCase(unittest.TestCase):
695
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000696 def assertUnchanged(self, text):
697 """assert that dedent() has no effect on 'text'"""
Ezio Melottib3aedd42010-11-20 19:04:17 +0000698 self.assertEqual(text, dedent(text))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000699
Greg Ward9e082f42003-05-08 01:58:26 +0000700 def test_dedent_nomargin(self):
701 # No lines indented.
702 text = "Hello there.\nHow are you?\nOh good, I'm glad."
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000703 self.assertUnchanged(text)
Greg Ward9e082f42003-05-08 01:58:26 +0000704
705 # Similar, with a blank line.
706 text = "Hello there.\n\nBoo!"
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000707 self.assertUnchanged(text)
Greg Ward9e082f42003-05-08 01:58:26 +0000708
709 # Some lines indented, but overall margin is still zero.
710 text = "Hello there.\n This is indented."
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000711 self.assertUnchanged(text)
Greg Ward9e082f42003-05-08 01:58:26 +0000712
713 # Again, add a blank line.
714 text = "Hello there.\n\n Boo!\n"
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000715 self.assertUnchanged(text)
Greg Ward9e082f42003-05-08 01:58:26 +0000716
717 def test_dedent_even(self):
718 # All lines indented by two spaces.
719 text = " Hello there.\n How are ya?\n Oh good."
720 expect = "Hello there.\nHow are ya?\nOh good."
Ezio Melottib3aedd42010-11-20 19:04:17 +0000721 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000722
723 # Same, with blank lines.
724 text = " Hello there.\n\n How are ya?\n Oh good.\n"
725 expect = "Hello there.\n\nHow are ya?\nOh good.\n"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000726 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000727
728 # Now indent one of the blank lines.
729 text = " Hello there.\n \n How are ya?\n Oh good.\n"
730 expect = "Hello there.\n\nHow are ya?\nOh good.\n"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000731 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000732
733 def test_dedent_uneven(self):
734 # Lines indented unevenly.
735 text = '''\
736 def foo():
737 while 1:
738 return foo
739 '''
740 expect = '''\
741def foo():
742 while 1:
743 return foo
744'''
Ezio Melottib3aedd42010-11-20 19:04:17 +0000745 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000746
747 # Uneven indentation with a blank line.
748 text = " Foo\n Bar\n\n Baz\n"
749 expect = "Foo\n Bar\n\n Baz\n"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000750 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000751
752 # Uneven indentation with a whitespace-only line.
753 text = " Foo\n Bar\n \n Baz\n"
754 expect = "Foo\n Bar\n\n Baz\n"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000755 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000756
Jonathan Eunice214f7ee2017-06-15 22:18:54 -0400757 def test_dedent_declining(self):
Jonathan Eunice601483d2017-06-13 15:04:10 -0400758 # Uneven indentation with declining indent level.
759 text = " Foo\n Bar\n" # 5 spaces, then 4
760 expect = " Foo\nBar\n"
761 self.assertEqual(expect, dedent(text))
762
Jonathan Eunice214f7ee2017-06-15 22:18:54 -0400763 # Declining indent level with blank line.
764 text = " Foo\n\n Bar\n" # 5 spaces, blank, then 4
765 expect = " Foo\n\nBar\n"
766 self.assertEqual(expect, dedent(text))
767
768 # Declining indent level with whitespace only line.
769 text = " Foo\n \n Bar\n" # 5 spaces, then 4, then 4
770 expect = " Foo\n\nBar\n"
771 self.assertEqual(expect, dedent(text))
772
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000773 # dedent() should not mangle internal tabs
774 def test_dedent_preserve_internal_tabs(self):
775 text = " hello\tthere\n how are\tyou?"
776 expect = "hello\tthere\nhow are\tyou?"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000777 self.assertEqual(expect, dedent(text))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000778
779 # make sure that it preserves tabs when it's not making any
780 # changes at all
Ezio Melottib3aedd42010-11-20 19:04:17 +0000781 self.assertEqual(expect, dedent(expect))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000782
783 # dedent() should not mangle tabs in the margin (i.e.
784 # tabs and spaces both count as margin, but are *not*
785 # considered equivalent)
786 def test_dedent_preserve_margin_tabs(self):
787 text = " hello there\n\thow are you?"
788 self.assertUnchanged(text)
789
790 # same effect even if we have 8 spaces
791 text = " hello there\n\thow are you?"
792 self.assertUnchanged(text)
793
794 # dedent() only removes whitespace that can be uniformly removed!
795 text = "\thello there\n\thow are you?"
796 expect = "hello there\nhow are you?"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000797 self.assertEqual(expect, dedent(text))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000798
799 text = " \thello there\n \thow are you?"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000800 self.assertEqual(expect, dedent(text))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000801
802 text = " \t hello there\n \t how are you?"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000803 self.assertEqual(expect, dedent(text))
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000804
805 text = " \thello there\n \t how are you?"
806 expect = "hello there\n how are you?"
Ezio Melottib3aedd42010-11-20 19:04:17 +0000807 self.assertEqual(expect, dedent(text))
Greg Ward9e082f42003-05-08 01:58:26 +0000808
Serhiy Storchakaea4cb632015-10-28 21:39:36 +0200809 # test margin is smaller than smallest indent
810 text = " \thello there\n \thow are you?\n \tI'm fine, thanks"
811 expect = " \thello there\n \thow are you?\n\tI'm fine, thanks"
812 self.assertEqual(expect, dedent(text))
813
Greg Ward9e082f42003-05-08 01:58:26 +0000814
Nick Coghlan4fae8cd2012-06-11 23:07:51 +1000815# Test textwrap.indent
816class IndentTestCase(unittest.TestCase):
817 # The examples used for tests. If any of these change, the expected
818 # results in the various test cases must also be updated.
819 # The roundtrip cases are separate, because textwrap.dedent doesn't
820 # handle Windows line endings
821 ROUNDTRIP_CASES = (
822 # Basic test case
823 "Hi.\nThis is a test.\nTesting.",
824 # Include a blank line
825 "Hi.\nThis is a test.\n\nTesting.",
826 # Include leading and trailing blank lines
827 "\nHi.\nThis is a test.\nTesting.\n",
828 )
829 CASES = ROUNDTRIP_CASES + (
830 # Use Windows line endings
831 "Hi.\r\nThis is a test.\r\nTesting.\r\n",
832 # Pathological case
833 "\nHi.\r\nThis is a test.\n\r\nTesting.\r\n\n",
834 )
835
836 def test_indent_nomargin_default(self):
837 # indent should do nothing if 'prefix' is empty.
838 for text in self.CASES:
839 self.assertEqual(indent(text, ''), text)
840
841 def test_indent_nomargin_explicit_default(self):
842 # The same as test_indent_nomargin, but explicitly requesting
843 # the default behaviour by passing None as the predicate
844 for text in self.CASES:
845 self.assertEqual(indent(text, '', None), text)
846
847 def test_indent_nomargin_all_lines(self):
848 # The same as test_indent_nomargin, but using the optional
849 # predicate argument
850 predicate = lambda line: True
851 for text in self.CASES:
852 self.assertEqual(indent(text, '', predicate), text)
853
854 def test_indent_no_lines(self):
855 # Explicitly skip indenting any lines
856 predicate = lambda line: False
857 for text in self.CASES:
858 self.assertEqual(indent(text, ' ', predicate), text)
859
860 def test_roundtrip_spaces(self):
861 # A whitespace prefix should roundtrip with dedent
862 for text in self.ROUNDTRIP_CASES:
863 self.assertEqual(dedent(indent(text, ' ')), text)
864
865 def test_roundtrip_tabs(self):
866 # A whitespace prefix should roundtrip with dedent
867 for text in self.ROUNDTRIP_CASES:
868 self.assertEqual(dedent(indent(text, '\t\t')), text)
869
870 def test_roundtrip_mixed(self):
871 # A whitespace prefix should roundtrip with dedent
872 for text in self.ROUNDTRIP_CASES:
873 self.assertEqual(dedent(indent(text, ' \t \t ')), text)
874
875 def test_indent_default(self):
876 # Test default indenting of lines that are not whitespace only
877 prefix = ' '
878 expected = (
879 # Basic test case
880 " Hi.\n This is a test.\n Testing.",
881 # Include a blank line
882 " Hi.\n This is a test.\n\n Testing.",
883 # Include leading and trailing blank lines
884 "\n Hi.\n This is a test.\n Testing.\n",
885 # Use Windows line endings
886 " Hi.\r\n This is a test.\r\n Testing.\r\n",
887 # Pathological case
888 "\n Hi.\r\n This is a test.\n\r\n Testing.\r\n\n",
889 )
890 for text, expect in zip(self.CASES, expected):
891 self.assertEqual(indent(text, prefix), expect)
892
893 def test_indent_explicit_default(self):
894 # Test default indenting of lines that are not whitespace only
895 prefix = ' '
896 expected = (
897 # Basic test case
898 " Hi.\n This is a test.\n Testing.",
899 # Include a blank line
900 " Hi.\n This is a test.\n\n Testing.",
901 # Include leading and trailing blank lines
902 "\n Hi.\n This is a test.\n Testing.\n",
903 # Use Windows line endings
904 " Hi.\r\n This is a test.\r\n Testing.\r\n",
905 # Pathological case
906 "\n Hi.\r\n This is a test.\n\r\n Testing.\r\n\n",
907 )
908 for text, expect in zip(self.CASES, expected):
909 self.assertEqual(indent(text, prefix, None), expect)
910
911 def test_indent_all_lines(self):
912 # Add 'prefix' to all lines, including whitespace-only ones.
913 prefix = ' '
914 expected = (
915 # Basic test case
916 " Hi.\n This is a test.\n Testing.",
917 # Include a blank line
918 " Hi.\n This is a test.\n \n Testing.",
919 # Include leading and trailing blank lines
920 " \n Hi.\n This is a test.\n Testing.\n",
921 # Use Windows line endings
922 " Hi.\r\n This is a test.\r\n Testing.\r\n",
923 # Pathological case
924 " \n Hi.\r\n This is a test.\n \r\n Testing.\r\n \n",
925 )
926 predicate = lambda line: True
927 for text, expect in zip(self.CASES, expected):
928 self.assertEqual(indent(text, prefix, predicate), expect)
929
930 def test_indent_empty_lines(self):
931 # Add 'prefix' solely to whitespace-only lines.
932 prefix = ' '
933 expected = (
934 # Basic test case
935 "Hi.\nThis is a test.\nTesting.",
936 # Include a blank line
937 "Hi.\nThis is a test.\n \nTesting.",
938 # Include leading and trailing blank lines
939 " \nHi.\nThis is a test.\nTesting.\n",
940 # Use Windows line endings
941 "Hi.\r\nThis is a test.\r\nTesting.\r\n",
942 # Pathological case
943 " \nHi.\r\nThis is a test.\n \r\nTesting.\r\n \n",
944 )
945 predicate = lambda line: not line.strip()
946 for text, expect in zip(self.CASES, expected):
947 self.assertEqual(indent(text, prefix, predicate), expect)
948
949
Antoine Pitrou389dec82013-08-12 22:39:09 +0200950class ShortenTestCase(BaseTestCase):
951
Serhiy Storchakaacc9f3f2013-10-15 21:22:54 +0300952 def check_shorten(self, text, width, expect, **kwargs):
953 result = shorten(text, width, **kwargs)
954 self.check(result, expect)
955
Antoine Pitrou389dec82013-08-12 22:39:09 +0200956 def test_simple(self):
957 # Simple case: just words, spaces, and a bit of punctuation
958 text = "Hello there, how are you this fine day? I'm glad to hear it!"
959
Antoine Pitrouc5930562013-08-16 22:31:12 +0200960 self.check_shorten(text, 18, "Hello there, [...]")
Antoine Pitrou389dec82013-08-12 22:39:09 +0200961 self.check_shorten(text, len(text), text)
962 self.check_shorten(text, len(text) - 1,
963 "Hello there, how are you this fine day? "
Antoine Pitrouc5930562013-08-16 22:31:12 +0200964 "I'm glad to [...]")
Antoine Pitrou389dec82013-08-12 22:39:09 +0200965
966 def test_placeholder(self):
967 text = "Hello there, how are you this fine day? I'm glad to hear it!"
968
969 self.check_shorten(text, 17, "Hello there,$$", placeholder='$$')
970 self.check_shorten(text, 18, "Hello there, how$$", placeholder='$$')
971 self.check_shorten(text, 18, "Hello there, $$", placeholder=' $$')
972 self.check_shorten(text, len(text), text, placeholder='$$')
973 self.check_shorten(text, len(text) - 1,
974 "Hello there, how are you this fine day? "
975 "I'm glad to hear$$", placeholder='$$')
976
977 def test_empty_string(self):
978 self.check_shorten("", 6, "")
979
980 def test_whitespace(self):
981 # Whitespace collapsing
982 text = """
983 This is a paragraph that already has
984 line breaks and \t tabs too."""
985 self.check_shorten(text, 62,
986 "This is a paragraph that already has line "
987 "breaks and tabs too.")
988 self.check_shorten(text, 61,
989 "This is a paragraph that already has line "
Antoine Pitrouc5930562013-08-16 22:31:12 +0200990 "breaks and [...]")
Antoine Pitrou389dec82013-08-12 22:39:09 +0200991
992 self.check_shorten("hello world! ", 12, "hello world!")
Antoine Pitrouc5930562013-08-16 22:31:12 +0200993 self.check_shorten("hello world! ", 11, "hello [...]")
Antoine Pitrou389dec82013-08-12 22:39:09 +0200994 # The leading space is trimmed from the placeholder
995 # (it would be ugly otherwise).
Antoine Pitrouc5930562013-08-16 22:31:12 +0200996 self.check_shorten("hello world! ", 10, "[...]")
Antoine Pitrou389dec82013-08-12 22:39:09 +0200997
998 def test_width_too_small_for_placeholder(self):
Serhiy Storchakaacc9f3f2013-10-15 21:22:54 +0300999 shorten("x" * 20, width=8, placeholder="(......)")
Antoine Pitrou389dec82013-08-12 22:39:09 +02001000 with self.assertRaises(ValueError):
Serhiy Storchakaacc9f3f2013-10-15 21:22:54 +03001001 shorten("x" * 20, width=8, placeholder="(.......)")
Antoine Pitrou389dec82013-08-12 22:39:09 +02001002
1003 def test_first_word_too_long_but_placeholder_fits(self):
Antoine Pitrouc5930562013-08-16 22:31:12 +02001004 self.check_shorten("Helloo", 5, "[...]")
Antoine Pitrou389dec82013-08-12 22:39:09 +02001005
Greg Wardf6765782002-08-22 18:35:49 +00001006
Greg Ward90c0b072002-08-22 18:11:10 +00001007if __name__ == '__main__':
Antoine Pitrou389dec82013-08-12 22:39:09 +02001008 unittest.main()