summaryrefslogtreecommitdiff
path: root/lib/python2.7/idlelib/idle_test/htest.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/idlelib/idle_test/htest.py')
-rw-r--r--lib/python2.7/idlelib/idle_test/htest.py403
1 files changed, 403 insertions, 0 deletions
diff --git a/lib/python2.7/idlelib/idle_test/htest.py b/lib/python2.7/idlelib/idle_test/htest.py
new file mode 100644
index 0000000..f341409
--- /dev/null
+++ b/lib/python2.7/idlelib/idle_test/htest.py
@@ -0,0 +1,403 @@
+'''Run human tests of Idle's window, dialog, and popup widgets.
+
+run(*tests)
+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 '_'.
+
+
+End the module with
+
+if __name__ == '__main__':
+ <unittest, if there is one>
+ from idlelib.idle_test.htest import run
+ run(X)
+
+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__.:
+
+(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': '',
+ 'kwds': {'title': ''},
+ 'msg': ""
+ }
+
+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 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
+
+AboutDialog_spec = {
+ 'file': 'aboutDialog',
+ 'kwds': {'title': 'aboutDialog test',
+ '_htest': True,
+ },
+ 'msg': "Test every button. Ensure Python, TK and IDLE versions "
+ "are correctly displayed.\n [Close] to exit.",
+ }
+
+_calltip_window_spec = {
+ 'file': 'CallTipWindow',
+ 'kwds': {},
+ 'msg': "Typing '(' should display a calltip.\n"
+ "Typing ') should hide the calltip.\n"
+ }
+
+_class_browser_spec = {
+ 'file': 'ClassBrowser',
+ 'kwds': {},
+ 'msg': "Inspect names of module, class(with superclass if "
+ "applicable), methods and functions.\nToggle nested items.\n"
+ "Double clicking on items prints a traceback for an exception "
+ "that is ignored."
+ }
+
+_color_delegator_spec = {
+ 'file': 'ColorDelegator',
+ 'kwds': {},
+ 'msg': "The text is sample Python code.\n"
+ "Ensure components like comments, keywords, builtins,\n"
+ "string, definitions, and break are correctly colored.\n"
+ "The default color scheme is in idlelib/config-highlight.def"
+ }
+
+ConfigDialog_spec = {
+ 'file': 'configDialog',
+ 'kwds': {'title': 'ConfigDialogTest',
+ '_htest': True,},
+ 'msg': "IDLE preferences dialog.\n"
+ "In the 'Fonts/Tabs' tab, changing font face, should update the "
+ "font face of the text in the area below it.\nIn the "
+ "'Highlighting' tab, try different color schemes. Clicking "
+ "items in the sample program should update the choices above it."
+ "\nIn the 'Keys', 'General' and 'Extensions' tabs, test settings"
+ "of interest."
+ "\n[Ok] to close the dialog.[Apply] to apply the settings and "
+ "and [Cancel] to revert all changes.\nRe-run the test to ensure "
+ "changes made have persisted."
+ }
+
+# TODO Improve message
+_dyn_option_menu_spec = {
+ 'file': 'dynOptionMenuWidget',
+ 'kwds': {},
+ 'msg': "Select one of the many options in the 'old option set'.\n"
+ "Click the button to change the option set.\n"
+ "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.\n"
+ "Best to close editor first."
+ }
+
+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]",
+ }
+
+GetHelpSourceDialog_spec = {
+ 'file': 'configHelpSourceEdit',
+ 'kwds': {'title': 'Get helpsource',
+ '_htest': True},
+ 'msg': "Enter menu item name and help file path\n "
+ "<nothing> and more than 30 chars are invalid menu item names.\n"
+ "<nothing>, file does not exist are invalid path items.\n"
+ "Test for incomplete web address for help file path.\n"
+ "A valid entry will be printed to shell with [0k].\n"
+ "[Cancel] will print None to shell",
+ }
+
+# Update once issue21519 is resolved.
+GetKeysDialog_spec = {
+ 'file': 'keybindingDialog',
+ 'kwds': {'title': 'Test keybindings',
+ 'action': 'find-again',
+ 'currentKeySequences': [''] ,
+ '_htest': True,
+ },
+ 'msg': "Test for different key modifier sequences.\n"
+ "<nothing> is invalid.\n"
+ "No modifier key is invalid.\n"
+ "Shift key with [a-z],[0-9], function key, move key, tab, space"
+ "is invalid.\nNo validitity checking if advanced key binding "
+ "entry is used."
+ }
+
+_grep_dialog_spec = {
+ 'file': 'GrepDialog',
+ 'kwds': {},
+ 'msg': "Click the 'Show GrepDialog' button.\n"
+ "Test the various 'Find-in-files' functions.\n"
+ "The results should be displayed in a new '*Output*' window.\n"
+ "'Right-click'->'Goto file/line' anywhere in the search results "
+ "should open that file \nin a new EditorWindow."
+ }
+
+_io_binding_spec = {
+ 'file': 'IOBinding',
+ 'kwds': {},
+ 'msg': "Test the following bindings.\n"
+ "<Control-o> to open file from dialog.\n"
+ "Edit the file.\n"
+ "<Control-p> to print the file.\n"
+ "<Control-s> to save the file.\n"
+ "<Alt-s> to save-as another file.\n"
+ "<Control-c> to save-copy-as another file.\n"
+ "Check that changes were saved by opening the file elsewhere."
+ }
+
+_multi_call_spec = {
+ 'file': 'MultiCall',
+ 'kwds': {},
+ 'msg': "The following actions should trigger a print to console or IDLE"
+ " Shell.\nEntering and leaving the text area, key entry, "
+ "<Control-Key>,\n<Alt-Key-a>, <Control-Key-a>, "
+ "<Alt-Control-Key-a>, \n<Control-Button-1>, <Alt-Button-1> and "
+ "focusing out of the window\nare sequences to be tested."
+ }
+
+_multistatus_bar_spec = {
+ 'file': 'MultiStatusBar',
+ 'kwds': {},
+ 'msg': "Ensure presence of multi-status bar below text area.\n"
+ "Click 'Update Status' to change the multi-status text"
+ }
+
+_object_browser_spec = {
+ 'file': 'ObjectBrowser',
+ 'kwds': {},
+ 'msg': "Double click on items upto the lowest level.\n"
+ "Attributes of the objects and related information "
+ "will be displayed side-by-side at each level."
+ }
+
+_path_browser_spec = {
+ 'file': 'PathBrowser',
+ 'kwds': {},
+ 'msg': "Test for correct display of all paths in sys.path.\n"
+ "Toggle nested items upto the lowest level.\n"
+ "Double clicking on an item prints a traceback\n"
+ "for an exception that is ignored."
+ }
+
+_percolator_spec = {
+ 'file': 'Percolator',
+ 'kwds': {},
+ 'msg': "There are two tracers which can be toggled using a checkbox.\n"
+ "Toggling a tracer 'on' by checking it should print tracer"
+ "output to the console or to the IDLE shell.\n"
+ "If both the tracers are 'on', the output from the tracer which "
+ "was switched 'on' later, should be printed first\n"
+ "Test for actions like text entry, and removal."
+ }
+
+_replace_dialog_spec = {
+ 'file': 'ReplaceDialog',
+ 'kwds': {},
+ 'msg': "Click the 'Replace' button.\n"
+ "Test various replace options in the 'Replace dialog'.\n"
+ "Click [Close] or [X] to close the 'Replace Dialog'."
+ }
+
+_search_dialog_spec = {
+ 'file': 'SearchDialog',
+ 'kwds': {},
+ 'msg': "Click the 'Search' button.\n"
+ "Test various search options in the 'Search dialog'.\n"
+ "Click [Close] or [X] to close the 'Search Dialog'."
+ }
+
+_scrolled_list_spec = {
+ 'file': 'ScrolledList',
+ 'kwds': {},
+ 'msg': "You should see a scrollable list of items\n"
+ "Selecting (clicking) or double clicking an item "
+ "prints the name to the console or Idle shell.\n"
+ "Right clicking an item will display a popup."
+ }
+
+show_idlehelp_spec = {
+ 'file': 'help',
+ 'kwds': {},
+ 'msg': "If the help text displays, this works.\n"
+ "Text is selectable. Window is scrollable."
+ }
+
+_stack_viewer_spec = {
+ 'file': 'StackViewer',
+ 'kwds': {},
+ 'msg': "A stacktrace for a NameError exception.\n"
+ "Expand 'idlelib ...' and '<locals>'.\n"
+ "Check that exc_value, exc_tb, and exc_type are correct.\n"
+ }
+
+_tabbed_pages_spec = {
+ 'file': 'tabbedpages',
+ 'kwds': {},
+ 'msg': "Toggle between the two tabs 'foo' and 'bar'\n"
+ "Add a tab by entering a suitable name for it.\n"
+ "Remove an existing tab by entering its name.\n"
+ "Remove all existing tabs.\n"
+ "<nothing> is an invalid add page and remove page name.\n"
+ }
+
+TextViewer_spec = {
+ 'file': 'textView',
+ 'kwds': {'title': 'Test textView',
+ 'text':'The quick brown fox jumps over the lazy dog.\n'*35,
+ '_htest': True},
+ 'msg': "Test for read-only property of text.\n"
+ "Text is selectable. Window is scrollable.",
+ }
+
+_tooltip_spec = {
+ 'file': 'ToolTip',
+ 'kwds': {},
+ 'msg': "Place mouse cursor over both the buttons\n"
+ "A tooltip should appear with some text."
+ }
+
+_tree_widget_spec = {
+ 'file': 'TreeWidget',
+ 'kwds': {},
+ 'msg': "The canvas is scrollable.\n"
+ "Click on folders upto to the lowest level."
+ }
+
+_undo_delegator_spec = {
+ 'file': 'UndoDelegator',
+ 'kwds': {},
+ 'msg': "Click [Undo] to undo any action.\n"
+ "Click [Redo] to redo any action.\n"
+ "Click [Dump] to dump the current state "
+ "by printing to the console or the IDLE shell.\n"
+ }
+
+_widget_redirector_spec = {
+ 'file': 'WidgetRedirector',
+ 'kwds': {},
+ 'msg': "Every text insert should be printed to the console."
+ "or the IDLE shell."
+ }
+
+def run(*tests):
+ root = tk.Tk()
+ root.title('IDLE htest')
+ root.resizable(0, 0)
+ _initializeTkVariantTests(root)
+
+ # a scrollable Label like constant width text widget.
+ frameLabel = tk.Frame(root, padx=10)
+ frameLabel.pack()
+ text = tk.Text(frameLabel, wrap='word')
+ text.configure(bg=root.cget('bg'), relief='flat', height=4, width=70)
+ scrollbar = tk.Scrollbar(frameLabel, command=text.yview)
+ text.config(yscrollcommand=scrollbar.set)
+ scrollbar.pack(side='right', fill='y', expand=False)
+ text.pack(side='left', fill='both', expand=True)
+
+ test_list = [] # List of tuples of the form (spec, callable widget)
+ if tests:
+ for test in tests:
+ test_spec = globals()[test.__name__ + '_spec']
+ test_spec['name'] = test.__name__
+ test_list.append((test_spec, test))
+ else:
+ for k, d in globals().items():
+ if k.endswith('_spec'):
+ test_name = k[:-5]
+ test_spec = d
+ test_spec['name'] = test_name
+ mod = import_module('idlelib.' + test_spec['file'])
+ test = getattr(mod, test_name)
+ test_list.append((test_spec, test))
+
+ test_name = [tk.StringVar('')]
+ callable_object = [None]
+ test_kwds = [None]
+
+
+ def next():
+ if len(test_list) == 1:
+ next_button.pack_forget()
+ test_spec, callable_object[0] = test_list.pop()
+ test_kwds[0] = test_spec['kwds']
+ test_kwds[0]['parent'] = root
+ test_name[0].set('Test ' + test_spec['name'])
+
+ text.configure(state='normal') # enable text editing
+ text.delete('1.0','end')
+ text.insert("1.0",test_spec['msg'])
+ text.configure(state='disabled') # preserve read-only property
+
+ def run_test():
+ widget = callable_object[0](**test_kwds[0])
+ try:
+ print(widget.result)
+ except AttributeError:
+ pass
+
+ button = tk.Button(root, textvariable=test_name[0], command=run_test)
+ button.pack()
+ next_button = tk.Button(root, text="Next", command=next)
+ next_button.pack()
+
+ next()
+
+ root.mainloop()
+
+if __name__ == '__main__':
+ run()