[Python-checkins] bpo-33855: Minimally test all IDLE modules. (GH-7689)

Miss Islington (bot) webhook-mailer at python.org
Fri Jun 15 18:38:38 EDT 2018


https://github.com/python/cpython/commit/508568764593dca3844a51c10f1493413a51d66f
commit: 508568764593dca3844a51c10f1493413a51d66f
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2018-06-15T15:38:35-07:00
summary:

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 ee5ef309c7e2daef1248730145408f700732c42e)

Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu>

files:
A Lib/idlelib/idle_test/template.py
A Lib/idlelib/idle_test/test_autocomplete_w.py
A Lib/idlelib/idle_test/test_calltip_w.py
A Lib/idlelib/idle_test/test_debugger_r.py
A Lib/idlelib/idle_test/test_debugobj.py
A Lib/idlelib/idle_test/test_debugobj_r.py
A Lib/idlelib/idle_test/test_filelist.py
A Misc/NEWS.d/next/IDLE/2018-06-14-11-35-50.bpo-33855.XL230W.rst
M Lib/idlelib/autocomplete.py
M Lib/idlelib/autocomplete_w.py
M Lib/idlelib/calltip_w.py
M Lib/idlelib/colorizer.py
M Lib/idlelib/debugger.py
M Lib/idlelib/debugger_r.py
M Lib/idlelib/debugobj.py
M Lib/idlelib/debugobj_r.py
M Lib/idlelib/editor.py
M Lib/idlelib/filelist.py
M Lib/idlelib/grep.py
M Lib/idlelib/help.py
M Lib/idlelib/idle_test/test_autocomplete.py
M Lib/idlelib/idle_test/test_autoexpand.py
M Lib/idlelib/idle_test/test_browser.py
M Lib/idlelib/idle_test/test_calltips.py
M Lib/idlelib/idle_test/test_codecontext.py
M Lib/idlelib/idle_test/test_colorizer.py
M Lib/idlelib/idle_test/test_config.py
M Lib/idlelib/idle_test/test_config_key.py
M Lib/idlelib/idle_test/test_configdialog.py
M Lib/idlelib/idle_test/test_debugger.py
M Lib/idlelib/idle_test/test_delegator.py
M Lib/idlelib/idle_test/test_editor.py
M Lib/idlelib/idle_test/test_grep.py
M Lib/idlelib/idle_test/test_help.py

diff --git a/Lib/idlelib/autocomplete.py b/Lib/idlelib/autocomplete.py
index edf445f08b58..9caf50d5d0c2 100644
--- a/Lib/idlelib/autocomplete.py
+++ b/Lib/idlelib/autocomplete.py
@@ -226,7 +226,6 @@ def get_entity(self, name):
 
 AutoComplete.reload()
 
-
 if __name__ == '__main__':
     from unittest import main
     main('idlelib.idle_test.test_autocomplete', verbosity=2)
diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py
index 12113f95e63a..66211d4554a2 100644
--- a/Lib/idlelib/autocomplete_w.py
+++ b/Lib/idlelib/autocomplete_w.py
@@ -458,3 +458,10 @@ def hide_window(self):
         self.listbox = None
         self.autocompletewindow.destroy()
         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
diff --git a/Lib/idlelib/calltip_w.py b/Lib/idlelib/calltip_w.py
index bf967f40b6ab..122b73abef68 100644
--- a/Lib/idlelib/calltip_w.py
+++ b/Lib/idlelib/calltip_w.py
@@ -159,6 +159,9 @@ def calltip_hide(event):
     text.bind("<<calltip-hide>>", calltip_hide)
     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
     run(_calltip_window)
diff --git a/Lib/idlelib/colorizer.py b/Lib/idlelib/colorizer.py
index 1f31ce22d7e5..d626d23121df 100644
--- a/Lib/idlelib/colorizer.py
+++ b/Lib/idlelib/colorizer.py
@@ -286,9 +286,8 @@ def _color_delegator(parent):  # htest #
     p.insertfilter(d)
 
 if __name__ == "__main__":
