Ticket #1601: 1601v5.patch

File 1601v5.patch, 5.0 KB (added by Stephen Solis, 9 years ago)

Added a better word wrap implementation and more unit tests

  • twisted/test/test_usage.py

     
    2424                 """],
    2525                ['flout', 'o'],
    2626                ]
     27    longdesc = ("\nA test documentation string.\n"
     28                "    This is an indented line longer than 80 characters: "
     29                "PADDING PADDING PADDING PADDING PADDING PADDING\n")
    2730
    2831    def opt_myflag(self):
    2932        self.opts['myflag'] = "PONY!"
     
    378381        self.failUnless(len(lines) > 0)
    379382        self.failUnless(lines[0].find("flagallicious") >= 0)
    380383
    381     def test_longdescNotWrapped(self):
     384    def test_getUsageWrapped(self):
    382385        """
    383         L{usage.Options.getUsage} does not wrap lines in C{longdesc}.
     386        L{usage.Options.getUsage} wraps lines to the specified width.
     387        """       
     388        usage = self.nice.getUsage(width=80)
     389        for line in usage.splitlines():
     390            self.assertTrue(len(line) <= 80)
     391
     392    def test_getUsageIndentation(self):
    384393        """
    385         self.nice.longdesc = ("\nA test documentation string.\n"
    386                     "This line has more than 80 characters-"
    387                     "PADDINGXXPADDINGXXPADDINGXXPADDINGXXPADDINGXXPADDING\n")
    388         self.nice.getUsage(width=80)
    389         self.assertTrue(len(self.nice.longdesc.splitlines()[2]) > 80)
     394        L{usage.Options.getUsage} maintains consistent indentation when
     395        wrapping lines in longdesc.
     396        """
     397        usage = self.nice.getUsage(width=80)
     398        self.assertEqual(usage.splitlines()[-2][:4], "    ")
     399        self.assertEqual(usage.splitlines()[-1][:4], "    ")
    390400
    391401
    392402class PortCoerceTestCase(unittest.TestCase):
  • twisted/test/test_text.py

     
    7373                      "%d < %s" % (len(failures), len(self.output),
    7474                                   self.lineWidth, failures))
    7575
     76
     77    def test_singleNewline(self):
     78        """
     79        Lines separated by one \n are considered part of the same paragraph.
     80        """
     81        sampleText = "foo\nbar\ndaz"
     82        result = text.wordWrap(sampleText, self.lineWidth)
     83        self.assertEqual(result, ["foo bar daz"])
     84
     85
    7686    def test_doubleNewline(self):
    7787        """
    78         Allow paragraphs delimited by two \ns.
     88        Allow paragraphs delimited by two \ns, but don't add a random trailing
     89        line at the end.
    7990        """
    8091        sampleText = "et\n\nphone\nhome."
    8192        result = text.wordWrap(sampleText, self.lineWidth)
    82         self.assertEqual(result, ["et", "", "phone home.", ""])
     93        self.assertEqual(result, ["et", "", "phone home."])
    8394
    8495
    8596
  • twisted/python/usage.py

     
    1616import os
    1717import sys
    1818import getopt
     19import textwrap
    1920from os import path
    2021
    2122# Sibling Imports
     
    534535                longdesc = ''
    535536
    536537        if longdesc:
    537             longdesc = '\n' + longdesc.strip() + '\n'
     538            wrappedLongdesc = '\n'
     539            for line in longdesc.strip().splitlines():
     540                indent = line[:len(line) - len(line.lstrip())]
     541                wrappedLongdesc += '\n'.join(
     542                                        textwrap.wrap(line, width,
     543                                                      subsequent_indent=indent)
     544                                        ) + '\n'
    538545
    539546        if optDicts:
    540547            chunks = docMakeChunks(optDicts, width)
     
    542549        else:
    543550            s = "Options: None\n"
    544551
    545         return s + longdesc + commands
     552        return s + wrappedLongdesc + commands
    546553
    547554    #def __repr__(self):
    548555    #    XXX: It'd be cool if we could return a succinct representation
  • twisted/python/text.py

     
    77Miscellany of text-munging functions.
    88"""
    99
     10# System imports
     11import textwrap
    1012
     13
    1114def stringyString(object, indentation=''):
    1215    """
    1316    Expansive string formatting for sequence types.
     
    127130    return outLines
    128131
    129132
    130 wordWrap = greedyWrap
     133def pythonWrap(text, width=80):
     134    """
     135    Given a string and a column width, return a list of lines each with length
     136    at most width.
     137    \n\n is the paragraph delimiter, and forces a line break.
    131138
     139    L{textwrap.wrap} from the standard library is used to do the wrapping.
     140    """
    132141
     142    outLines = []
     143
     144    for paragraph in text.split('\n\n'):
     145        outLines.extend(textwrap.wrap(paragraph, width) + [''])
     146
     147    # remove the final blank line from outLines
     148    outLines.pop()
     149
     150    return outLines
     151
     152
     153wordWrap = pythonWrap
     154
     155
    133156def removeLeadingBlanks(lines):
    134157    ret = []
    135158    for line in lines: