Coverage for idle_test/test_textview.py: 2%

162 statements  

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

1"""Test textview, coverage 100%. 

2 

3Since all methods and functions create (or destroy) a ViewWindow, which 

4is a widget containing a widget, etcetera, all tests must be gui tests. 

5Using mock Text would not change this. Other mocks are used to retrieve 

6information about calls. 

7""" 

8from idlelib import textview as tv 

9from test.support import requires 

10requires('gui') 

11 

12import os 

13import unittest 

14from tkinter import Tk, TclError, CHAR, NONE, WORD 

15from tkinter.ttk import Button 

16from idlelib.idle_test.mock_idle import Func 

17from idlelib.idle_test.mock_tk import Mbox_func 

18 

19def setUpModule(): 

20 global root 

21 root = Tk() 

22 root.withdraw() 

23 

24def tearDownModule(): 

25 global root 

26 root.update_idletasks() 

27 root.destroy() 

28 del root 

29 

30# If we call ViewWindow or wrapper functions with defaults 

31# modal=True, _utest=False, test hangs on call to wait_window. 

32# Have also gotten tk error 'can't invoke "event" command'. 

33 

34 

35class VW(tv.ViewWindow): # Used in ViewWindowTest. 

36 transient = Func() 

37 grab_set = Func() 

38 wait_window = Func() 

39 

40 

41# Call wrapper class VW with mock wait_window. 

42class ViewWindowTest(unittest.TestCase): 

43 

44 def setUp(self): 

45 VW.transient.__init__() 

46 VW.grab_set.__init__() 

47 VW.wait_window.__init__() 

48 

49 def test_init_modal(self): 

50 view = VW(root, 'Title', 'test text') 

51 self.assertTrue(VW.transient.called) 

52 self.assertTrue(VW.grab_set.called) 

53 self.assertTrue(VW.wait_window.called) 

54 view.ok() 

55 

56 def test_init_nonmodal(self): 

57 view = VW(root, 'Title', 'test text', modal=False) 

58 self.assertFalse(VW.transient.called) 

59 self.assertFalse(VW.grab_set.called) 

60 self.assertFalse(VW.wait_window.called) 

61 view.ok() 

62 

63 def test_ok(self): 

64 view = VW(root, 'Title', 'test text', modal=False) 

65 view.destroy = Func() 

66 view.ok() 

67 self.assertTrue(view.destroy.called) 

68 del view.destroy # Unmask real function. 

69 view.destroy() 

70 

71 

72class AutoHideScrollbarTest(unittest.TestCase): 

73 # Method set is tested in ScrollableTextFrameTest 

74 def test_forbidden_geometry(self): 

75 scroll = tv.AutoHideScrollbar(root) 

76 self.assertRaises(TclError, scroll.pack) 

77 self.assertRaises(TclError, scroll.place) 

78 

79 

80class ScrollableTextFrameTest(unittest.TestCase): 

81 

82 @classmethod 

83 def setUpClass(cls): 

84 cls.root = root = Tk() 

85 root.withdraw() 

86 

87 @classmethod 

88 def tearDownClass(cls): 

89 cls.root.update_idletasks() 

90 cls.root.destroy() 

91 del cls.root 

92 

93 def make_frame(self, wrap=NONE, **kwargs): 

94 frame = tv.ScrollableTextFrame(self.root, wrap=wrap, **kwargs) 

95 def cleanup_frame(): 

96 frame.update_idletasks() 

97 frame.destroy() 

98 self.addCleanup(cleanup_frame) 

99 return frame 

100 

101 def test_line1(self): 

102 frame = self.make_frame() 

103 frame.text.insert('1.0', 'test text') 

104 self.assertEqual(frame.text.get('1.0', '1.end'), 'test text') 

105 

106 def test_horiz_scrollbar(self): 

107 # The horizontal scrollbar should be shown/hidden according to 

108 # the 'wrap' setting: It should only be shown when 'wrap' is 

109 # set to NONE. 

110 

111 # wrap = NONE -> with horizontal scrolling 

112 frame = self.make_frame(wrap=NONE) 

113 self.assertEqual(frame.text.cget('wrap'), NONE) 

114 self.assertIsNotNone(frame.xscroll) 

115 

116 # wrap != NONE -> no horizontal scrolling 

117 for wrap in [CHAR, WORD]: 

118 with self.subTest(wrap=wrap): 

119 frame = self.make_frame(wrap=wrap) 

120 self.assertEqual(frame.text.cget('wrap'), wrap) 

