bpo-33855: Still more edits and minimal tests for IDLE (GH-7784)

Part 3 of 3, continuing PR #7689. This covers 14 idlelib modules and their tests,
rpc to zoomheight except for run (already done) and tooltip (being done separately).
This commit is contained in:
Terry Jan Reedy
2018-06-19 19:12:52 -04:00
committed by GitHub
parent 00f9edb98d
commit 4d92158f4c
36 changed files with 358 additions and 97 deletions

View File

@@ -92,5 +92,5 @@ class AutoExpand:
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_autoexpand', verbosity=2)
from unittest import main
main('idlelib.idle_test.test_autoexpand', verbosity=2)

View File

@@ -233,6 +233,8 @@ class CodeContext:
CodeContext.reload()
if __name__ == "__main__": # pragma: no cover
import unittest
unittest.main('idlelib.idle_test.test_codecontext', verbosity=2, exit=False)
if __name__ == "__main__":
from unittest import main
main('idlelib.idle_test.test_codecontext', verbosity=2, exit=False)
# Add htest.

View File

@@ -925,7 +925,7 @@ def _dump(): # htest # (not really, but ignore in coverage)
print('\nlines = ', line, ', crc = ', crc, sep='')
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_config',
verbosity=2, exit=False)
#_dump()
from unittest import main
main('idlelib.idle_test.test_config', verbosity=2, exit=False)
# Run revised _dump() as htest?

View File

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

View File

@@ -2269,8 +2269,8 @@ class VerticalScrolledFrame(Frame):
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_configdialog',
verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_configdialog', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(ConfigDialog)

View File

@@ -2,10 +2,10 @@
from idlelib import codecontext
import unittest
from unittest import mock
from test.support import requires
from tkinter import Tk, Frame, Text, TclError
from unittest import mock
import re
from idlelib import config

View File

