diff -r 8e9a00257305 Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py Sun May 11 19:05:23 2014 +0200 +++ b/Lib/idlelib/EditorWindow.py Sun May 11 22:54:10 2014 -0400 @@ -79,6 +79,8 @@ self.parent = None helpDialog = HelpDialog() # singleton instance +def _Help_dialog(parent): # wrapper for htest + helpDialog.show_dialog(parent) class EditorWindow(object): @@ -1064,7 +1066,7 @@ try: try: mod = importlib.import_module('.' + name, package=__package__) - except ImportError: + except (ImportError, TypeError): mod = importlib.import_module(name) except ImportError: print("\nFailed to import extension: ", name) @@ -1700,19 +1702,21 @@ tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]') -def test(): - root = Tk() +def _Editor_window(parent): + root = parent fixwordbreaks(root) root.withdraw() if sys.argv[1:]: filename = sys.argv[1] else: filename = None + macosxSupport.setupApp(root, None) edit = EditorWindow(root=root, filename=filename) edit.set_close_hook(root.quit) edit.text.bind("<>", edit.close_event) - root.mainloop() - root.destroy() if __name__ == '__main__': - test() + from idlelib.idle_test.htest import run + if len(sys.argv) <= 1: + run(_Help_dialog) + run(_Editor_window) diff -r 8e9a00257305 Lib/idlelib/aboutDialog.py --- a/Lib/idlelib/aboutDialog.py Sun May 11 19:05:23 2014 +0200 +++ b/Lib/idlelib/aboutDialog.py Sun May 11 22:54:10 2014 -0400 @@ -12,7 +12,7 @@ """Modal about dialog for idle """ - def __init__(self,parent,title): + def __init__(self, parent, title): Toplevel.__init__(self, parent) self.configure(borderwidth=5) self.geometry("+%d+%d" % (parent.winfo_rootx()+30, @@ -136,10 +136,5 @@ self.destroy() if __name__ == '__main__': - # test the dialog - root = Tk() - def run(): - from idlelib import aboutDialog - aboutDialog.AboutDialog(root, 'About') - Button(root, text='Dialog', command=run).pack() - root.mainloop() + from idlelib.idle_test.htest import run + run(AboutDialog) diff -r 8e9a00257305 Lib/idlelib/configSectionNameDialog.py --- a/Lib/idlelib/configSectionNameDialog.py Sun May 11 19:05:23 2014 +0200 +++ b/Lib/idlelib/configSectionNameDialog.py Sun May 11 22:54:10 2014 -0400 @@ -8,10 +8,11 @@ import tkinter.messagebox as tkMessageBox 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 used_names - string collection, names already in use for validity check + _htest - bool, change box location when running htest """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) @@ -30,11 +31,12 @@ self.messageInfo.config(width=self.frameMain.winfo_reqwidth()) self.geometry( "+%d+%d" % ( - parent.winfo_rootx() + - (parent.winfo_width()/2 - self.winfo_reqwidth()/2), - parent.winfo_rooty() + - (parent.winfo_height()/2 - self.winfo_reqheight()/2) - ) ) #centre dialog over parent + parent.winfo_rootx() + + (parent.winfo_width()/2 - self.winfo_reqwidth()/2), + parent.winfo_rooty() + + ((parent.winfo_height()/2 - self.winfo_reqheight()/2) + if not _htest else 100) + ) ) #centre dialog over parent (or below htest box) self.deiconify() #geometry set, unhide self.wait_window() @@ -92,15 +94,5 @@ import unittest unittest.main('idlelib.idle_test.test_config_name', verbosity=2, exit=False) - # also human test the dialog - root = Tk() - def run(): - dlg=GetCfgSectionNameDialog(root,'Get Name', - "After the text entered with [Ok] is stripped, , " - "'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() + from idlelib.idle_test.htest import run + run(GetCfgSectionNameDialog) diff -r 8e9a00257305 Lib/idlelib/idle_test/htest.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/idlelib/idle_test/htest.py Sun May 11 22:54:10 2014 -0400 @@ -0,0 +1,91 @@ +'''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__': + + 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, , " + "'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() +