Mailing List Archive

bpo-33855: Minimally test all IDLE modules. (GH-7689)
https://github.com/python/cpython/commit/ee5ef309c7e2daef1248730145408f700732c42e
commit: ee5ef309c7e2daef1248730145408f700732c42e
branch: master
author: Terry Jan Reedy <tjreedy@udel.edu>
committer: GitHub <noreply@github.com>
date: 2018-06-15T18:20:55-04: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.

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.

_______________________________________________
Python-checkins mailing list
Python-checkins@python.org
https://mail.python.org/mailman/listinfo/python-checkins
bpo-33855: Minimally test all IDLE modules. (GH-7689) [ In reply to ]
https://github.com/python/cpython/commit/508568764593dca3844a51c10f1493413a51d66f
commit: 508568764593dca3844a51c10f1493413a51d66f
branch: 3.7
author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
committer: GitHub <noreply@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@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.

_______________________________________________
Python-checkins mailing list
Python-checkins@python.org
https://mail.python.org/mailman/listinfo/python-checkins