1edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#
2edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test suite for the textwrap module.
3edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#
4edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Original tests written by Greg Ward <gward@python.net>.
5edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Converted to PyUnit by Peter Hansen <peter@engcorp.com>.
6edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Currently maintained by Greg Ward.
7edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#
8edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# $Id$
9edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#
10edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
11edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport unittest
12edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom test import test_support
13edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
14edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom textwrap import TextWrapper, wrap, fill, dedent
15edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
16edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
17edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass BaseTestCase(unittest.TestCase):
18edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    '''Parent class with utility methods for textwrap tests.'''
19edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
20edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def show(self, textin):
21edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        if isinstance(textin, list):
22edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            result = []
23edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            for i in range(len(textin)):
24edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                result.append("  %d: %r" % (i, textin[i]))
25edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            result = '\n'.join(result)
26edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        elif isinstance(textin, basestring):
27edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            result = "  %s\n" % repr(textin)
28edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return result
29edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
30edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
31edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def check(self, result, expect):
32edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(result, expect,
33edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            'expected:\n%s\nbut got:\n%s' % (
34edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                self.show(expect), self.show(result)))
35edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
36edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def check_wrap(self, text, width, expect, **kwargs):
37edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = wrap(text, width, **kwargs)
38edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(result, expect)
39edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
40edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def check_split(self, text, expect):
41edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = self.wrapper._split(text)
42edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(result, expect,
43edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "\nexpected %r\n"
44edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "but got  %r" % (expect, result))
45edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
46edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
47edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass WrapTestCase(BaseTestCase):
48edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
49edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def setUp(self):
50edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.wrapper = TextWrapper(width=45)
51edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
52edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_simple(self):
53edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Simple case: just words, spaces, and a bit of punctuation
54edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
55edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "Hello there, how are you this fine day?  I'm glad to hear it!"
56edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
57edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 12,
58edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ["Hello there,",
59edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "how are you",
60edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "this fine",
61edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "day?  I'm",
62edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "glad to hear",
63edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "it!"])
64edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 42,
65edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ["Hello there, how are you this fine day?",
66edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "I'm glad to hear it!"])
67edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 80, [text])
68edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
69edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_empty_string(self):
70edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Check that wrapping the empty string returns an empty list.
71edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap("", 6, [])
72edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap("", 6, [], drop_whitespace=False)
73edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
74edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_empty_string_with_initial_indent(self):
75edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Check that the empty string is not indented.
76edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap("", 6, [], initial_indent="++")
77edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap("", 6, [], initial_indent="++", drop_whitespace=False)
78edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
79edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_whitespace(self):
80edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Whitespace munging and end-of-sentence detection
81edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
82edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = """\
83edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepThis is a paragraph that already has
84edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepline breaks.  But some of its lines are much longer than the others,
85edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepso it needs to be wrapped.
86edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSome lines are \ttabbed too.
87edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepWhat a mess!
88edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep"""
89edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
90edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["This is a paragraph that already has line",
91edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "breaks.  But some of its lines are much",
92edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "longer than the others, so it needs to be",
93edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "wrapped.  Some lines are  tabbed too.  What a",
94edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "mess!"]
95edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
96edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        wrapper = TextWrapper(45, fix_sentence_endings=True)
97edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = wrapper.wrap(text)
98edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(result, expect)
99edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = wrapper.fill(text)
101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(result, '\n'.join(expect))
102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_fix_sentence_endings(self):
104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        wrapper = TextWrapper(60, fix_sentence_endings=True)
105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # SF #847346: ensure that fix_sentence_endings=True does the
107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # right thing even on input short enough that it doesn't need to
108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # be wrapped.
109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "A short line. Note the single space."
110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["A short line.  Note the single space."]
111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(wrapper.wrap(text), expect)
112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Test some of the hairy end cases that _fix_sentence_endings()
114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # is supposed to handle (the easy stuff is tested in
115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # test_whitespace() above).
116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "Well, Doctor? What do you think?"
117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["Well, Doctor?  What do you think?"]
118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(wrapper.wrap(text), expect)
119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "Well, Doctor?\nWhat do you think?"
121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(wrapper.wrap(text), expect)
122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = 'I say, chaps! Anyone for "tennis?"\nHmmph!'
124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ['I say, chaps!  Anyone for "tennis?"  Hmmph!']
125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(wrapper.wrap(text), expect)
126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        wrapper.width = 20
128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ['I say, chaps!', 'Anyone for "tennis?"', 'Hmmph!']
129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(wrapper.wrap(text), expect)
130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = 'And she said, "Go to hell!"\nCan you believe that?'
132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ['And she said, "Go to',
133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  'hell!"  Can you',
134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  'believe that?']
135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(wrapper.wrap(text), expect)
136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        wrapper.width = 60
138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ['And she said, "Go to hell!"  Can you believe that?']
139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(wrapper.wrap(text), expect)
140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = 'File stdio.h is nice.'
142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ['File stdio.h is nice.']
143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(wrapper.wrap(text), expect)
144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_wrap_short(self):
146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Wrapping to make short lines longer
147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "This is a\nshort paragraph."
149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 20, ["This is a short",
151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                   "paragraph."])
152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 40, ["This is a short paragraph."])
153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_wrap_short_1line(self):
156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Test endcases
157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "This is a short line."
159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 30, ["This is a short line."])
161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 30, ["(1) This is a short line."],
162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        initial_indent="(1) ")
163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_hyphenated(self):
166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Test breaking hyphenated words
167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = ("this-is-a-useful-feature-for-"
169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                "reformatting-posts-from-tim-peters'ly")
170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 40,
172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ["this-is-a-useful-feature-for-",
173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "reformatting-posts-from-tim-peters'ly"])
174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 41,
175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ["this-is-a-useful-feature-for-",
176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "reformatting-posts-from-tim-peters'ly"])
177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 42,
178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ["this-is-a-useful-feature-for-reformatting-",
179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "posts-from-tim-peters'ly"])
180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_hyphenated_numbers(self):
182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Test that hyphenated numbers (eg. dates) are not broken like words.
183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = ("Python 1.0.0 was released on 1994-01-26.  Python 1.0.1 was\n"
184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                "released on 1994-02-15.")
185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 35, ['Python 1.0.0 was released on',
187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                   '1994-01-26.  Python 1.0.1 was',
188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                   'released on 1994-02-15.'])
189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 40, ['Python 1.0.0 was released on 1994-01-26.',
190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                   'Python 1.0.1 was released on 1994-02-15.'])
191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "I do all my shopping at 7-11."
193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 25, ["I do all my shopping at",
194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                   "7-11."])
195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 27, ["I do all my shopping at",
196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                                   "7-11."])
197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 29, ["I do all my shopping at 7-11."])
198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_em_dash(self):
200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Test text with em-dashes
201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "Em-dashes should be written -- thus."
202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 25,
203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ["Em-dashes should be",
204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "written -- thus."])
205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Probe the boundaries of the properly written em-dash,
207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # ie. " -- ".
208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 29,
209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ["Em-dashes should be written",
210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "-- thus."])
211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["Em-dashes should be written --",
212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "thus."]
213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 30, expect)
214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 35, expect)
215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 36,
216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ["Em-dashes should be written -- thus."])
217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # The improperly written em-dash is handled too, because
219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # it's adjacent to non-whitespace on both sides.
220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "You can also do--this or even---this."
221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["You can also do",
222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "--this or even",
223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "---this."]
224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 15, expect)
225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 16, expect)
226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["You can also do--",
227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "this or even---",
228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "this."]
229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 17, expect)
230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 19, expect)
231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["You can also do--this or even",
232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "---this."]
233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 29, expect)
234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 31, expect)
235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["You can also do--this or even---",
236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "this."]
237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 32, expect)
238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 35, expect)
239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # All of the above behaviour could be deduced by probing the
241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # _split() method.
242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "Here's an -- em-dash and--here's another---and another!"
243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["Here's", " ", "an", " ", "--", " ", "em-", "dash", " ",
244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "and", "--", "here's", " ", "another", "---",
245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "and", " ", "another!"]
246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split(text, expect)
247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "and then--bam!--he was gone"
249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["and", " ", "then", "--", "bam!", "--",
250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "he", " ", "was", " ", "gone"]
251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split(text, expect)
252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_unix_options (self):
255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Test that Unix-style command-line options are wrapped correctly.
256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Both Optik (OptionParser) and Docutils rely on this behaviour!
257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "You should use the -n option, or --dry-run in its long form."
259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 20,
260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ["You should use the",
261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "-n option, or --dry-",
262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "run in its long",
263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "form."])
264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 21,
265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ["You should use the -n",
266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "option, or --dry-run",
267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "in its long form."])
268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["You should use the -n option, or",
269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "--dry-run in its long form."]
270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 32, expect)
271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 34, expect)
272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 35, expect)
273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 38, expect)
274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["You should use the -n option, or --dry-",
275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "run in its long form."]
276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 39, expect)
277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 41, expect)
278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["You should use the -n option, or --dry-run",
279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "in its long form."]
280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 42, expect)
281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Again, all of the above can be deduced from _split().
283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "the -n option, or --dry-run or --dryrun"
284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["the", " ", "-n", " ", "option,", " ", "or", " ",
285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "--dry-", "run", " ", "or", " ", "--dryrun"]
286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split(text, expect)
287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_funky_hyphens (self):
289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Screwy edge cases cooked up by David Goodger.  All reported
290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # in SF bug #596434.
291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("what the--hey!", ["what", " ", "the", "--", "hey!"])
292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("what the--", ["what", " ", "the--"])
293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("what the--.", ["what", " ", "the--."])
294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("--text--.", ["--text--."])
295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # When I first read bug #596434, this is what I thought David
297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # was talking about.  I was wrong; these have always worked
298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # fine.  The real problem is tested in test_funky_parens()
299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # below...
300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("--option", ["--option"])
301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("--option-opt", ["--option-", "opt"])
302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("foo --option-opt bar",
303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         ["foo", " ", "--option-", "opt", " ", "bar"])
304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_punct_hyphens(self):
306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Oh bother, SF #965425 found another problem with hyphens --
307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # hyphenated words in single quotes weren't handled correctly.
308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # In fact, the bug is that *any* punctuation around a hyphenated
309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # word was handled incorrectly, except for a leading "--", which
310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # was special-cased for Optik and Docutils.  So test a variety
311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # of styles of punctuation around a hyphenated word.
312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # (Actually this is based on an Optik bug report, #813077).
313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("the 'wibble-wobble' widget",
314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         ['the', ' ', "'wibble-", "wobble'", ' ', 'widget'])
315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split('the "wibble-wobble" widget',
316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         ['the', ' ', '"wibble-', 'wobble"', ' ', 'widget'])
317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("the (wibble-wobble) widget",
318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         ['the', ' ', "(wibble-", "wobble)", ' ', 'widget'])
319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("the ['wibble-wobble'] widget",
320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         ['the', ' ', "['wibble-", "wobble']", ' ', 'widget'])
321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_funky_parens (self):
323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Second part of SF bug #596434: long option strings inside
324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # parentheses.
325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("foo (--option) bar",
326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         ["foo", " ", "(--option)", " ", "bar"])
327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Related stuff -- make sure parens work in simpler contexts.
329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("foo (bar) baz",
330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         ["foo", " ", "(bar)", " ", "baz"])
331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_split("blah (ding dong), wubba",
332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         ["blah", " ", "(ding", " ", "dong),",
333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                          " ", "wubba"])
334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_drop_whitespace_false(self):
336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Check that drop_whitespace=False preserves whitespace.
337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # SF patch #1581073
338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = " This is a    sentence with     much whitespace."
339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 10,
340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        [" This is a", "    ", "sentence ",
341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         "with     ", "much white", "space."],
342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        drop_whitespace=False)
343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_drop_whitespace_false_whitespace_only(self):
345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Check that drop_whitespace=False preserves a whitespace-only string.
346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap("   ", 6, ["   "], drop_whitespace=False)
347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_drop_whitespace_false_whitespace_only_with_indent(self):
349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Check that a whitespace-only string gets indented (when
350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # drop_whitespace is False).
351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap("   ", 6, ["     "], drop_whitespace=False,
352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        initial_indent="  ")
353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_drop_whitespace_whitespace_only(self):
355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Check drop_whitespace on a whitespace-only string.
356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap("  ", 6, [])
357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_drop_whitespace_leading_whitespace(self):
359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Check that drop_whitespace does not drop leading whitespace (if
360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # followed by non-whitespace).
361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # SF bug #622849 reported inconsistent handling of leading
362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # whitespace; let's test that a bit, shall we?
363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = " This is a sentence with leading whitespace."
364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 50,
365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        [" This is a sentence with leading whitespace."])
366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 30,
367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        [" This is a sentence with", "leading whitespace."])
368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_drop_whitespace_whitespace_line(self):
370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Check that drop_whitespace skips the whole line if a non-leading
371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # line consists only of whitespace.
372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "abcd    efgh"
373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Include the result for drop_whitespace=False for comparison.
374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 6, ["abcd", "    ", "efgh"],
375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        drop_whitespace=False)
376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 6, ["abcd", "efgh"])
377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_drop_whitespace_whitespace_only_with_indent(self):
379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Check that initial_indent is not applied to a whitespace-only
380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # string.  This checks a special case of the fact that dropping
381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # whitespace occurs before indenting.
382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap("  ", 6, [], initial_indent="++")
383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_drop_whitespace_whitespace_indent(self):
385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Check that drop_whitespace does not drop whitespace indents.
386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # This checks a special case of the fact that dropping whitespace
387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # occurs before indenting.
388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap("abcd efgh", 6, ["  abcd", "  efgh"],
389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        initial_indent="  ", subsequent_indent="  ")
390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    if test_support.have_unicode:
392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        def test_unicode(self):
393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # *Very* simple test of wrapping Unicode strings.  I'm sure
394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # there's more to it than this, but let's at least make
395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            # sure textwrap doesn't crash on Unicode input!
396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            text = u"Hello there, how are you today?"
397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.check_wrap(text, 50, [u"Hello there, how are you today?"])
398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.check_wrap(text, 20, [u"Hello there, how are", "you today?"])
399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            olines = self.wrapper.wrap(text)
400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertIsInstance(olines, list)
401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertIsInstance(olines[0], unicode)
402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            otext = self.wrapper.fill(text)
403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.assertIsInstance(otext, unicode)
404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        def test_no_split_at_umlaut(self):
406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            text = u"Die Empf\xe4nger-Auswahl"
407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.check_wrap(text, 13, [u"Die", u"Empf\xe4nger-", u"Auswahl"])
408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        def test_umlaut_followed_by_dash(self):
410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            text = u"aa \xe4\xe4-\xe4\xe4"
411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            self.check_wrap(text, 7, [u"aa \xe4\xe4-", u"\xe4\xe4"])
412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_split(self):
414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Ensure that the standard _split() method works as advertised
415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # in the comments
416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "Hello there -- you goof-ball, use the -b option!"
418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = self.wrapper._split(text)
420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(result,
421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep             ["Hello", " ", "there", " ", "--", " ", "you", " ", "goof-",
422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep              "ball,", " ", "use", " ", "the", " ", "-b", " ",  "option!"])
423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_break_on_hyphens(self):
425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Ensure that the break_on_hyphens attributes work
426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "yaba daba-doo"
427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 10, ["yaba daba-", "doo"],
428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        break_on_hyphens=True)
429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(text, 10, ["yaba", "daba-doo"],
430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        break_on_hyphens=False)
431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_bad_width(self):
433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Ensure that width <= 0 is caught.
434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "Whatever, it doesn't matter."
435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertRaises(ValueError, wrap, text, 0)
436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertRaises(ValueError, wrap, text, -1)
437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass LongWordTestCase (BaseTestCase):
440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def setUp(self):
441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.wrapper = TextWrapper()
442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.text = '''\
443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDid you say "supercalifragilisticexpialidocious?"
444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepHow *do* you spell that odd word, anyways?
445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep'''
446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_break_long(self):
448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Wrap text with long words and lots of punctuation
449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(self.text, 30,
451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ['Did you say "supercalifragilis',
452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         'ticexpialidocious?" How *do*',
453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         'you spell that odd word,',
454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         'anyways?'])
455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(self.text, 50,
456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ['Did you say "supercalifragilisticexpialidocious?"',
457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         'How *do* you spell that odd word, anyways?'])
458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # SF bug 797650.  Prevent an infinite loop by making sure that at
460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # least one character gets split off on every pass.
461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap('-'*10+'hello', 10,
462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ['----------',
463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         '               h',
464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         '               e',
465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         '               l',
466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         '               l',
467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         '               o'],
468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        subsequent_indent = ' '*15)
469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # bug 1146.  Prevent a long word to be wrongly wrapped when the
471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # preceding word is exactly one character shorter than the width
472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check_wrap(self.text, 12,
473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                        ['Did you say ',
474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         '"supercalifr',
475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         'agilisticexp',
476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         'ialidocious?',
477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         '" How *do*',
478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         'you spell',
479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         'that odd',
480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         'word,',
481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                         'anyways?'])
482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_nobreak_long(self):
484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Test with break_long_words disabled
485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.wrapper.break_long_words = 0
486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.wrapper.width = 30
487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ['Did you say',
488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  '"supercalifragilisticexpialidocious?"',
489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  'How *do* you spell that odd',
490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  'word, anyways?'
491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  ]
492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = self.wrapper.wrap(self.text)
493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(result, expect)
494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Same thing with kwargs passed to standalone wrap() function.
496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = wrap(self.text, width=30, break_long_words=0)
497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(result, expect)
498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass IndentTestCases(BaseTestCase):
501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # called before each test method
503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def setUp(self):
504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.text = '''\
505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepThis paragraph will be filled, first without any indentation,
506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepand then with some (including a hanging indent).'''
507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_fill(self):
510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Test the fill() method
511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = '''\
513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepThis paragraph will be filled, first
514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepwithout any indentation, and then with
515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepsome (including a hanging indent).'''
516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = fill(self.text, 40)
518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(result, expect)
519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_initial_indent(self):
522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Test initial_indent parameter
523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = ["     This paragraph will be filled,",
525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "first without any indentation, and then",
526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                  "with some (including a hanging indent)."]
527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = wrap(self.text, 40, initial_indent="     ")
528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(result, expect)
529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = "\n".join(expect)
531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = fill(self.text, 40, initial_indent="     ")
532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(result, expect)
533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_subsequent_indent(self):
536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Test subsequent_indent parameter
537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = '''\
539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep  * This paragraph will be filled, first
540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    without any indentation, and then
541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    with some (including a hanging
542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    indent).'''
543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        result = fill(self.text, 40,
545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                      initial_indent="  * ", subsequent_indent="    ")
546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.check(result, expect)
547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Despite the similar names, DedentTestCase is *not* the inverse
550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# of IndentTestCase!
551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DedentTestCase(unittest.TestCase):
552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def assertUnchanged(self, text):
554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        """assert that dedent() has no effect on 'text'"""
555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(text, dedent(text))
556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_dedent_nomargin(self):
558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # No lines indented.
559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "Hello there.\nHow are you?\nOh good, I'm glad."
560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertUnchanged(text)
561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Similar, with a blank line.
563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "Hello there.\n\nBoo!"
564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertUnchanged(text)
565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Some lines indented, but overall margin is still zero.
567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "Hello there.\n  This is indented."
568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertUnchanged(text)
569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Again, add a blank line.
571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "Hello there.\n\n  Boo!\n"
572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertUnchanged(text)
573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_dedent_even(self):
575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # All lines indented by two spaces.
576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "  Hello there.\n  How are ya?\n  Oh good."
577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = "Hello there.\nHow are ya?\nOh good."
578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(text))
579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Same, with blank lines.
581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "  Hello there.\n\n  How are ya?\n  Oh good.\n"
582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = "Hello there.\n\nHow are ya?\nOh good.\n"
583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(text))
584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Now indent one of the blank lines.
586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "  Hello there.\n  \n  How are ya?\n  Oh good.\n"
587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = "Hello there.\n\nHow are ya?\nOh good.\n"
588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(text))
589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_dedent_uneven(self):
591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Lines indented unevenly.
592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = '''\
593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        def foo():
594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep            while 1:
595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                return foo
596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        '''
597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = '''\
598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef foo():
599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    while 1:
600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        return foo
601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep'''
602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(text))
603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Uneven indentation with a blank line.
605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "  Foo\n    Bar\n\n   Baz\n"
606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = "Foo\n  Bar\n\n Baz\n"
607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(text))
608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # Uneven indentation with a whitespace-only line.
610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "  Foo\n    Bar\n \n   Baz\n"
611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = "Foo\n  Bar\n\n Baz\n"
612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(text))
613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # dedent() should not mangle internal tabs
615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_dedent_preserve_internal_tabs(self):
616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "  hello\tthere\n  how are\tyou?"
617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = "hello\tthere\nhow are\tyou?"
618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(text))
619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # make sure that it preserves tabs when it's not making any
621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # changes at all
622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(expect))
623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # dedent() should not mangle tabs in the margin (i.e.
625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # tabs and spaces both count as margin, but are *not*
626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    # considered equivalent)
627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    def test_dedent_preserve_margin_tabs(self):
628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "  hello there\n\thow are you?"
629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertUnchanged(text)
630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # same effect even if we have 8 spaces
632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "        hello there\n\thow are you?"
633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertUnchanged(text)
634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        # dedent() only removes whitespace that can be uniformly removed!
636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "\thello there\n\thow are you?"
637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = "hello there\nhow are you?"
638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(text))
639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "  \thello there\n  \thow are you?"
641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(text))
642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "  \t  hello there\n  \t  how are you?"
644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(text))
645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        text = "  \thello there\n  \t  how are you?"
647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        expect = "hello there\n  how are you?"
648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep        self.assertEqual(expect, dedent(text))
649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef test_main():
652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    test_support.run_unittest(WrapTestCase,
653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                              LongWordTestCase,
654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                              IndentTestCases,
655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep                              DedentTestCase)
656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep
657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepif __name__ == '__main__':
658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep    test_main()
659