Coverage for idle_test/test_editor.py: 53%

101 statements  

« prev     ^ index     » next       coverage.py v7.2.5, created at 2023-05-11 13:22 -0700

1"Test editor, coverage 35%." 

2 

3from idlelib import editor 

4import unittest 

5from collections import namedtuple 

6from test.support import requires 

7from tkinter import Tk 

8 

9Editor = editor.EditorWindow 

10 

11 

12class EditorWindowTest(unittest.TestCase): 

13 

14 @classmethod 

15 def setUpClass(cls): 

16 requires('gui') 

17 cls.root = Tk() 

18 cls.root.withdraw() 

19 

20 @classmethod 

21 def tearDownClass(cls): 

22 cls.root.update_idletasks() 

23 for id in cls.root.tk.call('after', 'info'): 

24 cls.root.after_cancel(id) 

25 cls.root.destroy() 

26 del cls.root 

27 

28 def test_init(self): 

29 e = Editor(root=self.root) 

30 self.assertEqual(e.root, self.root) 

31 e._close() 

32 

33 

34class TestGetLineIndent(unittest.TestCase): 

35 def test_empty_lines(self): 

36 for tabwidth in [1, 2, 4, 6, 8]: 1b

37 for line in ['', '\n']: 1b

38 with self.subTest(line=line, tabwidth=tabwidth): 1b

39 self.assertEqual( 1b

40 editor.get_line_indent(line, tabwidth=tabwidth), 

41 (0, 0), 

42 ) 

43 

44 def test_tabwidth_4(self): 

45 # (line, (raw, effective)) 

46 tests = (('no spaces', (0, 0)), 1c

47 # Internal space isn't counted. 

48 (' space test', (4, 4)), 

49 ('\ttab test', (1, 4)), 

50 ('\t\tdouble tabs test', (2, 8)), 

51 # Different results when mixing tabs and spaces. 

52 (' \tmixed test', (5, 8)), 

53 (' \t mixed test', (5, 6)), 

54 ('\t mixed test', (5, 8)), 

55 # Spaces not divisible by tabwidth. 

56 (' \tmixed test', (3, 4)), 

57 (' \t mixed test', (3, 5)), 

58 ('\t mixed test', (3, 6)), 

59 # Only checks spaces and tabs. 

60 ('\nnewline test', (0, 0))) 

61 

62 for line, expected in tests: 1c

63 with self.subTest(line=line): 1c

64 self.assertEqual( 1c

65 editor.get_line_indent(line, tabwidth=4), 

66 expected, 

67 ) 

68 

69 def test_tabwidth_8(self): 

70 # (line, (raw, effective)) 

71 tests = (('no spaces', (0, 0)), 1d

72 # Internal space isn't counted. 

73 (' space test', (8, 8)), 

74 ('\ttab test', (1, 8)), 

75 ('\t\tdouble tabs test', (2, 16)), 

76 # Different results when mixing tabs and spaces. 

77 (' \tmixed test', (9, 16)), 

78 (' \t mixed test', (9, 10)), 

79 ('\t mixed test', (9, 16)), 

80 # Spaces not divisible by tabwidth. 

81 (' \tmixed test', (3, 8)), 

82 (' \t mixed test', (3, 9)), 

83 ('\t mixed test', (3, 10)), 

84 # Only checks spaces and tabs. 

85 ('\nnewline test', (0, 0))) 

86 

87 for line, expected in tests: 1d

88 with self.subTest(line=line): 1d

89 self.assertEqual( 1d

90 editor.get_line_indent(line, tabwidth=8), 

91 expected, 

92 ) 

93 

94 

95def insert(text, string): 

96 text.delete('1.0', 'end') 

97 text.insert('end', string) 

98 text.update() # Force update for colorizer to finish. 

99 

100 

101class IndentAndNewlineTest(unittest.TestCase): 

102 

103 @classmethod 

104 def setUpClass(cls): 

105 requires('gui') 

106 cls.root = Tk() 