-    import unittest
-    unittest.main('idlelib.idle_test.test_colorizer',
-                  verbosity=2, exit=False)
+    from unittest import main
+    main('idlelib.idle_test.test_colorizer', verbosity=2, exit=False)
 
     from idlelib.idle_test.htest import run
     run(_color_delegator)
diff --git a/Lib/idlelib/debugger.py b/Lib/idlelib/debugger.py
index 114d0d128e88..477b514180c6 100644
--- a/Lib/idlelib/debugger.py
+++ b/Lib/idlelib/debugger.py
@@ -12,7 +12,7 @@
 class Idb(bdb.Bdb):
 
     def __init__(self, gui):
-        self.gui = gui
+        self.gui = gui  # An instance of Debugger or proxy of remote.
         bdb.Bdb.__init__(self)
 
     def user_line(self, frame):
@@ -63,7 +63,7 @@ def __init__(self, pyshell, idb=None):
         if idb is None:
             idb = Idb(self)
         self.pyshell = pyshell
-        self.idb = idb
+        self.idb = idb  # If passed, a proxy of remote instance.
         self.frame = None
         self.make_gui()
         self.interacting = 0
@@ -542,3 +542,9 @@ def load_dict(self, dict, force=0, rpc_client=None):
 
     def close(self):
         self.frame.destroy()
+
+if __name__ == "__main__":
+    from unittest import main
+    main('idlelib.idle_test.test_debugger', verbosity=2, exit=False)
+
+# TODO: htest?
diff --git a/Lib/idlelib/debugger_r.py b/Lib/idlelib/debugger_r.py
index bc971276de67..01a3bd25998f 100644
--- a/Lib/idlelib/debugger_r.py
+++ b/Lib/idlelib/debugger_r.py
@@ -386,3 +386,8 @@ def restart_subprocess_debugger(rpcclt):
     idb_adap_oid_ret = rpcclt.remotecall("exec", "start_the_debugger",\
                                          (gui_adap_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)
diff --git a/Lib/idlelib/debugobj.py b/Lib/idlelib/debugobj.py
index b70b13cec481..5a4c99788420 100644
--- a/Lib/idlelib/debugobj.py
+++ b/Lib/idlelib/debugobj.py
@@ -71,7 +71,7 @@ def GetSubList(self):
 
 class AtomicObjectTreeItem(ObjectTreeItem):
     def IsExpandable(self):
-        return 0
+        return False
 
 class SequenceTreeItem(ObjectTreeItem):
     def IsExpandable(self):
@@ -135,5 +135,8 @@ def _object_browser(parent):  # htest #
     node.update()
 
 if __name__ == '__main__':
+    from unittest import main
+    main('idlelib.idle_test.test_debugobj', verbosity=2, exit=False)
+
     from idlelib.idle_test.htest import run
     run(_object_browser)
diff --git a/Lib/idlelib/debugobj_r.py b/Lib/idlelib/debugobj_r.py
index 8031aaeaf1f2..75e75ebe5aca 100644
--- a/Lib/idlelib/debugobj_r.py
+++ b/Lib/idlelib/debugobj_r.py
@@ -34,3 +34,8 @@ def __getattr__(self, name):
     def _GetSubList(self):
         sub_list = self.sockio.remotecall(self.oid, "_GetSubList", (), {})
         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)
diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py
index 7c3f215e9f96..0095bd03bb7b 100644
--- a/Lib/idlelib/editor.py
+++ b/Lib/idlelib/editor.py
@@ -1706,8 +1706,8 @@ def _editor_window(parent):  # htest #
     # edit.text.bind("<<close-window>>", edit.close_event)
 
 if __name__ == '__main__':
-    import unittest
-    unittest.main('idlelib.idle_test.test_editor', verbosity=2, exit=False)
+    from unittest import main
+    main('idlelib.idle_test.test_editor', verbosity=2, exit=False)
 
     from idlelib.idle_test.htest import run
     run(_editor_window)
diff --git a/Lib/idlelib/filelist.py b/Lib/idlelib/filelist.py
index 5e1a3dcd77dc..52628392e617 100644
--- a/Lib/idlelib/filelist.py
+++ b/Lib/idlelib/filelist.py
@@ -1,7 +1,7 @@
-import os
+"idlelib.filelist"
 
-from tkinter import *
-import tkinter.messagebox as tkMessageBox
+import os
+from tkinter import messagebox as tkMessageBox
 
 
 class FileList:
@@ -111,7 +111,8 @@ def canonize(self, 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.run import fix_scaling
     import sys
@@ -120,13 +121,12 @@ def _test():
     fixwordbreaks(root)
     root.withdraw()
     flist = FileList(root)
-    if sys.argv[1:]:
-        for filename in sys.argv[1:]:
-            flist.open(filename)
-    else:
-        flist.new()
+    flist.new()
     if flist.inversedict:
         root.mainloop()
 
 if __name__ == '__main__':
-    _test()
+    from unittest import main
+    main('idlelib.idle_test.test_filelist', verbosity=2)
+
+#    _test()
diff --git a/Lib/idlelib/grep.py b/Lib/idlelib/grep.py
index c55c48cf2d69..8cc293c380de 100644
--- a/Lib/idlelib/grep.py
+++ b/Lib/idlelib/grep.py
@@ -193,8 +193,8 @@ def show_grep_dialog():
     button.pack()
 
 if __name__ == "__main__":
-    import unittest
-    unittest.main('idlelib.idle_test.test_grep', verbosity=2, exit=False)
+    from unittest import main
+    main('idlelib.idle_test.test_grep', verbosity=2, exit=False)
 
     from idlelib.idle_test.htest import run
     run(_grep_dialog)
diff --git a/Lib/idlelib/help.py b/Lib/idlelib/help.py
index fa6112a33944..21b5ea5a816e 100644
--- a/Lib/idlelib/help.py
+++ b/Lib/idlelib/help.py
@@ -271,5 +271,8 @@ def show_idlehelp(parent):
     HelpWindow(parent, filename, 'IDLE Help (%s)' % python_version())
 
 if __name__ == '__main__':
+    from unittest import main
+    main('idlelib.idle_test.test_help', verbosity=2, exit=False)
+
     from idlelib.idle_test.htest import run
     run(show_idlehelp)
diff --git a/Lib/idlelib/idle_test/template.py b/Lib/idlelib/idle_test/template.py
new file mode 100644
index 000000000000..34ceac3f405e
--- /dev/null
+++ b/Lib/idlelib/idle_test/template.py
@@ -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)
diff --git a/Lib/idlelib/idle_test/test_autocomplete.py b/Lib/idlelib/idle_test/test_autocomplete.py
index f3f2dea4246d..d7ee00af94b4 100644
--- a/Lib/idlelib/idle_test/test_autocomplete.py
+++ b/Lib/idlelib/idle_test/test_autocomplete.py
@@ -1,7 +1,5 @@
-''' Test autocomplete and autocomple_w
+"Test autocomplete, coverage 57%."
 
-Coverage of autocomple: 56%
-'''
 import unittest
 from test.support import requires
 from tkinter import Tk, Text
@@ -11,9 +9,6 @@
 from idlelib.idle_test.mock_idle import Func
 from idlelib.idle_test.mock_tk import Event
 
-class AutoCompleteWindow:
-    def complete():
-        return
 
 class DummyEditwin:
     def __init__(self, root, text):
diff --git a/Lib/idlelib/idle_test/test_autocomplete_w.py b/Lib/idlelib/idle_test/test_autocomplete_w.py
new file mode 100644
index 000000000000..b1bdc6c7c6e1
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_autocomplete_w.py
@@ -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)
diff --git a/Lib/idlelib/idle_test/test_autoexpand.py b/Lib/idlelib/idle_test/test_autoexpand.py
index ae8186cdc49f..e5f44c468713 100644
--- a/Lib/idlelib/idle_test/test_autoexpand.py
+++ b/Lib/idlelib/idle_test/test_autoexpand.py
@@ -1,9 +1,9 @@
-"""Unit tests for idlelib.autoexpand"""
+"Test autoexpand, coverage 100%."
+
+from idlelib.autoexpand import AutoExpand
 import unittest
 from test.support import requires
 from tkinter import Text, Tk
-#from idlelib.idle_test.mock_tk import Text
-from idlelib.autoexpand import AutoExpand
 
 
 class Dummy_Editwin:
@@ -15,15 +15,27 @@ class AutoExpandTest(unittest.TestCase):
 
     @classmethod
     def setUpClass(cls):
-        if 'tkinter' in str(Text):
-            requires('gui')
-            cls.tk = Tk()
-            cls.text = Text(cls.tk)
-        else:
-            cls.text = Text()
+        requires('gui')
+        cls.tk = Tk()
+        cls.text = Text(cls.tk)
         cls.auto_expand = AutoExpand(Dummy_Editwin(cls.text))
         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
     def tearDownClass(cls):
         del cls.text, cls.auto_expand
diff --git a/Lib/idlelib/idle_test/test_browser.py b/Lib/idlelib/idle_test/test_browser.py
index 34eb332c1df4..905dc1f47e34 100644
--- a/Lib/idlelib/idle_test/test_browser.py
+++ b/Lib/idlelib/idle_test/test_browser.py
@@ -1,20 +1,16 @@
-""" Test idlelib.browser.
+"Test browser, coverage 90%."
 
-Coverage: 88%
-(Higher, because should exclude 3 lines that .coveragerc won't exclude.)
-"""
+from idlelib import browser
+from test.support import requires
+import unittest
+from unittest import mock
+from idlelib.idle_test.mock_idle import Func
 
 from collections import deque
 import os.path
 import pyclbr
 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.tree import TreeNode
 
diff --git a/Lib/idlelib/idle_test/test_calltip_w.py b/Lib/idlelib/idle_test/test_calltip_w.py
new file mode 100644
index 000000000000..03f1e9a68a25
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_calltip_w.py
@@ -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)
diff --git a/Lib/idlelib/idle_test/test_calltips.py b/Lib/idlelib/idle_test/test_calltips.py
index a58229d36ede..2cf0e188dae6 100644
--- a/Lib/idlelib/idle_test/test_calltips.py
+++ b/Lib/idlelib/idle_test/test_calltips.py
@@ -1,9 +1,12 @@
+"Test calltips, coverage 60%"
+
+from idlelib import calltips
 import unittest
-import idlelib.calltips as ct
 import textwrap
 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
 class TC():
@@ -31,9 +34,11 @@ def cm(cls, a): 'doc'
     @staticmethod
     def sm(b): 'doc'
 
+
 tc = TC()
+signature = calltips.get_argspec  # 2.7 and 3.x use different functions
+
 
-signature = ct.get_argspec  # 2.7 and 3.x use different functions
 class Get_signatureTest(unittest.TestCase):
     # The signature function must return a string, even if blank.
     # Test a variety of objects to be sure that none cause it to raise
@@ -54,14 +59,18 @@ def gtest(obj, out):
             self.assertEqual(signature(obj), out)
 
         if List.__doc__ is not None:
-            gtest(List, '(iterable=(), /)' + ct._argument_positional + '\n' +
-                  List.__doc__)
+            gtest(List, '(iterable=(), /)' + calltips._argument_positional
+                  + '\n' + List.__doc__)
         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__,
-               '(self, /, *args, **kwargs)' + ct._argument_positional + '\n' +
-               'Initialize self.  See help(type(self)) for accurate signature.')
-        append_doc = ct._argument_positional + "\nAppend object to the end of the list."
+              '(self, /, *args, **kwargs)'
+              + calltips._argument_positional + '\n' +
+              'Initialize self.  See help(type(self)) for accurate signature.')
+        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([].append, '(object, /)' + append_doc)
@@ -70,12 +79,17 @@ def gtest(obj, out):
         gtest(SB(), default_tip)
         import re
         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
 replacement repl.  repl can be either a string or a callable;
 if a string, backslash escapes in it are processed.  If it is
 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):
         if textwrap.TextWrapper.__doc__ is not None:
@@ -88,7 +102,7 @@ def test_signature_wrap(self):
     def test_docline_truncation(self):
         def f(): pass
         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):
         # Test fewer lines than max.
@@ -107,7 +121,7 @@ def test_multiline_docstring(self):
         # Test more than max lines
         def f(): pass
         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 t1(): 'doc'
