13d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# Test the functions and main class method of FormatParagraph.py
23d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyimport unittest
33d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyfrom idlelib import FormatParagraph as fp
43d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyfrom idlelib.EditorWindow import EditorWindow
5d39d962cbd9c2ac74fc91d1c022e1430586c67baTerry Jan Reedyfrom Tkinter import Tk, Text
674b3290c104d6bb04c1ddb18299d67142678069aTerry Jan Reedyfrom test.test_support import requires
73d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
83d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
93d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyclass Is_Get_Test(unittest.TestCase):
103d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    """Test the is_ and get_ functions"""
113d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    test_comment = '# This is a comment'
123d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    test_nocomment = 'This is not a comment'
133d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    trailingws_comment = '# This is a comment   '
143d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    leadingws_comment = '    # This is a comment'
153d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    leadingws_nocomment = '    This is not a comment'
163d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
173d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def test_is_all_white(self):
183d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.assertTrue(fp.is_all_white(''))
193d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.assertTrue(fp.is_all_white('\t\n\r\f\v'))
203d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.assertFalse(fp.is_all_white(self.test_comment))
213d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
223d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def test_get_indent(self):
233d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal = self.assertEqual
243d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(fp.get_indent(self.test_comment), '')
253d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(fp.get_indent(self.trailingws_comment), '')
263d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(fp.get_indent(self.leadingws_comment), '    ')
273d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(fp.get_indent(self.leadingws_nocomment), '    ')
283d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
293d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def test_get_comment_header(self):
303d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal = self.assertEqual
313d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # Test comment strings
323d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(fp.get_comment_header(self.test_comment), '#')
333d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(fp.get_comment_header(self.trailingws_comment), '#')
343d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(fp.get_comment_header(self.leadingws_comment), '    #')
353d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # Test non-comment strings
363d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(fp.get_comment_header(self.leadingws_nocomment), '    ')
373d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(fp.get_comment_header(self.test_nocomment), '')
383d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
393d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
403d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyclass FindTest(unittest.TestCase):
413d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    """Test the find_paragraph function in FormatParagraph.
423d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
433d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    Using the runcase() function, find_paragraph() is called with 'mark' set at
443d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    multiple indexes before and inside the test paragraph.
453d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
463d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    It appears that code with the same indentation as a quoted string is grouped
473d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    as part of the same paragraph, which is probably incorrect behavior.
483d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    """
493d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
503d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    @classmethod
513d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def setUpClass(cls):
523d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        from idlelib.idle_test.mock_tk import Text
533d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        cls.text = Text()
543d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
553d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def runcase(self, inserttext, stopline, expected):
563d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # Check that find_paragraph returns the expected paragraph when
573d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # the mark index is set to beginning, middle, end of each line
583d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # up to but not including the stop line
593d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text = self.text
603d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.insert('1.0', inserttext)
613d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        for line in range(1, stopline):
623d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            linelength = int(text.index("%d.end" % line).split('.')[1])
633d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            for col in (0, linelength//2, linelength):
643d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy                tempindex = "%d.%d" % (line, col)
653d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy                self.assertEqual(fp.find_paragraph(text, tempindex), expected)
663d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.delete('1.0', 'end')
673d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
683d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def test_find_comment(self):
693d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        comment = (
703d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "# Comment block with no blank lines before\n"
713d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "# Comment line\n"
723d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n")
733d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(comment, 3, ('1.0', '3.0', '#', comment[0:58]))
743d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
753d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        comment = (
763d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n"
773d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "# Comment block with whitespace line before and after\n"
783d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "# Comment line\n"
793d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n")
803d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(comment, 4, ('2.0', '4.0', '#', comment[1:70]))
813d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
823d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        comment = (
833d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n"
843d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "    # Indented comment block with whitespace before and after\n"
853d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "    # Comment line\n"
863d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n")
873d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(comment, 4, ('2.0', '4.0', '    #', comment[1:82]))
883d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
893d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        comment = (
903d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n"
913d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "# Single line comment\n"
923d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n")
933d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:23]))
943d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
953d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        comment = (
963d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n"
973d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "    # Single line comment with leading whitespace\n"
983d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n")
993d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(comment, 3, ('2.0', '3.0', '    #', comment[1:51]))
1003d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1013d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        comment = (
1023d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n"
1033d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "# Comment immediately followed by code\n"
1043d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "x = 42\n"
1053d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n")
1063d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:40]))
1073d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1083d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        comment = (
1093d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n"
1103d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "    # Indented comment immediately followed by code\n"
1113d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "x = 42\n"
1123d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n")
1133d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(comment, 3, ('2.0', '3.0', '    #', comment[1:53]))
1143d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1153d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        comment = (
1163d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n"
1173d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "# Comment immediately followed by indented code\n"
1183d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "    x = 42\n"
1193d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n")
1203d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:49]))
1213d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1223d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def test_find_paragraph(self):
1233d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        teststring = (
1243d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '"""String with no blank lines before\n'
1253d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            'String line\n'
1263d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '"""\n'
1273d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '\n')
1283d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(teststring, 4, ('1.0', '4.0', '', teststring[0:53]))
1293d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1303d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        teststring = (
1313d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "\n"
1323d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '"""String with whitespace line before and after\n'
1333d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            'String line.\n'
1343d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '"""\n'
1353d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '\n')
1363d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(teststring, 5, ('2.0', '5.0', '', teststring[1:66]))
1373d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1383d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        teststring = (
1393d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '\n'
1403d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '    """Indented string with whitespace before and after\n'
1413d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '    Comment string.\n'
1423d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '    """\n'
1433d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '\n')
1443d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(teststring, 5, ('2.0', '5.0', '    ', teststring[1:85]))
1453d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1463d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        teststring = (
1473d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '\n'
1483d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '"""Single line string."""\n'
1493d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '\n')
1503d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(teststring, 3, ('2.0', '3.0', '', teststring[1:27]))
1513d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1523d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        teststring = (
1533d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '\n'
1543d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '    """Single line string with leading whitespace."""\n'
1553d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            '\n')
1563d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.runcase(teststring, 3, ('2.0', '3.0', '    ', teststring[1:55]))
1573d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1583d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1593d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyclass ReformatFunctionTest(unittest.TestCase):
1603d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    """Test the reformat_paragraph function without the editor window."""
1613d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1626507657dddebc629e49f3dc683d89a96a481fb86Martin Panter    def test_reformat_paragraph(self):
1633d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal = self.assertEqual
1643d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        reform = fp.reformat_paragraph
1653d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        hw = "O hello world"
1663d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform(' ', 1), ' ')
1673d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform("Hello    world", 20), "Hello  world")
1683d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1693d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # Test without leading newline
1703d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform(hw, 1), "O\nhello\nworld")
1713d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform(hw, 6), "O\nhello\nworld")
1723d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform(hw, 7), "O hello\nworld")
1733d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform(hw, 12), "O hello\nworld")
1743d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform(hw, 13), "O hello world")
1753d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1763d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # Test with leading newline
1773d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        hw = "\nO hello world"
1783d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform(hw, 1), "\nO\nhello\nworld")
1793d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform(hw, 6), "\nO\nhello\nworld")
1803d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform(hw, 7), "\nO hello\nworld")
1813d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform(hw, 12), "\nO hello\nworld")
1823d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(reform(hw, 13), "\nO hello world")
1833d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1843d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1853d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyclass ReformatCommentTest(unittest.TestCase):
1863d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    """Test the reformat_comment function without the editor window."""
1873d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1883d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def test_reformat_comment(self):
1893d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal = self.assertEqual
1903d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
1913d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # reformat_comment formats to a minimum of 20 characters
1923d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        test_string = (
1933d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "    \"\"\"this is a test of a reformat for a triple quoted string"
1943d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            " will it reformat to less than 70 characters for me?\"\"\"")
1953d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        result = fp.reformat_comment(test_string, 70, "    ")
1963d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        expected = (
1973d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "    \"\"\"this is a test of a reformat for a triple quoted string will it\n"
1983d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "    reformat to less than 70 characters for me?\"\"\"")
1993d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(result, expected)
2003d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2013d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        test_comment = (
2023d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "# this is a test of a reformat for a triple quoted string will "
2033d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "it reformat to less than 70 characters for me?")
2043d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        result = fp.reformat_comment(test_comment, 70, "#")
2053d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        expected = (
2063d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "# this is a test of a reformat for a triple quoted string will it\n"
2073d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy            "# reformat to less than 70 characters for me?")
2083d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        Equal(result, expected)
2093d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2103d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2113d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyclass FormatClassTest(unittest.TestCase):
2123d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def test_init_close(self):
2133d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        instance = fp.FormatParagraph('editor')
2143d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.assertEqual(instance.editwin, 'editor')
2153d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        instance.close()
2163d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.assertEqual(instance.editwin, None)
2173d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2183d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2193d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# For testing format_paragraph_event, Initialize FormatParagraph with
2203d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# a mock Editor with .text and  .get_selection_indices.  The text must
2213d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# be a Text wrapper that adds two methods
2223d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2233d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# A real EditorWindow creates unneeded, time-consuming baggage and
2243d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# sometimes emits shutdown warnings like this:
2253d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# "warning: callback failed in WindowList <class '_tkinter.TclError'>
2263d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# : invalid command name ".55131368.windows".
2273d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# Calling EditorWindow._close in tearDownClass prevents this but causes
2283d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# other problems (windows left open).
2293d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2303d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyclass TextWrapper:
2313d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def __init__(self, master):
2323d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.text = Text(master=master)
2333d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def __getattr__(self, name):
2343d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        return getattr(self.text, name)
2353d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def undo_block_start(self): pass
2363d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def undo_block_stop(self): pass
2373d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2383d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyclass Editor:
2393d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def __init__(self, root):
2403d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.text = TextWrapper(root)
24174b3290c104d6bb04c1ddb18299d67142678069aTerry Jan Reedy    get_selection_indices = EditorWindow. get_selection_indices.im_func
2423d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2433d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyclass FormatEventTest(unittest.TestCase):
2443d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    """Test the formatting of text inside a Text widget.
2453d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2463d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    This is done with FormatParagraph.format.paragraph_event,
2475dd99ebbc25ac0e182cb00ac4c67aef8d32a6755Ezio Melotti    which calls functions in the module as appropriate.
2483d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    """
2493d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    test_string = (
2503d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "    '''this is a test of a reformat for a triple "
2513d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "quoted string will it reformat to less than 70 "
2523d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "characters for me?'''\n")
2533d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    multiline_test_string = (
2543d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "    '''The first line is under the max width.\n"
2553d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "    The second line's length is way over the max width. It goes "
2563d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "on and on until it is over 100 characters long.\n"
2573d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "    Same thing with the third line. It is also way over the max "
2583d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "width, but FormatParagraph will fix it.\n"
2593d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "    '''\n")
2603d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    multiline_test_comment = (
2613d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "# The first line is under the max width.\n"
2623d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "# The second line's length is way over the max width. It goes on "
2633d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "and on until it is over 100 characters long.\n"
2643d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "# Same thing with the third line. It is also way over the max "
2653d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "width, but FormatParagraph will fix it.\n"
2663d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        "# The fourth line is short like the first line.")
2673d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2683d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    @classmethod
2693d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def setUpClass(cls):
2703d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        requires('gui')
2713d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        cls.root = Tk()
2723d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        editor = Editor(root=cls.root)
2733d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        cls.text = editor.text.text  # Test code does not need the wrapper.
2743d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        cls.formatter = fp.FormatParagraph(editor).format_paragraph_event
2753d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # Sets the insert mark just after the re-wrapped and inserted  text.
2763d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2773d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    @classmethod
2783d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def tearDownClass(cls):
279bbf29ee6e4c5d46dfd48685cd65ef4bdd132dd40Terry Jan Reedy        del cls.text, cls.formatter
2803d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        cls.root.destroy()
28144fad467b94718beb9fae6c4af4f5c87330b2dafTerry Jan Reedy        del cls.root
2823d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2833d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def test_short_line(self):
2843d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.text.insert('1.0', "Short line\n")
2853d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.formatter("Dummy")
2863d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.assertEqual(self.text.get('1.0', 'insert'), "Short line\n" )
2873d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.text.delete('1.0', 'end')
2883d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2893d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def test_long_line(self):
2903d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text = self.text
2913d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
2923d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # Set cursor ('insert' mark) to '1.0', within text.
2933d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.insert('1.0', self.test_string)
2943d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.mark_set('insert', '1.0')
2950edf52a2c21d6c0cd44ec9d9e8f6e580d42f62c8Terry Jan Reedy        self.formatter('ParameterDoesNothing', limit=70)
2963d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        result = text.get('1.0', 'insert')
2973d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # find function includes \n
2983d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        expected = (
2993d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"    '''this is a test of a reformat for a triple quoted string will it\n"
3003d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"    reformat to less than 70 characters for me?'''\n")  # yes
3013d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.assertEqual(result, expected)
3023d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.delete('1.0', 'end')
3033d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
3043d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # Select from 1.11 to line end.
3053d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.insert('1.0', self.test_string)
3063d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.tag_add('sel', '1.11', '1.end')
3070edf52a2c21d6c0cd44ec9d9e8f6e580d42f62c8Terry Jan Reedy        self.formatter('ParameterDoesNothing', limit=70)
3083d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        result = text.get('1.0', 'insert')
3093d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # selection excludes \n
3103d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        expected = (
3113d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"    '''this is a test of a reformat for a triple quoted string will it reformat\n"
3123d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy" to less than 70 characters for me?'''")  # no
3133d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.assertEqual(result, expected)
3143d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.delete('1.0', 'end')
3153d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
3163d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def test_multiple_lines(self):
3173d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text = self.text
3183d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        #  Select 2 long lines.
3193d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.insert('1.0', self.multiline_test_string)
3203d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.tag_add('sel', '2.0', '4.0')
3210edf52a2c21d6c0cd44ec9d9e8f6e580d42f62c8Terry Jan Reedy        self.formatter('ParameterDoesNothing', limit=70)
3223d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        result = text.get('2.0', 'insert')
3233d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        expected = (
3243d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"    The second line's length is way over the max width. It goes on and\n"
3253d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"    on until it is over 100 characters long. Same thing with the third\n"
3263d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"    line. It is also way over the max width, but FormatParagraph will\n"
3273d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"    fix it.\n")
3283d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.assertEqual(result, expected)
3293d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.delete('1.0', 'end')
3303d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
3313d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    def test_comment_block(self):
3323d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text = self.text
3333d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
3343d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # Set cursor ('insert') to '1.0', within block.
3353d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.insert('1.0', self.multiline_test_comment)
3360edf52a2c21d6c0cd44ec9d9e8f6e580d42f62c8Terry Jan Reedy        self.formatter('ParameterDoesNothing', limit=70)
3373d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        result = text.get('1.0', 'insert')
3383d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        expected = (
3393d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"# The first line is under the max width. The second line's length is\n"
3403d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"# way over the max width. It goes on and on until it is over 100\n"
3413d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"# characters long. Same thing with the third line. It is also way over\n"
3423d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"# the max width, but FormatParagraph will fix it. The fourth line is\n"
3433d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"# short like the first line.\n")
3443d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.assertEqual(result, expected)
3453d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.delete('1.0', 'end')
3463d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
3473d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        # Select line 2, verify line 1 unaffected.
3483d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.insert('1.0', self.multiline_test_comment)
3493d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.tag_add('sel', '2.0', '3.0')
3500edf52a2c21d6c0cd44ec9d9e8f6e580d42f62c8Terry Jan Reedy        self.formatter('ParameterDoesNothing', limit=70)
3513d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        result = text.get('1.0', 'insert')
3523d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        expected = (
3533d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"# The first line is under the max width.\n"
3543d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"# The second line's length is way over the max width. It goes on and\n"
3553d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy"# on until it is over 100 characters long.\n")
3563d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        self.assertEqual(result, expected)
3573d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy        text.delete('1.0', 'end')
3583d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
3593d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# The following block worked with EditorWindow but fails with the mock.
3603d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# Lines 2 and 3 get pasted together even though the previous block left
3613d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy# the previous line alone. More investigation is needed.
3623d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy##        # Select lines 3 and 4
3633d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy##        text.insert('1.0', self.multiline_test_comment)
3643d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy##        text.tag_add('sel', '3.0', '5.0')
3653d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy##        self.formatter('ParameterDoesNothing')
3663d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy##        result = text.get('3.0', 'insert')
3673d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy##        expected = (
3683d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy##"# Same thing with the third line. It is also way over the max width,\n"
3693d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy##"# but FormatParagraph will fix it. The fourth line is short like the\n"
3703d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy##"# first line.\n")
3713d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy##        self.assertEqual(result, expected)
3723d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy##        text.delete('1.0', 'end')
3733d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
3743d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy
3753d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedyif __name__ == '__main__':
3763d35489169c40231bf3f432c40b69781147f828cTerry Jan Reedy    unittest.main(verbosity=2, exit=2)
377