bpo-33855: More edits and new minimal tests for IDLE (GH-7761)

Part 2 of 3.  Continues PR #7689, changeset ee5ef30.
Edit and add tests for 18 modules, help_about to replace and run.
This commit is contained in:
Terry Jan Reedy 2018-06-18 04:47:59 -04:00 committed by GitHub
parent 5092439c2c
commit ea3dc8029a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 480 additions and 335 deletions

View File

@ -199,7 +199,8 @@ class AboutDialog(Toplevel):
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_help_about', verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_help_about', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(AboutDialog)

View File

@ -308,5 +308,5 @@ class HyperParser:
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_hyperparser', verbosity=2)
from unittest import main
main('idlelib.idle_test.test_hyperparser', verbosity=2)

View File

@ -1,18 +1,19 @@
'''Test idlelib.help_about.
"""Test help_about, coverage 100%.
help_about.build_bits branches on sys.platform='darwin'.
'100% combines coverage on Mac and others.
"""
Coverage: 100%
'''
from idlelib import help_about
import unittest
from test.support import requires, findfile
from tkinter import Tk, TclError
import unittest
from unittest import mock
from idlelib.idle_test.mock_idle import Func
from idlelib.idle_test.mock_tk import Mbox_func
from idlelib.help_about import AboutDialog as About
from idlelib import help_about
from idlelib import textview
import os.path
from platform import python_version, architecture
from platform import python_version
About = help_about.AboutDialog
class LiveDialogTest(unittest.TestCase):

View File

@ -1,15 +1,18 @@
" Test history, coverage 100%."
from idlelib.history import History
import unittest
from test.support import requires
import tkinter as tk
from tkinter import Text as tkText
from idlelib.idle_test.mock_tk import Text as mkText
from idlelib.history import History
from idlelib.config import idleConf
line1 = 'a = 7'
line2 = 'b = a'
class StoreTest(unittest.TestCase):
'''Tests History.__init__ and History.store with mock Text'''
@ -61,6 +64,7 @@ class TextWrapper:
def bell(self):
self._bell = True
class FetchTest(unittest.TestCase):
'''Test History.fetch with wrapped tk.Text.
'''

View File

