| import sys |
| import unittest |
| from nose_helper.config import Config |
| from nose_helper.util import resolve_name, try_run |
| import imp |
| |
| class Test(unittest.TestCase): |
| """The universal test case wrapper. |
| """ |
| __test__ = False # do not collect |
| def __init__(self, test, config=None): |
| if not hasattr(test, '__call__'): |
| raise TypeError("Test called with argument %r that " |
| "is not callable. A callable is required." |
| % test) |
| self.test = test |
| if config is None: |
| config = Config() |
| self.config = config |
| unittest.TestCase.__init__(self) |
| |
| def __call__(self, *arg, **kwarg): |
| return self.run(*arg, **kwarg) |
| |
| def __str__(self): |
| return str(self.test) |
| |
| def _context(self): |
| try: |
| return self.test.context |
| except AttributeError: |
| pass |
| try: |
| return self.test.__class__ |
| except AttributeError: |
| pass |
| try: |
| return resolve_name(self.test.__module__) |
| except AttributeError: |
| pass |
| return None |
| context = property(_context, None, None, |
| """Get the context object of this test.""") |
| |
| def run(self, result): |
| try: |
| self.runTest(result) |
| except KeyboardInterrupt: |
| raise |
| except: |
| err = sys.exc_info() |
| result.addError(self, err) |
| |
| def runTest(self, result): |
| test = self.test |
| test(result) |
| |
| |
| class TestBase(unittest.TestCase): |
| """Common functionality for FunctionTestCase and MethodTestCase. |
| """ |
| __test__ = False # do not collect |
| |
| class Suite: |
| pass |
| |
| def runTest(self): |
| self.test(*self.arg) |
| |
| class FunctionTestCase(TestBase): |
| """TestCase wrapper for test functions. |
| """ |
| __test__ = False # do not collect |
| |
| def __init__(self, test, setUp=None, tearDown=None, arg=tuple(), |
| descriptor=None): |
| self.test = test |
| self.setUpFunc = setUp |
| self.tearDownFunc = tearDown |
| self.arg = arg |
| self.descriptor = descriptor |
| TestBase.__init__(self) |
| |
| self.suite = TestBase.Suite() |
| self.suite.__module__ = self.__get_module() |
| self.suite.__name__ = "" |
| has_module = True |
| try: |
| imp.find_module(self.suite.__module__)[1] |
| except ImportError: |
| has_module = False |
| if sys.version.find("IronPython") != -1 or not has_module: |
| # Iron Python doesn't fully support imp |
| self.suite.abs_location = "" |
| self.suite.location = "" |
| else: |
| self.suite.abs_location = "file://" + imp.find_module(self.suite.__module__)[1] |
| self.suite.location = "file://" + imp.find_module(self.suite.__module__)[1] |
| |
| def _context(self): |
| return resolve_name(self.test.__module__) |
| context = property(_context, None, None, |
| """Get context (module) of this test""") |
| |
| def setUp(self): |
| """Run any setup function attached to the test function |
| """ |
| if self.setUpFunc: |
| self.setUpFunc() |
| else: |
| names = ('setup', 'setUp', 'setUpFunc') |
| try_run(self.test, names) |
| |
| def tearDown(self): |
| """Run any teardown function attached to the test function |
| """ |
| if self.tearDownFunc: |
| self.tearDownFunc() |
| else: |
| names = ('teardown', 'tearDown', 'tearDownFunc') |
| try_run(self.test, names) |
| |
| def __str__(self): |
| func, arg = self._descriptors() |
| if hasattr(func, 'compat_func_name'): |
| name = func.compat_func_name |
| else: |
| name = func.__name__ |
| if arg: |
| name = "%s%s" % (name, arg) |
| return name |
| __repr__ = __str__ |
| |
| def __get_module(self): |
| func, arg = self._descriptors() |
| if hasattr(func, "__module__"): |
| return func.__module__ |
| else: |
| #TODO[kate]: get module of function in jython < 2.2 |
| return "Unknown module." |
| |
| def _descriptors(self): |
| """In most cases, this is the function itself and no arguments. For |
| tests generated by generator functions, the original |
| (generator) function and args passed to the generated function |
| are returned. |
| """ |
| if self.descriptor: |
| return self.descriptor, self.arg |
| else: |
| return self.test, self.arg |
| |
| |
| class MethodTestCase(TestBase): |
| """Test case wrapper for test methods. |
| """ |
| __test__ = False # do not collect |
| |
| def __init__(self, method, test=None, arg=tuple(), descriptor=None): |
| """Initialize the MethodTestCase. |
| """ |
| self.method = method |
| self.test = test |
| self.arg = arg |
| self.descriptor = descriptor |
| self.cls = method.im_class |
| self.inst = self.cls() |
| if self.test is None: |
| method_name = self.method.__name__ |
| self.test = getattr(self.inst, method_name) |
| TestBase.__init__(self) |
| |
| self.suite = TestBase.Suite() |
| self.suite.__module__, self.suite.__name__ = self.__get_module() |
| |
| has_module = True |
| try: |
| imp.find_module(self.suite.__module__)[1] |
| except ImportError: |
| has_module = False |
| if sys.version.find("IronPython") != -1 or not has_module: |
| # Iron Python doesn't fully support imp |
| self.suite.abs_location = "" |
| else: |
| self.suite.abs_location = "file://" + imp.find_module(self.suite.__module__)[1] |
| self.suite.location = "python_uttestid://" + self.suite.__module__ + "." + self.suite.__name__ |
| |
| def __get_module(self): |
| def get_class_that_defined_method(meth): |
| import inspect |
| obj = meth.im_self |
| for cls in inspect.getmro(meth.im_class): |
| if meth.__name__ in cls.__dict__: return (cls.__module__, cls.__name__) |
| return ("Unknown module", "") |
| |
| func, arg = self._descriptors() |
| return get_class_that_defined_method(func) |
| |
| def __str__(self): |
| func, arg = self._descriptors() |
| if hasattr(func, 'compat_func_name'): |
| name = func.compat_func_name |
| else: |
| name = func.__name__ |
| if arg: |
| name = "%s%s" % (name, arg) |
| return name |
| __repr__ = __str__ |
| |
| def _context(self): |
| return self.cls |
| context = property(_context, None, None, |
| """Get context (class) of this test""") |
| |
| def setUp(self): |
| try_run(self.inst, ('setup', 'setUp')) |
| |
| def tearDown(self): |
| try_run(self.inst, ('teardown', 'tearDown')) |
| |
| def _descriptors(self): |
| """in most cases, this is the method itself and no arguments. For |
| tests generated by generator methods, the original |
| (generator) method and args passed to the generated method |
| or function are returned. |
| """ |
| if self.descriptor: |
| return self.descriptor, self.arg |
| else: |
| return self.method, self.arg |