bpo-33855: Minimally test all IDLE modules. (GH-7689)

Create a template for minimally testing a tkinter-using module by importing it and instantiating its class(es).  Add a test file for all non-startup IDLE modules.  Edit existing files and update coverage.  This is part 1 of 3, covering the 21 autocomplete to help modules and touching 33 idlelib files.
(cherry picked from commit ee5ef309c7)

Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
This commit is contained in:
Miss Islington (bot) 2018-06-15 15:38:35 -07:00 committed by GitHub
parent 046da16695
commit 5085687645
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 422 additions and 108 deletions

View File

@ -226,7 +226,6 @@ class AutoComplete:
AutoComplete.reload() AutoComplete.reload()
if __name__ == '__main__': if __name__ == '__main__':
from unittest import main from unittest import main
main('idlelib.idle_test.test_autocomplete', verbosity=2) main('idlelib.idle_test.test_autocomplete', verbosity=2)

View File

@ -458,3 +458,10 @@ class AutoCompleteWindow:
self.listbox = None self.listbox = None
self.autocompletewindow.destroy() self.autocompletewindow.destroy()
self.autocompletewindow = None self.autocompletewindow = None
if __name__ == '__main__':
from unittest import main
main('idlelib.idle_test.test_autocomplete_w', verbosity=2, exit=False)
# TODO: autocomplete/w htest here

View File

@ -159,6 +159,9 @@ def _calltip_window(parent): # htest #
text.bind("<<calltip-hide>>", calltip_hide) text.bind("<<calltip-hide>>", calltip_hide)
text.focus_set() text.focus_set()
if __name__=='__main__': if __name__ == '__main__':
from unittest import main
main('idlelib.idle_test.test_calltips', verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(_calltip_window) run(_calltip_window)

View File

@ -286,9 +286,8 @@ def _color_delegator(parent): # htest #
p.insertfilter(d) p.insertfilter(d)
if __name__ == "__main__": if __name__ == "__main__":
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_colorizer', main('idlelib.idle_test.test_colorizer', verbosity=2, exit=False)
verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(_color_delegator) run(_color_delegator)

View File

@ -12,7 +12,7 @@ from idlelib.windows import ListedToplevel
class Idb(bdb.Bdb): class Idb(bdb.Bdb):
def __init__(self, gui): def __init__(self, gui):
self.gui = gui self.gui = gui # An instance of Debugger or proxy of remote.
bdb.Bdb.__init__(self) bdb.Bdb.__init__(self)
def user_line(self, frame): def user_line(self, frame):
@ -63,7 +63,7 @@ class Debugger:
if idb is None: if idb is None:
idb = Idb(self) idb = Idb(self)
self.pyshell = pyshell self.pyshell = pyshell
self.idb = idb self.idb = idb # If passed, a proxy of remote instance.
self.frame = None self.frame = None
self.make_gui() self.make_gui()
self.interacting = 0 self.interacting = 0
@ -542,3 +542,9 @@ class NamespaceViewer:
def close(self): def close(self):
self.frame.destroy() self.frame.destroy()
if __name__ == "__main__":
from unittest import main
main('idlelib.idle_test.test_debugger', verbosity=2, exit=False)
# TODO: htest?

View File

@ -386,3 +386,8 @@ def restart_subprocess_debugger(rpcclt):
idb_adap_oid_ret = rpcclt.remotecall("exec", "start_the_debugger",\ idb_adap_oid_ret = rpcclt.remotecall("exec", "start_the_debugger",\
(gui_adap_oid,), {}) (gui_adap_oid,), {})
assert idb_adap_oid_ret == idb_adap_oid, 'Idb restarted with different oid' assert idb_adap_oid_ret == idb_adap_oid, 'Idb restarted with different oid'
if __name__ == "__main__":
from unittest import main
main('idlelib.idle_test.test_debugger', verbosity=2, exit=False)

View File

@ -71,7 +71,7 @@ class ClassTreeItem(ObjectTreeItem):
class AtomicObjectTreeItem(ObjectTreeItem): class AtomicObjectTreeItem(ObjectTreeItem):
def IsExpandable(self): def IsExpandable(self):
return 0 return False
class SequenceTreeItem(ObjectTreeItem): class SequenceTreeItem(ObjectTreeItem):
def IsExpandable(self): def IsExpandable(self):
@ -135,5 +135,8 @@ def _object_browser(parent): # htest #
node.update() node.update()
if __name__ == '__main__': if __name__ == '__main__':
from unittest import main
main('idlelib.idle_test.test_debugobj', verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(_object_browser) run(_object_browser)

View File

@ -34,3 +34,8 @@ class StubObjectTreeItem:
def _GetSubList(self): def _GetSubList(self):
sub_list = self.sockio.remotecall(self.oid, "_GetSubList", (), {}) sub_list = self.sockio.remotecall(self.oid, "_GetSubList", (), {})
return [StubObjectTreeItem(self.sockio, oid) for oid in sub_list] return [StubObjectTreeItem(self.sockio, oid) for oid in sub_list]
if __name__ == '__main__':
from unittest import main
main('idlelib.idle_test.test_debugobj_r', verbosity=2)

View File

@ -1706,8 +1706,8 @@ def _editor_window(parent): # htest #
# edit.text.bind("<<close-window>>", edit.close_event) # edit.text.bind("<<close-window>>", edit.close_event)
if __name__ == '__main__': if __name__ == '__main__':
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_editor', verbosity=2, exit=False) main('idlelib.idle_test.test_editor', verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(_editor_window) run(_editor_window)

View File

@ -1,7 +1,7 @@
import os "idlelib.filelist"
from tkinter import * import os
import tkinter.messagebox as tkMessageBox from tkinter import messagebox as tkMessageBox
class FileList: class FileList:
@ -111,7 +111,8 @@ class FileList:
return os.path.normpath(filename) return os.path.normpath(filename)
def _test(): def _test(): # TODO check and convert to htest
from tkinter import Tk
from idlelib.editor import fixwordbreaks from idlelib.editor import fixwordbreaks
from idlelib.run import fix_scaling from idlelib.run import fix_scaling
import sys import sys
@ -120,13 +121,12 @@ def _test():
fixwordbreaks(root) fixwordbreaks(root)
root.withdraw() root.withdraw()
flist = FileList(root) flist = FileList(root)
if sys.argv[1:]:
for filename in sys.argv[1:]:
flist.open(filename)
else:
flist.new() flist.new()
if flist.inversedict: if flist.inversedict:
root.mainloop() root.mainloop()
if __name__ == '__main__': if __name__ == '__main__':
_test() from unittest import main
main('idlelib.idle_test.test_filelist', verbosity=2)
# _test()

View File

@ -193,8 +193,8 @@ def _grep_dialog(parent): # htest #
button.pack() button.pack()
if __name__ == "__main__": if __name__ == "__main__":
import unittest from unittest import main
unittest.main('idlelib.idle_test.test_grep', verbosity=2, exit=False) main('idlelib.idle_test.test_grep', verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(_grep_dialog) run(_grep_dialog)

View File

@ -271,5 +271,8 @@ def show_idlehelp(parent):
HelpWindow(parent, filename, 'IDLE Help (%s)' % python_version()) HelpWindow(parent, filename, 'IDLE Help (%s)' % python_version())
if __name__ == '__main__': if __name__ == '__main__':
from unittest import main
main('idlelib.idle_test.test_help', verbosity=2, exit=False)
from idlelib.idle_test.htest import run from idlelib.idle_test.htest import run
run(show_idlehelp) run(show_idlehelp)

View File

@ -0,0 +1,30 @@
"Test , coverage %."
from idlelib import
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):
self.assert
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -1,7 +1,5 @@
''' Test autocomplete and autocomple_w "Test autocomplete, coverage 57%."
Coverage of autocomple: 56%
'''
import unittest import unittest
from test.support import requires from test.support import requires
from tkinter import Tk, Text from tkinter import Tk, Text
@ -11,9 +9,6 @@ import idlelib.autocomplete_w as acw
from idlelib.idle_test.mock_idle import Func from idlelib.idle_test.mock_idle import Func
from idlelib.idle_test.mock_tk import Event from idlelib.idle_test.mock_tk import Event
class AutoCompleteWindow:
def complete():
return
class DummyEditwin: class DummyEditwin:
def __init__(self, root, text): def __init__(self, root, text):

View File

@ -0,0 +1,32 @@
"Test autocomplete_w, coverage 11%."
import unittest
from test.support import requires
from tkinter import Tk, Text
import idlelib.autocomplete_w as acw
class AutoCompleteWindowTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
cls.text = Text(cls.root)
cls.acw = acw.AutoCompleteWindow(cls.text)
@classmethod
def tearDownClass(cls):
del cls.text, cls.acw
cls.root.update_idletasks()
cls.root.destroy()
del cls.root
def test_init(self):
self.assertEqual(self.acw.widget, self.text)
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -1,9 +1,9 @@
"""Unit tests for idlelib.autoexpand""" "Test autoexpand, coverage 100%."
from idlelib.autoexpand import AutoExpand
import unittest import unittest
from test.support import requires from test.support import requires
from tkinter import Text, Tk from tkinter import Text, Tk
#from idlelib.idle_test.mock_tk import Text
from idlelib.autoexpand import AutoExpand
class Dummy_Editwin: class Dummy_Editwin:
@ -15,15 +15,27 @@ class AutoExpandTest(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
if 'tkinter' in str(Text):
requires('gui') requires('gui')
cls.tk = Tk() cls.tk = Tk()
cls.text = Text(cls.tk) cls.text = Text(cls.tk)
else:
cls.text = Text()
cls.auto_expand = AutoExpand(Dummy_Editwin(cls.text)) cls.auto_expand = AutoExpand(Dummy_Editwin(cls.text))
cls.auto_expand.bell = lambda: None cls.auto_expand.bell = lambda: None
# If mock_tk.Text._decode understood indexes 'insert' with suffixed 'linestart',
# 'wordstart', and 'lineend', used by autoexpand, we could use the following
# to run these test on non-gui machines (but check bell).
## try:
## requires('gui')
## #raise ResourceDenied() # Uncomment to test mock.
## except ResourceDenied:
## from idlelib.idle_test.mock_tk import Text
## cls.text = Text()
## cls.text.bell = lambda: None
## else:
## from tkinter import Tk, Text
## cls.tk = Tk()
## cls.text = Text(cls.tk)
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls):
del cls.text, cls.auto_expand del cls.text, cls.auto_expand

View File

@ -1,20 +1,16 @@
""" Test idlelib.browser. "Test browser, coverage 90%."
Coverage: 88% from idlelib import browser
(Higher, because should exclude 3 lines that .coveragerc won't exclude.) from test.support import requires
""" import unittest
from unittest import mock
from idlelib.idle_test.mock_idle import Func
from collections import deque from collections import deque
import os.path import os.path
import pyclbr import pyclbr
from tkinter import Tk from tkinter import Tk
from test.support import requires
import unittest
from unittest import mock
from idlelib.idle_test.mock_idle import Func
from idlelib import browser
from idlelib import filelist from idlelib import filelist
from idlelib.tree import TreeNode from idlelib.tree import TreeNode

View File

@ -0,0 +1,29 @@
"Test calltip_w, coverage 18%."
from idlelib import calltip_w
import unittest
from test.support import requires
from tkinter import Tk, Text
class CallTipTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
cls.text = Text(cls.root)
cls.calltip = calltip_w.CallTip(cls.text)
@classmethod
def tearDownClass(cls):
cls.root.update_idletasks()
cls.root.destroy()
del cls.text, cls.root
def test_init(self):
self.assertEqual(self.calltip.widget, self.text)
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -1,9 +1,12 @@
"Test calltips, coverage 60%"
from idlelib import calltips
import unittest import unittest
import idlelib.calltips as ct
import textwrap import textwrap
import types import types
default_tip = ct._default_callable_argspec default_tip = calltips._default_callable_argspec
# Test Class TC is used in multiple get_argspec test methods # Test Class TC is used in multiple get_argspec test methods
class TC(): class TC():
@ -31,9 +34,11 @@ class TC():
@staticmethod @staticmethod
def sm(b): 'doc' def sm(b): 'doc'
tc = TC()
signature = ct.get_argspec # 2.7 and 3.x use different functions tc = TC()
signature = calltips.get_argspec # 2.7 and 3.x use different functions
class Get_signatureTest(unittest.TestCase): class Get_signatureTest(unittest.TestCase):
# The signature function must return a string, even if blank. # The signature function must return a string, even if blank.
# Test a variety of objects to be sure that none cause it to raise # Test a variety of objects to be sure that none cause it to raise
@ -54,14 +59,18 @@ class Get_signatureTest(unittest.TestCase):
self.assertEqual(signature(obj), out) self.assertEqual(signature(obj), out)
if List.__doc__ is not None: if List.__doc__ is not None:
gtest(List, '(iterable=(), /)' + ct._argument_positional + '\n' + gtest(List, '(iterable=(), /)' + calltips._argument_positional
List.__doc__) + '\n' + List.__doc__)
gtest(list.__new__, gtest(list.__new__,
'(*args, **kwargs)\nCreate and return a new object. See help(type) for accurate signature.') '(*args, **kwargs)\n'
'Create and return a new object. '
'See help(type) for accurate signature.')
gtest(list.__init__, gtest(list.__init__,
'(self, /, *args, **kwargs)' + ct._argument_positional + '\n' + '(self, /, *args, **kwargs)'
+ calltips._argument_positional + '\n' +
'Initialize self. See help(type(self)) for accurate signature.') 'Initialize self. See help(type(self)) for accurate signature.')
append_doc = ct._argument_positional + "\nAppend object to the end of the list." append_doc = (calltips._argument_positional
+ "\nAppend object to the end of the list.")
gtest(list.append, '(self, object, /)' + append_doc) gtest(list.append, '(self, object, /)' + append_doc)
gtest(List.append, '(self, object, /)' + append_doc) gtest(List.append, '(self, object, /)' + append_doc)
gtest([].append, '(object, /)' + append_doc) gtest([].append, '(object, /)' + append_doc)
@ -70,12 +79,17 @@ class Get_signatureTest(unittest.TestCase):
gtest(SB(), default_tip) gtest(SB(), default_tip)
import re import re
p = re.compile('') p = re.compile('')
gtest(re.sub, '''(pattern, repl, string, count=0, flags=0)\nReturn the string obtained by replacing the leftmost gtest(re.sub, '''\
(pattern, repl, string, count=0, flags=0)
Return the string obtained by replacing the leftmost
non-overlapping occurrences of the pattern in string by the non-overlapping occurrences of the pattern in string by the
replacement repl. repl can be either a string or a callable; replacement repl. repl can be either a string or a callable;
if a string, backslash escapes in it are processed. If it is if a string, backslash escapes in it are processed. If it is
a callable, it's passed the Match object and must return''') a callable, it's passed the Match object and must return''')
gtest(p.sub, '''(repl, string, count=0)\nReturn the string obtained by replacing the leftmost non-overlapping occurrences o...''') gtest(p.sub, '''\
(repl, string, count=0)
Return the string obtained by replacing the leftmost \
non-overlapping occurrences o...''')
def test_signature_wrap(self): def test_signature_wrap(self):
if textwrap.TextWrapper.__doc__ is not None: if textwrap.TextWrapper.__doc__ is not None:
@ -88,7 +102,7 @@ a callable, it's passed the Match object and must return''')
def test_docline_truncation(self): def test_docline_truncation(self):
def f(): pass def f(): pass
f.__doc__ = 'a'*300 f.__doc__ = 'a'*300
self.assertEqual(signature(f), '()\n' + 'a' * (ct._MAX_COLS-3) + '...') self.assertEqual(signature(f), '()\n' + 'a' * (calltips._MAX_COLS-3) + '...')
def test_multiline_docstring(self): def test_multiline_docstring(self):
# Test fewer lines than max. # Test fewer lines than max.
@ -107,7 +121,7 @@ bytes() -> empty bytes object''')
# Test more than max lines # Test more than max lines
def f(): pass def f(): pass
f.__doc__ = 'a\n' * 15 f.__doc__ = 'a\n' * 15
self.assertEqual(signature(f), '()' + '\na' * ct._MAX_LINES) self.assertEqual(signature(f), '()' + '\na' * calltips._MAX_LINES)
def test_functions(self): def test_functions(self):
def t1(): 'doc' def t1(): 'doc'
@ -135,8 +149,9 @@ bytes() -> empty bytes object''')
def test_bound_methods(self): def test_bound_methods(self):
# test that first parameter is correctly removed from argspec # test that first parameter is correctly removed from argspec
doc = '\ndoc' if TC.__doc__ is not None else '' doc = '\ndoc' if TC.__doc__ is not None else ''
for meth, mtip in ((tc.t1, "()"), (tc.t4, "(*args)"), (tc.t6, "(self)"), for meth, mtip in ((tc.t1, "()"), (tc.t4, "(*args)"),
(tc.__call__, '(ci)'), (tc, '(ci)'), (TC.cm, "(a)"),): (tc.t6, "(self)"), (tc.__call__, '(ci)'),
(tc, '(ci)'), (TC.cm, "(a)"),):
self.assertEqual(signature(meth), mtip + doc) self.assertEqual(signature(meth), mtip + doc)
def test_starred_parameter(self): def test_starred_parameter(self):
@ -153,7 +168,7 @@ bytes() -> empty bytes object''')
class Test: class Test:
def __call__(*, a): pass def __call__(*, a): pass
mtip = ct._invalid_method mtip = calltips._invalid_method
self.assertEqual(signature(C().m2), mtip) self.assertEqual(signature(C().m2), mtip)
self.assertEqual(signature(Test()), mtip) self.assertEqual(signature(Test()), mtip)
@ -161,7 +176,7 @@ bytes() -> empty bytes object''')
# test that re works to delete a first parameter name that # test that re works to delete a first parameter name that
# includes non-ascii chars, such as various forms of A. # includes non-ascii chars, such as various forms of A.
uni = "(A\u0391\u0410\u05d0\u0627\u0905\u1e00\u3042, a)" uni = "(A\u0391\u0410\u05d0\u0627\u0905\u1e00\u3042, a)"
assert ct._first_param.sub('', uni) == '(a)' assert calltips._first_param.sub('', uni) == '(a)'
def test_no_docstring(self): def test_no_docstring(self):
def nd(s): def nd(s):
@ -194,9 +209,10 @@ bytes() -> empty bytes object''')
class Get_entityTest(unittest.TestCase): class Get_entityTest(unittest.TestCase):
def test_bad_entity(self): def test_bad_entity(self):
self.assertIsNone(ct.get_entity('1/0')) self.assertIsNone(calltips.get_entity('1/0'))
def test_good_entity(self): def test_good_entity(self):
self.assertIs(ct.get_entity('int'), int) self.assertIs(calltips.get_entity('int'), int)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(verbosity=2, exit=False) unittest.main(verbosity=2)

View File

@ -1,16 +1,12 @@
"""Test idlelib.codecontext. "Test codecontext, coverage 100%"
Coverage: 100%
"""
import re
from idlelib import codecontext
import unittest import unittest
from unittest import mock from unittest import mock
from test.support import requires from test.support import requires
from tkinter import Tk, Frame, Text, TclError from tkinter import Tk, Frame, Text, TclError
import idlelib.codecontext as codecontext import re
from idlelib import config from idlelib import config

View File

@ -1,10 +1,6 @@
'''Test idlelib/colorizer.py "Test colorizer, coverage 25%."
Perform minimal sanity checks that module imports and some things run. from idlelib import colorizer
Coverage 22%.
'''
from idlelib import colorizer # always test import
from test.support import requires from test.support import requires
from tkinter import Tk, Text from tkinter import Tk, Text
import unittest import unittest
@ -36,6 +32,7 @@ class ColorConfigTest(unittest.TestCase):
def test_colorizer(self): def test_colorizer(self):
colorizer.color_config(self.text) colorizer.color_config(self.text)
class ColorDelegatorTest(unittest.TestCase): class ColorDelegatorTest(unittest.TestCase):
@classmethod @classmethod

View File

@ -1,9 +1,9 @@
'''Test idlelib.config. """Test config, coverage 93%.
(100% for IdleConfParser, IdleUserConfParser*, ConfigChanges).
Coverage: 96% (100% for IdleConfParser, IdleUserConfParser*, ConfigChanges).
* Exception is OSError clause in Save method. * Exception is OSError clause in Save method.
Much of IdleConf is also exercised by ConfigDialog and test_configdialog. Much of IdleConf is also exercised by ConfigDialog and test_configdialog.
''' """
from idlelib import config
import copy import copy
import sys import sys
import os import os
@ -12,7 +12,6 @@ from test.support import captured_stderr, findfile
import unittest import unittest
from unittest import mock from unittest import mock
import idlelib import idlelib
from idlelib import config
from idlelib.idle_test.mock_idle import Func from idlelib.idle_test.mock_idle import Func
# Tests should not depend on fortuitous user configurations. # Tests should not depend on fortuitous user configurations.