@@ -135,8 +149,9 @@ def test_methods(self):
     def test_bound_methods(self):
         # test that first parameter is correctly removed from argspec
         doc = '\ndoc' if TC.__doc__ is not None else ''
-        for meth, mtip  in ((tc.t1, "()"), (tc.t4, "(*args)"), (tc.t6, "(self)"),
-                            (tc.__call__, '(ci)'), (tc, '(ci)'), (TC.cm, "(a)"),):
+        for meth, mtip  in ((tc.t1, "()"), (tc.t4, "(*args)"),
+                            (tc.t6, "(self)"), (tc.__call__, '(ci)'),
+                            (tc, '(ci)'), (TC.cm, "(a)"),):
             self.assertEqual(signature(meth), mtip + doc)
 
     def test_starred_parameter(self):
@@ -153,7 +168,7 @@ def m2(**kwargs): pass
         class Test:
             def __call__(*, a): pass
 
-        mtip = ct._invalid_method
+        mtip = calltips._invalid_method
         self.assertEqual(signature(C().m2), mtip)
         self.assertEqual(signature(Test()), mtip)
 
@@ -161,7 +176,7 @@ def test_non_ascii_name(self):
         # test that re works to delete a first parameter name that
         # includes non-ascii chars, such as various forms of 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 nd(s):
@@ -194,9 +209,10 @@ def test_non_callables(self):
 
 class Get_entityTest(unittest.TestCase):
     def test_bad_entity(self):
-        self.assertIsNone(ct.get_entity('1/0'))
+        self.assertIsNone(calltips.get_entity('1/0'))
     def test_good_entity(self):
-        self.assertIs(ct.get_entity('int'), int)
+        self.assertIs(calltips.get_entity('int'), int)
+
 
 if __name__ == '__main__':
-    unittest.main(verbosity=2, exit=False)
+    unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_codecontext.py b/Lib/idlelib/idle_test/test_codecontext.py
index 2e59b8501c91..c349456d741b 100644
--- a/Lib/idlelib/idle_test/test_codecontext.py
+++ b/Lib/idlelib/idle_test/test_codecontext.py
@@ -1,16 +1,12 @@
-"""Test idlelib.codecontext.
-
-Coverage: 100%
-"""
-
-import re
+"Test codecontext, coverage 100%"
 
+from idlelib import codecontext
 import unittest
 from unittest import mock
 from test.support import requires
 from tkinter import Tk, Frame, Text, TclError
 
-import idlelib.codecontext as codecontext
+import re
 from idlelib import config
 
 
diff --git a/Lib/idlelib/idle_test/test_colorizer.py b/Lib/idlelib/idle_test/test_colorizer.py
index 238bc3e11413..1e74bed1f0c0 100644
--- a/Lib/idlelib/idle_test/test_colorizer.py
+++ b/Lib/idlelib/idle_test/test_colorizer.py
@@ -1,10 +1,6 @@
-'''Test idlelib/colorizer.py
+"Test colorizer, coverage 25%."
 
-Perform minimal sanity checks that module imports and some things run.
-
-Coverage 22%.
-'''
-from idlelib import colorizer  # always test import
+from idlelib import colorizer
 from test.support import requires
 from tkinter import Tk, Text
 import unittest
@@ -36,6 +32,7 @@ def tearDownClass(cls):
     def test_colorizer(self):
         colorizer.color_config(self.text)
 
+
 class ColorDelegatorTest(unittest.TestCase):
 
     @classmethod
