1ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh""" 2ffab958fd8d42ed7227d83007350e61555a1fa36Andrew HsiehUse this module to get and run all tk tests. 3ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 4ffab958fd8d42ed7227d83007350e61555a1fa36Andrew HsiehTkinter tests should live in a package inside the directory where this file 5ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehlives, like test_tkinter. 6ffab958fd8d42ed7227d83007350e61555a1fa36Andrew HsiehExtensions also should live in packages following the same rule as above. 7ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh""" 8ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 9ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport os 10ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport sys 11ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport unittest 12ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport importlib 13ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport test.test_support 14ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 15ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehthis_dir_path = os.path.abspath(os.path.dirname(__file__)) 16ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 17ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh_tk_unavailable = None 18ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 19ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef check_tk_availability(): 20ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Check that Tk is installed and available.""" 21ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh global _tk_unavailable 22ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 23ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if _tk_unavailable is None: 24ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _tk_unavailable = False 25ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if sys.platform == 'darwin': 26ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # The Aqua Tk implementations on OS X can abort the process if 27ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # being called in an environment where a window server connection 28ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # cannot be made, for instance when invoked by a buildbot or ssh 29ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # process not running under the same user id as the current console 30ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # user. To avoid that, raise an exception if the window manager 31ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # connection is not available. 32ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh from ctypes import cdll, c_int, pointer, Structure 33ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh from ctypes.util import find_library 34ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 35ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh app_services = cdll.LoadLibrary(find_library("ApplicationServices")) 36ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 37ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if app_services.CGMainDisplayID() == 0: 38ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _tk_unavailable = "cannot run without OS X window manager" 39ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 40ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh class ProcessSerialNumber(Structure): 41ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _fields_ = [("highLongOfPSN", c_int), 42ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh ("lowLongOfPSN", c_int)] 43ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh psn = ProcessSerialNumber() 44ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh psn_p = pointer(psn) 45ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if ( (app_services.GetCurrentProcess(psn_p) < 0) or 46ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh (app_services.SetFrontProcess(psn_p) < 0) ): 47ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _tk_unavailable = "cannot run without OS X gui process" 48ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: # not OS X 49ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh import Tkinter 50ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 51ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh Tkinter.Button() 52ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except Tkinter.TclError as msg: 53ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # assuming tk is not available 54ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _tk_unavailable = "tk not available: %s" % msg 55ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 56ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if _tk_unavailable: 57ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh raise unittest.SkipTest(_tk_unavailable) 58ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return 59ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 60ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef is_package(path): 61ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for name in os.listdir(path): 62ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if name in ('__init__.py', '__init__.pyc', '__init.pyo'): 63ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return True 64ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return False 65ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 66ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef get_tests_modules(basepath=this_dir_path, gui=True, packages=None): 67ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """This will import and yield modules whose names start with test_ 68ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh and are inside packages found in the path starting at basepath. 69ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 70ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh If packages is specified it should contain package names that want 71ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh their tests colleted. 72ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """ 73ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh py_ext = '.py' 74ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 75ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for dirpath, dirnames, filenames in os.walk(basepath): 76ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for dirname in list(dirnames): 77ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if dirname[0] == '.': 78ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh dirnames.remove(dirname) 79ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 80ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if is_package(dirpath) and filenames: 81ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pkg_name = dirpath[len(basepath) + len(os.sep):].replace('/', '.') 82ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if packages and pkg_name not in packages: 83ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh continue 84ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 85ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh filenames = filter( 86ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh lambda x: x.startswith('test_') and x.endswith(py_ext), 87ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh filenames) 88ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 89ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for name in filenames: 90ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 91ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield importlib.import_module( 92ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh ".%s" % name[:-len(py_ext)], pkg_name) 93ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except test.test_support.ResourceDenied: 94ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if gui: 95ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh raise 96ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 97ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef get_tests(text=True, gui=True, packages=None): 98ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh """Yield all the tests in the modules found by get_tests_modules. 99ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 100ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh If nogui is True, only tests that do not require a GUI will be 101ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh returned.""" 102ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh attrs = [] 103ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if text: 104ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh attrs.append('tests_nogui') 105ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if gui: 106ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh attrs.append('tests_gui') 107ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for module in get_tests_modules(gui=gui, packages=packages): 108ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for attr in attrs: 109ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for test in getattr(module, attr, ()): 110ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh yield test 111ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 112ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehif __name__ == "__main__": 113ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh test.test_support.use_resources = ['gui'] 114ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh test.test_support.run_unittest(*get_tests()) 115