View File

@ -1,7 +1,5 @@
''' Test idlelib.config_key. "Test config_key, coverage 75%"
Coverage: 56% from creating and closing dialog.
'''
from idlelib import config_key from idlelib import config_key
from test.support import requires from test.support import requires
import sys import sys

View File

@ -1,7 +1,6 @@
"""Test idlelib.configdialog. """Test configdialog, coverage 94%.
Half the class creates dialog, half works with user customizations. Half the class creates dialog, half works with user customizations.
Coverage: 95%.
""" """
from idlelib import configdialog from idlelib import configdialog
from test.support import requires from test.support import requires

View File

@ -1,11 +1,9 @@
''' Test idlelib.debugger. "Test debugger, coverage 19%"
Coverage: 19%
'''
from idlelib import debugger from idlelib import debugger
import unittest
from test.support import requires from test.support import requires
requires('gui') requires('gui')
import unittest
from tkinter import Tk from tkinter import Tk
@ -25,5 +23,7 @@ class NameSpaceTest(unittest.TestCase):
debugger.NamespaceViewer(self.root, 'Test') debugger.NamespaceViewer(self.root, 'Test')
# Other classes are Idb, Debugger, and StackViewer.
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(verbosity=2) unittest.main(verbosity=2)

View File

@ -0,0 +1,29 @@
"Test debugger_r, coverage 30%."
from idlelib import debugger_r
import unittest
from test.support import requires
from tkinter import Tk
class Test(unittest.TestCase):
## @classmethod
## def setUpClass(cls):
## requires('gui')
## cls.root = Tk()
##
## @classmethod
## def tearDownClass(cls):
## cls.root.destroy()
## del cls.root
def test_init(self):
self.assertTrue(True) # Get coverage of import
# Classes GUIProxy, IdbAdapter, FrameProxy, CodeProxy, DictProxy,
# GUIAdapter, IdbProxy plus 7 module functions.
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -0,0 +1,57 @@
"Test debugobj, coverage 40%."
from idlelib import debugobj
import unittest
class ObjectTreeItemTest(unittest.TestCase):
def test_init(self):
ti = debugobj.ObjectTreeItem('label', 22)
self.assertEqual(ti.labeltext, 'label')
self.assertEqual(ti.object, 22)
self.assertEqual(ti.setfunction, None)
class ClassTreeItemTest(unittest.TestCase):
def test_isexpandable(self):
ti = debugobj.ClassTreeItem('label', 0)
self.assertTrue(ti.IsExpandable())
class AtomicObjectTreeItemTest(unittest.TestCase):
def test_isexpandable(self):
ti = debugobj.AtomicObjectTreeItem('label', 0)
self.assertFalse(ti.IsExpandable())
class SequenceTreeItemTest(unittest.TestCase):
def test_isexpandable(self):
ti = debugobj.SequenceTreeItem('label', ())
self.assertFalse(ti.IsExpandable())
ti = debugobj.SequenceTreeItem('label', (1,))
self.assertTrue(ti.IsExpandable())
def test_keys(self):
ti = debugobj.SequenceTreeItem('label', 'abc')
self.assertEqual(list(ti.keys()), [0, 1, 2])
class DictTreeItemTest(unittest.TestCase):
def test_isexpandable(self):
ti = debugobj.DictTreeItem('label', {})
self.assertFalse(ti.IsExpandable())
ti = debugobj.DictTreeItem('label', {1:1})
self.assertTrue(ti.IsExpandable())
def test_keys(self):
ti = debugobj.DictTreeItem('label', {1:1, 0:0, 2:2})
self.assertEqual(ti.keys(), [0, 1, 2])
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -0,0 +1,22 @@
"Test debugobj_r, coverage 56%."
from idlelib import debugobj_r
import unittest
class WrappedObjectTreeItemTest(unittest.TestCase):
def test_getattr(self):
ti = debugobj_r.WrappedObjectTreeItem(list)
self.assertEqual(ti.append, list.append)
class StubObjectTreeItemTest(unittest.TestCase):
def test_init(self):
ti = debugobj_r.StubObjectTreeItem('socket', 1111)
self.assertEqual(ti.sockio, 'socket')
self.assertEqual(ti.oid, 1111)
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -1,5 +1,8 @@
import unittest "Test delegator, coverage 100%."
from idlelib.delegator import Delegator from idlelib.delegator import Delegator
import unittest
class DelegatorTest(unittest.TestCase): class DelegatorTest(unittest.TestCase):
@ -36,5 +39,6 @@ class DelegatorTest(unittest.TestCase):
self.assertEqual(mydel._Delegator__cache, set()) self.assertEqual(mydel._Delegator__cache, set())
self.assertIs(mydel.delegate, float) self.assertIs(mydel.delegate, float)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(verbosity=2, exit=2) unittest.main(verbosity=2, exit=2)

