Commit 4d92158f authored by Terry Jan Reedy's avatar Terry Jan Reedy Committed by GitHub

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

Part 3 of 3, continuing PR #7689. This covers 14 idlelib modules and their tests,
rpc to zoomheight except for run (already done) and tooltip (being done separately).
parent 00f9edb9
......@@ -92,5 +92,5 @@ class AutoExpand:
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_autoexpand', verbosity=2)
from unittest import main
main('idlelib.idle_test.test_autoexpand', verbosity=2)
......@@ -233,6 +233,8 @@ class CodeContext:
CodeContext.reload()
if __name__ == "__main__": # pragma: no cover
import unittest
unittest.main('idlelib.idle_test.test_codecontext', verbosity=2, exit=False)
if __name__ == "__main__":
from unittest import main
main('idlelib.idle_test.test_codecontext', verbosity=2, exit=False)
# Add htest.
......@@ -925,7 +925,7 @@ def _dump(): # htest # (not really, but ignore in coverage)
print('\nlines = ', line, ', crc = ', crc, sep='')
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_config',
verbosity=2, exit=False)
#_dump()
from unittest import main
main('idlelib.idle_test.test_config', verbosity=2, exit=False)
# Run revised _dump() as htest?
......@@ -291,8 +291,8 @@ class GetKeysDialog(Toplevel):
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_config_key', verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_config_key', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(GetKeysDialog)
......@@ -2269,8 +2269,8 @@ class VerticalScrolledFrame(Frame):
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_configdialog',
verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_configdialog', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(ConfigDialog)
......@@ -2,10 +2,10 @@
from idlelib import codecontext
import unittest
from unittest import mock
from test.support import requires
from tkinter import Tk, Frame, Text, TclError
from unittest import mock
import re
from idlelib import config
......
"Test rpc, coverage 20%."
from idlelib import rpc
import unittest
import marshal
class CodePicklerTest(unittest.TestCase):
def test_pickle_unpickle(self):
def f(): return a + b + c
func, (cbytes,) = rpc.pickle_code(f.__code__)
self.assertIs(func, rpc.unpickle_code)
self.assertIn(b'test_rpc.py', cbytes)
code = rpc.unpickle_code(cbytes)
self.assertEqual(code.co_names, ('a', 'b', 'c'))
def test_code_pickler(self):
self.assertIn(type((lambda:None).__code__),
rpc.CodePickler.dispatch_table)
def test_dumps(self):
def f(): pass
# The main test here is that pickling code does not raise.
self.assertIn(b'test_rpc.py', rpc.dumps(f.__code__))
if __name__ == '__main__':
unittest.main(verbosity=2)
"Test rstrip, coverage 100%."
from idlelib import rstrip
import unittest
import idlelib.rstrip as rs
from idlelib.idle_test.mock_idle import Editor
class rstripTest(unittest.TestCase):
......@@ -7,7 +9,7 @@ class rstripTest(unittest.TestCase):
def test_rstrip_line(self):
editor = Editor()
text = editor.text
do_rstrip = rs.RstripExtension(editor).do_rstrip
do_rstrip = rstrip.RstripExtension(editor).do_rstrip
do_rstrip()
self.assertEqual(text.get('1.0', 'insert'), '')
......@@ -20,12 +22,12 @@ class rstripTest(unittest.TestCase):
def test_rstrip_multiple(self):
editor = Editor()
# Uncomment following to verify that test passes with real widgets.
## from idlelib.editor import EditorWindow as Editor
## from tkinter import Tk
## editor = Editor(root=Tk())
# Comment above, uncomment 3 below to test with real Editor & Text.
#from idlelib.editor import EditorWindow as Editor
#from tkinter import Tk
#editor = Editor(root=Tk())
text = editor.text
do_rstrip = rs.RstripExtension(editor).do_rstrip
do_rstrip = rstrip.RstripExtension(editor).do_rstrip
original = (
"Line with an ending tab \n"
......@@ -45,5 +47,7 @@ class rstripTest(unittest.TestCase):
do_rstrip()
self.assertEqual(text.get('1.0', 'insert'), stripped)
if __name__ == '__main__':
unittest.main(verbosity=2, exit=False)
unittest.main(verbosity=2)
"Test runscript, coverage 16%."
from idlelib import runscript
import unittest
from test.support import requires
from tkinter import Tk
from idlelib.editor import EditorWindow
class ScriptBindingTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
@classmethod
def tearDownClass(cls):
cls.root.update_idletasks()
for id in cls.root.tk.call('after', 'info'):
cls.root.after_cancel(id) # Need for EditorWindow.
cls.root.destroy()
del cls.root
def test_init(self):
ew = EditorWindow(root=self.root)
sb = runscript.ScriptBinding(ew)
ew._close()
if __name__ == '__main__':
unittest.main(verbosity=2)
''' Test idlelib.scrolledlist.
"Test scrolledlist, coverage 38%."
Coverage: 39%
'''
from idlelib import scrolledlist
from idlelib.scrolledlist import ScrolledList
import unittest
from test.support import requires
requires('gui')
import unittest
from tkinter import Tk
......@@ -22,7 +20,7 @@ class ScrolledListTest(unittest.TestCase):
def test_init(self):
scrolledlist.ScrolledList(self.root)
ScrolledList(self.root)
if __name__ == '__main__':
......
"""Test SearchDialog class in idlelib.search.py"""
"Test search, coverage 69%."
from idlelib import search
import unittest
from test.support import requires
requires('gui')
from tkinter import Tk, Text, BooleanVar
from idlelib import searchengine
# Does not currently test the event handler wrappers.
# A usage test should simulate clicks and check highlighting.
# Tests need to be coordinated with SearchDialogBase tests
# to avoid duplication.
from test.support import requires
requires('gui')
import unittest
import tkinter as tk
from tkinter import BooleanVar
import idlelib.searchengine as se
import idlelib.search as sd
class SearchDialogTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.root = tk.Tk()
cls.root = Tk()
@classmethod
def tearDownClass(cls):
......@@ -27,10 +25,10 @@ class SearchDialogTest(unittest.TestCase):
del cls.root
def setUp(self):
self.engine = se.SearchEngine(self.root)
self.dialog = sd.SearchDialog(self.root, self.engine)
self.engine = searchengine.SearchEngine(self.root)
self.dialog = search.SearchDialog(self.root, self.engine)
self.dialog.bell = lambda: None
self.text = tk.Text(self.root)
self.text = Text(self.root)
self.text.insert('1.0', 'Hello World!')
def test_find_again(self):
......
'''tests idlelib.searchbase.
"Test searchbase, coverage 98%."
# The only thing not covered is inconsequential --
# testing skipping of suite when self.needwrapbutton is false.
Coverage: 99%. The only thing not covered is inconsequential --
testing skipping of suite when self.needwrapbutton is false.
'''
import unittest
from test.support import requires
from tkinter import Tk, Frame ##, BooleanVar, StringVar
......@@ -22,6 +21,7 @@ from idlelib.idle_test.mock_idle import Func
## se.BooleanVar = BooleanVar
## se.StringVar = StringVar
class SearchDialogBaseTest(unittest.TestCase):
@classmethod
......
'''Test functions and SearchEngine class in idlelib.searchengine.py.'''
"Test searchengine, coverage 99%."
# With mock replacements, the module does not use any gui widgets.
# The use of tk.Text is avoided (for now, until mock Text is improved)
# by patching instances with an index function returning what is needed.
# This works because mock Text.get does not use .index.
import re
from idlelib import searchengine as se
import unittest
# from test.support import requires
from tkinter import BooleanVar, StringVar, TclError # ,Tk, Text
import tkinter.messagebox as tkMessageBox
from idlelib import searchengine as se
from idlelib.idle_test.mock_tk import Var, Mbox
from idlelib.idle_test.mock_tk import Text as mockText
import re
# With mock replacements, the module does not use any gui widgets.
# The use of tk.Text is avoided (for now, until mock Text is improved)
# by patching instances with an index function returning what is needed.
# This works because mock Text.get does not use .index.
# The tkinter imports are used to restore searchengine.
def setUpModule():
# Replace s-e module tkinter imports other than non-gui TclError.
......@@ -326,4 +327,4 @@ class ForwardBackwardTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main(verbosity=2, exit=2)
unittest.main(verbosity=2)
"Test stackviewer, coverage 19%."
from idlelib import stackviewer
import unittest
from test.support import requires
from tkinter import Tk
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
@classmethod
def tearDownClass(cls):
cls.root.update_idletasks()
## for id in cls.root.tk.call('after', 'info'):
## cls.root.after_cancel(id) # Need for EditorWindow.
cls.root.destroy()
del cls.root
def test_init(self):
try:
zzz
except NameError as e:
ex = e
# Test runners suppress setting of sys.last_xyx, which stackviewer needs.
# Revise stackviewer so following works.
# stackviewer.StackBrowser(self.root, ex=exc)
if __name__ == '__main__':
unittest.main(verbosity=2)
"Test statusbar, coverage 100%."
from idlelib import statusbar
import unittest
from test.support import requires
from tkinter import Tk
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
@classmethod
def tearDownClass(cls):
cls.root.update_idletasks()
cls.root.destroy()
del cls.root
def test_init(self):
bar = statusbar.MultiStatusBar(self.root)
self.assertEqual(bar.labels, {})
def test_set_label(self):
bar = statusbar.MultiStatusBar(self.root)
bar.set_label('left', text='sometext', width=10)
self.assertIn('left', bar.labels)
left = bar.labels['left']
self.assertEqual(left['text'], 'sometext')
self.assertEqual(left['width'], 10)
bar.set_label('left', text='revised text')
self.assertEqual(left['text'], 'revised text')
bar.set_label('right', text='correct text')
self.assertEqual(bar.labels['right']['text'], 'correct text')
if __name__ == '__main__':
unittest.main(verbosity=2)
'''Test idlelib.textview.
"""Test textview, coverage 100%.
Since all methods and functions create (or destroy) a ViewWindow, which
is a widget containing a widget, etcetera, all tests must be gui tests.
Using mock Text would not change this. Other mocks are used to retrieve
information about calls.
Coverage: 100%.
'''
"""
from idlelib import textview as tv
import unittest
from test.support import requires
requires('gui')
import unittest
import os
from tkinter import Tk
from tkinter.ttk import Button
......@@ -109,7 +107,7 @@ class ViewFunctionTest(unittest.TestCase):
view = tv.view_text(root, 'Title', 'test text', modal=False)
self.assertIsInstance(view, tv.ViewWindow)
self.assertIsInstance(view.viewframe, tv.ViewFrame)
view.ok()
view.viewframe.ok()
def test_view_file(self):
view = tv.view_file(root, 'Title', __file__, 'ascii', modal=False)
......
''' Test idlelib.tree.
"Test tree. coverage 56%."
Coverage: 56%
'''
from idlelib import tree
import unittest
from test.support import requires
requires('gui')
import unittest
from tkinter import Tk
......
"""Unittest for UndoDelegator in idlelib.undo.py.
"Test undo, coverage 77%."
# Only test UndoDelegator so far.
Coverage about 80% (retest).
"""
from idlelib.undo import UndoDelegator
import unittest
from test.support import requires
requires('gui')
import unittest
from unittest.mock import Mock
from tkinter import Text, Tk
from idlelib.undo import UndoDelegator
from idlelib.percolator import Percolator
......@@ -131,5 +130,6 @@ class UndoDelegatorTest(unittest.TestCase):
text.insert('insert', 'foo')
self.assertLessEqual(len(self.delegator.undolist), max_undo)
if __name__ == '__main__':
unittest.main(verbosity=2, exit=False)
......@@ -5,20 +5,18 @@ This file could be expanded to include traceback overrides
Revise if output destination changes (http://bugs.python.org/issue18318).
Make sure warnings module is left unaltered (http://bugs.python.org/issue18081).
'''
from idlelib import run
from idlelib import pyshell as shell
import unittest
from test.support import captured_stderr
import warnings
# Try to capture default showwarning before Idle modules are imported.
showwarning = warnings.showwarning
# But if we run this file within idle, we are in the middle of the run.main loop
# and default showwarnings has already been replaced.
running_in_idle = 'idle' in showwarning.__name__
from idlelib import run
from idlelib import pyshell as shell
# The following was generated from pyshell.idle_formatwarning
# and checked as matching expectation.
idlemsg = '''
......@@ -29,6 +27,7 @@ UserWarning: Test
'''
shellmsg = idlemsg + ">>> "
class RunWarnTest(unittest.TestCase):
@unittest.skipIf(running_in_idle, "Does not work when run within Idle.")
......@@ -46,6 +45,7 @@ class RunWarnTest(unittest.TestCase):
# The following uses .splitlines to erase line-ending differences
self.assertEqual(idlemsg.splitlines(), f.getvalue().splitlines())
class ShellWarnTest(unittest.TestCase):
@unittest.skipIf(running_in_idle, "Does not work when run within Idle.")
......@@ -70,4 +70,4 @@ class ShellWarnTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main(verbosity=2, exit=False)
unittest.main(verbosity=2)
"Test windows, coverage 47%."
from idlelib import windows
import unittest
from test.support import requires
from tkinter import Tk
class WindowListTest(unittest.TestCase):
def test_init(self):
wl = windows.WindowList()
self.assertEqual(wl.dict, {})
self.assertEqual(wl.callbacks, [])
# Further tests need mock Window.
class ListedToplevelTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
windows.registry = set()
requires('gui')
cls.root = Tk()
cls.root.withdraw()
@classmethod
def tearDownClass(cls):
windows.registry = windows.WindowList()
cls.root.update_idletasks()
## for id in cls.root.tk.call('after', 'info'):
## cls.root.after_cancel(id) # Need for EditorWindow.
cls.root.destroy()
del cls.root
def test_init(self):
win = windows.ListedToplevel(self.root)
self.assertIn(win, windows.registry)
self.assertEqual(win.focused_widget, win)
if __name__ == '__main__':
unittest.main(verbosity=2)
"Test zoomheight, coverage 66%."
# Some code is system dependent.
from idlelib import zoomheight
import unittest
from test.support import requires
from tkinter import Tk, Text
from idlelib.editor import EditorWindow
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
cls.editwin = EditorWindow(root=cls.root)
@classmethod
def tearDownClass(cls):
cls.editwin._close()
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):
zoom = zoomheight.ZoomHeight(self.editwin)
self.assertIs(zoom.editwin, self.editwin)
def test_zoom_height_event(self):
zoom = zoomheight.ZoomHeight(self.editwin)
zoom.zoom_height_event()
if __name__ == '__main__':
unittest.main(verbosity=2)
......@@ -184,5 +184,5 @@ class OnDemandOutputWindow:
self.write = self.owin.write
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_outwin', verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_outwin', verbosity=2, exit=False)
......@@ -43,16 +43,20 @@ import traceback
import types
def unpickle_code(ms):
"Return code object from marshal string ms."
co = marshal.loads(ms)
assert isinstance(co, types.CodeType)
return co
def pickle_code(co):
"Return unpickle function and tuple with marshalled co code object."
assert isinstance(co, types.CodeType)
ms = marshal.dumps(co)
return unpickle_code, (ms,)
def dumps(obj, protocol=None):
"Return pickled (or marshalled) string for obj."
# IDLE passes 'None' to select pickle.DEFAULT_PROTOCOL.
f = io.BytesIO()
p = CodePickler(f, protocol)
p.dump(obj)
......@@ -625,3 +629,8 @@ def displayhook(value):
sys.stdout.write(text)
sys.stdout.write("\n")
builtins._ = value
if __name__ == '__main__':
from unittest import main
main('idlelib.idle_test.test_rpc', verbosity=2,)
......@@ -25,5 +25,5 @@ class RstripExtension:
undo.undo_block_stop()
if __name__ == "__main__":
import unittest
unittest.main('idlelib.idle_test.test_rstrip', verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_rstrip', verbosity=2,)
......@@ -193,3 +193,8 @@ class ScriptBinding:
# XXX This should really be a function of EditorWindow...
tkMessageBox.showerror(title, message, parent=self.editwin.text)
self.editwin.text.focus_set()
if __name__ == "__main__":
from unittest import main
main('idlelib.idle_test.test_runscript', verbosity=2,)
......@@ -142,6 +142,8 @@ def _scrolled_list(parent): # htest #
scrolled_list.append("Item %02d" % i)
if __name__ == '__main__':
# At the moment, test_scrolledlist merely creates instance, like htest.
from unittest import main
main('idlelib.idle_test.test_scrolledlist', verbosity=2,)
from idlelib.idle_test.htest import run
run(_scrolled_list)
......@@ -94,9 +94,8 @@ def _search_dialog(parent): # htest #
button.pack()
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_search',
verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_search', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(_search_dialog)
......@@ -192,9 +192,10 @@ class _searchbase(SearchDialogBase): # htest #
def default_command(self, dummy): pass
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_searchbase', verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_searchbase', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(_searchbase)
......@@ -231,6 +231,7 @@ def get_line_col(index):
line, col = map(int, index.split(".")) # Fails on invalid index
return line, col
if __name__ == "__main__":
import unittest
unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_searchengine', verbosity=2)
......@@ -148,5 +148,8 @@ def _stack_viewer(parent): # htest #
del sys.last_traceback
if __name__ == '__main__':
from unittest import main
main('idlelib.idle_test.test_stackviewer', verbosity=2)
from idlelib.idle_test.htest import run
run(_stack_viewer)
......@@ -42,5 +42,8 @@ def _multistatus_bar(parent): # htest #
frame.pack()
if __name__ == '__main__':
from unittest import main
main('idlelib.idle_test.test_statusbar', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(_multistatus_bar)
......@@ -130,7 +130,8 @@ def view_file(parent, title, filename, encoding, modal=True, _utest=False):
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_textview', verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_textview', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(ViewWindow)
......@@ -462,6 +462,8 @@ def _tree_widget(parent): # htest #
node.expand()
if __name__ == '__main__':
# test_tree is currently a copy of this
from unittest import main
main('idlelib.idle_test.test_tree', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(_tree_widget)
......@@ -359,8 +359,8 @@ def _undo_delegator(parent): # htest #
dump.pack(side='left')
if __name__ == "__main__":
import unittest
unittest.main('idlelib.idle_test.test_undo', verbosity=2, exit=False)
from unittest import main
main('idlelib.idle_test.test_undo', verbosity=2, exit=False)
from idlelib.idle_test.htest import run
run(_undo_delegator)
......@@ -90,3 +90,8 @@ class ListedToplevel(Toplevel):
# This can happen when the window menu was torn off.
# Simply ignore it.
pass
if __name__ == "__main__":
from unittest import main
main('idlelib.idle_test.test_windows', verbosity=2)
......@@ -11,7 +11,7 @@ class ZoomHeight:
def __init__(self, editwin):
self.editwin = editwin
def zoom_height_event(self, event):
def zoom_height_event(self, event=None):
top = self.editwin.top
zoom_height(top)
return "break"
......@@ -46,3 +46,10 @@ def zoom_height(top):
else:
newgeom = "%dx%d+%d+%d" % (width, newheight, x, newy)
top.wm_geometry(newgeom)
if __name__ == "__main__":
from unittest import main
main('idlelib.idle_test.test_zoomheight', verbosity=2, exit=False)
# Add htest?
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment