diff options
Diffstat (limited to 'Lib')
| -rw-r--r-- | Lib/idlelib/CallTipWindow.py | 52 | ||||
| -rw-r--r-- | Lib/idlelib/ClassBrowser.py | 13 | ||||
| -rw-r--r-- | Lib/idlelib/ColorDelegator.py | 22 | ||||
| -rw-r--r-- | Lib/idlelib/EditorWindow.py | 6 | ||||
| -rw-r--r-- | Lib/idlelib/GrepDialog.py | 2 | ||||
| -rw-r--r-- | Lib/idlelib/configDialog.py | 4 | ||||
| -rw-r--r-- | Lib/idlelib/dynOptionMenuWidget.py | 30 | ||||
| -rw-r--r-- | Lib/idlelib/idle_test/htest.py | 65 | 
8 files changed, 112 insertions, 82 deletions
diff --git a/Lib/idlelib/CallTipWindow.py b/Lib/idlelib/CallTipWindow.py index 84d22fd667..170d14653a 100644 --- a/Lib/idlelib/CallTipWindow.py +++ b/Lib/idlelib/CallTipWindow.py @@ -133,37 +133,27 @@ class CallTip:  def _calltip_window(parent):  # htest # -    import re -    from tkinter import Tk, Text, LEFT, BOTH - -    root = Tk() -    root.title("Test calltips") -    width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) -    root.geometry("+%d+%d"%(x, y + 150)) - -    class MyEditWin: # conceptually an editor_window -        def __init__(self): -            text = self.text = Text(root) -            text.pack(side=LEFT, fill=BOTH, expand=1) -            text.insert("insert", "string.split") -            root.update() -            self.calltip = CallTip(text) - -            text.event_add("<<calltip-show>>", "(") -            text.event_add("<<calltip-hide>>", ")") -            text.bind("<<calltip-show>>", self.calltip_show) -            text.bind("<<calltip-hide>>", self.calltip_hide) - -            text.focus_set() -            root.mainloop() - -        def calltip_show(self, event): -            self.calltip.showtip("Hello world", "insert", "end") - -        def calltip_hide(self, event): -            self.calltip.hidetip() - -    MyEditWin() +    from tkinter import Toplevel, Text, LEFT, BOTH + +    top = Toplevel(parent) +    top.title("Test calltips") +    top.geometry("200x100+%d+%d" % (parent.winfo_rootx() + 200, +                  parent.winfo_rooty() + 150)) +    text = Text(top) +    text.pack(side=LEFT, fill=BOTH, expand=1) +    text.insert("insert", "string.split") +    top.update() +    calltip = CallTip(text) + +    def calltip_show(event): +        calltip.showtip("(s=Hello world)", "insert", "end") +    def calltip_hide(event): +        calltip.hidetip() +    text.event_add("<<calltip-show>>", "(") +    text.event_add("<<calltip-hide>>", ")") +    text.bind("<<calltip-show>>", calltip_show) +    text.bind("<<calltip-hide>>", calltip_hide) +    text.focus_set()  if __name__=='__main__':      from idlelib.idle_test.htest import run diff --git a/Lib/idlelib/ClassBrowser.py b/Lib/idlelib/ClassBrowser.py index a0e782e0f8..5be65efb9b 100644 --- a/Lib/idlelib/ClassBrowser.py +++ b/Lib/idlelib/ClassBrowser.py @@ -19,6 +19,9 @@ from idlelib.WindowList import ListedToplevel  from idlelib.TreeWidget import TreeNode, TreeItem, ScrolledCanvas  from idlelib.configHandler import idleConf +file_open = None  # Method...Item and Class...Item use this. +# Normally PyShell.flist.open, but there is no PyShell.flist for htest. +  class ClassBrowser:      def __init__(self, flist, name, path, _htest=False): @@ -27,6 +30,9 @@ class ClassBrowser:          """          _htest - bool, change box when location running htest.          """ +        global file_open +        if not _htest: +            file_open = PyShell.flist.open          self.name = name          self.file = os.path.join(path[0], self.name + ".py")          self._htest = _htest @@ -170,7 +176,7 @@ class ClassBrowserTreeItem(TreeItem):      def OnDoubleClick(self):          if not os.path.exists(self.file):              return -        edit = PyShell.flist.open(self.file) +        edit = file_open(self.file)          if hasattr(self.cl, 'lineno'):              lineno = self.cl.lineno              edit.gotoline(lineno) @@ -206,7 +212,7 @@ class MethodBrowserTreeItem(TreeItem):      def OnDoubleClick(self):          if not os.path.exists(self.file):              return -        edit = PyShell.flist.open(self.file) +        edit = file_open(self.file)          edit.gotoline(self.cl.methods[self.name])  def _class_browser(parent): #Wrapper for htest @@ -221,8 +227,9 @@ def _class_browser(parent): #Wrapper for htest      dir, file = os.path.split(file)      name = os.path.splitext(file)[0]      flist = PyShell.PyShellFileList(parent) +    global file_open +    file_open = flist.open      ClassBrowser(flist, name, [dir], _htest=True) -    parent.mainloop()  if __name__ == "__main__":      from idlelib.idle_test.htest import run diff --git a/Lib/idlelib/ColorDelegator.py b/Lib/idlelib/ColorDelegator.py index 22bb22f82b..13a9010313 100644 --- a/Lib/idlelib/ColorDelegator.py +++ b/Lib/idlelib/ColorDelegator.py @@ -2,7 +2,6 @@ import time  import re  import keyword  import builtins -from tkinter import *  from idlelib.Delegator import Delegator  from idlelib.configHandler import idleConf @@ -234,20 +233,23 @@ class ColorDelegator(Delegator):          for tag in self.tagdefs:              self.tag_remove(tag, "1.0", "end") -def _color_delegator(parent): +def _color_delegator(parent):  # htest # +    from tkinter import Toplevel, Text      from idlelib.Percolator import Percolator -    root = Tk() -    root.title("Test ColorDelegator") -    width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) -    root.geometry("+%d+%d"%(x, y + 150)) -    source = "if somename: x = 'abc' # comment\nprint" -    text = Text(root, background="white") -    text.insert("insert", source) + +    top = Toplevel(parent) +    top.title("Test ColorDelegator") +    top.geometry("200x100+%d+%d" % (parent.winfo_rootx() + 200, +                  parent.winfo_rooty() + 150)) +    source = "if somename: x = 'abc' # comment\nprint\n" +    text = Text(top, background="white")      text.pack(expand=1, fill="both") +    text.insert("insert", source) +    text.focus_set() +      p = Percolator(text)      d = ColorDelegator()      p.insertfilter(d) -    root.mainloop()  if __name__ == "__main__":      from idlelib.idle_test.htest import run diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py index 10565522f7..bdf4a1a6f6 100644 --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -1711,7 +1711,8 @@ def fixwordbreaks(root):      tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]') -def _editor_window(parent): +def _editor_window(parent):  # htest # +    # error if close master window first - timer event, after script      root = parent      fixwordbreaks(root)      if sys.argv[1:]: @@ -1721,7 +1722,8 @@ def _editor_window(parent):      macosxSupport.setupApp(root, None)      edit = EditorWindow(root=root, filename=filename)      edit.text.bind("<<close-all-windows>>", edit.close_event) -    parent.mainloop() +    # Does not stop error, neither does following +    # edit.text.bind("<<close-window>>", edit.close_event)  if __name__ == '__main__':      from idlelib.idle_test.htest import run diff --git a/Lib/idlelib/GrepDialog.py b/Lib/idlelib/GrepDialog.py index 5d22a9e932..aa866d0b75 100644 --- a/Lib/idlelib/GrepDialog.py +++ b/Lib/idlelib/GrepDialog.py @@ -131,7 +131,7 @@ class GrepDialog(SearchDialogBase):              self.top.withdraw() -def _grep_dialog(parent):  # for htest +def _grep_dialog(parent):  # htest #      from idlelib.PyShell import PyShellFileList      root = Tk()      root.title("Test GrepDialog") diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py index cd3d5c0131..938b0bc282 100644 --- a/Lib/idlelib/configDialog.py +++ b/Lib/idlelib/configDialog.py @@ -24,7 +24,7 @@ from idlelib import macosxSupport  class ConfigDialog(Toplevel): -    def __init__(self, parent, title, _htest=False, _utest=False): +    def __init__(self, parent, title='', _htest=False, _utest=False):          """          _htest - bool, change box location when running htest          _utest - bool, don't wait_window when running unittest @@ -36,7 +36,7 @@ class ConfigDialog(Toplevel):          self.wm_withdraw()          self.configure(borderwidth=5) -        self.title('IDLE Preferences') +        self.title(title or 'IDLE Preferences')          self.geometry(                  "+%d+%d" % (parent.winfo_rootx() + 20,                  parent.winfo_rooty() + (30 if not _htest else 150))) diff --git a/Lib/idlelib/dynOptionMenuWidget.py b/Lib/idlelib/dynOptionMenuWidget.py index 877ca1b14e..515b4bafc2 100644 --- a/Lib/idlelib/dynOptionMenuWidget.py +++ b/Lib/idlelib/dynOptionMenuWidget.py @@ -2,17 +2,15 @@  OptionMenu widget modified to allow dynamic menu reconfiguration  and setting of highlightthickness  """ -from tkinter import OptionMenu, _setit, Tk, StringVar, Button -  import copy -import re +from tkinter import OptionMenu, _setit, StringVar, Button  class DynOptionMenu(OptionMenu):      """      unlike OptionMenu, our kwargs can include highlightthickness      """      def __init__(self, master, variable, value, *values, **kwargs): -        #get a copy of kwargs before OptionMenu.__init__ munges them +        # TODO copy value instead of whole dict          kwargsCopy=copy.copy(kwargs)          if 'highlightthickness' in list(kwargs.keys()):              del(kwargs['highlightthickness']) @@ -35,22 +33,24 @@ class DynOptionMenu(OptionMenu):          if value:              self.variable.set(value) -def _dyn_option_menu(parent): -    root = Tk() -    root.title("Tets dynamic option menu") -    var = StringVar(root) -    width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) -    root.geometry("+%d+%d"%(x, y + 150)) +def _dyn_option_menu(parent):  # htest # +    from tkinter import Toplevel + +    top = Toplevel() +    top.title("Tets dynamic option menu") +    top.geometry("200x100+%d+%d" % (parent.winfo_rootx() + 200, +                  parent.winfo_rooty() + 150)) +    top.focus_set() + +    var = StringVar(top)      var.set("Old option set") #Set the default value -    dyn = DynOptionMenu(root,var, "old1","old2","old3","old4") +    dyn = DynOptionMenu(top,var, "old1","old2","old3","old4")      dyn.pack()      def update(): -        dyn.SetMenu(["new1","new2","new3","new4"],value="new option set") - -    button = Button(root, text="Change option set", command=update) +        dyn.SetMenu(["new1","new2","new3","new4"], value="new option set") +    button = Button(top, text="Change option set", command=update)      button.pack() -    root.mainloop()  if __name__ == '__main__':      from idlelib.idle_test.htest import run diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py index d0faf44d8a..d673fe4ea8 100644 --- a/Lib/idlelib/idle_test/htest.py +++ b/Lib/idlelib/idle_test/htest.py @@ -1,11 +1,24 @@  '''Run human tests of Idle's window, dialog, and popup widgets.  run(*tests) -Run each callable in tests after finding the matching test spec in this file. -If there are none, run an htest for each spec dict in this file after finding -the matching callable in the module named in the spec. +Create a master Tk window.  Within that, run each callable in tests +after finding the matching test spec in this file.  If tests is empty, +run an htest for each spec dict in this file after finding the matching +callable in the module named in the spec.  Close the window to skip or +end the test. + +In a tested module, let X be a global name bound to a callable (class +or function) whose .__name__ attrubute is also X (the usual situation). +The first parameter of X must be 'parent'.  When called, the parent +argument will be the root window.  X must create a child Toplevel +window (or subclass thereof).  The Toplevel may be a test widget or +dialog, in which case the callable is the corresonding class.  Or the +Toplevel may contain the widget to be tested or set up a context in +which a test widget is invoked.  In this latter case, the callable is a +wrapper function that sets up the Toplevel and other objects.  Wrapper +function names, such as _editor_window', should start with '_'. + -In a tested module, let X be a global name bound to a widget callable.  End the module with  if __name__ == '__main__': @@ -13,13 +26,25 @@ if __name__ == '__main__':      from idlelib.idle_test.htest import run      run(X) -The X object must have a .__name__ attribute and a 'parent' parameter. -X will often 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 '_'. +To have wrapper functions and test invocation code ignored by coveragepy +reports, put '# htest #' on the def statement header line. + +def _wrapper(parent):  # htest # + +Also make sure that the 'if __name__' line matches the above.  Then have +make sure that .coveragerc includes the following. + +[report] +exclude_lines = +    .*# htest # +    if __name__ == .__main__.: -This file must contain a matching instance of the following template, -with X.__name__ prepended, as in '_editor_window_spec ...'. +(The "." instead of "'" is intentional and necessary.) + + +To run any X, this file must contain a matching instance of the +following template, with X.__name__ prepended to '_spec'. +When all tests are run, the prefix is use to get X.  _spec = {      'file': '', @@ -27,18 +52,19 @@ _spec = {      'msg': ""      } -file (no .py): used in run() to import the file and get X. -kwds: passed to X (**kwds), after 'parent' is added, to initialize X. -title: an example; used for some widgets, delete if not. -msg: displayed in a master window. Hints as to how the user might -  test the widget. Close the window to skip or end the test. +file (no .py): run() imports file.py. +kwds: augmented with {'parent':root} and passed to X as **kwds. +title: an example kwd; some widgets need this, delete if not. +msg: master window hints about testing the widget. -Modules not being tested at the moment: + +Modules and classes not being tested at the moment:  PyShell.PyShellEditorWindow  Debugger.Debugger  AutoCompleteWindow.AutoCompleteWindow  OutputWindow.OutputWindow (indirectly being tested with grep test)  ''' +  from importlib import import_module  from idlelib.macosxSupport import _initializeTkVariantTests  import tkinter as tk @@ -79,7 +105,7 @@ _color_delegator_spec = {  ConfigDialog_spec = {      'file': 'configDialog', -    'kwds': {'title': 'Settings', +    'kwds': {'title': 'ConfigDialogTest',               '_htest': True,},      'msg': "IDLE preferences dialog.\n"             "In the 'Fonts/Tabs' tab, changing font face, should update the " @@ -92,6 +118,7 @@ ConfigDialog_spec = {             "changes made have persisted."      } +# TODO Improve message  _dyn_option_menu_spec = {      'file': 'dynOptionMenuWidget',      'kwds': {}, @@ -100,10 +127,12 @@ _dyn_option_menu_spec = {             "Select one of the many options in the 'new option set'."      } +# TODO edit wrapper  _editor_window_spec = {     'file': 'EditorWindow',      'kwds': {}, -    'msg': "Test editor functions of interest." +    'msg': "Test editor functions of interest.\n" +           "Best to close editor first."      }  GetCfgSectionNameDialog_spec = {  | 