@@ -0,0 +1,30 @@
"Test rpc, coverage 20%."
from idlelib import rpc
import unittest
import marshal
class CodePicklerTest(unittest.TestCase):
def test_pickle_unpickle(self):
def f(): return a + b + c
func, (cbytes,) = rpc.pickle_code(f.__code__)
self.assertIs(func, rpc.unpickle_code)
self.assertIn(b'test_rpc.py', cbytes)
code = rpc.unpickle_code(cbytes)
self.assertEqual(code.co_names, ('a', 'b', 'c'))
def test_code_pickler(self):
self.assertIn(type((lambda:None).__code__),
rpc.CodePickler.dispatch_table)
def test_dumps(self):
def f(): pass
# The main test here is that pickling code does not raise.
self.assertIn(b'test_rpc.py', rpc.dumps(f.__code__))
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@@ -1,5 +1,7 @@
"Test rstrip, coverage 100%."
from idlelib import rstrip
import unittest
import idlelib.rstrip as rs
from idlelib.idle_test.mock_idle import Editor
class rstripTest(unittest.TestCase):
@@ -7,7 +9,7 @@ class rstripTest(unittest.TestCase):
def test_rstrip_line(self):
editor = Editor()
text = editor.text
do_rstrip = rs.RstripExtension(editor).do_rstrip
do_rstrip = rstrip.RstripExtension(editor).do_rstrip
do_rstrip()
self.assertEqual(text.get('1.0', 'insert'), '')
@@ -20,12 +22,12 @@ class rstripTest(unittest.TestCase):
def test_rstrip_multiple(self):
editor = Editor()
# Uncomment following to verify that test passes with real widgets.
## from idlelib.editor import EditorWindow as Editor
## from tkinter import Tk
## editor = Editor(root=Tk())
# Comment above, uncomment 3 below to test with real Editor & Text.
#from idlelib.editor import EditorWindow as Editor
#from tkinter import Tk
#editor = Editor(root=Tk())
text = editor.text
do_rstrip = rs.RstripExtension(editor).do_rstrip
do_rstrip = rstrip.RstripExtension(editor).do_rstrip
original = (
"Line with an ending tab \n"
@@ -45,5 +47,7 @@ class rstripTest(unittest.TestCase):
do_rstrip()
self.assertEqual(text.get('1.0', 'insert'), stripped)
if __name__ == '__main__':
unittest.main(verbosity=2, exit=False)
unittest.main(verbosity=2)

View File

@@ -0,0 +1,33 @@
"Test runscript, coverage 16%."
from idlelib import runscript
import unittest
from test.support import requires
from tkinter import Tk
from idlelib.editor import EditorWindow
class ScriptBindingTest(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):
ew = EditorWindow(root=self.root)
sb = runscript.ScriptBinding(ew)
ew._close()
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@@ -1,11 +1,9 @@
''' Test idlelib.scrolledlist.
"Test scrolledlist, coverage 38%."
Coverage: 39%
'''
from idlelib import scrolledlist
from idlelib.scrolledlist import ScrolledList
import unittest
from test.support import requires
requires('gui')
import unittest
from tkinter import Tk
@@ -22,7 +20,7 @@ class ScrolledListTest(unittest.TestCase):
def test_init(self):
scrolledlist.ScrolledList(self.root)
ScrolledList(self.root)
if __name__ == '__main__':

View File

@@ -1,25 +1,23 @@
"""Test SearchDialog class in idlelib.search.py"""
"Test search, coverage 69%."
from idlelib import search
import unittest
from test.support import requires
requires('gui')
from tkinter import Tk, Text, BooleanVar
from idlelib import searchengine
# Does not currently test the event handler wrappers.
# A usage test should simulate clicks and check highlighting.
# Tests need to be coordinated with SearchDialogBase tests
# to avoid duplication.
from test.support import requires
requires('gui')
import unittest
import tkinter as tk
from tkinter import BooleanVar
import idlelib.searchengine as se
import idlelib.search as sd
class SearchDialogTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.root = tk.Tk()
cls.root = Tk()
@classmethod
def tearDownClass(cls):
@@ -27,10 +25,10 @@ class SearchDialogTest(unittest.TestCase):
del cls.root
def setUp(self):
self.engine = se.SearchEngine(self.root)
self.dialog = sd.SearchDialog(self.root, self.engine)
self.engine = searchengine.SearchEngine(self.root)
self.dialog = search.SearchDialog(self.root, self.engine)
self.dialog.bell = lambda: None
self.text = tk.Text(self.root)
self.text = Text(self.root)
self.text.insert('1.0', 'Hello World!')
def test_find_again(self):

View File

@@ -1,8 +1,7 @@
'''tests idlelib.searchbase.
"Test searchbase, coverage 98%."
# The only thing not covered is inconsequential --
# testing skipping of suite when self.needwrapbutton is false.
Coverage: 99%. The only thing not covered is inconsequential --
testing skipping of suite when self.needwrapbutton is false.
'''
import unittest
from test.support import requires
from tkinter import Tk, Frame ##, BooleanVar, StringVar
@@ -22,6 +21,7 @@ from idlelib.idle_test.mock_idle import Func
## se.BooleanVar = BooleanVar
## se.StringVar = StringVar
class SearchDialogBaseTest(unittest.TestCase):
@classmethod

View File

@@ -1,18 +1,19 @@
'''Test functions and SearchEngine class in idlelib.searchengine.py.'''
"Test searchengine, coverage 99%."
from idlelib import searchengine as se
import unittest
# from test.support import requires
from tkinter import BooleanVar, StringVar, TclError # ,Tk, Text
import tkinter.messagebox as tkMessageBox
from idlelib.idle_test.mock_tk import Var, Mbox
from idlelib.idle_test.mock_tk import Text as mockText
import re
# With mock replacements, the module does not use any gui widgets.
# The use of tk.Text is avoided (for now, until mock Text is improved)
# by patching instances with an index function returning what is needed.
# This works because mock Text.get does not use .index.
import re
import unittest
# from test.support import requires
from tkinter import BooleanVar, StringVar, TclError # ,Tk, Text
import tkinter.messagebox as tkMessageBox
from idlelib import searchengine as se
from idlelib.idle_test.mock_tk import Var, Mbox
from idlelib.idle_test.mock_tk import Text as mockText
# The tkinter imports are used to restore searchengine.
def setUpModule():
# Replace s-e module tkinter imports other than non-gui TclError.
@@ -326,4 +327,4 @@ class ForwardBackwardTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main(verbosity=2, exit=2)
unittest.main(verbosity=2)

View File

@@ -0,0 +1,36 @@
"Test stackviewer, coverage 19%."
from idlelib import stackviewer
import unittest
from test.support import requires
from tkinter import Tk
class Test(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):
try:
zzz
except NameError as e:
ex = e
# Test runners suppress setting of sys.last_xyx, which stackviewer needs.
# Revise stackviewer so following works.
# stackviewer.StackBrowser(self.root, ex=exc)
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@@ -0,0 +1,41 @@
"Test statusbar, coverage 100%."
from idlelib import statusbar
import unittest
from test.support import requires
from tkinter import Tk
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
@classmethod
def tearDownClass(cls):
cls.root.update_idletasks()
cls.root.destroy()
del cls.root
def test_init(self):
bar = statusbar.MultiStatusBar(self.root)
self.assertEqual(bar.labels, {})
def test_set_label(self):
bar = statusbar.MultiStatusBar(self.root)
bar.set_label('left', text='sometext', width=10)
self.assertIn('left', bar.labels)
left = bar.labels['left']
self.assertEqual(left['text'], 'sometext')
self.assertEqual(left['width'], 10)
bar.set_label('left', text='revised text')
self.assertEqual(left['text'], 'revised text')
bar.set_label('right', text='correct text')
self.assertEqual(bar.labels['right']['text'], 'correct text')
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@@ -1,17 +1,15 @@
'''Test idlelib.textview.
"""Test textview, coverage 100%.
Since all methods and functions create (or destroy) a ViewWindow, which
is a widget containing a widget, etcetera, all tests must be gui tests.
Using mock Text would not change this. Other mocks are used to retrieve
information about calls.
Coverage: 100%.
'''
"""
from idlelib import textview as tv
import unittest
from test.support import requires
requires('gui')
import unittest
import os
from tkinter import Tk
from tkinter.ttk import Button
@@ -109,7 +107,7 @@ class ViewFunctionTest(unittest.TestCase):
view = tv.view_text(root, 'Title', 'test text', modal=False)
self.assertIsInstance(view, tv.ViewWindow)
self.assertIsInstance(view.viewframe, tv.ViewFrame)
view.ok()
view.viewframe.ok()
def test_view_file(self):
view = tv.view_file(root, 'Title', __file__, 'ascii', modal=False)

View File

@@ -1,11 +1,9 @@
''' Test idlelib.tree.
"Test tree. coverage 56%."
Coverage: 56%
'''
from idlelib import tree
import unittest
from test.support import requires
requires('gui')
import unittest
from tkinter import Tk

View File

@@ -1,14 +1,13 @@
"""Unittest for UndoDelegator in idlelib.undo.py.
"Test undo, coverage 77%."
# Only test UndoDelegator so far.
Coverage about 80% (retest).
"""
from idlelib.undo import UndoDelegator
import unittest
from test.support import requires
requires('gui')
import unittest
from unittest.mock import Mock
from tkinter import Text, Tk
from idlelib.undo import UndoDelegator
from idlelib.percolator import Percolator
@@ -131,5 +130,6 @@ class UndoDelegatorTest(unittest.TestCase):
text.insert('insert', 'foo')
self.assertLessEqual(len(self.delegator.undolist), max_undo)
if __name__ == '__main__':
unittest.main(verbosity=2, exit=False)

View File

@@ -5,20 +5,18 @@ This file could be expanded to include traceback overrides
Revise if output destination changes (http://bugs.python.org/issue18318).
Make sure warnings module is left unaltered (http://bugs.python.org/issue18081).
'''
from idlelib import run
from idlelib import pyshell as shell
import unittest
from test.support import captured_stderr
import warnings
# Try to capture default showwarning before Idle modules are imported.
showwarning = warnings.showwarning
# But if we run this file within idle, we are in the middle of the run.main loop
# and default showwarnings has already been replaced.
running_in_idle = 'idle' in showwarning.__name__
from idlelib import run
from idlelib import pyshell as shell
# The following was generated from pyshell.idle_formatwarning
# and checked as matching expectation.
idlemsg = '''
@@ -29,6 +27,7 @@ UserWarning: Test
'''
shellmsg = idlemsg + ">>> "
class RunWarnTest(unittest.TestCase):
@unittest.skipIf(running_in_idle, "Does not work when run within Idle.")
@@ -46,6 +45,7 @@ class RunWarnTest(unittest.TestCase):
# The following uses .splitlines to erase line-ending differences
self.assertEqual(idlemsg.splitlines(), f.getvalue().splitlines())
class ShellWarnTest(unittest.TestCase):
@unittest.skipIf(running_in_idle, "Does not work when run within Idle.")
@@ -70,4 +70,4 @@ class ShellWarnTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main(verbosity=2, exit=False)
unittest.main(verbosity=2)

View File

@@ -0,0 +1,45 @@
"Test windows, coverage 47%."
from idlelib import windows
import unittest
from test.support import requires
from tkinter import Tk
class WindowListTest(unittest.TestCase):
def test_init(self):
wl = windows.WindowList()
self.assertEqual(wl.dict, {})
self.assertEqual(wl.callbacks, [])
# Further tests need mock Window.
class ListedToplevelTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
windows.registry = set()
requires('gui')
cls.root = Tk()
cls.root.withdraw()
@classmethod
def tearDownClass(cls):
windows.registry = windows.WindowList()
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):
win = windows.ListedToplevel(self.root)
self.assertIn(win, windows.registry)
self.assertEqual(win.focused_widget, win)
if __name__ == '__main__':
unittest.main(verbosity=2)

Some files were not shown because too many files have changed in this diff Show More