blob: 95e1728861938980fdd816ac1075ecdd25aba949 [file] [log] [blame]
Guilherme Polocda93aa2009-01-28 13:09:03 +00001"""
2Use this module to get and run all tk tests.
3
4Tkinter tests should live in a package inside the directory where this file
5lives, like test_tkinter.
6Extensions also should live in packages following the same rule as above.
7"""
8
9import os
10import sys
11import unittest
Guilherme Polob98cb432009-02-02 20:28:59 +000012import importlib
Guilherme Polocda93aa2009-01-28 13:09:03 +000013import test.test_support
14
15this_dir_path = os.path.abspath(os.path.dirname(__file__))
16
Ned Deily885b1642011-07-05 19:08:38 -070017_tk_unavailable = None
Ned Deily46268c42011-07-03 21:52:35 -070018
19def check_tk_availability():
20 """Check that Tk is installed and available."""
Ned Deily885b1642011-07-05 19:08:38 -070021 global _tk_unavailable
Ned Deily46268c42011-07-03 21:52:35 -070022
Ned Deily885b1642011-07-05 19:08:38 -070023 if _tk_unavailable is None:
24 _tk_unavailable = False
25 if sys.platform == 'darwin':
26 # The Aqua Tk implementations on OS X can abort the process if
27 # being called in an environment where a window server connection
28 # cannot be made, for instance when invoked by a buildbot or ssh
29 # process not running under the same user id as the current console
30 # user. To avoid that, raise an exception if the window manager
31 # connection is not available.
32 from ctypes import cdll, c_int, pointer, Structure
33 from ctypes.util import find_library
Ned Deily46268c42011-07-03 21:52:35 -070034
Ned Deily885b1642011-07-05 19:08:38 -070035 app_services = cdll.LoadLibrary(find_library("ApplicationServices"))
Ned Deily46268c42011-07-03 21:52:35 -070036
Ned Deily885b1642011-07-05 19:08:38 -070037 if app_services.CGMainDisplayID() == 0:
38 _tk_unavailable = "cannot run without OS X window manager"
39 else:
40 class ProcessSerialNumber(Structure):
41 _fields_ = [("highLongOfPSN", c_int),
42 ("lowLongOfPSN", c_int)]
43 psn = ProcessSerialNumber()
44 psn_p = pointer(psn)
45 if ( (app_services.GetCurrentProcess(psn_p) < 0) or
46 (app_services.SetFrontProcess(psn_p) < 0) ):
47 _tk_unavailable = "cannot run without OS X gui process"
48 else: # not OS X
49 import Tkinter
50 try:
51 Tkinter.Button()
52 except Tkinter.TclError as msg:
53 # assuming tk is not available
54 _tk_unavailable = "tk not available: %s" % msg
55
56 if _tk_unavailable:
57 raise unittest.SkipTest(_tk_unavailable)
Ned Deily46268c42011-07-03 21:52:35 -070058 return
59
Guilherme Polocda93aa2009-01-28 13:09:03 +000060def is_package(path):
61 for name in os.listdir(path):
62 if name in ('__init__.py', '__init__.pyc', '__init.pyo'):
63 return True
64 return False
65
Guilherme Polo6785cf02009-01-28 19:23:28 +000066def get_tests_modules(basepath=this_dir_path, gui=True, packages=None):
Guilherme Polocda93aa2009-01-28 13:09:03 +000067 """This will import and yield modules whose names start with test_
Guilherme Polo6785cf02009-01-28 19:23:28 +000068 and are inside packages found in the path starting at basepath.
69
70 If packages is specified it should contain package names that want
71 their tests colleted.
72 """
Guilherme Polocda93aa2009-01-28 13:09:03 +000073 py_ext = '.py'
74
75 for dirpath, dirnames, filenames in os.walk(basepath):
76 for dirname in list(dirnames):
77 if dirname[0] == '.':
78 dirnames.remove(dirname)
79
80 if is_package(dirpath) and filenames:
81 pkg_name = dirpath[len(basepath) + len(os.sep):].replace('/', '.')
Guilherme Polo6785cf02009-01-28 19:23:28 +000082 if packages and pkg_name not in packages:
83 continue
84
Guilherme Polocda93aa2009-01-28 13:09:03 +000085 filenames = filter(
86 lambda x: x.startswith('test_') and x.endswith(py_ext),
87 filenames)
88
89 for name in filenames:
90 try:
Guilherme Polob98cb432009-02-02 20:28:59 +000091 yield importlib.import_module(
92 ".%s" % name[:-len(py_ext)], pkg_name)
Guilherme Polocda93aa2009-01-28 13:09:03 +000093 except test.test_support.ResourceDenied:
94 if gui:
95 raise
96
Guilherme Polo6785cf02009-01-28 19:23:28 +000097def get_tests(text=True, gui=True, packages=None):
Guilherme Polocda93aa2009-01-28 13:09:03 +000098 """Yield all the tests in the modules found by get_tests_modules.
99
100 If nogui is True, only tests that do not require a GUI will be
101 returned."""
102 attrs = []
103 if text:
104 attrs.append('tests_nogui')
105 if gui:
106 attrs.append('tests_gui')
Guilherme Polo6785cf02009-01-28 19:23:28 +0000107 for module in get_tests_modules(gui=gui, packages=packages):
Guilherme Polocda93aa2009-01-28 13:09:03 +0000108 for attr in attrs:
109 for test in getattr(module, attr, ()):
110 yield test
111
112if __name__ == "__main__":
113 test.test_support.use_resources = ['gui']
114 test.test_support.run_unittest(*get_tests())