17db96d56Sopenharmony_ci"Test editor, coverage 53%." 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_cifrom idlelib import editor 47db96d56Sopenharmony_ciimport unittest 57db96d56Sopenharmony_cifrom collections import namedtuple 67db96d56Sopenharmony_cifrom test.support import requires 77db96d56Sopenharmony_cifrom tkinter import Tk, Text 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ciEditor = editor.EditorWindow 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ciclass EditorWindowTest(unittest.TestCase): 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci @classmethod 157db96d56Sopenharmony_ci def setUpClass(cls): 167db96d56Sopenharmony_ci requires('gui') 177db96d56Sopenharmony_ci cls.root = Tk() 187db96d56Sopenharmony_ci cls.root.withdraw() 197db96d56Sopenharmony_ci 207db96d56Sopenharmony_ci @classmethod 217db96d56Sopenharmony_ci def tearDownClass(cls): 227db96d56Sopenharmony_ci cls.root.update_idletasks() 237db96d56Sopenharmony_ci for id in cls.root.tk.call('after', 'info'): 247db96d56Sopenharmony_ci cls.root.after_cancel(id) 257db96d56Sopenharmony_ci cls.root.destroy() 267db96d56Sopenharmony_ci del cls.root 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ci def test_init(self): 297db96d56Sopenharmony_ci e = Editor(root=self.root) 307db96d56Sopenharmony_ci self.assertEqual(e.root, self.root) 317db96d56Sopenharmony_ci e._close() 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ciclass GetLineIndentTest(unittest.TestCase): 357db96d56Sopenharmony_ci def test_empty_lines(self): 367db96d56Sopenharmony_ci for tabwidth in [1, 2, 4, 6, 8]: 377db96d56Sopenharmony_ci for line in ['', '\n']: 387db96d56Sopenharmony_ci with self.subTest(line=line, tabwidth=tabwidth): 397db96d56Sopenharmony_ci self.assertEqual( 407db96d56Sopenharmony_ci editor.get_line_indent(line, tabwidth=tabwidth), 417db96d56Sopenharmony_ci (0, 0), 427db96d56Sopenharmony_ci ) 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci def test_tabwidth_4(self): 457db96d56Sopenharmony_ci # (line, (raw, effective)) 467db96d56Sopenharmony_ci tests = (('no spaces', (0, 0)), 477db96d56Sopenharmony_ci # Internal space isn't counted. 487db96d56Sopenharmony_ci (' space test', (4, 4)), 497db96d56Sopenharmony_ci ('\ttab test', (1, 4)), 507db96d56Sopenharmony_ci ('\t\tdouble tabs test', (2, 8)), 517db96d56Sopenharmony_ci # Different results when mixing tabs and spaces. 527db96d56Sopenharmony_ci (' \tmixed test', (5, 8)), 537db96d56Sopenharmony_ci (' \t mixed test', (5, 6)), 547db96d56Sopenharmony_ci ('\t mixed test', (5, 8)), 557db96d56Sopenharmony_ci # Spaces not divisible by tabwidth. 567db96d56Sopenharmony_ci (' \tmixed test', (3, 4)), 577db96d56Sopenharmony_ci (' \t mixed test', (3, 5)), 587db96d56Sopenharmony_ci ('\t mixed test', (3, 6)), 597db96d56Sopenharmony_ci # Only checks spaces and tabs. 607db96d56Sopenharmony_ci ('\nnewline test', (0, 0))) 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci for line, expected in tests: 637db96d56Sopenharmony_ci with self.subTest(line=line): 647db96d56Sopenharmony_ci self.assertEqual( 657db96d56Sopenharmony_ci editor.get_line_indent(line, tabwidth=4), 667db96d56Sopenharmony_ci expected, 677db96d56Sopenharmony_ci ) 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci def test_tabwidth_8(self): 707db96d56Sopenharmony_ci # (line, (raw, effective)) 717db96d56Sopenharmony_ci tests = (('no spaces', (0, 0)), 727db96d56Sopenharmony_ci # Internal space isn't counted. 737db96d56Sopenharmony_ci (' space test', (8, 8)), 747db96d56Sopenharmony_ci ('\ttab test', (1, 8)), 757db96d56Sopenharmony_ci ('\t\tdouble tabs test', (2, 16)), 767db96d56Sopenharmony_ci # Different results when mixing tabs and spaces. 777db96d56Sopenharmony_ci (' \tmixed test', (9, 16)), 787db96d56Sopenharmony_ci (' \t mixed test', (9, 10)), 797db96d56Sopenharmony_ci ('\t mixed test', (9, 16)), 807db96d56Sopenharmony_ci # Spaces not divisible by tabwidth. 817db96d56Sopenharmony_ci (' \tmixed test', (3, 8)), 827db96d56Sopenharmony_ci (' \t mixed test', (3, 9)), 837db96d56Sopenharmony_ci ('\t mixed test', (3, 10)), 847db96d56Sopenharmony_ci # Only checks spaces and tabs. 857db96d56Sopenharmony_ci ('\nnewline test', (0, 0))) 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ci for line, expected in tests: 887db96d56Sopenharmony_ci with self.subTest(line=line): 897db96d56Sopenharmony_ci self.assertEqual( 907db96d56Sopenharmony_ci editor.get_line_indent(line, tabwidth=8), 917db96d56Sopenharmony_ci expected, 927db96d56Sopenharmony_ci ) 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_cidef insert(text, string): 967db96d56Sopenharmony_ci text.delete('1.0', 'end') 977db96d56Sopenharmony_ci text.insert('end', string) 987db96d56Sopenharmony_ci text.update() # Force update for colorizer to finish. 997db96d56Sopenharmony_ci 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ciclass IndentAndNewlineTest(unittest.TestCase): 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci @classmethod 1047db96d56Sopenharmony_ci def setUpClass(cls): 1057db96d56Sopenharmony_ci requires('gui') 1067db96d56Sopenharmony_ci cls.root = Tk() 1077db96d56Sopenharmony_ci cls.root.withdraw() 1087db96d56Sopenharmony_ci cls.window = Editor(root=cls.root) 1097db96d56Sopenharmony_ci cls.window.indentwidth = 2 1107db96d56Sopenharmony_ci cls.window.tabwidth = 2 1117db96d56Sopenharmony_ci 1127db96d56Sopenharmony_ci @classmethod 1137db96d56Sopenharmony_ci def tearDownClass(cls): 1147db96d56Sopenharmony_ci cls.window._close() 1157db96d56Sopenharmony_ci del cls.window 1167db96d56Sopenharmony_ci cls.root.update_idletasks() 1177db96d56Sopenharmony_ci for id in cls.root.tk.call('after', 'info'): 1187db96d56Sopenharmony_ci cls.root.after_cancel(id) 1197db96d56Sopenharmony_ci cls.root.destroy() 1207db96d56Sopenharmony_ci del cls.root 1217db96d56Sopenharmony_ci 1227db96d56Sopenharmony_ci def test_indent_and_newline_event(self): 1237db96d56Sopenharmony_ci eq = self.assertEqual 1247db96d56Sopenharmony_ci w = self.window 1257db96d56Sopenharmony_ci text = w.text 1267db96d56Sopenharmony_ci get = text.get 1277db96d56Sopenharmony_ci nl = w.newline_and_indent_event 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_ci TestInfo = namedtuple('Tests', ['label', 'text', 'expected', 'mark']) 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_ci tests = (TestInfo('Empty line inserts with no indent.', 1327db96d56Sopenharmony_ci ' \n def __init__(self):', 1337db96d56Sopenharmony_ci '\n \n def __init__(self):\n', 1347db96d56Sopenharmony_ci '1.end'), 1357db96d56Sopenharmony_ci TestInfo('Inside bracket before space, deletes space.', 1367db96d56Sopenharmony_ci ' def f1(self, a, b):', 1377db96d56Sopenharmony_ci ' def f1(self,\n a, b):\n', 1387db96d56Sopenharmony_ci '1.14'), 1397db96d56Sopenharmony_ci TestInfo('Inside bracket after space, deletes space.', 1407db96d56Sopenharmony_ci ' def f1(self, a, b):', 1417db96d56Sopenharmony_ci ' def f1(self,\n a, b):\n', 1427db96d56Sopenharmony_ci '1.15'), 1437db96d56Sopenharmony_ci TestInfo('Inside string with one line - no indent.', 1447db96d56Sopenharmony_ci ' """Docstring."""', 1457db96d56Sopenharmony_ci ' """Docstring.\n"""\n', 1467db96d56Sopenharmony_ci '1.15'), 1477db96d56Sopenharmony_ci TestInfo('Inside string with more than one line.', 1487db96d56Sopenharmony_ci ' """Docstring.\n Docstring Line 2"""', 1497db96d56Sopenharmony_ci ' """Docstring.\n Docstring Line 2\n """\n', 1507db96d56Sopenharmony_ci '2.18'), 1517db96d56Sopenharmony_ci TestInfo('Backslash with one line.', 1527db96d56Sopenharmony_ci 'a =\\', 1537db96d56Sopenharmony_ci 'a =\\\n \n', 1547db96d56Sopenharmony_ci '1.end'), 1557db96d56Sopenharmony_ci TestInfo('Backslash with more than one line.', 1567db96d56Sopenharmony_ci 'a =\\\n multiline\\', 1577db96d56Sopenharmony_ci 'a =\\\n multiline\\\n \n', 1587db96d56Sopenharmony_ci '2.end'), 1597db96d56Sopenharmony_ci TestInfo('Block opener - indents +1 level.', 1607db96d56Sopenharmony_ci ' def f1(self):\n pass', 1617db96d56Sopenharmony_ci ' def f1(self):\n \n pass\n', 1627db96d56Sopenharmony_ci '1.end'), 1637db96d56Sopenharmony_ci TestInfo('Block closer - dedents -1 level.', 1647db96d56Sopenharmony_ci ' def f1(self):\n pass', 1657db96d56Sopenharmony_ci ' def f1(self):\n pass\n \n', 1667db96d56Sopenharmony_ci '2.end'), 1677db96d56Sopenharmony_ci ) 1687db96d56Sopenharmony_ci 1697db96d56Sopenharmony_ci for test in tests: 1707db96d56Sopenharmony_ci with self.subTest(label=test.label): 1717db96d56Sopenharmony_ci insert(text, test.text) 1727db96d56Sopenharmony_ci text.mark_set('insert', test.mark) 1737db96d56Sopenharmony_ci nl(event=None) 1747db96d56Sopenharmony_ci eq(get('1.0', 'end'), test.expected) 1757db96d56Sopenharmony_ci 1767db96d56Sopenharmony_ci # Selected text. 1777db96d56Sopenharmony_ci insert(text, ' def f1(self, a, b):\n return a + b') 1787db96d56Sopenharmony_ci text.tag_add('sel', '1.17', '1.end') 1797db96d56Sopenharmony_ci nl(None) 1807db96d56Sopenharmony_ci # Deletes selected text before adding new line. 1817db96d56Sopenharmony_ci eq(get('1.0', 'end'), ' def f1(self, a,\n \n return a + b\n') 1827db96d56Sopenharmony_ci 1837db96d56Sopenharmony_ci 1847db96d56Sopenharmony_ciclass IndentSearcherTest(unittest.TestCase): 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ci @classmethod 1877db96d56Sopenharmony_ci def setUpClass(cls): 1887db96d56Sopenharmony_ci requires('gui') 1897db96d56Sopenharmony_ci cls.root = Tk() 1907db96d56Sopenharmony_ci cls.root.withdraw() 1917db96d56Sopenharmony_ci cls.text = Text(cls.root) 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_ci @classmethod 1947db96d56Sopenharmony_ci def tearDownClass(cls): 1957db96d56Sopenharmony_ci cls.root.destroy() 1967db96d56Sopenharmony_ci del cls.root 1977db96d56Sopenharmony_ci 1987db96d56Sopenharmony_ci def test_searcher(self): 1997db96d56Sopenharmony_ci text = self.text 2007db96d56Sopenharmony_ci searcher = (self.text) 2017db96d56Sopenharmony_ci test_info = (# text, (block, indent)) 2027db96d56Sopenharmony_ci ("", (None, None)), 2037db96d56Sopenharmony_ci ("[1,", (None, None)), # TokenError 2047db96d56Sopenharmony_ci ("if 1:\n", ('if 1:\n', None)), 2057db96d56Sopenharmony_ci ("if 1:\n 2\n 3\n", ('if 1:\n', ' 2\n')), 2067db96d56Sopenharmony_ci ) 2077db96d56Sopenharmony_ci for code, expected_pair in test_info: 2087db96d56Sopenharmony_ci with self.subTest(code=code): 2097db96d56Sopenharmony_ci insert(text, code) 2107db96d56Sopenharmony_ci actual_pair = editor.IndentSearcher(text).run() 2117db96d56Sopenharmony_ci self.assertEqual(actual_pair, expected_pair) 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ciclass RMenuTest(unittest.TestCase): 2157db96d56Sopenharmony_ci 2167db96d56Sopenharmony_ci @classmethod 2177db96d56Sopenharmony_ci def setUpClass(cls): 2187db96d56Sopenharmony_ci requires('gui') 2197db96d56Sopenharmony_ci cls.root = Tk() 2207db96d56Sopenharmony_ci cls.root.withdraw() 2217db96d56Sopenharmony_ci cls.window = Editor(root=cls.root) 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_ci @classmethod 2247db96d56Sopenharmony_ci def tearDownClass(cls): 2257db96d56Sopenharmony_ci cls.window._close() 2267db96d56Sopenharmony_ci del cls.window 2277db96d56Sopenharmony_ci cls.root.update_idletasks() 2287db96d56Sopenharmony_ci for id in cls.root.tk.call('after', 'info'): 2297db96d56Sopenharmony_ci cls.root.after_cancel(id) 2307db96d56Sopenharmony_ci cls.root.destroy() 2317db96d56Sopenharmony_ci del cls.root 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_ci class DummyRMenu: 2347db96d56Sopenharmony_ci def tk_popup(x, y): pass 2357db96d56Sopenharmony_ci 2367db96d56Sopenharmony_ci def test_rclick(self): 2377db96d56Sopenharmony_ci pass 2387db96d56Sopenharmony_ci 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_ciif __name__ == '__main__': 2417db96d56Sopenharmony_ci unittest.main(verbosity=2) 242