diff --git a/Lib/idlelib/idle_test/test_config.py b/Lib/idlelib/idle_test/test_config.py
index abfec7993e07..e6f553d48471 100644
--- a/Lib/idlelib/idle_test/test_config.py
+++ b/Lib/idlelib/idle_test/test_config.py
@@ -1,9 +1,9 @@
-'''Test idlelib.config.
-
-Coverage: 96% (100% for IdleConfParser, IdleUserConfParser*, ConfigChanges).
+"""Test config, coverage 93%.
+(100% for IdleConfParser, IdleUserConfParser*, ConfigChanges).
 * Exception is OSError clause in Save method.
 Much of IdleConf is also exercised by ConfigDialog and test_configdialog.
-'''
+"""
+from idlelib import config
 import copy
 import sys
 import os
@@ -12,7 +12,6 @@
 import unittest
 from unittest import mock
 import idlelib
-from idlelib import config
 from idlelib.idle_test.mock_idle import Func
 
 # Tests should not depend on fortuitous user configurations.
diff --git a/Lib/idlelib/idle_test/test_config_key.py b/Lib/idlelib/idle_test/test_config_key.py
index 9074e23aab35..08471666a452 100644
--- a/Lib/idlelib/idle_test/test_config_key.py
+++ b/Lib/idlelib/idle_test/test_config_key.py
@@ -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 test.support import requires
 import sys
diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py
index 26aba32c47e6..fe712b18a5e0 100644
--- a/Lib/idlelib/idle_test/test_configdialog.py
+++ b/Lib/idlelib/idle_test/test_configdialog.py
@@ -1,7 +1,6 @@
-"""Test idlelib.configdialog.
+"""Test configdialog, coverage 94%.
 
 Half the class creates dialog, half works with user customizations.
-Coverage: 95%.
 """
 from idlelib import configdialog
 from test.support import requires
diff --git a/Lib/idlelib/idle_test/test_debugger.py b/Lib/idlelib/idle_test/test_debugger.py
index bcba9a45c160..35efb3411c73 100644
--- a/Lib/idlelib/idle_test/test_debugger.py
+++ b/Lib/idlelib/idle_test/test_debugger.py
@@ -1,11 +1,9 @@
-''' Test idlelib.debugger.
+"Test debugger, coverage 19%"
 
-Coverage: 19%
-'''
 from idlelib import debugger
+import unittest
 from test.support import requires
 requires('gui')
-import unittest
 from tkinter import Tk
 
 
@@ -25,5 +23,7 @@ def test_init(self):
         debugger.NamespaceViewer(self.root, 'Test')
 
 
+# Other classes are Idb, Debugger, and StackViewer.
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_debugger_r.py b/Lib/idlelib/idle_test/test_debugger_r.py
new file mode 100644
index 000000000000..199f63447ce6
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_debugger_r.py
@@ -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)
diff --git a/Lib/idlelib/idle_test/test_debugobj.py b/Lib/idlelib/idle_test/test_debugobj.py
new file mode 100644
index 000000000000..131ce22b8bb6
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_debugobj.py
@@ -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)
diff --git a/Lib/idlelib/idle_test/test_debugobj_r.py b/Lib/idlelib/idle_test/test_debugobj_r.py
new file mode 100644
index 000000000000..86e51b6cb2cb
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_debugobj_r.py
@@ -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)
diff --git a/Lib/idlelib/idle_test/test_delegator.py b/Lib/idlelib/idle_test/test_delegator.py
index 85624fbc127c..922416297a42 100644
--- a/Lib/idlelib/idle_test/test_delegator.py
+++ b/Lib/idlelib/idle_test/test_delegator.py
@@ -1,5 +1,8 @@
-import unittest
+"Test delegator, coverage 100%."
+
 from idlelib.delegator import Delegator
+import unittest
+
 
 class DelegatorTest(unittest.TestCase):
 
@@ -36,5 +39,6 @@ def test_mydel(self):
         self.assertEqual(mydel._Delegator__cache, set())
         self.assertIs(mydel.delegate, float)
 
+
 if __name__ == '__main__':
     unittest.main(verbosity=2, exit=2)
diff --git a/Lib/idlelib/idle_test/test_editor.py b/Lib/idlelib/idle_test/test_editor.py
index 64a2a88b7e37..12bc84736683 100644
--- a/Lib/idlelib/idle_test/test_editor.py
+++ b/Lib/idlelib/idle_test/test_editor.py
@@ -1,14 +1,46 @@
+"Test editor, coverage 35%."
+
+from idlelib import editor
 import unittest
