Home | History | Annotate | Download | only in test
      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
     12 import importlib
     13 import test.test_support
     14 
     15 this_dir_path = os.path.abspath(os.path.dirname(__file__))
     16 
     17 _tk_unavailable = None
     18 
     19 def check_tk_availability():
     20     """Check that Tk is installed and available."""
     21     global _tk_unavailable
     22 
     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
     34 
     35             app_services = cdll.LoadLibrary(find_library("ApplicationServices"))
     36 
     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)
     58     return
     59 
     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 
     66 def get_tests_modules(basepath=this_dir_path, gui=True, packages=None):
     67     """This will import and yield modules whose names start with test_
     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     """
     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('/', '.')
     82             if packages and pkg_name not in packages:
     83                 continue
     84 
     85             filenames = filter(
     86                     lambda x: x.startswith('test_') and x.endswith(py_ext),
     87                     filenames)
     88 
     89             for name in filenames:
     90                 try:
     91                     yield importlib.import_module(
     92                             ".%s" % name[:-len(py_ext)], pkg_name)
     93                 except test.test_support.ResourceDenied:
     94                     if gui:
     95                         raise
     96 
     97 def get_tests(text=True, gui=True, packages=None):
     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')
    107     for module in get_tests_modules(gui=gui, packages=packages):
    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())
    115