Guilherme Polo | cda93aa | 2009-01-28 13:09:03 +0000 | [diff] [blame] | 1 | """ |
| 2 | Use this module to get and run all tk tests. |
| 3 | |
| 4 | Tkinter tests should live in a package inside the directory where this file |
| 5 | lives, like test_tkinter. |
| 6 | Extensions also should live in packages following the same rule as above. |
| 7 | """ |
| 8 | |
| 9 | import os |
| 10 | import sys |
| 11 | import unittest |
Guilherme Polo | b98cb43 | 2009-02-02 20:28:59 +0000 | [diff] [blame] | 12 | import importlib |
Guilherme Polo | cda93aa | 2009-01-28 13:09:03 +0000 | [diff] [blame] | 13 | import test.test_support |
| 14 | |
| 15 | this_dir_path = os.path.abspath(os.path.dirname(__file__)) |
| 16 | |
Ned Deily | 885b164 | 2011-07-05 19:08:38 -0700 | [diff] [blame] | 17 | _tk_unavailable = None |
Ned Deily | 46268c4 | 2011-07-03 21:52:35 -0700 | [diff] [blame] | 18 | |
| 19 | def check_tk_availability(): |
| 20 | """Check that Tk is installed and available.""" |
Ned Deily | 885b164 | 2011-07-05 19:08:38 -0700 | [diff] [blame] | 21 | global _tk_unavailable |
Ned Deily | 46268c4 | 2011-07-03 21:52:35 -0700 | [diff] [blame] | 22 | |
Ned Deily | 885b164 | 2011-07-05 19:08:38 -0700 | [diff] [blame] | 23 | 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 Deily | 46268c4 | 2011-07-03 21:52:35 -0700 | [diff] [blame] | 34 | |
Ned Deily | 885b164 | 2011-07-05 19:08:38 -0700 | [diff] [blame] | 35 | app_services = cdll.LoadLibrary(find_library("ApplicationServices")) |
Ned Deily | 46268c4 | 2011-07-03 21:52:35 -0700 | [diff] [blame] | 36 | |
Ned Deily | 885b164 | 2011-07-05 19:08:38 -0700 | [diff] [blame] | 37 | 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 Deily | 46268c4 | 2011-07-03 21:52:35 -0700 | [diff] [blame] | 58 | return |
| 59 | |
Guilherme Polo | cda93aa | 2009-01-28 13:09:03 +0000 | [diff] [blame] | 60 | def 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 Polo | 6785cf0 | 2009-01-28 19:23:28 +0000 | [diff] [blame] | 66 | def get_tests_modules(basepath=this_dir_path, gui=True, packages=None): |
Guilherme Polo | cda93aa | 2009-01-28 13:09:03 +0000 | [diff] [blame] | 67 | """This will import and yield modules whose names start with test_ |
Guilherme Polo | 6785cf0 | 2009-01-28 19:23:28 +0000 | [diff] [blame] | 68 | 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 Polo | cda93aa | 2009-01-28 13:09:03 +0000 | [diff] [blame] | 73 | 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 Polo | 6785cf0 | 2009-01-28 19:23:28 +0000 | [diff] [blame] | 82 | if packages and pkg_name not in packages: |
| 83 | continue |
| 84 | |
Guilherme Polo | cda93aa | 2009-01-28 13:09:03 +0000 | [diff] [blame] | 85 | filenames = filter( |
| 86 | lambda x: x.startswith('test_') and x.endswith(py_ext), |
| 87 | filenames) |
| 88 | |
| 89 | for name in filenames: |
| 90 | try: |
Guilherme Polo | b98cb43 | 2009-02-02 20:28:59 +0000 | [diff] [blame] | 91 | yield importlib.import_module( |
| 92 | ".%s" % name[:-len(py_ext)], pkg_name) |
Guilherme Polo | cda93aa | 2009-01-28 13:09:03 +0000 | [diff] [blame] | 93 | except test.test_support.ResourceDenied: |
| 94 | if gui: |
| 95 | raise |
| 96 | |
Guilherme Polo | 6785cf0 | 2009-01-28 19:23:28 +0000 | [diff] [blame] | 97 | def get_tests(text=True, gui=True, packages=None): |
Guilherme Polo | cda93aa | 2009-01-28 13:09:03 +0000 | [diff] [blame] | 98 | """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 Polo | 6785cf0 | 2009-01-28 19:23:28 +0000 | [diff] [blame] | 107 | for module in get_tests_modules(gui=gui, packages=packages): |
Guilherme Polo | cda93aa | 2009-01-28 13:09:03 +0000 | [diff] [blame] | 108 | for attr in attrs: |
| 109 | for test in getattr(module, attr, ()): |
| 110 | yield test |
| 111 | |
| 112 | if __name__ == "__main__": |
| 113 | test.test_support.use_resources = ['gui'] |
| 114 | test.test_support.run_unittest(*get_tests()) |