1"Test run, coverage 42%." 2 3from idlelib import run 4import unittest 5from unittest import mock 6from test.support import captured_stderr 7 8import io 9import sys 10 11 12class RunTest(unittest.TestCase): 13 14 def test_print_exception_unhashable(self): 15 class UnhashableException(Exception): 16 def __eq__(self, other): 17 return True 18 19 ex1 = UnhashableException('ex1') 20 ex2 = UnhashableException('ex2') 21 try: 22 raise ex2 from ex1 23 except UnhashableException: 24 try: 25 raise ex1 26 except UnhashableException: 27 with captured_stderr() as output: 28 with mock.patch.object(run, 29 'cleanup_traceback') as ct: 30 ct.side_effect = lambda t, e: t 31 run.print_exception() 32 33 tb = output.getvalue().strip().splitlines() 34 self.assertEqual(11, len(tb)) 35 self.assertIn('UnhashableException: ex2', tb[3]) 36 self.assertIn('UnhashableException: ex1', tb[10]) 37 38 39# StdioFile tests. 40 41class S(str): 42 def __str__(self): 43 return '%s:str' % type(self).__name__ 44 def __unicode__(self): 45 return '%s:unicode' % type(self).__name__ 46 def __len__(self): 47 return 3 48 def __iter__(self): 49 return iter('abc') 50 def __getitem__(self, *args): 51 return '%s:item' % type(self).__name__ 52 def __getslice__(self, *args): 53 return '%s:slice' % type(self).__name__ 54 55 56class MockShell: 57 def __init__(self): 58 self.reset() 59 def write(self, *args): 60 self.written.append(args) 61 def readline(self): 62 return self.lines.pop() 63 def close(self): 64 pass 65 def reset(self): 66 self.written = [] 67 def push(self, lines): 68 self.lines = list(lines)[::-1] 69 70 71class StdInputFilesTest(unittest.TestCase): 72 73 def test_misc(self): 74 shell = MockShell() 75 f = run.StdInputFile(shell, 'stdin') 76 self.assertIsInstance(f, io.TextIOBase) 77 self.assertEqual(f.encoding, 'utf-8') 78 self.assertEqual(f.errors, 'strict') 79 self.assertIsNone(f.newlines) 80 self.assertEqual(f.name, '<stdin>') 81 self.assertFalse(f.closed) 82 self.assertTrue(f.isatty()) 83 self.assertTrue(f.readable()) 84 self.assertFalse(f.writable()) 85 self.assertFalse(f.seekable()) 86 87 def test_unsupported(self): 88 shell = MockShell() 89 f = run.StdInputFile(shell, 'stdin') 90 self.assertRaises(OSError, f.fileno) 91 self.assertRaises(OSError, f.tell) 92 self.assertRaises(OSError, f.seek, 0) 93 self.assertRaises(OSError, f.write, 'x') 94 self.assertRaises(OSError, f.writelines, ['x']) 95 96 def test_read(self): 97 shell = MockShell() 98 f = run.StdInputFile(shell, 'stdin') 99 shell.push(['one\n', 'two\n', '']) 100 self.assertEqual(f.read(), 'one\ntwo\n') 101 shell.push(['one\n', 'two\n', '']) 102 self.assertEqual(f.read(-1), 'one\ntwo\n') 103 shell.push(['one\n', 'two\n', '']) 104 self.assertEqual(f.read(None), 'one\ntwo\n') 105 shell.push(['one\n', 'two\n', 'three\n', '']) 106 self.assertEqual(f.read(2), 'on') 107 self.assertEqual(f.read(3), 'e\nt') 108 self.assertEqual(f.read(10), 'wo\nthree\n') 109 110 shell.push(['one\n', 'two\n']) 111 self.assertEqual(f.read(0), '') 112 self.assertRaises(TypeError, f.read, 1.5) 113 self.assertRaises(TypeError, f.read, '1') 114 self.assertRaises(TypeError, f.read, 1, 1) 115 116 def test_readline(self): 117 shell = MockShell() 118 f = run.StdInputFile(shell, 'stdin') 119 shell.push(['one\n', 'two\n', 'three\n', 'four\n']) 120 self.assertEqual(f.readline(), 'one\n') 121 self.assertEqual(f.readline(-1), 'two\n') 122 self.assertEqual(f.readline(None), 'three\n') 123 shell.push(['one\ntwo\n']) 124 self.assertEqual(f.readline(), 'one\n') 125 self.assertEqual(f.readline(), 'two\n') 126 shell.push(['one', 'two', 'three']) 127 self.assertEqual(f.readline(), 'one') 128 self.assertEqual(f.readline(), 'two') 129 shell.push(['one\n', 'two\n', 'three\n']) 130 self.assertEqual(f.readline(2), 'on') 131 self.assertEqual(f.readline(1), 'e') 132 self.assertEqual(f.readline(1), '\n') 133 self.assertEqual(f.readline(10), 'two\n') 134 135 shell.push(['one\n', 'two\n']) 136 self.assertEqual(f.readline(0), '') 137 self.assertRaises(TypeError, f.readlines, 1.5) 138 self.assertRaises(TypeError, f.readlines, '1') 139 self.assertRaises(TypeError, f.readlines, 1, 1) 140 141 def test_readlines(self): 142 shell = MockShell() 143 f = run.StdInputFile(shell, 'stdin') 144 shell.push(['one\n', 'two\n', '']) 145 self.assertEqual(f.readlines(), ['one\n', 'two\n']) 146 shell.push(['one\n', 'two\n', '']) 147 self.assertEqual(f.readlines(-1), ['one\n', 'two\n']) 148 shell.push(['one\n', 'two\n', '']) 149 self.assertEqual(f.readlines(None), ['one\n', 'two\n']) 150 shell.push(['one\n', 'two\n', '']) 151 self.assertEqual(f.readlines(0), ['one\n', 'two\n']) 152 shell.push(['one\n', 'two\n', '']) 153 self.assertEqual(f.readlines(3), ['one\n']) 154 shell.push(['one\n', 'two\n', '']) 155 self.assertEqual(f.readlines(4), ['one\n', 'two\n']) 156 157 shell.push(['one\n', 'two\n', '']) 158 self.assertRaises(TypeError, f.readlines, 1.5) 159 self.assertRaises(TypeError, f.readlines, '1') 160 self.assertRaises(TypeError, f.readlines, 1, 1) 161 162 def test_close(self): 163 shell = MockShell() 164 f = run.StdInputFile(shell, 'stdin') 165 shell.push(['one\n', 'two\n', '']) 166 self.assertFalse(f.closed) 167 self.assertEqual(f.readline(), 'one\n') 168 f.close() 169 self.assertFalse(f.closed) 170 self.assertEqual(f.readline(), 'two\n') 171 self.assertRaises(TypeError, f.close, 1) 172 173 174class StdOutputFilesTest(unittest.TestCase): 175 176 def test_misc(self): 177 shell = MockShell() 178 f = run.StdOutputFile(shell, 'stdout') 179 self.assertIsInstance(f, io.TextIOBase) 180 self.assertEqual(f.encoding, 'utf-8') 181 self.assertEqual(f.errors, 'strict') 182 self.assertIsNone(f.newlines) 183 self.assertEqual(f.name, '<stdout>') 184 self.assertFalse(f.closed) 185 self.assertTrue(f.isatty()) 186 self.assertFalse(f.readable()) 187 self.assertTrue(f.writable()) 188 self.assertFalse(f.seekable()) 189 190 def test_unsupported(self): 191 shell = MockShell() 192 f = run.StdOutputFile(shell, 'stdout') 193 self.assertRaises(OSError, f.fileno) 194 self.assertRaises(OSError, f.tell) 195 self.assertRaises(OSError, f.seek, 0) 196 self.assertRaises(OSError, f.read, 0) 197 self.assertRaises(OSError, f.readline, 0) 198 199 def test_write(self): 200 shell = MockShell() 201 f = run.StdOutputFile(shell, 'stdout') 202 f.write('test') 203 self.assertEqual(shell.written, [('test', 'stdout')]) 204 shell.reset() 205 f.write('t\xe8\u015b\U0001d599') 206 self.assertEqual(shell.written, [('t\xe8\u015b\U0001d599', 'stdout')]) 207 shell.reset() 208 209 f.write(S('t\xe8\u015b\U0001d599')) 210 self.assertEqual(shell.written, [('t\xe8\u015b\U0001d599', 'stdout')]) 211 self.assertEqual(type(shell.written[0][0]), str) 212 shell.reset() 213 214 self.assertRaises(TypeError, f.write) 215 self.assertEqual(shell.written, []) 216 self.assertRaises(TypeError, f.write, b'test') 217 self.assertRaises(TypeError, f.write, 123) 218 self.assertEqual(shell.written, []) 219 self.assertRaises(TypeError, f.write, 'test', 'spam') 220 self.assertEqual(shell.written, []) 221 222 def test_write_stderr_nonencodable(self): 223 shell = MockShell() 224 f = run.StdOutputFile(shell, 'stderr', 'iso-8859-15', 'backslashreplace') 225 f.write('t\xe8\u015b\U0001d599\xa4') 226 self.assertEqual(shell.written, [('t\xe8\\u015b\\U0001d599\\xa4', 'stderr')]) 227 shell.reset() 228 229 f.write(S('t\xe8\u015b\U0001d599\xa4')) 230 self.assertEqual(shell.written, [('t\xe8\\u015b\\U0001d599\\xa4', 'stderr')]) 231 self.assertEqual(type(shell.written[0][0]), str) 232 shell.reset() 233 234 self.assertRaises(TypeError, f.write) 235 self.assertEqual(shell.written, []) 236 self.assertRaises(TypeError, f.write, b'test') 237 self.assertRaises(TypeError, f.write, 123) 238 self.assertEqual(shell.written, []) 239 self.assertRaises(TypeError, f.write, 'test', 'spam') 240 self.assertEqual(shell.written, []) 241 242 def test_writelines(self): 243 shell = MockShell() 244 f = run.StdOutputFile(shell, 'stdout') 245 f.writelines([]) 246 self.assertEqual(shell.written, []) 247 shell.reset() 248 f.writelines(['one\n', 'two']) 249 self.assertEqual(shell.written, 250 [('one\n', 'stdout'), ('two', 'stdout')]) 251 shell.reset() 252 f.writelines(['on\xe8\n', 'tw\xf2']) 253 self.assertEqual(shell.written, 254 [('on\xe8\n', 'stdout'), ('tw\xf2', 'stdout')]) 255 shell.reset() 256 257 f.writelines([S('t\xe8st')]) 258 self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) 259 self.assertEqual(type(shell.written[0][0]), str) 260 shell.reset() 261 262 self.assertRaises(TypeError, f.writelines) 263 self.assertEqual(shell.written, []) 264 self.assertRaises(TypeError, f.writelines, 123) 265 self.assertEqual(shell.written, []) 266 self.assertRaises(TypeError, f.writelines, [b'test']) 267 self.assertRaises(TypeError, f.writelines, [123]) 268 self.assertEqual(shell.written, []) 269 self.assertRaises(TypeError, f.writelines, [], []) 270 self.assertEqual(shell.written, []) 271 272 def test_close(self): 273 shell = MockShell() 274 f = run.StdOutputFile(shell, 'stdout') 275 self.assertFalse(f.closed) 276 f.write('test') 277 f.close() 278 self.assertTrue(f.closed) 279 self.assertRaises(ValueError, f.write, 'x') 280 self.assertEqual(shell.written, [('test', 'stdout')]) 281 f.close() 282 self.assertRaises(TypeError, f.close, 1) 283 284 285class TestSysRecursionLimitWrappers(unittest.TestCase): 286 287 def test_bad_setrecursionlimit_calls(self): 288 run.install_recursionlimit_wrappers() 289 self.addCleanup(run.uninstall_recursionlimit_wrappers) 290 f = sys.setrecursionlimit 291 self.assertRaises(TypeError, f, limit=100) 292 self.assertRaises(TypeError, f, 100, 1000) 293 self.assertRaises(ValueError, f, 0) 294 295 def test_roundtrip(self): 296 run.install_recursionlimit_wrappers() 297 self.addCleanup(run.uninstall_recursionlimit_wrappers) 298 299 # check that setting the recursion limit works 300 orig_reclimit = sys.getrecursionlimit() 301 self.addCleanup(sys.setrecursionlimit, orig_reclimit) 302 sys.setrecursionlimit(orig_reclimit + 3) 303 304 # check that the new limit is returned by sys.getrecursionlimit() 305 new_reclimit = sys.getrecursionlimit() 306 self.assertEqual(new_reclimit, orig_reclimit + 3) 307 308 def test_default_recursion_limit_preserved(self): 309 orig_reclimit = sys.getrecursionlimit() 310 run.install_recursionlimit_wrappers() 311 self.addCleanup(run.uninstall_recursionlimit_wrappers) 312 new_reclimit = sys.getrecursionlimit() 313 self.assertEqual(new_reclimit, orig_reclimit) 314 315 def test_fixdoc(self): 316 def func(): "docstring" 317 run.fixdoc(func, "more") 318 self.assertEqual(func.__doc__, "docstring\n\nmore") 319 func.__doc__ = None 320 run.fixdoc(func, "more") 321 self.assertEqual(func.__doc__, "more") 322 323 324if __name__ == '__main__': 325 unittest.main(verbosity=2) 326