1"Test outwin, coverage 76%." 2 3from idlelib import outwin 4import unittest 5from test.support import requires 6from tkinter import Tk, Text 7from idlelib.idle_test.mock_tk import Mbox_func 8from idlelib.idle_test.mock_idle import Func 9from unittest import mock 10 11 12class OutputWindowTest(unittest.TestCase): 13 14 @classmethod 15 def setUpClass(cls): 16 requires('gui') 17 root = cls.root = Tk() 18 root.withdraw() 19 w = cls.window = outwin.OutputWindow(None, None, None, root) 20 cls.text = w.text = Text(root) 21 22 @classmethod 23 def tearDownClass(cls): 24 cls.window.close() 25 del cls.text, cls.window 26 cls.root.destroy() 27 del cls.root 28 29 def setUp(self): 30 self.text.delete('1.0', 'end') 31 32 def test_ispythonsource(self): 33 # OutputWindow overrides ispythonsource to always return False. 34 w = self.window 35 self.assertFalse(w.ispythonsource('test.txt')) 36 self.assertFalse(w.ispythonsource(__file__)) 37 38 def test_window_title(self): 39 self.assertEqual(self.window.top.title(), 'Output') 40 41 def test_maybesave(self): 42 w = self.window 43 eq = self.assertEqual 44 w.get_saved = Func() 45 46 w.get_saved.result = False 47 eq(w.maybesave(), 'no') 48 eq(w.get_saved.called, 1) 49 50 w.get_saved.result = True 51 eq(w.maybesave(), 'yes') 52 eq(w.get_saved.called, 2) 53 del w.get_saved 54 55 def test_write(self): 56 eq = self.assertEqual 57 delete = self.text.delete 58 get = self.text.get 59 write = self.window.write 60 61 # No new line - insert stays on same line. 62 delete('1.0', 'end') 63 test_text = 'test text' 64 eq(write(test_text), len(test_text)) 65 eq(get('1.0', '1.end'), 'test text') 66 eq(get('insert linestart', 'insert lineend'), 'test text') 67 68 # New line - insert moves to next line. 69 delete('1.0', 'end') 70 test_text = 'test text\n' 71 eq(write(test_text), len(test_text)) 72 eq(get('1.0', '1.end'), 'test text') 73 eq(get('insert linestart', 'insert lineend'), '') 74 75 # Text after new line is tagged for second line of Text widget. 76 delete('1.0', 'end') 77 test_text = 'test text\nLine 2' 78 eq(write(test_text), len(test_text)) 79 eq(get('1.0', '1.end'), 'test text') 80 eq(get('2.0', '2.end'), 'Line 2') 81 eq(get('insert linestart', 'insert lineend'), 'Line 2') 82 83 # Test tags. 84 delete('1.0', 'end') 85 test_text = 'test text\n' 86 test_text2 = 'Line 2\n' 87 eq(write(test_text, tags='mytag'), len(test_text)) 88 eq(write(test_text2, tags='secondtag'), len(test_text2)) 89 eq(get('mytag.first', 'mytag.last'), test_text) 90 eq(get('secondtag.first', 'secondtag.last'), test_text2) 91 eq(get('1.0', '1.end'), test_text.rstrip('\n')) 92 eq(get('2.0', '2.end'), test_text2.rstrip('\n')) 93 94 def test_writelines(self): 95 eq = self.assertEqual 96 get = self.text.get 97 writelines = self.window.writelines 98 99 writelines(('Line 1\n', 'Line 2\n', 'Line 3\n')) 100 eq(get('1.0', '1.end'), 'Line 1') 101 eq(get('2.0', '2.end'), 'Line 2') 102 eq(get('3.0', '3.end'), 'Line 3') 103 eq(get('insert linestart', 'insert lineend'), '') 104 105 def test_goto_file_line(self): 106 eq = self.assertEqual 107 w = self.window 108 text = self.text 109 110 w.flist = mock.Mock() 111 gfl = w.flist.gotofileline = Func() 112 showerror = w.showerror = Mbox_func() 113 114 # No file/line number. 115 w.write('Not a file line') 116 self.assertIsNone(w.goto_file_line()) 117 eq(gfl.called, 0) 118 eq(showerror.title, 'No special line') 119 120 # Current file/line number. 121 w.write(f'{str(__file__)}: 42: spam\n') 122 w.write(f'{str(__file__)}: 21: spam') 123 self.assertIsNone(w.goto_file_line()) 124 eq(gfl.args, (str(__file__), 21)) 125 126 # Previous line has file/line number. 127 text.delete('1.0', 'end') 128 w.write(f'{str(__file__)}: 42: spam\n') 129 w.write('Not a file line') 130 self.assertIsNone(w.goto_file_line()) 131 eq(gfl.args, (str(__file__), 42)) 132 133 del w.flist.gotofileline, w.showerror 134 135 136class ModuleFunctionTest(unittest.TestCase): 137 138 @classmethod 139 def setUp(cls): 140 outwin.file_line_progs = None 141 142 def test_compile_progs(self): 143 outwin.compile_progs() 144 for pat, regex in zip(outwin.file_line_pats, outwin.file_line_progs): 145 self.assertEqual(regex.pattern, pat) 146 147 @mock.patch('builtins.open') 148 def test_file_line_helper(self, mock_open): 149 flh = outwin.file_line_helper 150 test_lines = ( 151 (r'foo file "testfile1", line 42, bar', ('testfile1', 42)), 152 (r'foo testfile2(21) bar', ('testfile2', 21)), 153 (r' testfile3 : 42: foo bar\n', (' testfile3 ', 42)), 154 (r'foo testfile4.py :1: ', ('foo testfile4.py ', 1)), 155 ('testfile5: \u19D4\u19D2: ', ('testfile5', 42)), 156 (r'testfile6: 42', None), # only one `:` 157 (r'testfile7 42 text', None) # no separators 158 ) 159 for line, expected_output in test_lines: 160 self.assertEqual(flh(line), expected_output) 161 if expected_output: 162 mock_open.assert_called_with(expected_output[0], 'r') 163 164 165if __name__ == '__main__': 166 unittest.main(verbosity=2) 167