-from idlelib.editor import EditorWindow
+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):
-        func = EditorWindow._filename_to_unicode
-        class dummy(): filesystemencoding = 'utf-8'
+        func = Editor._filename_to_unicode
+        class dummy():
+            filesystemencoding = 'utf-8'
         pairs = (('abc', 'abc'), ('a\U00011111c', 'a\ufffdc'),
                  (b'abc', 'abc'), (b'a\xf0\x91\x84\x91c', 'a\ufffdc'))
         for inp, out in pairs:
             self.assertEqual(func(dummy, inp), out)
 
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_filelist.py b/Lib/idlelib/idle_test/test_filelist.py
new file mode 100644
index 000000000000..731f1975e50e
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_filelist.py
@@ -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)
diff --git a/Lib/idlelib/idle_test/test_grep.py b/Lib/idlelib/idle_test/test_grep.py
index 6b54c1313153..ab0d7860f789 100644
--- a/Lib/idlelib/idle_test/test_grep.py
+++ b/Lib/idlelib/idle_test/test_grep.py
@@ -3,14 +3,15 @@
 dummy_command calls grep_it calls findfiles.
 An exception raised in one method will fail callers.
 Otherwise, tests are mostly independent.
-*** Currently only test grep_it.
+Currently only test grep_it, coverage 51%.
 """
+from idlelib.grep import GrepDialog
 import unittest
 from test.support import captured_stdout
 from idlelib.idle_test.mock_tk import Var
-from idlelib.grep import GrepDialog
 import re
 
+
 class Dummy_searchengine:
     '''GrepDialog.__init__ calls parent SearchDiabolBase which attaches the
     passed in SearchEngine instance as attribute 'engine'. Only a few of the
@@ -21,6 +22,7 @@ def getpat(self):
 
 searchengine = Dummy_searchengine()
 
+
 class Dummy_grep:
     # Methods tested
     #default_command = GrepDialog.default_command
@@ -34,6 +36,7 @@ def close(self):  # gui method
 
 grep = Dummy_grep()
 
+
 class FindfilesTest(unittest.TestCase):
     # findfiles is really a function, not a method, could be iterator
     # test that filename return filename
@@ -41,6 +44,7 @@ class FindfilesTest(unittest.TestCase):
     # test that recursive flag adds idle_test .py files
     pass
 
+
 class Grep_itTest(unittest.TestCase):
     # Test captured reports with 0 and some hits.
     # Should test file names, but Windows reports have mixed / and \ separators
@@ -71,10 +75,12 @@ def test_found(self):
         self.assertIn('2', lines[3])  # hits found 2
         self.assertTrue(lines[4].startswith('(Hint:'))
 
+
 class Default_commandTest(unittest.TestCase):
     # To write this, move outwin import to top of GrepDialog
     # so it can be replaced by captured_stdout in class setup/teardown.
     pass
 
+
 if __name__ == '__main__':
-    unittest.main(verbosity=2, exit=False)
+    unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_help.py b/Lib/idlelib/idle_test/test_help.py
index 2c68e23b328c..b54265998189 100644
--- a/Lib/idlelib/idle_test/test_help.py
+++ b/Lib/idlelib/idle_test/test_help.py
@@ -1,13 +1,12 @@
-'''Test idlelib.help.
+"Test help, coverage 87%."
 
-Coverage: 87%
-'''
 from idlelib import help
+import unittest
 from test.support import requires
 requires('gui')
 from os.path import abspath, dirname, join
 from tkinter import Tk
-import unittest
+
 
 class HelpFrameTest(unittest.TestCase):
 
@@ -30,5 +29,6 @@ def test_line1(self):
         text = self.frame.text
         self.assertEqual(text.get('1.0', '1.end'), ' IDLE ')
 
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/Misc/NEWS.d/next/IDLE/2018-06-14-11-35-50.bpo-33855.XL230W.rst b/Misc/NEWS.d/next/IDLE/2018-06-14-11-35-50.bpo-33855.XL230W.rst
new file mode 100644
index 000000000000..aaf4f8fe2b0a
--- /dev/null
+++ b/Misc/NEWS.d/next/IDLE/2018-06-14-11-35-50.bpo-33855.XL230W.rst
@@ -0,0 +1,2 @@
+Minimally test all IDLE modules. Add missing files, import module,
+instantiate classes, and check coverage. Check existing files.



More information about the Python-checkins mailing list