107 cls.root.withdraw() 

108 cls.window = Editor(root=cls.root) 

109 cls.window.indentwidth = 2 

110 cls.window.tabwidth = 2 

111 

112 @classmethod 

113 def tearDownClass(cls): 

114 cls.window._close() 

115 del cls.window 

116 cls.root.update_idletasks() 

117 for id in cls.root.tk.call('after', 'info'): 

118 cls.root.after_cancel(id) 

119 cls.root.destroy() 

120 del cls.root 

121 

122 def test_indent_and_newline_event(self): 

123 eq = self.assertEqual 

124 w = self.window 

125 text = w.text 

126 get = text.get 

127 nl = w.newline_and_indent_event 

128 

129 TestInfo = namedtuple('Tests', ['label', 'text', 'expected', 'mark']) 

130 

131 tests = (TestInfo('Empty line inserts with no indent.', 

132 ' \n def __init__(self):', 

133 '\n \n def __init__(self):\n', 

134 '1.end'), 

135 TestInfo('Inside bracket before space, deletes space.', 

136 ' def f1(self, a, b):', 

137 ' def f1(self,\n a, b):\n', 

138 '1.14'), 

139 TestInfo('Inside bracket after space, deletes space.', 

140 ' def f1(self, a, b):', 

141 ' def f1(self,\n a, b):\n', 

142 '1.15'), 

143 TestInfo('Inside string with one line - no indent.', 

144 ' """Docstring."""', 

145 ' """Docstring.\n"""\n', 

146 '1.15'), 

147 TestInfo('Inside string with more than one line.', 

148 ' """Docstring.\n Docstring Line 2"""', 

149 ' """Docstring.\n Docstring Line 2\n """\n', 

150 '2.18'), 

151 TestInfo('Backslash with one line.', 

152 'a =\\', 

153 'a =\\\n \n', 

154 '1.end'), 

155 TestInfo('Backslash with more than one line.', 

156 'a =\\\n multiline\\', 

157 'a =\\\n multiline\\\n \n', 

158 '2.end'), 

159 TestInfo('Block opener - indents +1 level.', 

160 ' def f1(self):\n pass', 

161 ' def f1(self):\n \n pass\n', 

162 '1.end'), 

163 TestInfo('Block closer - dedents -1 level.', 

164 ' def f1(self):\n pass', 

165 ' def f1(self):\n pass\n \n', 

166 '2.end'), 

167 ) 

168 

169 for test in tests: 

170 with self.subTest(label=test.label): 

171 insert(text, test.text) 

172 text.mark_set('insert', test.mark) 

173 nl(event=None) 

174 eq(get('1.0', 'end'), test.expected) 

175 

176 # Selected text. 

177 insert(text, ' def f1(self, a, b):\n return a + b') 

178 text.tag_add('sel', '1.17', '1.end') 

179 nl(None) 

180 # Deletes selected text before adding new line. 

181 eq(get('1.0', 'end'), ' def f1(self, a,\n \n return a + b\n') 

182 

183 

184class RMenuTest(unittest.TestCase): 

185 

186 @classmethod 

187 def setUpClass(cls): 

188 requires('gui') 

189 cls.root = Tk() 

190 cls.root.withdraw() 

191 cls.window = Editor(root=cls.root) 

192 

193 @classmethod 

194 def tearDownClass(cls): 

195 cls.window._close() 

196 del cls.window 

197 cls.root.update_idletasks() 

198 for id in cls.root.tk.call('after', 'info'): 

199 cls.root.after_cancel(id) 

200 cls.root.destroy() 

201 del cls.root 

202 

203 class DummyRMenu: 

204 def tk_popup(x, y): pass 204 ↛ exitline 204 didn't return from function 'tk_popup'

205 

206 def test_rclick(self): 

207 pass 

208 

209 

210if __name__ == '__main__': 210 ↛ 211line 210 didn't jump to line 211, because the condition on line 210 was never true

211 unittest.main(verbosity=2)