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