| Viewing file:  _asyncrunner.py (4.42 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
# -*- test-case-name: twisted.trial.test -*-# Copyright (c) Twisted Matrix Laboratories.
 # See LICENSE for details.
 
 """
 Infrastructure for test running and suites.
 """
 
 from __future__ import division, absolute_import
 
 import doctest
 import gc
 
 from twisted.python import components
 
 from twisted.trial import itrial, reporter
 from twisted.trial._synctest import _logObserver
 
 pyunit = __import__('unittest')
 
 from zope.interface import implementer
 
 
 
 class TestSuite(pyunit.TestSuite):
 """
 Extend the standard library's C{TestSuite} with a consistently overrideable
 C{run} method.
 """
 
 def run(self, result):
 """
 Call C{run} on every member of the suite.
 """
 for test in self._tests:
 if result.shouldStop:
 break
 test(result)
 return result
 
 
 
 @implementer(itrial.ITestCase)
 class TestDecorator(components.proxyForInterface(itrial.ITestCase,
 "_originalTest")):
 """
 Decorator for test cases.
 
 @param _originalTest: The wrapped instance of test.
 @type _originalTest: A provider of L{itrial.ITestCase}
 """
 
 def __call__(self, result):
 """
 Run the unit test.
 
 @param result: A TestResult object.
 """
 return self.run(result)
 
 
 def run(self, result):
 """
 Run the unit test.
 
 @param result: A TestResult object.
 """
 return self._originalTest.run(
 reporter._AdaptedReporter(result, self.__class__))
 
 
 
 def _clearSuite(suite):
 """
 Clear all tests from C{suite}.
 
 This messes with the internals of C{suite}. In particular, it assumes that
 the suite keeps all of its tests in a list in an instance variable called
 C{_tests}.
 """
 suite._tests = []
 
 
 def decorate(test, decorator):
 """
 Decorate all test cases in C{test} with C{decorator}.
 
 C{test} can be a test case or a test suite. If it is a test suite, then the
 structure of the suite is preserved.
 
 L{decorate} tries to preserve the class of the test suites it finds, but
 assumes the presence of the C{_tests} attribute on the suite.
 
 @param test: The C{TestCase} or C{TestSuite} to decorate.
 
 @param decorator: A unary callable used to decorate C{TestCase}s.
 
 @return: A decorated C{TestCase} or a C{TestSuite} containing decorated
 C{TestCase}s.
 """
 
 try:
 tests = iter(test)
 except TypeError:
 return decorator(test)
 
 # At this point, we know that 'test' is a test suite.
 _clearSuite(test)
 
 for case in tests:
 test.addTest(decorate(case, decorator))
 return test
 
 
 
 class _PyUnitTestCaseAdapter(TestDecorator):
 """
 Adapt from pyunit.TestCase to ITestCase.
 """
 
 
 
 class _BrokenIDTestCaseAdapter(_PyUnitTestCaseAdapter):
 """
 Adapter for pyunit-style C{TestCase} subclasses that have undesirable id()
 methods. That is C{unittest.FunctionTestCase} and C{unittest.DocTestCase}.
 """
 
 def id(self):
 """
 Return the fully-qualified Python name of the doctest.
 """
 testID = self._originalTest.shortDescription()
 if testID is not None:
 return testID
 return self._originalTest.id()
 
 
 
 class _ForceGarbageCollectionDecorator(TestDecorator):
 """
 Forces garbage collection to be run before and after the test. Any errors
 logged during the post-test collection are added to the test result as
 errors.
 """
 
 def run(self, result):
 gc.collect()
 TestDecorator.run(self, result)
 _logObserver._add()
 gc.collect()
 for error in _logObserver.getErrors():
 result.addError(self, error)
 _logObserver.flushErrors()
 _logObserver._remove()
 
 
 components.registerAdapter(
 _PyUnitTestCaseAdapter, pyunit.TestCase, itrial.ITestCase)
 
 
 components.registerAdapter(
 _BrokenIDTestCaseAdapter, pyunit.FunctionTestCase, itrial.ITestCase)
 
 
 _docTestCase = getattr(doctest, 'DocTestCase', None)
 if _docTestCase:
 components.registerAdapter(
 _BrokenIDTestCaseAdapter, _docTestCase, itrial.ITestCase)
 
 
 def _iterateTests(testSuiteOrCase):
 """
 Iterate through all of the test cases in C{testSuiteOrCase}.
 """
 try:
 suite = iter(testSuiteOrCase)
 except TypeError:
 yield testSuiteOrCase
 else:
 for test in suite:
 for subtest in _iterateTests(test):
 yield subtest
 
 |