diff options
author | 2016-03-23 10:43:40 +0200 | |
---|---|---|
committer | 2016-03-23 13:01:10 +0200 | |
commit | 89a2be8247936e2d3d8323c0e51a86c198a879a2 (patch) | |
tree | 3433141e9eb84d35816c938308347686608ae6a3 /scripts/external_libs/nose-1.3.4/nose/suite.py | |
parent | a380bf1055c6cb4432b1c928f73a3ca3ada52d9d (diff) |
yes...again Python3....
Diffstat (limited to 'scripts/external_libs/nose-1.3.4/nose/suite.py')
-rwxr-xr-x | scripts/external_libs/nose-1.3.4/nose/suite.py | 609 |
1 files changed, 0 insertions, 609 deletions
diff --git a/scripts/external_libs/nose-1.3.4/nose/suite.py b/scripts/external_libs/nose-1.3.4/nose/suite.py deleted file mode 100755 index a831105e..00000000 --- a/scripts/external_libs/nose-1.3.4/nose/suite.py +++ /dev/null @@ -1,609 +0,0 @@ -""" -Test Suites ------------ - -Provides a LazySuite, which is a suite whose test list is a generator -function, and ContextSuite,which can run fixtures (setup/teardown -functions or methods) for the context that contains its tests. - -""" -from __future__ import generators - -import logging -import sys -import unittest -from nose.case import Test -from nose.config import Config -from nose.proxy import ResultProxyFactory -from nose.util import isclass, resolve_name, try_run - -if sys.platform == 'cli': - if sys.version_info[:2] < (2, 6): - import clr - clr.AddReference("IronPython") - from IronPython.Runtime.Exceptions import StringException - else: - class StringException(Exception): - pass - -log = logging.getLogger(__name__) -#log.setLevel(logging.DEBUG) - -# Singleton for default value -- see ContextSuite.__init__ below -_def = object() - - -def _strclass(cls): - return "%s.%s" % (cls.__module__, cls.__name__) - -class MixedContextError(Exception): - """Error raised when a context suite sees tests from more than - one context. - """ - pass - - -class LazySuite(unittest.TestSuite): - """A suite that may use a generator as its list of tests - """ - def __init__(self, tests=()): - """Initialize the suite. tests may be an iterable or a generator - """ - super(LazySuite, self).__init__() - self._set_tests(tests) - - def __iter__(self): - return iter(self._tests) - - def __repr__(self): - return "<%s tests=generator (%s)>" % ( - _strclass(self.__class__), id(self)) - - def __hash__(self): - return object.__hash__(self) - - __str__ = __repr__ - - def addTest(self, test): - self._precache.append(test) - - # added to bypass run changes in 2.7's unittest - def run(self, result): - for test in self._tests: - if result.shouldStop: - break - test(result) - return result - - def __nonzero__(self): - log.debug("tests in %s?", id(self)) - if self._precache: - return True - if self.test_generator is None: - return False - try: - test = self.test_generator.next() - if test is not None: - self._precache.append(test) - return True - except StopIteration: - pass - return False - - def _get_tests(self): - log.debug("precache is %s", self._precache) - for test in self._precache: - yield test - if self.test_generator is None: - return - for test in self.test_generator: - yield test - - def _set_tests(self, tests): - self._precache = [] - is_suite = isinstance(tests, unittest.TestSuite) - if callable(tests) and not is_suite: - self.test_generator = tests() - elif is_suite: - # Suites need special treatment: they must be called like - # tests for their setup/teardown to run (if any) - self.addTests([tests]) - self.test_generator = None - else: - self.addTests(tests) - self.test_generator = None - - _tests = property(_get_tests, _set_tests, None, - "Access the tests in this suite. Access is through a " - "generator, so iteration may not be repeatable.") - - -class ContextSuite(LazySuite): - """A suite with context. - - A ContextSuite executes fixtures (setup and teardown functions or - methods) for the context containing its tests. - - The context may be explicitly passed. If it is not, a context (or - nested set of contexts) will be constructed by examining the tests - in the suite. - """ - failureException = unittest.TestCase.failureException - was_setup = False - was_torndown = False - classSetup = ('setup_class', 'setup_all', 'setupClass', 'setupAll', - 'setUpClass', 'setUpAll') - classTeardown = ('teardown_class', 'teardown_all', 'teardownClass', - 'teardownAll', 'tearDownClass', 'tearDownAll') - moduleSetup = ('setup_module', 'setupModule', 'setUpModule', 'setup', - 'setUp') - moduleTeardown = ('teardown_module', 'teardownModule', 'tearDownModule', - 'teardown', 'tearDown') - packageSetup = ('setup_package', 'setupPackage', 'setUpPackage') - packageTeardown = ('teardown_package', 'teardownPackage', - 'tearDownPackage') - - def __init__(self, tests=(), context=None, factory=None, - config=None, resultProxy=None, can_split=True): - log.debug("Context suite for %s (%s) (%s)", tests, context, id(self)) - self.context = context - self.factory = factory - if config is None: - config = Config() - self.config = config - self.resultProxy = resultProxy - self.has_run = False - self.can_split = can_split - self.error_context = None - super(ContextSuite, self).__init__(tests) - - def __repr__(self): - return "<%s context=%s>" % ( - _strclass(self.__class__), - getattr(self.context, '__name__', self.context)) - __str__ = __repr__ - - def id(self): - if self.error_context: - return '%s:%s' % (repr(self), self.error_context) - else: - return repr(self) - - def __hash__(self): - return object.__hash__(self) - - # 2.3 compat -- force 2.4 call sequence - def __call__(self, *arg, **kw): - return self.run(*arg, **kw) - - def exc_info(self): - """Hook for replacing error tuple output - """ - return sys.exc_info() - - def _exc_info(self): - """Bottleneck to fix up IronPython string exceptions - """ - e = self.exc_info() - if sys.platform == 'cli': - if isinstance(e[0], StringException): - # IronPython throws these StringExceptions, but - # traceback checks type(etype) == str. Make a real - # string here. - e = (str(e[0]), e[1], e[2]) - - return e - - def run(self, result): - """Run tests in suite inside of suite fixtures. - """ - # proxy the result for myself - log.debug("suite %s (%s) run called, tests: %s", id(self), self, self._tests) - #import pdb - #pdb.set_trace() - if self.resultProxy: - result, orig = self.resultProxy(result, self), result - else: - result, orig = result, result - try: - self.setUp() - except KeyboardInterrupt: - raise - except: - self.error_context = 'setup' - result.addError(self, self._exc_info()) - return - try: - for test in self._tests: - if result.shouldStop: - log.debug("stopping") - break - # each nose.case.Test will create its own result proxy - # so the cases need the original result, to avoid proxy - # chains - test(orig) - finally: - self.has_run = True - try: - self.tearDown() - except KeyboardInterrupt: - raise - except: - self.error_context = 'teardown' - result.addError(self, self._exc_info()) - - def hasFixtures(self, ctx_callback=None): - context = self.context - if context is None: - return False - if self.implementsAnyFixture(context, ctx_callback=ctx_callback): - return True - # My context doesn't have any, but its ancestors might - factory = self.factory - if factory: - ancestors = factory.context.get(self, []) - for ancestor in ancestors: - if self.implementsAnyFixture( - ancestor, ctx_callback=ctx_callback): - return True - return False - - def implementsAnyFixture(self, context, ctx_callback): - if isclass(context): - names = self.classSetup + self.classTeardown - else: - names = self.moduleSetup + self.moduleTeardown - if hasattr(context, '__path__'): - names += self.packageSetup + self.packageTeardown - # If my context has any fixture attribute, I have fixtures - fixt = False - for m in names: - if hasattr(context, m): - fixt = True - break - if ctx_callback is None: - return fixt - return ctx_callback(context, fixt) - - def setUp(self): - log.debug("suite %s setUp called, tests: %s", id(self), self._tests) - if not self: - # I have no tests - log.debug("suite %s has no tests", id(self)) - return - if self.was_setup: - log.debug("suite %s already set up", id(self)) - return - context = self.context - if context is None: - return - # before running my own context's setup, I need to - # ask the factory if my context's contexts' setups have been run - factory = self.factory - if factory: - # get a copy, since we'll be destroying it as we go - ancestors = factory.context.get(self, [])[:] - while ancestors: - ancestor = ancestors.pop() - log.debug("ancestor %s may need setup", ancestor) - if ancestor in factory.was_setup: - continue - log.debug("ancestor %s does need setup", ancestor) - self.setupContext(ancestor) - if not context in factory.was_setup: - self.setupContext(context) - else: - self.setupContext(context) - self.was_setup = True - log.debug("completed suite setup") - - def setupContext(self, context): - self.config.plugins.startContext(context) - log.debug("%s setup context %s", self, context) - if self.factory: - if context in self.factory.was_setup: - return - # note that I ran the setup for this context, so that I'll run - # the teardown in my teardown - self.factory.was_setup[context] = self - if isclass(context): - names = self.classSetup - else: - names = self.moduleSetup - if hasattr(context, '__path__'): - names = self.packageSetup + names - try_run(context, names) - - def shortDescription(self): - if self.context is None: - return "test suite" - return "test suite for %s" % self.context - - def tearDown(self): - log.debug('context teardown') - if not self.was_setup or self.was_torndown: - log.debug( - "No reason to teardown (was_setup? %s was_torndown? %s)" - % (self.was_setup, self.was_torndown)) - return - self.was_torndown = True - context = self.context - if context is None: - log.debug("No context to tear down") - return - - # for each ancestor... if the ancestor was setup - # and I did the setup, I can do teardown - factory = self.factory - if factory: - ancestors = factory.context.get(self, []) + [context] - for ancestor in ancestors: - log.debug('ancestor %s may need teardown', ancestor) - if not ancestor in factory.was_setup: - log.debug('ancestor %s was not setup', ancestor) - continue - if ancestor in factory.was_torndown: - log.debug('ancestor %s already torn down', ancestor) - continue - setup = factory.was_setup[ancestor] - log.debug("%s setup ancestor %s", setup, ancestor) - if setup is self: - self.teardownContext(ancestor) - else: - self.teardownContext(context) - - def teardownContext(self, context): - log.debug("%s teardown context %s", self, context) - if self.factory: - if context in self.factory.was_torndown: - return - self.factory.was_torndown[context] = self - if isclass(context): - names = self.classTeardown - else: - names = self.moduleTeardown - if hasattr(context, '__path__'): - names = self.packageTeardown + names - try_run(context, names) - self.config.plugins.stopContext(context) - - # FIXME the wrapping has to move to the factory? - def _get_wrapped_tests(self): - for test in self._get_tests(): - if isinstance(test, Test) or isinstance(test, unittest.TestSuite): - yield test - else: - yield Test(test, - config=self.config, - resultProxy=self.resultProxy) - - _tests = property(_get_wrapped_tests, LazySuite._set_tests, None, - "Access the tests in this suite. Tests are returned " - "inside of a context wrapper.") - - -class ContextSuiteFactory(object): - """Factory for ContextSuites. Called with a collection of tests, - the factory decides on a hierarchy of contexts by introspecting - the collection or the tests themselves to find the objects - containing the test objects. It always returns one suite, but that - suite may consist of a hierarchy of nested suites. - """ - suiteClass = ContextSuite - def __init__(self, config=None, suiteClass=None, resultProxy=_def): - if config is None: - config = Config() - self.config = config - if suiteClass is not None: - self.suiteClass = suiteClass - # Using a singleton to represent default instead of None allows - # passing resultProxy=None to turn proxying off. - if resultProxy is _def: - resultProxy = ResultProxyFactory(config=config) - self.resultProxy = resultProxy - self.suites = {} - self.context = {} - self.was_setup = {} - self.was_torndown = {} - - def __call__(self, tests, **kw): - """Return ``ContextSuite`` for tests. ``tests`` may either - be a callable (in which case the resulting ContextSuite will - have no parent context and be evaluated lazily) or an - iterable. In that case the tests will wrapped in - nose.case.Test, be examined and the context of each found and a - suite of suites returned, organized into a stack with the - outermost suites belonging to the outermost contexts. - """ - log.debug("Create suite for %s", tests) - context = kw.pop('context', getattr(tests, 'context', None)) - log.debug("tests %s context %s", tests, context) - if context is None: - tests = self.wrapTests(tests) - try: - context = self.findContext(tests) - except MixedContextError: - return self.makeSuite(self.mixedSuites(tests), None, **kw) - return self.makeSuite(tests, context, **kw) - - def ancestry(self, context): - """Return the ancestry of the context (that is, all of the - packages and modules containing the context), in order of - descent with the outermost ancestor last. - This method is a generator. - """ - log.debug("get ancestry %s", context) - if context is None: - return - # Methods include reference to module they are defined in, we - # don't want that, instead want the module the class is in now - # (classes are re-ancestored elsewhere). - if hasattr(context, 'im_class'): - context = context.im_class - elif hasattr(context, '__self__'): - context = context.__self__.__class__ - if hasattr(context, '__module__'): - ancestors = context.__module__.split('.') - elif hasattr(context, '__name__'): - ancestors = context.__name__.split('.')[:-1] - else: - raise TypeError("%s has no ancestors?" % context) - while ancestors: - log.debug(" %s ancestors %s", context, ancestors) - yield resolve_name('.'.join(ancestors)) - ancestors.pop() - - def findContext(self, tests): - if callable(tests) or isinstance(tests, unittest.TestSuite): - return None - context = None - for test in tests: - # Don't look at suites for contexts, only tests - ctx = getattr(test, 'context', None) - if ctx is None: - continue - if context is None: - context = ctx - elif context != ctx: - raise MixedContextError( - "Tests with different contexts in same suite! %s != %s" - % (context, ctx)) - return context - - def makeSuite(self, tests, context, **kw): - suite = self.suiteClass( - tests, context=context, config=self.config, factory=self, - resultProxy=self.resultProxy, **kw) - if context is not None: - self.suites.setdefault(context, []).append(suite) - self.context.setdefault(suite, []).append(context) - log.debug("suite %s has context %s", suite, - getattr(context, '__name__', None)) - for ancestor in self.ancestry(context): - self.suites.setdefault(ancestor, []).append(suite) - self.context[suite].append(ancestor) - log.debug("suite %s has ancestor %s", suite, ancestor.__name__) - return suite - - def mixedSuites(self, tests): - """The complex case where there are tests that don't all share - the same context. Groups tests into suites with common ancestors, - according to the following (essentially tail-recursive) procedure: - - Starting with the context of the first test, if it is not - None, look for tests in the remaining tests that share that - ancestor. If any are found, group into a suite with that - ancestor as the context, and replace the current suite with - that suite. Continue this process for each ancestor of the - first test, until all ancestors have been processed. At this - point if any tests remain, recurse with those tests as the - input, returning a list of the common suite (which may be the - suite or test we started with, if no common tests were found) - plus the results of recursion. - """ - if not tests: - return [] - head = tests.pop(0) - if not tests: - return [head] # short circuit when none are left to combine - suite = head # the common ancestry suite, so far - tail = tests[:] - context = getattr(head, 'context', None) - if context is not None: - ancestors = [context] + [a for a in self.ancestry(context)] - for ancestor in ancestors: - common = [suite] # tests with ancestor in common, so far - remain = [] # tests that remain to be processed - for test in tail: - found_common = False - test_ctx = getattr(test, 'context', None) - if test_ctx is None: - remain.append(test) - continue - if test_ctx is ancestor: - common.append(test) - continue - for test_ancestor in self.ancestry(test_ctx): - if test_ancestor is ancestor: - common.append(test) - found_common = True - break - if not found_common: - remain.append(test) - if common: - suite = self.makeSuite(common, ancestor) - tail = self.mixedSuites(remain) - return [suite] + tail - - def wrapTests(self, tests): - log.debug("wrap %s", tests) - if callable(tests) or isinstance(tests, unittest.TestSuite): - log.debug("I won't wrap") - return tests - wrapped = [] - for test in tests: - log.debug("wrapping %s", test) - if isinstance(test, Test) or isinstance(test, unittest.TestSuite): - wrapped.append(test) - elif isinstance(test, ContextList): - wrapped.append(self.makeSuite(test, context=test.context)) - else: - wrapped.append( - Test(test, config=self.config, resultProxy=self.resultProxy) - ) - return wrapped - - -class ContextList(object): - """Not quite a suite -- a group of tests in a context. This is used - to hint the ContextSuiteFactory about what context the tests - belong to, in cases where it may be ambiguous or missing. - """ - def __init__(self, tests, context=None): - self.tests = tests - self.context = context - - def __iter__(self): - return iter(self.tests) - - -class FinalizingSuiteWrapper(unittest.TestSuite): - """Wraps suite and calls final function after suite has - executed. Used to call final functions in cases (like running in - the standard test runner) where test running is not under nose's - control. - """ - def __init__(self, suite, finalize): - super(FinalizingSuiteWrapper, self).__init__() - self.suite = suite - self.finalize = finalize - - def __call__(self, *arg, **kw): - return self.run(*arg, **kw) - - # 2.7 compat - def __iter__(self): - return iter(self.suite) - - def run(self, *arg, **kw): - try: - return self.suite(*arg, **kw) - finally: - self.finalize(*arg, **kw) - - -# backwards compat -- sort of -class TestDir: - def __init__(*arg, **kw): - raise NotImplementedError( - "TestDir is not usable with nose 0.10. The class is present " - "in nose.suite for backwards compatibility purposes but it " - "may not be used.") - - -class TestModule: - def __init__(*arg, **kw): - raise NotImplementedError( - "TestModule is not usable with nose 0.10. The class is present " - "in nose.suite for backwards compatibility purposes but it " - "may not be used.") |