1 "Test outwin, coverage 76%."
2
3 from idlelib import outwin
4 import unittest
5 from test.support import requires
6 from tkinter import Tk, Text
7 from idlelib.idle_test.mock_tk import Mbox_func
8 from idlelib.idle_test.mock_idle import Func
9 from unittest import mock
10
11
12 class ESC[4;38;5;81mOutputWindowTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
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
136 class ESC[4;38;5;81mModuleFunctionTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
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])
163
164
165 if __name__ == '__main__':
166 unittest.main(verbosity=2)