Kaydet (Commit) 06313b79 authored tarafından Terry Jan Reedy's avatar Terry Jan Reedy

Issue #18104: Add idlelib/idle_test/htest.py with a few sample tests to begin

consolidating and improving human-validated tests of Idle. Change other files
as needed to work with htest.  Running the module as __main__ runs all tests.
üst 23a192d9
...@@ -79,6 +79,8 @@ class HelpDialog(object): ...@@ -79,6 +79,8 @@ class HelpDialog(object):
self.parent = None self.parent = None
helpDialog = HelpDialog() # singleton instance helpDialog = HelpDialog() # singleton instance
def _Help_dialog(parent): # wrapper for htest
helpDialog.show_dialog(parent)
class EditorWindow(object): class EditorWindow(object):
...@@ -1064,7 +1066,7 @@ class EditorWindow(object): ...@@ -1064,7 +1066,7 @@ class EditorWindow(object):
try: try:
try: try:
mod = importlib.import_module('.' + name, package=__package__) mod = importlib.import_module('.' + name, package=__package__)
except ImportError: except (ImportError, TypeError):
mod = importlib.import_module(name) mod = importlib.import_module(name)
except ImportError: except ImportError:
print("\nFailed to import extension: ", name) print("\nFailed to import extension: ", name)
...@@ -1700,19 +1702,21 @@ def fixwordbreaks(root): ...@@ -1700,19 +1702,21 @@ def fixwordbreaks(root):
tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]') tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]')
def test(): def _Editor_window(parent):
root = Tk() root = parent
fixwordbreaks(root) fixwordbreaks(root)
root.withdraw() root.withdraw()
if sys.argv[1:]: if sys.argv[1:]:
filename = sys.argv[1] filename = sys.argv[1]
else: else:
filename = None filename = None
macosxSupport.setupApp(root, None)
edit = EditorWindow(root=root, filename=filename) edit = EditorWindow(root=root, filename=filename)
edit.set_close_hook(root.quit) edit.set_close_hook(root.quit)
edit.text.bind("<<close-all-windows>>", edit.close_event) edit.text.bind("<<close-all-windows>>", edit.close_event)
root.mainloop()
root.destroy()
if __name__ == '__main__': if __name__ == '__main__':
test() from idlelib.idle_test.htest import run
if len(sys.argv) <= 1:
run(_Help_dialog)
run(_Editor_window)
...@@ -12,7 +12,7 @@ class AboutDialog(Toplevel): ...@@ -12,7 +12,7 @@ class AboutDialog(Toplevel):
"""Modal about dialog for idle """Modal about dialog for idle
""" """
def __init__(self,parent,title): def __init__(self, parent, title):
Toplevel.__init__(self, parent) Toplevel.__init__(self, parent)
self.configure(borderwidth=5) self.configure(borderwidth=5)
self.geometry("+%d+%d" % (parent.winfo_rootx()+30, self.geometry("+%d+%d" % (parent.winfo_rootx()+30,
...@@ -136,10 +136,5 @@ class AboutDialog(Toplevel): ...@@ -136,10 +136,5 @@ class AboutDialog(Toplevel):
self.destroy() self.destroy()
if __name__ == '__main__': if __name__ == '__main__':
# test the dialog from idlelib.idle_test.htest import run
root = Tk() run(AboutDialog)
def run():
from idlelib import aboutDialog
aboutDialog.AboutDialog(root, 'About')
Button(root, text='Dialog', command=run).pack()
root.mainloop()
...@@ -8,10 +8,11 @@ from tkinter import * ...@@ -8,10 +8,11 @@ from tkinter import *
import tkinter.messagebox as tkMessageBox import tkinter.messagebox as tkMessageBox
class GetCfgSectionNameDialog(Toplevel): class GetCfgSectionNameDialog(Toplevel):
def __init__(self, parent, title, message, used_names): def __init__(self, parent, title, message, used_names, _htest=False):
""" """
message - string, informational message to display message - string, informational message to display
used_names - string collection, names already in use for validity check used_names - string collection, names already in use for validity check
_htest - bool, change box location when running htest
""" """
Toplevel.__init__(self, parent) Toplevel.__init__(self, parent)
self.configure(borderwidth=5) self.configure(borderwidth=5)
...@@ -30,11 +31,12 @@ class GetCfgSectionNameDialog(Toplevel): ...@@ -30,11 +31,12 @@ class GetCfgSectionNameDialog(Toplevel):
self.messageInfo.config(width=self.frameMain.winfo_reqwidth()) self.messageInfo.config(width=self.frameMain.winfo_reqwidth())
self.geometry( self.geometry(
"+%d+%d" % ( "+%d+%d" % (
parent.winfo_rootx() + parent.winfo_rootx() +
(parent.winfo_width()/2 - self.winfo_reqwidth()/2), (parent.winfo_width()/2 - self.winfo_reqwidth()/2),
parent.winfo_rooty() + parent.winfo_rooty() +
(parent.winfo_height()/2 - self.winfo_reqheight()/2) ((parent.winfo_height()/2 - self.winfo_reqheight()/2)
) ) #centre dialog over parent if not _htest else 100)
) ) #centre dialog over parent (or below htest box)
self.deiconify() #geometry set, unhide self.deiconify() #geometry set, unhide
self.wait_window() self.wait_window()
...@@ -92,15 +94,5 @@ if __name__ == '__main__': ...@@ -92,15 +94,5 @@ if __name__ == '__main__':
import unittest import unittest
unittest.main('idlelib.idle_test.test_config_name', verbosity=2, exit=False) unittest.main('idlelib.idle_test.test_config_name', verbosity=2, exit=False)
# also human test the dialog from idlelib.idle_test.htest import run
root = Tk() run(GetCfgSectionNameDialog)
def run():
dlg=GetCfgSectionNameDialog(root,'Get Name',
"After the text entered with [Ok] is stripped, <nothing>, "
"'abc', or more that 30 chars are errors. "
"Close with a valid entry (printed), [Cancel], or [X]",
{'abc'})
print(dlg.result)
Message(root, text='').pack() # will be needed for oher dialog tests
Button(root, text='Click to begin dialog test', command=run).pack()
root.mainloop()
'''Run a human test of Idle wndow, dialog, and other widget classes.
run(klass) runs a test for one class.
runall() runs all the defined tests
The file wih the widget class should end with
if __name__ == '__main__':
<unittest, if there is one>
from idlelib.idle_test.htest import run
run(X)
where X is a global object of the module. X must be a callable with a
.__name__ attribute that accepts a 'parent' attribute. X will usually be
a widget class, but a callable instance with .__name__ or a wrapper
function also work. The name of wrapper functions, like _Editor_Window,
should start with '_'.
This file must then contain an instance of this template.
_spec = {
'file': '',
'kwds': {'title': ''},
'msg': ""
}
with X.__name__ prepended to _spec.
File (no .py) is used in runall() to import the file and get the class.
Kwds is passed to X (**kwds) after 'parent' is added, to initialize X.
Msg. displayed is a window with a start button. hint as to how the user
might test the widget. Closing The box skips or ends the test.
'''
from importlib import import_module
import tkinter as tk
# Template for class_spec dicts, copy and uncomment
_Editor_window_spec = {
'file': 'EditorWindow',
'kwds': {},
'msg': "Test editor functions of interest"
}
_Help_dialog_spec = {
'file': 'EditorWindow',
'kwds': {},
'msg': "If the help text displays, this works"
}
AboutDialog_spec = {
'file': 'aboutDialog',
'kwds': {'title': 'About test'},
'msg': "Try each button"
}
GetCfgSectionNameDialog_spec = {
'file': 'configSectionNameDialog',
'kwds': {'title':'Get Name',
'message':'Enter something',
'used_names': {'abc'},
'_htest': True},
'msg': "After the text entered with [Ok] is stripped, <nothing>, "
"'abc', or more that 30 chars are errors.\n"
"Close 'Get Name' with a valid entry (printed to Shell), [Cancel], or [X]",
}
def run(klas):
"Test the widget class klas using _spec dict"
root = tk.Tk()
klas_spec = globals()[klas.__name__+'_spec']
klas_kwds = klas_spec['kwds']
klas_kwds['parent'] = root
# This presumes that Idle consistently uses 'parent'
def run_klas():
widget = klas(**klas_kwds)
try:
print(widget.result)
except AttributeError:
pass
tk.Label(root, text=klas_spec['msg'], justify='left').pack()
tk.Button(root, text='Test ' + klas.__name__, command=run_klas).pack()
root.mainloop()
def runall():
'Run all tests. Quick and dirty version.'
for k, d in globals().items():
if k.endswith('_spec'):
mod = import_module('idlelib.' + d['file'])
klas = getattr(mod, k[:-5])
run(klas)
if __name__ == '__main__':
runall()
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