View File

@ -1,14 +1,46 @@
import unittest "Test editor, coverage 35%."
from idlelib.editor import EditorWindow
from idlelib import editor
import unittest
from test.support import requires
from tkinter import Tk
Editor = editor.EditorWindow
class EditorWindowTest(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)
cls.root.destroy()
del cls.root
def test_init(self):
e = Editor(root=self.root)
self.assertEqual(e.root, self.root)
e._close()
class EditorFunctionTest(unittest.TestCase):
class Editor_func_test(unittest.TestCase):
def test_filename_to_unicode(self): def test_filename_to_unicode(self):
func = EditorWindow._filename_to_unicode func = Editor._filename_to_unicode
class dummy(): filesystemencoding = 'utf-8' class dummy():
filesystemencoding = 'utf-8'
pairs = (('abc', 'abc'), ('a\U00011111c', 'a\ufffdc'), pairs = (('abc', 'abc'), ('a\U00011111c', 'a\ufffdc'),
(b'abc', 'abc'), (b'a\xf0\x91\x84\x91c', 'a\ufffdc')) (b'abc', 'abc'), (b'a\xf0\x91\x84\x91c', 'a\ufffdc'))
for inp, out in pairs: for inp, out in pairs:
self.assertEqual(func(dummy, inp), out) self.assertEqual(func(dummy, inp), out)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(verbosity=2) unittest.main(verbosity=2)

View File

@ -0,0 +1,33 @@
"Test filelist, coverage 19%."
from idlelib import filelist
import unittest
from test.support import requires
from tkinter import Tk
class FileListTest(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)
cls.root.destroy()
del cls.root
def test_new_empty(self):
flist = filelist.FileList(self.root)
self.assertEqual(flist.root, self.root)
e = flist.new()
self.assertEqual(type(e), flist.EditorWindow)
e._close()
if __name__ == '__main__':
unittest.main(verbosity=2)

View File

@ -3,14 +3,15 @@ Non-gui unit tests for grep.GrepDialog methods.
dummy_command calls grep_it calls findfiles. dummy_command calls grep_it calls findfiles.
An exception raised in one method will fail callers. An exception raised in one method will fail callers.
Otherwise, tests are mostly independent. Otherwise, tests are mostly independent.
*** Currently only test grep_it. Currently only test grep_it, coverage 51%.
""" """
from idlelib.grep import GrepDialog
import unittest import unittest
from test.support import captured_stdout from test.support import captured_stdout
from idlelib.idle_test.mock_tk import Var from idlelib.idle_test.mock_tk import Var
from idlelib.grep import GrepDialog
import re import re
class Dummy_searchengine: class Dummy_searchengine:
'''GrepDialog.__init__ calls parent SearchDiabolBase which attaches the '''GrepDialog.__init__ calls parent SearchDiabolBase which attaches the
passed in SearchEngine instance as attribute 'engine'. Only a few of the passed in SearchEngine instance as attribute 'engine'. Only a few of the
@ -21,6 +22,7 @@ class Dummy_searchengine:
searchengine = Dummy_searchengine() searchengine = Dummy_searchengine()
class Dummy_grep: class Dummy_grep:
# Methods tested # Methods tested
#default_command = GrepDialog.default_command #default_command = GrepDialog.default_command
@ -34,6 +36,7 @@ class Dummy_grep:
grep = Dummy_grep() grep = Dummy_grep()
class FindfilesTest(unittest.TestCase): class FindfilesTest(unittest.TestCase):
# findfiles is really a function, not a method, could be iterator # findfiles is really a function, not a method, could be iterator
# test that filename return filename # test that filename return filename
@ -41,6 +44,7 @@ class FindfilesTest(unittest.TestCase):
# test that recursive flag adds idle_test .py files # test that recursive flag adds idle_test .py files
pass pass
class Grep_itTest(unittest.TestCase): class Grep_itTest(unittest.TestCase):
# Test captured reports with 0 and some hits. # Test captured reports with 0 and some hits.
# Should test file names, but Windows reports have mixed / and \ separators # Should test file names, but Windows reports have mixed / and \ separators
@ -71,10 +75,12 @@ class Grep_itTest(unittest.TestCase):
self.assertIn('2', lines[3]) # hits found 2 self.assertIn('2', lines[3]) # hits found 2
self.assertTrue(lines[4].startswith('(Hint:')) self.assertTrue(lines[4].startswith('(Hint:'))
class Default_commandTest(unittest.TestCase): class Default_commandTest(unittest.TestCase):
# To write this, move outwin import to top of GrepDialog # To write this, move outwin import to top of GrepDialog
# so it can be replaced by captured_stdout in class setup/teardown. # so it can be replaced by captured_stdout in class setup/teardown.
pass pass
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(verbosity=2, exit=False) unittest.main(verbosity=2)

View File

@ -1,13 +1,12 @@
'''Test idlelib.help. "Test help, coverage 87%."
Coverage: 87%
'''
from idlelib import help from idlelib import help
import unittest
from test.support import requires from test.support import requires
requires('gui') requires('gui')
from os.path import abspath, dirname, join from os.path import abspath, dirname, join
from tkinter import Tk from tkinter import Tk
import unittest
class HelpFrameTest(unittest.TestCase): class HelpFrameTest(unittest.TestCase):
@ -30,5 +29,6 @@ class HelpFrameTest(unittest.TestCase):
text = self.frame.text text = self.frame.text
self.assertEqual(text.get('1.0', '1.end'), ' IDLE ') self.assertEqual(text.get('1.0', '1.end'), ' IDLE ')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main(verbosity=2) unittest.main(verbosity=2)

View File

@ -0,0 +1,2 @@
Minimally test all IDLE modules. Add missing files, import module,
instantiate classes, and check coverage. Check existing files.