@ -1,9 +1,10 @@
"""Unittest for idlelib.hyperparser.py."""
"Test hyperparser, coverage 98%."
from idlelib.hyperparser import HyperParser
import unittest
from test.support import requires
from tkinter import Tk, Text
from idlelib.editor import EditorWindow
from idlelib.hyperparser import HyperParser
class DummyEditwin:
def __init__(self, text):
@ -270,5 +271,6 @@ class HyperParserTest(unittest.TestCase):
self.assertEqual(eat_id('2' + 'a' * (length - 1), 0, length), 0)
self.assertEqual(eat_id('2' + 'é' * (length - 1), 0, length), 0)
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -1,233 +1,36 @@
"Test , coverage 16%."
from idlelib import iomenu
import unittest
import io
from test.support import requires
from tkinter import Tk
from idlelib.run import PseudoInputFile, PseudoOutputFile
from idlelib.editor import EditorWindow
class S(str):
def __str__(self):
return '%s:str' % type(self).__name__
def __unicode__(self):
return '%s:unicode' % type(self).__name__
def __len__(self):
return 3
def __iter__(self):
return iter('abc')
def __getitem__(self, *args):
return '%s:item' % type(self).__name__
def __getslice__(self, *args):
return '%s:slice' % type(self).__name__
class IOBindigTest(unittest.TestCase):
class MockShell:
def __init__(self):
self.reset()
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
cls.editwin = EditorWindow(root=cls.root)
def write(self, *args):
self.written.append(args)
@classmethod
def tearDownClass(cls):
cls.editwin._close()
del cls.editwin
cls.root.update_idletasks()
for id in cls.root.tk.call('after', 'info'):
cls.root.after_cancel(id) # Need for EditorWindow.
cls.root.destroy()
del cls.root
def readline(self):
return self.lines.pop()
def close(self):
pass
def reset(self):
self.written = []
def push(self, lines):
self.lines = list(lines)[::-1]
class PseudeOutputFilesTest(unittest.TestCase):
def test_misc(self):
shell = MockShell()
f = PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertIsInstance(f, io.TextIOBase)
self.assertEqual(f.encoding, 'utf-8')
self.assertIsNone(f.errors)
self.assertIsNone(f.newlines)
self.assertEqual(f.name, '<stdout>')
self.assertFalse(f.closed)
self.assertTrue(f.isatty())
self.assertFalse(f.readable())
self.assertTrue(f.writable())
self.assertFalse(f.seekable())
def test_unsupported(self):
shell = MockShell()
f = PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertRaises(OSError, f.fileno)
self.assertRaises(OSError, f.tell)
self.assertRaises(OSError, f.seek, 0)
self.assertRaises(OSError, f.read, 0)
self.assertRaises(OSError, f.readline, 0)
def test_write(self):
shell = MockShell()
f = PseudoOutputFile(shell, 'stdout', 'utf-8')
f.write('test')
self.assertEqual(shell.written, [('test', 'stdout')])
shell.reset()
f.write('t\xe8st')
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
shell.reset()
f.write(S('t\xe8st'))
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
self.assertEqual(type(shell.written[0][0]), str)
shell.reset()
self.assertRaises(TypeError, f.write)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.write, b'test')
self.assertRaises(TypeError, f.write, 123)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.write, 'test', 'spam')
self.assertEqual(shell.written, [])
def test_writelines(self):
shell = MockShell()
f = PseudoOutputFile(shell, 'stdout', 'utf-8')
f.writelines([])
self.assertEqual(shell.written, [])
shell.reset()
f.writelines(['one\n', 'two'])
self.assertEqual(shell.written,
[('one\n', 'stdout'), ('two', 'stdout')])
shell.reset()
f.writelines(['on\xe8\n', 'tw\xf2'])
self.assertEqual(shell.written,
[('on\xe8\n', 'stdout'), ('tw\xf2', 'stdout')])
shell.reset()
f.writelines([S('t\xe8st')])
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
self.assertEqual(type(shell.written[0][0]), str)
shell.reset()
self.assertRaises(TypeError, f.writelines)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, 123)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, [b'test'])
self.assertRaises(TypeError, f.writelines, [123])
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, [], [])
self.assertEqual(shell.written, [])
def test_close(self):
shell = MockShell()
f = PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertFalse(f.closed)
f.write('test')
f.close()
self.assertTrue(f.closed)
self.assertRaises(ValueError, f.write, 'x')
self.assertEqual(shell.written, [('test', 'stdout')])
f.close()
self.assertRaises(TypeError, f.close, 1)
class PseudeInputFilesTest(unittest.TestCase):
def test_misc(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
self.assertIsInstance(f, io.TextIOBase)
self.assertEqual(f.encoding, 'utf-8')
self.assertIsNone(f.errors)
self.assertIsNone(f.newlines)
self.assertEqual(f.name, '<stdin>')
self.assertFalse(f.closed)
self.assertTrue(f.isatty())
self.assertTrue(f.readable())
self.assertFalse(f.writable())
self.assertFalse(f.seekable())
def test_unsupported(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
self.assertRaises(OSError, f.fileno)
self.assertRaises(OSError, f.tell)
self.assertRaises(OSError, f.seek, 0)
self.assertRaises(OSError, f.write, 'x')
self.assertRaises(OSError, f.writelines, ['x'])
def test_read(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(), 'one\ntwo\n')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(-1), 'one\ntwo\n')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(None), 'one\ntwo\n')
shell.push(['one\n', 'two\n', 'three\n', ''])
self.assertEqual(f.read(2), 'on')
self.assertEqual(f.read(3), 'e\nt')
self.assertEqual(f.read(10), 'wo\nthree\n')
shell.push(['one\n', 'two\n'])
self.assertEqual(f.read(0), '')
self.assertRaises(TypeError, f.read, 1.5)
self.assertRaises(TypeError, f.read, '1')
self.assertRaises(TypeError, f.read, 1, 1)
def test_readline(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', 'three\n', 'four\n'])
self.assertEqual(f.readline(), 'one\n')
self.assertEqual(f.readline(-1), 'two\n')
self.assertEqual(f.readline(None), 'three\n')
shell.push(['one\ntwo\n'])
self.assertEqual(f.readline(), 'one\n')
self.assertEqual(f.readline(), 'two\n')
shell.push(['one', 'two', 'three'])
self.assertEqual(f.readline(), 'one')
self.assertEqual(f.readline(), 'two')
shell.push(['one\n', 'two\n', 'three\n'])
self.assertEqual(f.readline(2), 'on')
self.assertEqual(f.readline(1), 'e')
self.assertEqual(f.readline(1), '\n')
self.assertEqual(f.readline(10), 'two\n')
shell.push(['one\n', 'two\n'])
self.assertEqual(f.readline(0), '')
self.assertRaises(TypeError, f.readlines, 1.5)
self.assertRaises(TypeError, f.readlines, '1')
self.assertRaises(TypeError, f.readlines, 1, 1)
def test_readlines(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(-1), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(None), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(0), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(3), ['one\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(4), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertRaises(TypeError, f.readlines, 1.5)
self.assertRaises(TypeError, f.readlines, '1')
self.assertRaises(TypeError, f.readlines, 1, 1)
def test_close(self):
shell = MockShell()
f = PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertFalse(f.closed)
self.assertEqual(f.readline(), 'one\n')
f.close()
self.assertFalse(f.closed)
self.assertEqual(f.readline(), 'two\n')
self.assertRaises(TypeError, f.close, 1)
def test_init(self):
io = iomenu.IOBinding(self.editwin)
self.assertIs(io.editwin, self.editwin)
io.close
if __name__ == '__main__':

View File

@ -1,11 +1,9 @@
'''Test idlelib.macosx.py.
"Test macosx, coverage 45% on Windows."
Coverage: 71% on Windows.
'''
from idlelib import macosx
import unittest
from test.support import requires
import tkinter as tk
import unittest
import unittest.mock as mock
from idlelib.filelist import FileList

View File

@ -0,0 +1,21 @@
"Test mainmenu, coverage 100%."
# Reported as 88%; mocking turtledemo absence would have no point.
from idlelib import mainmenu
import unittest
class MainMenuTest(unittest.TestCase):
def test_menudefs(self):
actual = [item[0] for item in mainmenu.menudefs]
expect = ['file', 'edit', 'format', 'run', 'shell',
'debug', 'options', 'windows', 'help']
self.assertEqual(actual, expect)
def test_default_keydefs(self):
self.assertGreaterEqual(len(mainmenu.default_keydefs), 50)
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -0,0 +1,40 @@
"Test multicall, coverage 33%."
from idlelib import multicall
import unittest
from test.support import requires
from tkinter import Tk, Text
class MultiCallTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
cls.mc = multicall.MultiCallCreator(Text)
@classmethod
def tearDownClass(cls):
del cls.mc
cls.root.update_idletasks()
## for id in cls.root.tk.call('after', 'info'):
## cls.root.after_cancel(id) # Need for EditorWindow.
cls.root.destroy()
del cls.root
def test_creator(self):
mc = self.mc
self.assertIs(multicall._multicall_dict[Text], mc)
self.assertTrue(issubclass(mc, Text))
mc2 = multicall.MultiCallCreator(Text)
self.assertIs(mc, mc2)
def test_init(self):
mctext = self.mc(self.root)
self.assertIsInstance(mctext._MultiCall__binders, list)
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -1,12 +1,11 @@
""" Test idlelib.outwin.
"""
"Test outwin, coverage 76%."
from idlelib import outwin
import unittest
from test.support import requires
from tkinter import Tk, Text
from idlelib.idle_test.mock_tk import Mbox_func
from idlelib.idle_test.mock_idle import Func
from idlelib import outwin
from test.support import requires
from unittest import mock

View File

@ -1,9 +1,10 @@
# Test the functions and main class method of paragraph.py
"Test paragraph, coverage 76%."
from idlelib import paragraph as pg
import unittest
from idlelib import paragraph as fp
from idlelib.editor import EditorWindow
from tkinter import Tk, Text
from test.support import requires
from tkinter import Tk, Text
from idlelib.editor import EditorWindow
class Is_Get_Test(unittest.TestCase):
@ -15,26 +16,26 @@ class Is_Get_Test(unittest.TestCase):
leadingws_nocomment = ' This is not a comment'
def test_is_all_white(self):
self.assertTrue(fp.is_all_white(''))
self.assertTrue(fp.is_all_white('\t\n\r\f\v'))
self.assertFalse(fp.is_all_white(self.test_comment))
self.assertTrue(pg.is_all_white(''))
self.assertTrue(pg.is_all_white('\t\n\r\f\v'))
self.assertFalse(pg.is_all_white(self.test_comment))
def test_get_indent(self):
Equal = self.assertEqual
Equal(fp.get_indent(self.test_comment), '')
Equal(fp.get_indent(self.trailingws_comment), '')
Equal(fp.get_indent(self.leadingws_comment), ' ')
Equal(fp.get_indent(self.leadingws_nocomment), ' ')
Equal(pg.get_indent(self.test_comment), '')
Equal(pg.get_indent(self.trailingws_comment), '')
Equal(pg.get_indent(self.leadingws_comment), ' ')
Equal(pg.get_indent(self.leadingws_nocomment), ' ')
def test_get_comment_header(self):
Equal = self.assertEqual
# Test comment strings
Equal(fp.get_comment_header(self.test_comment), '#')
Equal(fp.get_comment_header(self.trailingws_comment), '#')
Equal(fp.get_comment_header(self.leadingws_comment), ' #')
Equal(pg.get_comment_header(self.test_comment), '#')
Equal(pg.get_comment_header(self.trailingws_comment), '#')
Equal(pg.get_comment_header(self.leadingws_comment), ' #')
# Test non-comment strings
Equal(fp.get_comment_header(self.leadingws_nocomment), ' ')
Equal(fp.get_comment_header(self.test_nocomment), '')
Equal(pg.get_comment_header(self.leadingws_nocomment), ' ')
Equal(pg.get_comment_header(self.test_nocomment), '')
class FindTest(unittest.TestCase):
@ -62,7 +63,7 @@ class FindTest(unittest.TestCase):
linelength = int(text.index("%d.end" % line).split('.')[1])
for col in (0, linelength//2, linelength):
tempindex = "%d.%d" % (line, col)
self.assertEqual(fp.find_paragraph(text, tempindex), expected)
self.assertEqual(pg.find_paragraph(text, tempindex), expected)
text.delete('1.0', 'end')
def test_find_comment(self):
@ -161,7 +162,7 @@ class ReformatFunctionTest(unittest.TestCase):
def test_reformat_paragraph(self):
Equal = self.assertEqual
reform = fp.reformat_paragraph
reform = pg.reformat_paragraph
hw = "O hello world"
Equal(reform(' ', 1), ' ')
Equal(reform("Hello world", 20), "Hello world")
@ -192,7 +193,7 @@ class ReformatCommentTest(unittest.TestCase):
test_string = (
" \"\"\"this is a test of a reformat for a triple quoted string"
" will it reformat to less than 70 characters for me?\"\"\"")
result = fp.reformat_comment(test_string, 70, " ")
result = pg.reformat_comment(test_string, 70, " ")
expected = (
" \"\"\"this is a test of a reformat for a triple quoted string will it\n"
" reformat to less than 70 characters for me?\"\"\"")
@ -201,7 +202,7 @@ class ReformatCommentTest(unittest.TestCase):
test_comment = (
"# this is a test of a reformat for a triple quoted string will "
"it reformat to less than 70 characters for me?")
result = fp.reformat_comment(test_comment, 70, "#")
result = pg.reformat_comment(test_comment, 70, "#")
expected = (
"# this is a test of a reformat for a triple quoted string will it\n"
"# reformat to less than 70 characters for me?")
@ -210,7 +211,7 @@ class ReformatCommentTest(unittest.TestCase):
class FormatClassTest(unittest.TestCase):
def test_init_close(self):
instance = fp.FormatParagraph('editor')
instance = pg.FormatParagraph('editor')
self.assertEqual(instance.editwin, 'editor')
instance.close()
self.assertEqual(instance.editwin, None)
@ -269,14 +270,16 @@ class FormatEventTest(unittest.TestCase):
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
editor = Editor(root=cls.root)
cls.text = editor.text.text # Test code does not need the wrapper.
cls.formatter = fp.FormatParagraph(editor).format_paragraph_event
cls.formatter = pg.FormatParagraph(editor).format_paragraph_event
# Sets the insert mark just after the re-wrapped and inserted text.
@classmethod
def tearDownClass(cls):
del cls.text, cls.formatter
cls.root.update_idletasks()
cls.root.destroy()
del cls.root

View File

@ -1,8 +1,8 @@
'''Test idlelib.parenmatch.
"""Test parenmatch, coverage 91%.
This must currently be a gui test because ParenMatch methods use
several text methods not defined on idlelib.idle_test.mock_tk.Text.
'''
"""
from idlelib.parenmatch import ParenMatch
from test.support import requires
requires('gui')

View File

@ -1,19 +1,17 @@
""" Test idlelib.pathbrowser.
"""
"Test pathbrowser, coverage 95%."
from idlelib import pathbrowser
import unittest
from test.support import requires
from tkinter import Tk
import os.path
import pyclbr # for _modules
import sys # for sys.path
from tkinter import Tk
from test.support import requires
import unittest
from idlelib.idle_test.mock_idle import Func
import idlelib # for __file__
from idlelib import browser
from idlelib import pathbrowser
from idlelib.tree import TreeNode

View File

@ -1,10 +1,10 @@
'''Test percolator.py.'''
"Test percolator, coverage 100%."
from idlelib.percolator import Percolator, Delegator
import unittest
from test.support import requires
requires('gui')
import unittest
from tkinter import Text, Tk, END
from idlelib.percolator import Percolator, Delegator
class MyFilter(Delegator):

View File

@ -1,11 +1,8 @@
"""Unittest for idlelib.pyparse.py.
"Test pyparse, coverage 96%."
Coverage: 97%
"""
from collections import namedtuple
import unittest
from idlelib import pyparse
import unittest
from collections import namedtuple
class ParseMapTest(unittest.TestCase):

View File

@ -0,0 +1,42 @@
"Test pyshell, coverage 12%."
# Plus coverage of test_warning. Was 20% with test_openshell.
from idlelib import pyshell
import unittest
from test.support import requires
from tkinter import Tk
class PyShellFileListTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
@classmethod
def tearDownClass(cls):
#cls.root.update_idletasks()
## for id in cls.root.tk.call('after', 'info'):
## cls.root.after_cancel(id) # Need for EditorWindow.
cls.root.destroy()
del cls.root
def test_init(self):
psfl = pyshell.PyShellFileList(self.root)
self.assertEqual(psfl.EditorWindow, pyshell.PyShellEditorWindow)
self.assertIsNone(psfl.pyshell)
# The following sometimes causes 'invalid command name "109734456recolorize"'.
# Uncommenting after_cancel above prevents this, but results in
# TclError: bad window path name ".!listedtoplevel.!frame.text"
# which is normally prevented by after_cancel.
## def test_openshell(self):
## pyshell.use_subprocess = False
## ps = pyshell.PyShellFileList(self.root).open_shell()
## self.assertIsInstance(ps, pyshell.PyShell)
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -1,4 +1,4 @@
"""Test idlelib.query.
"""Test query, coverage 91%).
Non-gui tests for Query, SectionName, ModuleName, and HelpSource use
dummy versions that extract the non-gui methods and add other needed
@ -8,17 +8,15 @@ the subclass definition.
The appearance of the widgets is checked by the Query and
HelpSource htests. These are run by running query.py.
Coverage: 94% (100% for Query and SectionName).
6 of 8 missing are ModuleName exceptions I don't know how to trigger.
"""
from test.support import requires
import sys
from tkinter import Tk
from idlelib import query
import unittest
from test.support import requires
from tkinter import Tk
import sys
from unittest import mock
from idlelib.idle_test.mock_tk import Var
from idlelib import query
# NON-GUI TESTS

View File

@ -1,12 +1,10 @@
'''Test idlelib.redirector.
"Test redirector, coverage 100%."
100% coverage
'''
from test.support import requires
import unittest
from idlelib.idle_test.mock_idle import Func
from tkinter import Tk, Text, TclError
from idlelib.redirector import WidgetRedirector
import unittest
from test.support import requires
from tkinter import Tk, Text, TclError
from idlelib.idle_test.mock_idle import Func
class InitCloseTest(unittest.TestCase):

View File

@ -1,13 +1,14 @@
"""Unittest for idlelib.replace.py"""
"Test replace, coverage 78%."
from idlelib.replace import ReplaceDialog
import unittest
from test.support import requires
requires('gui')
import unittest
from unittest.mock import Mock
from tkinter import Tk, Text
from unittest.mock import Mock
from idlelib.idle_test.mock_tk import Mbox
import idlelib.searchengine as se
from idlelib.replace import ReplaceDialog
orig_mbox = se.tkMessageBox
showerror = Mbox.showerror

View File

@ -1,11 +1,14 @@
"Test run, coverage 42%."
from idlelib import run
import unittest
from unittest import mock
from test.support import captured_stderr
import idlelib.run as idlerun
import io
class RunTest(unittest.TestCase):
def test_print_exception_unhashable(self):
class UnhashableException(Exception):
def __eq__(self, other):
@ -20,10 +23,10 @@ class RunTest(unittest.TestCase):
raise ex1
except UnhashableException:
with captured_stderr() as output:
with mock.patch.object(idlerun,
with mock.patch.object(run,
'cleanup_traceback') as ct:
ct.side_effect = lambda t, e: t
idlerun.print_exception()
run.print_exception()
tb = output.getvalue().strip().splitlines()
self.assertEqual(11, len(tb))
@ -31,5 +34,231 @@ class RunTest(unittest.TestCase):
self.assertIn('UnhashableException: ex1', tb[10])
# PseudoFile tests.
class S(str):
def __str__(self):
return '%s:str' % type(self).__name__
def __unicode__(self):
return '%s:unicode' % type(self).__name__
def __len__(self):
return 3
def __iter__(self):
return iter('abc')
def __getitem__(self, *args):
return '%s:item' % type(self).__name__
def __getslice__(self, *args):
return '%s:slice' % type(self).__name__
class MockShell:
def __init__(self):
self.reset()
def write(self, *args):
self.written.append(args)
def readline(self):
return self.lines.pop()
def close(self):
pass
def reset(self):
self.written = []
def push(self, lines):
self.lines = list(lines)[::-1]
class PseudeInputFilesTest(unittest.TestCase):
def test_misc(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
self.assertIsInstance(f, io.TextIOBase)
self.assertEqual(f.encoding, 'utf-8')
self.assertIsNone(f.errors)
self.assertIsNone(f.newlines)
self.assertEqual(f.name, '<stdin>')
self.assertFalse(f.closed)
self.assertTrue(f.isatty())
self.assertTrue(f.readable())
self.assertFalse(f.writable())
self.assertFalse(f.seekable())
def test_unsupported(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
self.assertRaises(OSError, f.fileno)
self.assertRaises(OSError, f.tell)
self.assertRaises(OSError, f.seek, 0)
self.assertRaises(OSError, f.write, 'x')
self.assertRaises(OSError, f.writelines, ['x'])
def test_read(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(), 'one\ntwo\n')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(-1), 'one\ntwo\n')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.read(None), 'one\ntwo\n')
shell.push(['one\n', 'two\n', 'three\n', ''])
self.assertEqual(f.read(2), 'on')
self.assertEqual(f.read(3), 'e\nt')
self.assertEqual(f.read(10), 'wo\nthree\n')
shell.push(['one\n', 'two\n'])
self.assertEqual(f.read(0), '')
self.assertRaises(TypeError, f.read, 1.5)
self.assertRaises(TypeError, f.read, '1')
self.assertRaises(TypeError, f.read, 1, 1)
def test_readline(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', 'three\n', 'four\n'])
self.assertEqual(f.readline(), 'one\n')
self.assertEqual(f.readline(-1), 'two\n')
self.assertEqual(f.readline(None), 'three\n')
shell.push(['one\ntwo\n'])
self.assertEqual(f.readline(), 'one\n')
self.assertEqual(f.readline(), 'two\n')
shell.push(['one', 'two', 'three'])
self.assertEqual(f.readline(), 'one')
self.assertEqual(f.readline(), 'two')
shell.push(['one\n', 'two\n', 'three\n'])
self.assertEqual(f.readline(2), 'on')
self.assertEqual(f.readline(1), 'e')
self.assertEqual(f.readline(1), '\n')
self.assertEqual(f.readline(10), 'two\n')
shell.push(['one\n', 'two\n'])
self.assertEqual(f.readline(0), '')
self.assertRaises(TypeError, f.readlines, 1.5)
self.assertRaises(TypeError, f.readlines, '1')
self.assertRaises(TypeError, f.readlines, 1, 1)
def test_readlines(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(-1), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(None), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(0), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(3), ['one\n'])
shell.push(['one\n', 'two\n', ''])
self.assertEqual(f.readlines(4), ['one\n', 'two\n'])
shell.push(['one\n', 'two\n', ''])
self.assertRaises(TypeError, f.readlines, 1.5)
self.assertRaises(TypeError, f.readlines, '1')
self.assertRaises(TypeError, f.readlines, 1, 1)
def test_close(self):
shell = MockShell()
f = run.PseudoInputFile(shell, 'stdin', 'utf-8')
shell.push(['one\n', 'two\n', ''])
self.assertFalse(f.closed)
self.assertEqual(f.readline(), 'one\n')
f.close()
self.assertFalse(f.closed)
self.assertEqual(f.readline(), 'two\n')
self.assertRaises(TypeError, f.close, 1)
class PseudeOutputFilesTest(unittest.TestCase):
def test_misc(self):
shell = MockShell()
f = run.PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertIsInstance(f, io.TextIOBase)
self.assertEqual(f.encoding, 'utf-8')
self.assertIsNone(f.errors)
self.assertIsNone(f.newlines)
self.assertEqual(f.name, '<stdout>')
self.assertFalse(f.closed)
self.assertTrue(f.isatty())
self.assertFalse(f.readable())
self.assertTrue(f.writable())
self.assertFalse(f.seekable())
def test_unsupported(self):
shell = MockShell()
f = run.PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertRaises(OSError, f.fileno)
self.assertRaises(OSError, f.tell)
self.assertRaises(OSError, f.seek, 0)
self.assertRaises(OSError, f.read, 0)
self.assertRaises(OSError, f.readline, 0)
def test_write(self):
shell = MockShell()
f = run.PseudoOutputFile(shell, 'stdout', 'utf-8')
f.write('test')
self.assertEqual(shell.written, [('test', 'stdout')])
shell.reset()
f.write('t\xe8st')
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
shell.reset()
f.write(S('t\xe8st'))
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
self.assertEqual(type(shell.written[0][0]), str)
shell.reset()
self.assertRaises(TypeError, f.write)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.write, b'test')
self.assertRaises(TypeError, f.write, 123)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.write, 'test', 'spam')
self.assertEqual(shell.written, [])
def test_writelines(self):
shell = MockShell()
f = run.PseudoOutputFile(shell, 'stdout', 'utf-8')
f.writelines([])
self.assertEqual(shell.written, [])
shell.reset()
f.writelines(['one\n', 'two'])
self.assertEqual(shell.written,
[('one\n', 'stdout'), ('two', 'stdout')])
shell.reset()
f.writelines(['on\xe8\n', 'tw\xf2'])
self.assertEqual(shell.written,
[('on\xe8\n', 'stdout'), ('tw\xf2', 'stdout')])
shell.reset()
f.writelines([S('t\xe8st')])
self.assertEqual(shell.written, [('t\xe8st', 'stdout')])
self.assertEqual(type(shell.written[0][0]), str)
shell.reset()
self.assertRaises(TypeError, f.writelines)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, 123)
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, [b'test'])
self.assertRaises(TypeError, f.writelines, [123])
self.assertEqual(shell.written, [])
self.assertRaises(TypeError, f.writelines, [], [])
self.assertEqual(shell.written, [])
def test_close(self):
shell = MockShell()
f = run.PseudoOutputFile(shell, 'stdout', 'utf-8')
self.assertFalse(f.closed)
f.write('test')
f.close()
self.assertTrue(f.closed)
self.assertRaises(ValueError, f.write, 'x')
self.assertEqual(shell.written, [('test', 'stdout')])
f.close()
self.assertRaises(TypeError, f.close, 1)
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -567,8 +567,8 @@ def _io_binding(parent): # htest #
IOBinding(editwin)
if __name__ == "__main__":
import unittest
unittest.main('idlelib.idle_test.test_iomenu', verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_iomenu', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(_io_binding)

View File

@ -36,7 +36,8 @@ menudefs = [
None,
('_Close', '<<close-window>>'),
('E_xit', '<<close-all-windows>>'),
]),
]),
('edit', [
('_Undo', '<<undo>>'),
('_Redo', '<<redo>>'),
@ -56,9 +57,9 @@ menudefs = [
('E_xpand Word', '<<expand-word>>'),
('Show C_all Tip', '<<force-open-calltip>>'),
('Show Surrounding P_arens', '<<flash-paren>>'),
]),
]),
('format', [
('format', [
('_Indent Region', '<<indent-region>>'),
('_Dedent Region', '<<dedent-region>>'),
('Comment _Out Region', '<<comment-region>>'),
@ -70,30 +71,36 @@ menudefs = [
('F_ormat Paragraph', '<<format-paragraph>>'),
('S_trip Trailing Whitespace', '<<do-rstrip>>'),
]),
('run', [
('Python Shell', '<<open-python-shell>>'),
('C_heck Module', '<<check-module>>'),
('R_un Module', '<<run-module>>'),
]),
('shell', [
('_View Last Restart', '<<view-restart>>'),
('_Restart Shell', '<<restart-shell>>'),
None,
('_Interrupt Execution', '<<interrupt-execution>>'),
]),
('debug', [
('_Go to File/Line', '<<goto-file-line>>'),
('!_Debugger', '<<toggle-debugger>>'),
('_Stack Viewer', '<<open-stack-viewer>>'),
('!_Auto-open Stack Viewer', '<<toggle-jit-stack-viewer>>'),
]),
('options', [
('Configure _IDLE', '<<open-config-dialog>>'),
('_Code Context', '<<toggle-code-context>>'),
]),
('windows', [
('Zoom Height', '<<zoom-height>>'),
]),
('help', [
('_About IDLE', '<<about-idle>>'),
None,
@ -106,3 +113,7 @@ if find_spec('turtledemo'):
menudefs[-1][1].append(('Turtle Demo', '<<open-turtle-demo>>'))
default_keydefs = idleConf.GetCurrentKeySet()
if __name__ == '__main__':
from unittest import main
main('idlelib.idle_test.test_mainmenu', verbosity=2)

View File

@ -441,5 +441,8 @@ def _multi_call(parent): # htest #
bindseq("<Leave>")
if __name__ == "__main__":
from unittest import main
main('idlelib.idle_test.test_mainmenu', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(_multi_call)

View File

@ -190,6 +190,5 @@ def get_comment_header(line):
if __name__ == "__main__":
import unittest
unittest.main('idlelib.idle_test.test_paragraph',
verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_paragraph', verbosity=2, exit=False)

View File

@ -179,5 +179,5 @@ ParenMatch.reload()
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_parenmatch', verbosity=2)
from unittest import main
main('idlelib.idle_test.test_parenmatch', verbosity=2)

View File

@ -96,9 +96,8 @@ def _percolator(parent): # htest #
cb2.pack()
if __name__ == "__main__":
import unittest
unittest.main('idlelib.idle_test.test_percolator', verbosity=2,
exit=False)
from unittest import main
main('idlelib.idle_test.test_percolator', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(_percolator)

View File

@ -594,6 +594,6 @@ class Parser:
return self.stmt_bracketing
if __name__ == '__main__': #pragma: nocover
import unittest
unittest.main('idlelib.idle_test.test_pyparse', verbosity=2)
if __name__ == '__main__':
from unittest import main
main('idlelib.idle_test.test_pyparse', verbosity=2)

View File

@ -301,8 +301,8 @@ class HelpSource(Query):
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_query', verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_query', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(Query, HelpSource)

View File

@ -167,9 +167,8 @@ def _widget_redirector(parent): # htest #
original_insert = redir.register("insert", my_insert)
if __name__ == "__main__":
import unittest
unittest.main('idlelib.idle_test.test_redirector',
verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_redirector', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(_widget_redirector)

View File

@ -235,9 +235,8 @@ def _replace_dialog(parent): # htest #
button.pack()
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_replace',
verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_replace', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(_replace_dialog)