0001 # 0002 # Test suite for the textwrap module. 0003 # 0004 # Original tests written by Greg Ward <gward@python.net>. 0005 # Converted to PyUnit by Peter Hansen <peter@engcorp.com>. 0006 # Currently maintained by Greg Ward. 0007 # 0008 # $Id: test_textwrap.py,v 1.27 2004/07/08 04:22:19 tim_one Exp $ 0009 # 0010 0011 import unittest 0012 from test import test_support 0013 0014 from textwrap import TextWrapper, wrap, fill, dedent 0015 0016 0017 class BaseTestCase(unittest.TestCase): 0018 '''Parent class with utility methods for textwrap tests.''' 0019 0020 def show(self, textin): 0021 if isinstance(textin, list): 0022 result = [] 0023 for i in range(len(textin)): 0024 result.append(" %d: %r" % (i, textin[i])) 0025 result = '\n'.join(result) 0026 elif isinstance(textin, basestring): 0027 result = " %s\n" % repr(textin) 0028 return result 0029 0030 0031 def check(self, result, expect): 0032 self.assertEquals(result, expect, 0033 'expected:\n%s\nbut got:\n%s' % ( 0034 self.show(expect), self.show(result))) 0035 0036 def check_wrap(self, text, width, expect, **kwargs): 0037 result = wrap(text, width, **kwargs) 0038 self.check(result, expect) 0039 0040 def check_split(self, text, expect): 0041 result = self.wrapper._split(text) 0042 self.assertEquals(result, expect, 0043 "\nexpected %r\n" 0044 "but got %r" % (expect, result)) 0045 0046 0047 class WrapTestCase(BaseTestCase): 0048 0049 def setUp(self): 0050 self.wrapper = TextWrapper(width=45) 0051 0052 def test_simple(self): 0053 # Simple case: just words, spaces, and a bit of punctuation 0054 0055 text = "Hello there, how are you this fine day? I'm glad to hear it!" 0056 0057 self.check_wrap(text, 12, 0058 ["Hello there,", 0059 "how are you", 0060 "this fine", 0061 "day? I'm", 0062 "glad to hear", 0063 "it!"]) 0064 self.check_wrap(text, 42, 0065 ["Hello there, how are you this fine day?", 0066 "I'm glad to hear it!"]) 0067 self.check_wrap(text, 80, [text]) 0068 0069 0070 def test_whitespace(self): 0071 # Whitespace munging and end-of-sentence detection 0072 0073 text = """\ 0074 This is a paragraph that already has 0075 line breaks. But some of its lines are much longer than the others, 0076 so it needs to be wrapped. 0077 Some lines are \ttabbed too. 0078 What a mess! 0079 """ 0080 0081 expect = ["This is a paragraph that already has line", 0082 "breaks. But some of its lines are much", 0083 "longer than the others, so it needs to be", 0084 "wrapped. Some lines are tabbed too. What a", 0085 "mess!"] 0086 0087 wrapper = TextWrapper(45, fix_sentence_endings=True) 0088 result = wrapper.wrap(text) 0089 self.check(result, expect) 0090 0091 result = wrapper.fill(text) 0092 self.check(result, '\n'.join(expect)) 0093 0094 def test_fix_sentence_endings(self): 0095 wrapper = TextWrapper(60, fix_sentence_endings=True) 0096 0097 # SF #847346: ensure that fix_sentence_endings=True does the 0098 # right thing even on input short enough that it doesn't need to 0099 # be wrapped. 0100 text = "A short line. Note the single space." 0101 expect = ["A short line. Note the single space."] 0102 self.check(wrapper.wrap(text), expect) 0103 0104 # Test some of the hairy end cases that _fix_sentence_endings() 0105 # is supposed to handle (the easy stuff is tested in 0106 # test_whitespace() above). 0107 text = "Well, Doctor? What do you think?" 0108 expect = ["Well, Doctor? What do you think?"] 0109 self.check(wrapper.wrap(text), expect) 0110 0111 text = "Well, Doctor?\nWhat do you think?" 0112 self.check(wrapper.wrap(text), expect) 0113 0114 text = 'I say, chaps! Anyone for "tennis?"\nHmmph!' 0115 expect = ['I say, chaps! Anyone for "tennis?" Hmmph!'] 0116 self.check(wrapper.wrap(text), expect) 0117 0118 wrapper.width = 20 0119 expect = ['I say, chaps!', 'Anyone for "tennis?"', 'Hmmph!'] 0120 self.check(wrapper.wrap(text), expect) 0121 0122 text = 'And she said, "Go to hell!"\nCan you believe that?' 0123 expect = ['And she said, "Go to', 0124 'hell!" Can you', 0125 'believe that?'] 0126 self.check(wrapper.wrap(text), expect) 0127 0128 wrapper.width = 60 0129 expect = ['And she said, "Go to hell!" Can you believe that?'] 0130 self.check(wrapper.wrap(text), expect) 0131 0132 def test_wrap_short(self): 0133 # Wrapping to make short lines longer 0134 0135 text = "This is a\nshort paragraph." 0136 0137 self.check_wrap(text, 20, ["This is a short", 0138 "paragraph."]) 0139 self.check_wrap(text, 40, ["This is a short paragraph."]) 0140 0141 0142 def test_wrap_short_1line(self): 0143 # Test endcases 0144 0145 text = "This is a short line." 0146 0147 self.check_wrap(text, 30, ["This is a short line."]) 0148 self.check_wrap(text, 30, ["(1) This is a short line."], 0149 initial_indent="(1) ") 0150 0151 0152 def test_hyphenated(self): 0153 # Test breaking hyphenated words 0154 0155 text = ("this-is-a-useful-feature-for-" 0156 "reformatting-posts-from-tim-peters'ly") 0157 0158 self.check_wrap(text, 40, 0159 ["this-is-a-useful-feature-for-", 0160 "reformatting-posts-from-tim-peters'ly"]) 0161 self.check_wrap(text, 41, 0162 ["this-is-a-useful-feature-for-", 0163 "reformatting-posts-from-tim-peters'ly"]) 0164 self.check_wrap(text, 42, 0165 ["this-is-a-useful-feature-for-reformatting-", 0166 "posts-from-tim-peters'ly"]) 0167 0168 def test_em_dash(self): 0169 # Test text with em-dashes 0170 text = "Em-dashes should be written -- thus." 0171 self.check_wrap(text, 25, 0172 ["Em-dashes should be", 0173 "written -- thus."]) 0174 0175 # Probe the boundaries of the properly written em-dash, 0176 # ie. " -- ". 0177 self.check_wrap(text, 29, 0178 ["Em-dashes should be written", 0179 "-- thus."]) 0180 expect = ["Em-dashes should be written --", 0181 "thus."] 0182 self.check_wrap(text, 30, expect) 0183 self.check_wrap(text, 35, expect) 0184 self.check_wrap(text, 36, 0185 ["Em-dashes should be written -- thus."]) 0186 0187 # The improperly written em-dash is handled too, because 0188 # it's adjacent to non-whitespace on both sides. 0189 text = "You can also do--this or even---this." 0190 expect = ["You can also do", 0191 "--this or even", 0192 "---this."] 0193 self.check_wrap(text, 15, expect) 0194 self.check_wrap(text, 16, expect) 0195 expect = ["You can also do--", 0196 "this or even---", 0197 "this."] 0198 self.check_wrap(text, 17, expect) 0199 self.check_wrap(text, 19, expect) 0200 expect = ["You can also do--this or even", 0201 "---this."] 0202 self.check_wrap(text, 29, expect) 0203 self.check_wrap(text, 31, expect) 0204 expect = ["You can also do--this or even---", 0205 "this."] 0206 self.check_wrap(text, 32, expect) 0207 self.check_wrap(text, 35, expect) 0208 0209 # All of the above behaviour could be deduced by probing the 0210 # _split() method. 0211 text = "Here's an -- em-dash and--here's another---and another!" 0212 expect = ["Here's", " ", "an", " ", "--", " ", "em-", "dash", " ", 0213 "and", "--", "here's", " ", "another", "---", 0214 "and", " ", "another!"] 0215 self.check_split(text, expect) 0216 0217 text = "and then--bam!--he was gone" 0218 expect = ["and", " ", "then", "--", "bam!", "--", 0219 "he", " ", "was", " ", "gone"] 0220 self.check_split(text, expect) 0221 0222 0223 def test_unix_options (self): 0224 # Test that Unix-style command-line options are wrapped correctly. 0225 # Both Optik (OptionParser) and Docutils rely on this behaviour! 0226 0227 text = "You should use the -n option, or --dry-run in its long form." 0228 self.check_wrap(text, 20, 0229 ["You should use the", 0230 "-n option, or --dry-", 0231 "run in its long", 0232 "form."]) 0233 self.check_wrap(text, 21, 0234 ["You should use the -n", 0235 "option, or --dry-run", 0236 "in its long form."]) 0237 expect = ["You should use the -n option, or", 0238 "--dry-run in its long form."] 0239 self.check_wrap(text, 32, expect) 0240 self.check_wrap(text, 34, expect) 0241 self.check_wrap(text, 35, expect) 0242 self.check_wrap(text, 38, expect) 0243 expect = ["You should use the -n option, or --dry-", 0244 "run in its long form."] 0245 self.check_wrap(text, 39, expect) 0246 self.check_wrap(text, 41, expect) 0247 expect = ["You should use the -n option, or --dry-run", 0248 "in its long form."] 0249 self.check_wrap(text, 42, expect) 0250 0251 # Again, all of the above can be deduced from _split(). 0252 text = "the -n option, or --dry-run or --dryrun" 0253 expect = ["the", " ", "-n", " ", "option,", " ", "or", " ", 0254 "--dry-", "run", " ", "or", " ", "--dryrun"] 0255 self.check_split(text, expect) 0256 0257 def test_funky_hyphens (self): 0258 # Screwy edge cases cooked up by David Goodger. All reported 0259 # in SF bug #596434. 0260 self.check_split("what the--hey!", ["what", " ", "the", "--", "hey!"]) 0261 self.check_split("what the--", ["what", " ", "the--"]) 0262 self.check_split("what the--.", ["what", " ", "the--."]) 0263 self.check_split("--text--.", ["--text--."]) 0264 0265 # When I first read bug #596434, this is what I thought David 0266 # was talking about. I was wrong; these have always worked 0267 # fine. The real problem is tested in test_funky_parens() 0268 # below... 0269 self.check_split("--option", ["--option"]) 0270 self.check_split("--option-opt", ["--option-", "opt"]) 0271 self.check_split("foo --option-opt bar", 0272 ["foo", " ", "--option-", "opt", " ", "bar"]) 0273 0274 def test_punct_hyphens(self): 0275 # Oh bother, SF #965425 found another problem with hyphens -- 0276 # hyphenated words in single quotes weren't handled correctly. 0277 # In fact, the bug is that *any* punctuation around a hyphenated 0278 # word was handled incorrectly, except for a leading "--", which 0279 # was special-cased for Optik and Docutils. So test a variety 0280 # of styles of punctuation around a hyphenated word. 0281 # (Actually this is based on an Optik bug report, #813077). 0282 self.check_split("the 'wibble-wobble' widget", 0283 ['the', ' ', "'wibble-", "wobble'", ' ', 'widget']) 0284 self.check_split('the "wibble-wobble" widget', 0285 ['the', ' ', '"wibble-', 'wobble"', ' ', 'widget']) 0286 self.check_split("the (wibble-wobble) widget", 0287 ['the', ' ', "(wibble-", "wobble)", ' ', 'widget']) 0288 self.check_split("the ['wibble-wobble'] widget", 0289 ['the', ' ', "['wibble-", "wobble']", ' ', 'widget']) 0290 0291 def test_funky_parens (self): 0292 # Second part of SF bug #596434: long option strings inside 0293 # parentheses. 0294 self.check_split("foo (--option) bar", 0295 ["foo", " ", "(--option)", " ", "bar"]) 0296 0297 # Related stuff -- make sure parens work in simpler contexts. 0298 self.check_split("foo (bar) baz", 0299 ["foo", " ", "(bar)", " ", "baz"]) 0300 self.check_split("blah (ding dong), wubba", 0301 ["blah", " ", "(ding", " ", "dong),", 0302 " ", "wubba"]) 0303 0304 def test_initial_whitespace(self): 0305 # SF bug #622849 reported inconsistent handling of leading 0306 # whitespace; let's test that a bit, shall we? 0307 text = " This is a sentence with leading whitespace." 0308 self.check_wrap(text, 50, 0309 [" This is a sentence with leading whitespace."]) 0310 self.check_wrap(text, 30, 0311 [" This is a sentence with", "leading whitespace."]) 0312 0313 def test_unicode(self): 0314 # *Very* simple test of wrapping Unicode strings. I'm sure 0315 # there's more to it than this, but let's at least make 0316 # sure textwrap doesn't crash on Unicode input! 0317 text = u"Hello there, how are you today?" 0318 self.check_wrap(text, 50, [u"Hello there, how are you today?"]) 0319 self.check_wrap(text, 20, [u"Hello there, how are", "you today?"]) 0320 olines = self.wrapper.wrap(text) 0321 assert isinstance(olines, list) and isinstance(olines[0], unicode) 0322 otext = self.wrapper.fill(text) 0323 assert isinstance(otext, unicode) 0324 0325 def test_split(self): 0326 # Ensure that the standard _split() method works as advertised 0327 # in the comments 0328 0329 text = "Hello there -- you goof-ball, use the -b option!" 0330 0331 result = self.wrapper._split(text) 0332 self.check(result, 0333 ["Hello", " ", "there", " ", "--", " ", "you", " ", "goof-", 0334 "ball,", " ", "use", " ", "the", " ", "-b", " ", "option!"]) 0335 0336 def test_bad_width(self): 0337 # Ensure that width <= 0 is caught. 0338 text = "Whatever, it doesn't matter." 0339 self.assertRaises(ValueError, wrap, text, 0) 0340 self.assertRaises(ValueError, wrap, text, -1) 0341 0342 0343 class LongWordTestCase (BaseTestCase): 0344 def setUp(self): 0345 self.wrapper = TextWrapper() 0346 self.text = '''\ 0347 Did you say "supercalifragilisticexpialidocious?" 0348 How *do* you spell that odd word, anyways? 0349 ''' 0350 0351 def test_break_long(self): 0352 # Wrap text with long words and lots of punctuation 0353 0354 self.check_wrap(self.text, 30, 0355 ['Did you say "supercalifragilis', 0356 'ticexpialidocious?" How *do*', 0357 'you spell that odd word,', 0358 'anyways?']) 0359 self.check_wrap(self.text, 50, 0360 ['Did you say "supercalifragilisticexpialidocious?"', 0361 'How *do* you spell that odd word, anyways?']) 0362 0363 # SF bug 797650. Prevent an infinite loop by making sure that at 0364 # least one character gets split off on every pass. 0365 self.check_wrap('-'*10+'hello', 10, 0366 ['----------', 0367 ' h', 0368 ' e', 0369 ' l', 0370 ' l', 0371 ' o'], 0372 subsequent_indent = ' '*15) 0373 0374 def test_nobreak_long(self): 0375 # Test with break_long_words disabled 0376 self.wrapper.break_long_words = 0 0377 self.wrapper.width = 30 0378 expect = ['Did you say', 0379 '"supercalifragilisticexpialidocious?"', 0380 'How *do* you spell that odd', 0381 'word, anyways?' 0382 ] 0383 result = self.wrapper.wrap(self.text) 0384 self.check(result, expect) 0385 0386 # Same thing with kwargs passed to standalone wrap() function. 0387 result = wrap(self.text, width=30, break_long_words=0) 0388 self.check(result, expect) 0389 0390 0391 class IndentTestCases(BaseTestCase): 0392 0393 # called before each test method 0394 def setUp(self): 0395 self.text = '''\ 0396 This paragraph will be filled, first without any indentation, 0397 and then with some (including a hanging indent).''' 0398 0399 0400 def test_fill(self): 0401 # Test the fill() method 0402 0403 expect = '''\ 0404 This paragraph will be filled, first 0405 without any indentation, and then with 0406 some (including a hanging indent).''' 0407 0408 result = fill(self.text, 40) 0409 self.check(result, expect) 0410 0411 0412 def test_initial_indent(self): 0413 # Test initial_indent parameter 0414 0415 expect = [" This paragraph will be filled,", 0416 "first without any indentation, and then", 0417 "with some (including a hanging indent)."] 0418 result = wrap(self.text, 40, initial_indent=" ") 0419 self.check(result, expect) 0420 0421 expect = "\n".join(expect) 0422 result = fill(self.text, 40, initial_indent=" ") 0423 self.check(result, expect) 0424 0425 0426 def test_subsequent_indent(self): 0427 # Test subsequent_indent parameter 0428 0429 expect = '''\ 0430 * This paragraph will be filled, first 0431 without any indentation, and then 0432 with some (including a hanging 0433 indent).''' 0434 0435 result = fill(self.text, 40, 0436 initial_indent=" * ", subsequent_indent=" ") 0437 self.check(result, expect) 0438 0439 0440 # Despite the similar names, DedentTestCase is *not* the inverse 0441 # of IndentTestCase! 0442 class DedentTestCase(unittest.TestCase): 0443 0444 def test_dedent_nomargin(self): 0445 # No lines indented. 0446 text = "Hello there.\nHow are you?\nOh good, I'm glad." 0447 self.assertEquals(dedent(text), text) 0448 0449 # Similar, with a blank line. 0450 text = "Hello there.\n\nBoo!" 0451 self.assertEquals(dedent(text), text) 0452 0453 # Some lines indented, but overall margin is still zero. 0454 text = "Hello there.\n This is indented." 0455 self.assertEquals(dedent(text), text) 0456 0457 # Again, add a blank line. 0458 text = "Hello there.\n\n Boo!\n" 0459 self.assertEquals(dedent(text), text) 0460 0461 def test_dedent_even(self): 0462 # All lines indented by two spaces. 0463 text = " Hello there.\n How are ya?\n Oh good." 0464 expect = "Hello there.\nHow are ya?\nOh good." 0465 self.assertEquals(dedent(text), expect) 0466 0467 # Same, with blank lines. 0468 text = " Hello there.\n\n How are ya?\n Oh good.\n" 0469 expect = "Hello there.\n\nHow are ya?\nOh good.\n" 0470 self.assertEquals(dedent(text), expect) 0471 0472 # Now indent one of the blank lines. 0473 text = " Hello there.\n \n How are ya?\n Oh good.\n" 0474 expect = "Hello there.\n\nHow are ya?\nOh good.\n" 0475 self.assertEquals(dedent(text), expect) 0476 0477 def test_dedent_uneven(self): 0478 # Lines indented unevenly. 0479 text = '''\ 0480 def foo(): 0481 while 1: 0482 return foo 0483 ''' 0484 expect = '''\ 0485 def foo(): 0486 while 1: 0487 return foo 0488 ''' 0489 self.assertEquals(dedent(text), expect) 0490 0491 # Uneven indentation with a blank line. 0492 text = " Foo\n Bar\n\n Baz\n" 0493 expect = "Foo\n Bar\n\n Baz\n" 0494 self.assertEquals(dedent(text), expect) 0495 0496 # Uneven indentation with a whitespace-only line. 0497 text = " Foo\n Bar\n \n Baz\n" 0498 expect = "Foo\n Bar\n\n Baz\n" 0499 self.assertEquals(dedent(text), expect) 0500 0501 0502 0503 def test_main(): 0504 test_support.run_unittest(WrapTestCase, 0505 LongWordTestCase, 0506 IndentTestCases, 0507 DedentTestCase) 0508 0509 if __name__ == '__main__': 0510 test_main() 0511
Generated by PyXR 0.9.4