121 self.assertIsNone(frame.xscroll) 

122 

123 

124class ViewFrameTest(unittest.TestCase): 

125 

126 @classmethod 

127 def setUpClass(cls): 

128 cls.root = root = Tk() 

129 root.withdraw() 

130 cls.frame = tv.ViewFrame(root, 'test text') 

131 

132 @classmethod 

133 def tearDownClass(cls): 

134 del cls.frame 

135 cls.root.update_idletasks() 

136 cls.root.destroy() 

137 del cls.root 

138 

139 def test_line1(self): 

140 get = self.frame.text.get 

141 self.assertEqual(get('1.0', '1.end'), 'test text') 

142 

143 

144# Call ViewWindow with modal=False. 

145class ViewFunctionTest(unittest.TestCase): 

146 

147 @classmethod 

148 def setUpClass(cls): 

149 cls.orig_error = tv.showerror 

150 tv.showerror = Mbox_func() 

151 

152 @classmethod 

153 def tearDownClass(cls): 

154 tv.showerror = cls.orig_error 

155 del cls.orig_error 

156 

157 def test_view_text(self): 

158 view = tv.view_text(root, 'Title', 'test text', modal=False) 

159 self.assertIsInstance(view, tv.ViewWindow) 

160 self.assertIsInstance(view.viewframe, tv.ViewFrame) 

161 view.viewframe.ok() 

162 

163 def test_view_file(self): 

164 view = tv.view_file(root, 'Title', __file__, 'ascii', modal=False) 

165 self.assertIsInstance(view, tv.ViewWindow) 

166 self.assertIsInstance(view.viewframe, tv.ViewFrame) 

167 get = view.viewframe.textframe.text.get 

168 self.assertIn('Test', get('1.0', '1.end')) 

169 view.ok() 

170 

171 def test_bad_file(self): 

172 # Mock showerror will be used; view_file will return None. 

173 view = tv.view_file(root, 'Title', 'abc.xyz', 'ascii', modal=False) 

174 self.assertIsNone(view) 

175 self.assertEqual(tv.showerror.title, 'File Load Error') 

176 

177 def test_bad_encoding(self): 

178 p = os.path 

179 fn = p.abspath(p.join(p.dirname(__file__), '..', 'CREDITS.txt')) 

180 view = tv.view_file(root, 'Title', fn, 'ascii', modal=False) 

181 self.assertIsNone(view) 

182 self.assertEqual(tv.showerror.title, 'Unicode Decode Error') 

183 

184 def test_nowrap(self): 

185 view = tv.view_text(root, 'Title', 'test', modal=False, wrap='none') 

186 text_widget = view.viewframe.textframe.text 

187 self.assertEqual(text_widget.cget('wrap'), 'none') 

188 

189 

190# Call ViewWindow with _utest=True. 

191class ButtonClickTest(unittest.TestCase): 

192 

193 def setUp(self): 

194 self.view = None 

195 self.called = False 

196 

197 def tearDown(self): 

198 if self.view: 

199 self.view.destroy() 

200 

201 def test_view_text_bind_with_button(self): 

202 def _command(): 

203 self.called = True 

204 self.view = tv.view_text(root, 'TITLE_TEXT', 'COMMAND', _utest=True) 

205 button = Button(root, text='BUTTON', command=_command) 

206 button.invoke() 

207 self.addCleanup(button.destroy) 

208 

209 self.assertEqual(self.called, True) 

210 self.assertEqual(self.view.title(), 'TITLE_TEXT') 

211 self.assertEqual(self.view.viewframe.textframe.text.get('1.0', '1.end'), 

212 'COMMAND') 

213 

214 def test_view_file_bind_with_button(self): 

215 def _command(): 

216 self.called = True 

217 self.view = tv.view_file(root, 'TITLE_FILE', __file__, 

218 encoding='ascii', _utest=True) 

219 button = Button(root, text='BUTTON', command=_command) 

220 button.invoke() 

221 self.addCleanup(button.destroy) 

222 

223 self.assertEqual(self.called, True) 

224 self.assertEqual(self.view.title(), 'TITLE_FILE') 

225 get = self.view.viewframe.textframe.text.get 

226 with open(__file__) as f: 

227 self.assertEqual(get('1.0', '1.end'), f.readline().strip()) 

228 f.readline() 

229 self.assertEqual(get('3.0', '3.end'), f.readline().strip()) 

230 

231 

232if __name__ == '__main__': 

233 unittest.main(verbosity=2)