mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 21:32:31 +00:00
python-3.6.zip added from Github
README.cosmo contains the necessary links.
This commit is contained in:
parent
75fc601ff5
commit
0c4c56ff39
4219 changed files with 1968626 additions and 0 deletions
78
third_party/python/Lib/unittest/__init__.py
vendored
Normal file
78
third_party/python/Lib/unittest/__init__.py
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
"""
|
||||
Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
|
||||
Smalltalk testing framework (used with permission).
|
||||
|
||||
This module contains the core framework classes that form the basis of
|
||||
specific test cases and suites (TestCase, TestSuite etc.), and also a
|
||||
text-based utility class for running the tests and reporting the results
|
||||
(TextTestRunner).
|
||||
|
||||
Simple usage:
|
||||
|
||||
import unittest
|
||||
|
||||
class IntegerArithmeticTestCase(unittest.TestCase):
|
||||
def testAdd(self): # test method names begin with 'test'
|
||||
self.assertEqual((1 + 2), 3)
|
||||
self.assertEqual(0 + 1, 1)
|
||||
def testMultiply(self):
|
||||
self.assertEqual((0 * 10), 0)
|
||||
self.assertEqual((5 * 8), 40)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Further information is available in the bundled documentation, and from
|
||||
|
||||
http://docs.python.org/library/unittest.html
|
||||
|
||||
Copyright (c) 1999-2003 Steve Purcell
|
||||
Copyright (c) 2003-2010 Python Software Foundation
|
||||
This module is free software, and you may redistribute it and/or modify
|
||||
it under the same terms as Python itself, so long as this copyright message
|
||||
and disclaimer are retained in their original form.
|
||||
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
|
||||
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
|
||||
THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
|
||||
AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
|
||||
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
"""
|
||||
|
||||
__all__ = ['TestResult', 'TestCase', 'TestSuite',
|
||||
'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main',
|
||||
'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
|
||||
'expectedFailure', 'TextTestResult', 'installHandler',
|
||||
'registerResult', 'removeResult', 'removeHandler']
|
||||
|
||||
# Expose obsolete functions for backwards compatibility
|
||||
__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
|
||||
|
||||
__unittest = True
|
||||
|
||||
from .result import TestResult
|
||||
from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf,
|
||||
skipUnless, expectedFailure)
|
||||
from .suite import BaseTestSuite, TestSuite
|
||||
from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames,
|
||||
findTestCases)
|
||||
from .main import TestProgram, main
|
||||
from .runner import TextTestRunner, TextTestResult
|
||||
from .signals import installHandler, registerResult, removeResult, removeHandler
|
||||
|
||||
# deprecated
|
||||
_TextTestResult = TextTestResult
|
||||
|
||||
# There are no tests here, so don't try to run anything discovered from
|
||||
# introspecting the symbols (e.g. FunctionTestCase). Instead, all our
|
||||
# tests come from within unittest.test.
|
||||
def load_tests(loader, tests, pattern):
|
||||
import os.path
|
||||
# top level directory cached on loader instance
|
||||
this_dir = os.path.dirname(__file__)
|
||||
return loader.discover(start_dir=this_dir, pattern=pattern)
|
18
third_party/python/Lib/unittest/__main__.py
vendored
Normal file
18
third_party/python/Lib/unittest/__main__.py
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
"""Main entry point"""
|
||||
|
||||
import sys
|
||||
if sys.argv[0].endswith("__main__.py"):
|
||||
import os.path
|
||||
# We change sys.argv[0] to make help message more useful
|
||||
# use executable without path, unquoted
|
||||
# (it's just a hint anyway)
|
||||
# (if you have spaces in your executable you get what you deserve!)
|
||||
executable = os.path.basename(sys.executable)
|
||||
sys.argv[0] = executable + " -m unittest"
|
||||
del os
|
||||
|
||||
__unittest = True
|
||||
|
||||
from .main import main, TestProgram
|
||||
|
||||
main(module=None)
|
1429
third_party/python/Lib/unittest/case.py
vendored
Normal file
1429
third_party/python/Lib/unittest/case.py
vendored
Normal file
File diff suppressed because it is too large
Load diff
508
third_party/python/Lib/unittest/loader.py
vendored
Normal file
508
third_party/python/Lib/unittest/loader.py
vendored
Normal file
|
@ -0,0 +1,508 @@
|
|||
"""Loading unittests."""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import traceback
|
||||
import types
|
||||
import functools
|
||||
import warnings
|
||||
|
||||
from fnmatch import fnmatch
|
||||
|
||||
from . import case, suite, util
|
||||
|
||||
__unittest = True
|
||||
|
||||
# what about .pyc (etc)
|
||||
# we would need to avoid loading the same tests multiple times
|
||||
# from '.py', *and* '.pyc'
|
||||
VALID_MODULE_NAME = re.compile(r'[_a-z]\w*\.py$', re.IGNORECASE)
|
||||
|
||||
|
||||
class _FailedTest(case.TestCase):
|
||||
_testMethodName = None
|
||||
|
||||
def __init__(self, method_name, exception):
|
||||
self._exception = exception
|
||||
super(_FailedTest, self).__init__(method_name)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name != self._testMethodName:
|
||||
return super(_FailedTest, self).__getattr__(name)
|
||||
def testFailure():
|
||||
raise self._exception
|
||||
return testFailure
|
||||
|
||||
|
||||
def _make_failed_import_test(name, suiteClass):
|
||||
message = 'Failed to import test module: %s\n%s' % (
|
||||
name, traceback.format_exc())
|
||||
return _make_failed_test(name, ImportError(message), suiteClass, message)
|
||||
|
||||
def _make_failed_load_tests(name, exception, suiteClass):
|
||||
message = 'Failed to call load_tests:\n%s' % (traceback.format_exc(),)
|
||||
return _make_failed_test(
|
||||
name, exception, suiteClass, message)
|
||||
|
||||
def _make_failed_test(methodname, exception, suiteClass, message):
|
||||
test = _FailedTest(methodname, exception)
|
||||
return suiteClass((test,)), message
|
||||
|
||||
def _make_skipped_test(methodname, exception, suiteClass):
|
||||
@case.skip(str(exception))
|
||||
def testSkipped(self):
|
||||
pass
|
||||
attrs = {methodname: testSkipped}
|
||||
TestClass = type("ModuleSkipped", (case.TestCase,), attrs)
|
||||
return suiteClass((TestClass(methodname),))
|
||||
|
||||
def _jython_aware_splitext(path):
|
||||
if path.lower().endswith('$py.class'):
|
||||
return path[:-9]
|
||||
return os.path.splitext(path)[0]
|
||||
|
||||
|
||||
class TestLoader(object):
|
||||
"""
|
||||
This class is responsible for loading tests according to various criteria
|
||||
and returning them wrapped in a TestSuite
|
||||
"""
|
||||
testMethodPrefix = 'test'
|
||||
sortTestMethodsUsing = staticmethod(util.three_way_cmp)
|
||||
suiteClass = suite.TestSuite
|
||||
_top_level_dir = None
|
||||
|
||||
def __init__(self):
|
||||
super(TestLoader, self).__init__()
|
||||
self.errors = []
|
||||
# Tracks packages which we have called into via load_tests, to
|
||||
# avoid infinite re-entrancy.
|
||||
self._loading_packages = set()
|
||||
|
||||
def loadTestsFromTestCase(self, testCaseClass):
|
||||
"""Return a suite of all test cases contained in testCaseClass"""
|
||||
if issubclass(testCaseClass, suite.TestSuite):
|
||||
raise TypeError("Test cases should not be derived from "
|
||||
"TestSuite. Maybe you meant to derive from "
|
||||
"TestCase?")
|
||||
testCaseNames = self.getTestCaseNames(testCaseClass)
|
||||
if not testCaseNames and hasattr(testCaseClass, 'runTest'):
|
||||
testCaseNames = ['runTest']
|
||||
loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
|
||||
return loaded_suite
|
||||
|
||||
# XXX After Python 3.5, remove backward compatibility hacks for
|
||||
# use_load_tests deprecation via *args and **kws. See issue 16662.
|
||||
def loadTestsFromModule(self, module, *args, pattern=None, **kws):
|
||||
"""Return a suite of all test cases contained in the given module"""
|
||||
# This method used to take an undocumented and unofficial
|
||||
# use_load_tests argument. For backward compatibility, we still
|
||||
# accept the argument (which can also be the first position) but we
|
||||
# ignore it and issue a deprecation warning if it's present.
|
||||
if len(args) > 0 or 'use_load_tests' in kws:
|
||||
warnings.warn('use_load_tests is deprecated and ignored',
|
||||
DeprecationWarning)
|
||||
kws.pop('use_load_tests', None)
|
||||
if len(args) > 1:
|
||||
# Complain about the number of arguments, but don't forget the
|
||||
# required `module` argument.
|
||||
complaint = len(args) + 1
|
||||
raise TypeError('loadTestsFromModule() takes 1 positional argument but {} were given'.format(complaint))
|
||||
if len(kws) != 0:
|
||||
# Since the keyword arguments are unsorted (see PEP 468), just
|
||||
# pick the alphabetically sorted first argument to complain about,
|
||||
# if multiple were given. At least the error message will be
|
||||
# predictable.
|
||||
complaint = sorted(kws)[0]
|
||||
raise TypeError("loadTestsFromModule() got an unexpected keyword argument '{}'".format(complaint))
|
||||
tests = []
|
||||
for name in dir(module):
|
||||
obj = getattr(module, name)
|
||||
if isinstance(obj, type) and issubclass(obj, case.TestCase):
|
||||
tests.append(self.loadTestsFromTestCase(obj))
|
||||
|
||||
load_tests = getattr(module, 'load_tests', None)
|
||||
tests = self.suiteClass(tests)
|
||||
if load_tests is not None:
|
||||
try:
|
||||
return load_tests(self, tests, pattern)
|
||||
except Exception as e:
|
||||
error_case, error_message = _make_failed_load_tests(
|
||||
module.__name__, e, self.suiteClass)
|
||||
self.errors.append(error_message)
|
||||
return error_case
|
||||
return tests
|
||||
|
||||
def loadTestsFromName(self, name, module=None):
|
||||
"""Return a suite of all test cases given a string specifier.
|
||||
|
||||
The name may resolve either to a module, a test case class, a
|
||||
test method within a test case class, or a callable object which
|
||||
returns a TestCase or TestSuite instance.
|
||||
|
||||
The method optionally resolves the names relative to a given module.
|
||||
"""
|
||||
parts = name.split('.')
|
||||
error_case, error_message = None, None
|
||||
if module is None:
|
||||
parts_copy = parts[:]
|
||||
while parts_copy:
|
||||
try:
|
||||
module_name = '.'.join(parts_copy)
|
||||
module = __import__(module_name)
|
||||
break
|
||||
except ImportError:
|
||||
next_attribute = parts_copy.pop()
|
||||
# Last error so we can give it to the user if needed.
|
||||
error_case, error_message = _make_failed_import_test(
|
||||
next_attribute, self.suiteClass)
|
||||
if not parts_copy:
|
||||
# Even the top level import failed: report that error.
|
||||
self.errors.append(error_message)
|
||||
return error_case
|
||||
parts = parts[1:]
|
||||
obj = module
|
||||
for part in parts:
|
||||
try:
|
||||
parent, obj = obj, getattr(obj, part)
|
||||
except AttributeError as e:
|
||||
# We can't traverse some part of the name.
|
||||
if (getattr(obj, '__path__', None) is not None
|
||||
and error_case is not None):
|
||||
# This is a package (no __path__ per importlib docs), and we
|
||||
# encountered an error importing something. We cannot tell
|
||||
# the difference between package.WrongNameTestClass and
|
||||
# package.wrong_module_name so we just report the
|
||||
# ImportError - it is more informative.
|
||||
self.errors.append(error_message)
|
||||
return error_case
|
||||
else:
|
||||
# Otherwise, we signal that an AttributeError has occurred.
|
||||
error_case, error_message = _make_failed_test(
|
||||
part, e, self.suiteClass,
|
||||
'Failed to access attribute:\n%s' % (
|
||||
traceback.format_exc(),))
|
||||
self.errors.append(error_message)
|
||||
return error_case
|
||||
|
||||
if isinstance(obj, types.ModuleType):
|
||||
return self.loadTestsFromModule(obj)
|
||||
elif isinstance(obj, type) and issubclass(obj, case.TestCase):
|
||||
return self.loadTestsFromTestCase(obj)
|
||||
elif (isinstance(obj, types.FunctionType) and
|
||||
isinstance(parent, type) and
|
||||
issubclass(parent, case.TestCase)):
|
||||
name = parts[-1]
|
||||
inst = parent(name)
|
||||
# static methods follow a different path
|
||||
if not isinstance(getattr(inst, name), types.FunctionType):
|
||||
return self.suiteClass([inst])
|
||||
elif isinstance(obj, suite.TestSuite):
|
||||
return obj
|
||||
if callable(obj):
|
||||
test = obj()
|
||||
if isinstance(test, suite.TestSuite):
|
||||
return test
|
||||
elif isinstance(test, case.TestCase):
|
||||
return self.suiteClass([test])
|
||||
else:
|
||||
raise TypeError("calling %s returned %s, not a test" %
|
||||
(obj, test))
|
||||
else:
|
||||
raise TypeError("don't know how to make test from: %s" % obj)
|
||||
|
||||
def loadTestsFromNames(self, names, module=None):
|
||||
"""Return a suite of all test cases found using the given sequence
|
||||
of string specifiers. See 'loadTestsFromName()'.
|
||||
"""
|
||||
suites = [self.loadTestsFromName(name, module) for name in names]
|
||||
return self.suiteClass(suites)
|
||||
|
||||
def getTestCaseNames(self, testCaseClass):
|
||||
"""Return a sorted sequence of method names found within testCaseClass
|
||||
"""
|
||||
def isTestMethod(attrname, testCaseClass=testCaseClass,
|
||||
prefix=self.testMethodPrefix):
|
||||
return attrname.startswith(prefix) and \
|
||||
callable(getattr(testCaseClass, attrname))
|
||||
testFnNames = list(filter(isTestMethod, dir(testCaseClass)))
|
||||
if self.sortTestMethodsUsing:
|
||||
testFnNames.sort(key=functools.cmp_to_key(self.sortTestMethodsUsing))
|
||||
return testFnNames
|
||||
|
||||
def discover(self, start_dir, pattern='test*.py', top_level_dir=None):
|
||||
"""Find and return all test modules from the specified start
|
||||
directory, recursing into subdirectories to find them and return all
|
||||
tests found within them. Only test files that match the pattern will
|
||||
be loaded. (Using shell style pattern matching.)
|
||||
|
||||
All test modules must be importable from the top level of the project.
|
||||
If the start directory is not the top level directory then the top
|
||||
level directory must be specified separately.
|
||||
|
||||
If a test package name (directory with '__init__.py') matches the
|
||||
pattern then the package will be checked for a 'load_tests' function. If
|
||||
this exists then it will be called with (loader, tests, pattern) unless
|
||||
the package has already had load_tests called from the same discovery
|
||||
invocation, in which case the package module object is not scanned for
|
||||
tests - this ensures that when a package uses discover to further
|
||||
discover child tests that infinite recursion does not happen.
|
||||
|
||||
If load_tests exists then discovery does *not* recurse into the package,
|
||||
load_tests is responsible for loading all tests in the package.
|
||||
|
||||
The pattern is deliberately not stored as a loader attribute so that
|
||||
packages can continue discovery themselves. top_level_dir is stored so
|
||||
load_tests does not need to pass this argument in to loader.discover().
|
||||
|
||||
Paths are sorted before being imported to ensure reproducible execution
|
||||
order even on filesystems with non-alphabetical ordering like ext3/4.
|
||||
"""
|
||||
set_implicit_top = False
|
||||
if top_level_dir is None and self._top_level_dir is not None:
|
||||
# make top_level_dir optional if called from load_tests in a package
|
||||
top_level_dir = self._top_level_dir
|
||||
elif top_level_dir is None:
|
||||
set_implicit_top = True
|
||||
top_level_dir = start_dir
|
||||
|
||||
top_level_dir = os.path.abspath(top_level_dir)
|
||||
|
||||
if not top_level_dir in sys.path:
|
||||
# all test modules must be importable from the top level directory
|
||||
# should we *unconditionally* put the start directory in first
|
||||
# in sys.path to minimise likelihood of conflicts between installed
|
||||
# modules and development versions?
|
||||
sys.path.insert(0, top_level_dir)
|
||||
self._top_level_dir = top_level_dir
|
||||
|
||||
is_not_importable = False
|
||||
is_namespace = False
|
||||
tests = []
|
||||
if os.path.isdir(os.path.abspath(start_dir)):
|
||||
start_dir = os.path.abspath(start_dir)
|
||||
if start_dir != top_level_dir:
|
||||
is_not_importable = not os.path.isfile(os.path.join(start_dir, '__init__.py'))
|
||||
else:
|
||||
# support for discovery from dotted module names
|
||||
try:
|
||||
__import__(start_dir)
|
||||
except ImportError:
|
||||
is_not_importable = True
|
||||
else:
|
||||
the_module = sys.modules[start_dir]
|
||||
top_part = start_dir.split('.')[0]
|
||||
try:
|
||||
start_dir = os.path.abspath(
|
||||
os.path.dirname((the_module.__file__)))
|
||||
except AttributeError:
|
||||
# look for namespace packages
|
||||
try:
|
||||
spec = the_module.__spec__
|
||||
except AttributeError:
|
||||
spec = None
|
||||
|
||||
if spec and spec.loader is None:
|
||||
if spec.submodule_search_locations is not None:
|
||||
is_namespace = True
|
||||
|
||||
for path in the_module.__path__:
|
||||
if (not set_implicit_top and
|
||||
not path.startswith(top_level_dir)):
|
||||
continue
|
||||
self._top_level_dir = \
|
||||
(path.split(the_module.__name__
|
||||
.replace(".", os.path.sep))[0])
|
||||
tests.extend(self._find_tests(path,
|
||||
pattern,
|
||||
namespace=True))
|
||||
elif the_module.__name__ in sys.builtin_module_names:
|
||||
# builtin module
|
||||
raise TypeError('Can not use builtin modules '
|
||||
'as dotted module names') from None
|
||||
else:
|
||||
raise TypeError(
|
||||
'don\'t know how to discover from {!r}'
|
||||
.format(the_module)) from None
|
||||
|
||||
if set_implicit_top:
|
||||
if not is_namespace:
|
||||
self._top_level_dir = \
|
||||
self._get_directory_containing_module(top_part)
|
||||
sys.path.remove(top_level_dir)
|
||||
else:
|
||||
sys.path.remove(top_level_dir)
|
||||
|
||||
if is_not_importable:
|
||||
raise ImportError('Start directory is not importable: %r' % start_dir)
|
||||
|
||||
if not is_namespace:
|
||||
tests = list(self._find_tests(start_dir, pattern))
|
||||
return self.suiteClass(tests)
|
||||
|
||||
def _get_directory_containing_module(self, module_name):
|
||||
module = sys.modules[module_name]
|
||||
full_path = os.path.abspath(module.__file__)
|
||||
|
||||
if os.path.basename(full_path).lower().startswith('__init__.py'):
|
||||
return os.path.dirname(os.path.dirname(full_path))
|
||||
else:
|
||||
# here we have been given a module rather than a package - so
|
||||
# all we can do is search the *same* directory the module is in
|
||||
# should an exception be raised instead
|
||||
return os.path.dirname(full_path)
|
||||
|
||||
def _get_name_from_path(self, path):
|
||||
if path == self._top_level_dir:
|
||||
return '.'
|
||||
path = _jython_aware_splitext(os.path.normpath(path))
|
||||
|
||||
_relpath = os.path.relpath(path, self._top_level_dir)
|
||||
assert not os.path.isabs(_relpath), "Path must be within the project"
|
||||
assert not _relpath.startswith('..'), "Path must be within the project"
|
||||
|
||||
name = _relpath.replace(os.path.sep, '.')
|
||||
return name
|
||||
|
||||
def _get_module_from_name(self, name):
|
||||
__import__(name)
|
||||
return sys.modules[name]
|
||||
|
||||
def _match_path(self, path, full_path, pattern):
|
||||
# override this method to use alternative matching strategy
|
||||
return fnmatch(path, pattern)
|
||||
|
||||
def _find_tests(self, start_dir, pattern, namespace=False):
|
||||
"""Used by discovery. Yields test suites it loads."""
|
||||
# Handle the __init__ in this package
|
||||
name = self._get_name_from_path(start_dir)
|
||||
# name is '.' when start_dir == top_level_dir (and top_level_dir is by
|
||||
# definition not a package).
|
||||
if name != '.' and name not in self._loading_packages:
|
||||
# name is in self._loading_packages while we have called into
|
||||
# loadTestsFromModule with name.
|
||||
tests, should_recurse = self._find_test_path(
|
||||
start_dir, pattern, namespace)
|
||||
if tests is not None:
|
||||
yield tests
|
||||
if not should_recurse:
|
||||
# Either an error occurred, or load_tests was used by the
|
||||
# package.
|
||||
return
|
||||
# Handle the contents.
|
||||
paths = sorted(os.listdir(start_dir))
|
||||
for path in paths:
|
||||
full_path = os.path.join(start_dir, path)
|
||||
tests, should_recurse = self._find_test_path(
|
||||
full_path, pattern, namespace)
|
||||
if tests is not None:
|
||||
yield tests
|
||||
if should_recurse:
|
||||
# we found a package that didn't use load_tests.
|
||||
name = self._get_name_from_path(full_path)
|
||||
self._loading_packages.add(name)
|
||||
try:
|
||||
yield from self._find_tests(full_path, pattern, namespace)
|
||||
finally:
|
||||
self._loading_packages.discard(name)
|
||||
|
||||
def _find_test_path(self, full_path, pattern, namespace=False):
|
||||
"""Used by discovery.
|
||||
|
||||
Loads tests from a single file, or a directories' __init__.py when
|
||||
passed the directory.
|
||||
|
||||
Returns a tuple (None_or_tests_from_file, should_recurse).
|
||||
"""
|
||||
basename = os.path.basename(full_path)
|
||||
if os.path.isfile(full_path):
|
||||
if not VALID_MODULE_NAME.match(basename):
|
||||
# valid Python identifiers only
|
||||
return None, False
|
||||
if not self._match_path(basename, full_path, pattern):
|
||||
return None, False
|
||||
# if the test file matches, load it
|
||||
name = self._get_name_from_path(full_path)
|
||||
try:
|
||||
module = self._get_module_from_name(name)
|
||||
except case.SkipTest as e:
|
||||
return _make_skipped_test(name, e, self.suiteClass), False
|
||||
except:
|
||||
error_case, error_message = \
|
||||
_make_failed_import_test(name, self.suiteClass)
|
||||
self.errors.append(error_message)
|
||||
return error_case, False
|
||||
else:
|
||||
mod_file = os.path.abspath(
|
||||
getattr(module, '__file__', full_path))
|
||||
realpath = _jython_aware_splitext(
|
||||
os.path.realpath(mod_file))
|
||||
fullpath_noext = _jython_aware_splitext(
|
||||
os.path.realpath(full_path))
|
||||
if realpath.lower() != fullpath_noext.lower():
|
||||
module_dir = os.path.dirname(realpath)
|
||||
mod_name = _jython_aware_splitext(
|
||||
os.path.basename(full_path))
|
||||
expected_dir = os.path.dirname(full_path)
|
||||
msg = ("%r module incorrectly imported from %r. Expected "
|
||||
"%r. Is this module globally installed?")
|
||||
raise ImportError(
|
||||
msg % (mod_name, module_dir, expected_dir))
|
||||
return self.loadTestsFromModule(module, pattern=pattern), False
|
||||
elif os.path.isdir(full_path):
|
||||
if (not namespace and
|
||||
not os.path.isfile(os.path.join(full_path, '__init__.py'))):
|
||||
return None, False
|
||||
|
||||
load_tests = None
|
||||
tests = None
|
||||
name = self._get_name_from_path(full_path)
|
||||
try:
|
||||
package = self._get_module_from_name(name)
|
||||
except case.SkipTest as e:
|
||||
return _make_skipped_test(name, e, self.suiteClass), False
|
||||
except:
|
||||
error_case, error_message = \
|
||||
_make_failed_import_test(name, self.suiteClass)
|
||||
self.errors.append(error_message)
|
||||
return error_case, False
|
||||
else:
|
||||
load_tests = getattr(package, 'load_tests', None)
|
||||
# Mark this package as being in load_tests (possibly ;))
|
||||
self._loading_packages.add(name)
|
||||
try:
|
||||
tests = self.loadTestsFromModule(package, pattern=pattern)
|
||||
if load_tests is not None:
|
||||
# loadTestsFromModule(package) has loaded tests for us.
|
||||
return tests, False
|
||||
return tests, True
|
||||
finally:
|
||||
self._loading_packages.discard(name)
|
||||
else:
|
||||
return None, False
|
||||
|
||||
|
||||
defaultTestLoader = TestLoader()
|
||||
|
||||
|
||||
def _makeLoader(prefix, sortUsing, suiteClass=None):
|
||||
loader = TestLoader()
|
||||
loader.sortTestMethodsUsing = sortUsing
|
||||
loader.testMethodPrefix = prefix
|
||||
if suiteClass:
|
||||
loader.suiteClass = suiteClass
|
||||
return loader
|
||||
|
||||
def getTestCaseNames(testCaseClass, prefix, sortUsing=util.three_way_cmp):
|
||||
return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
|
||||
|
||||
def makeSuite(testCaseClass, prefix='test', sortUsing=util.three_way_cmp,
|
||||
suiteClass=suite.TestSuite):
|
||||
return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(
|
||||
testCaseClass)
|
||||
|
||||
def findTestCases(module, prefix='test', sortUsing=util.three_way_cmp,
|
||||
suiteClass=suite.TestSuite):
|
||||
return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(\
|
||||
module)
|
260
third_party/python/Lib/unittest/main.py
vendored
Normal file
260
third_party/python/Lib/unittest/main.py
vendored
Normal file
|
@ -0,0 +1,260 @@
|
|||
"""Unittest main program"""
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import os
|
||||
|
||||
from . import loader, runner
|
||||
from .signals import installHandler
|
||||
|
||||
__unittest = True
|
||||
|
||||
MAIN_EXAMPLES = """\
|
||||
Examples:
|
||||
%(prog)s test_module - run tests from test_module
|
||||
%(prog)s module.TestClass - run tests from module.TestClass
|
||||
%(prog)s module.Class.test_method - run specified test method
|
||||
%(prog)s path/to/test_file.py - run tests from test_file.py
|
||||
"""
|
||||
|
||||
MODULE_EXAMPLES = """\
|
||||
Examples:
|
||||
%(prog)s - run default set of tests
|
||||
%(prog)s MyTestSuite - run suite 'MyTestSuite'
|
||||
%(prog)s MyTestCase.testSomething - run MyTestCase.testSomething
|
||||
%(prog)s MyTestCase - run all 'test*' test methods
|
||||
in MyTestCase
|
||||
"""
|
||||
|
||||
def _convert_name(name):
|
||||
# on Linux / Mac OS X 'foo.PY' is not importable, but on
|
||||
# Windows it is. Simpler to do a case insensitive match
|
||||
# a better check would be to check that the name is a
|
||||
# valid Python module name.
|
||||
if os.path.isfile(name) and name.lower().endswith('.py'):
|
||||
if os.path.isabs(name):
|
||||
rel_path = os.path.relpath(name, os.getcwd())
|
||||
if os.path.isabs(rel_path) or rel_path.startswith(os.pardir):
|
||||
return name
|
||||
name = rel_path
|
||||
# on Windows both '\' and '/' are used as path
|
||||
# separators. Better to replace both than rely on os.path.sep
|
||||
return name[:-3].replace('\\', '.').replace('/', '.')
|
||||
return name
|
||||
|
||||
def _convert_names(names):
|
||||
return [_convert_name(name) for name in names]
|
||||
|
||||
|
||||
class TestProgram(object):
|
||||
"""A command-line program that runs a set of tests; this is primarily
|
||||
for making test modules conveniently executable.
|
||||
"""
|
||||
# defaults for testing
|
||||
module=None
|
||||
verbosity = 1
|
||||
failfast = catchbreak = buffer = progName = warnings = None
|
||||
_discovery_parser = None
|
||||
|
||||
def __init__(self, module='__main__', defaultTest=None, argv=None,
|
||||
testRunner=None, testLoader=loader.defaultTestLoader,
|
||||
exit=True, verbosity=1, failfast=None, catchbreak=None,
|
||||
buffer=None, warnings=None, *, tb_locals=False):
|
||||
if isinstance(module, str):
|
||||
self.module = __import__(module)
|
||||
for part in module.split('.')[1:]:
|
||||
self.module = getattr(self.module, part)
|
||||
else:
|
||||
self.module = module
|
||||
if argv is None:
|
||||
argv = sys.argv
|
||||
|
||||
self.exit = exit
|
||||
self.failfast = failfast
|
||||
self.catchbreak = catchbreak
|
||||
self.verbosity = verbosity
|
||||
self.buffer = buffer
|
||||
self.tb_locals = tb_locals
|
||||
if warnings is None and not sys.warnoptions:
|
||||
# even if DeprecationWarnings are ignored by default
|
||||
# print them anyway unless other warnings settings are
|
||||
# specified by the warnings arg or the -W python flag
|
||||
self.warnings = 'default'
|
||||
else:
|
||||
# here self.warnings is set either to the value passed
|
||||
# to the warnings args or to None.
|
||||
# If the user didn't pass a value self.warnings will
|
||||
# be None. This means that the behavior is unchanged
|
||||
# and depends on the values passed to -W.
|
||||
self.warnings = warnings
|
||||
self.defaultTest = defaultTest
|
||||
self.testRunner = testRunner
|
||||
self.testLoader = testLoader
|
||||
self.progName = os.path.basename(argv[0])
|
||||
self.parseArgs(argv)
|
||||
self.runTests()
|
||||
|
||||
def usageExit(self, msg=None):
|
||||
if msg:
|
||||
print(msg)
|
||||
if self._discovery_parser is None:
|
||||
self._initArgParsers()
|
||||
self._print_help()
|
||||
sys.exit(2)
|
||||
|
||||
def _print_help(self, *args, **kwargs):
|
||||
if self.module is None:
|
||||
print(self._main_parser.format_help())
|
||||
print(MAIN_EXAMPLES % {'prog': self.progName})
|
||||
self._discovery_parser.print_help()
|
||||
else:
|
||||
print(self._main_parser.format_help())
|
||||
print(MODULE_EXAMPLES % {'prog': self.progName})
|
||||
|
||||
def parseArgs(self, argv):
|
||||
self._initArgParsers()
|
||||
if self.module is None:
|
||||
if len(argv) > 1 and argv[1].lower() == 'discover':
|
||||
self._do_discovery(argv[2:])
|
||||
return
|
||||
self._main_parser.parse_args(argv[1:], self)
|
||||
if not self.tests:
|
||||
# this allows "python -m unittest -v" to still work for
|
||||
# test discovery.
|
||||
self._do_discovery([])
|
||||
return
|
||||
else:
|
||||
self._main_parser.parse_args(argv[1:], self)
|
||||
|
||||
if self.tests:
|
||||
self.testNames = _convert_names(self.tests)
|
||||
if __name__ == '__main__':
|
||||
# to support python -m unittest ...
|
||||
self.module = None
|
||||
elif self.defaultTest is None:
|
||||
# createTests will load tests from self.module
|
||||
self.testNames = None
|
||||
elif isinstance(self.defaultTest, str):
|
||||
self.testNames = (self.defaultTest,)
|
||||
else:
|
||||
self.testNames = list(self.defaultTest)
|
||||
self.createTests()
|
||||
|
||||
def createTests(self):
|
||||
if self.testNames is None:
|
||||
self.test = self.testLoader.loadTestsFromModule(self.module)
|
||||
else:
|
||||
self.test = self.testLoader.loadTestsFromNames(self.testNames,
|
||||
self.module)
|
||||
|
||||
def _initArgParsers(self):
|
||||
parent_parser = self._getParentArgParser()
|
||||
self._main_parser = self._getMainArgParser(parent_parser)
|
||||
self._discovery_parser = self._getDiscoveryArgParser(parent_parser)
|
||||
|
||||
def _getParentArgParser(self):
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
|
||||
parser.add_argument('-v', '--verbose', dest='verbosity',
|
||||
action='store_const', const=2,
|
||||
help='Verbose output')
|
||||
parser.add_argument('-q', '--quiet', dest='verbosity',
|
||||
action='store_const', const=0,
|
||||
help='Quiet output')
|
||||
parser.add_argument('--locals', dest='tb_locals',
|
||||
action='store_true',
|
||||
help='Show local variables in tracebacks')
|
||||
if self.failfast is None:
|
||||
parser.add_argument('-f', '--failfast', dest='failfast',
|
||||
action='store_true',
|
||||
help='Stop on first fail or error')
|
||||
self.failfast = False
|
||||
if self.catchbreak is None:
|
||||
parser.add_argument('-c', '--catch', dest='catchbreak',
|
||||
action='store_true',
|
||||
help='Catch Ctrl-C and display results so far')
|
||||
self.catchbreak = False
|
||||
if self.buffer is None:
|
||||
parser.add_argument('-b', '--buffer', dest='buffer',
|
||||
action='store_true',
|
||||
help='Buffer stdout and stderr during tests')
|
||||
self.buffer = False
|
||||
|
||||
return parser
|
||||
|
||||
def _getMainArgParser(self, parent):
|
||||
parser = argparse.ArgumentParser(parents=[parent])
|
||||
parser.prog = self.progName
|
||||
parser.print_help = self._print_help
|
||||
|
||||
parser.add_argument('tests', nargs='*',
|
||||
help='a list of any number of test modules, '
|
||||
'classes and test methods.')
|
||||
|
||||
return parser
|
||||
|
||||
def _getDiscoveryArgParser(self, parent):
|
||||
parser = argparse.ArgumentParser(parents=[parent])
|
||||
parser.prog = '%s discover' % self.progName
|
||||
parser.epilog = ('For test discovery all test modules must be '
|
||||
'importable from the top level directory of the '
|
||||
'project.')
|
||||
|
||||
parser.add_argument('-s', '--start-directory', dest='start',
|
||||
help="Directory to start discovery ('.' default)")
|
||||
parser.add_argument('-p', '--pattern', dest='pattern',
|
||||
help="Pattern to match tests ('test*.py' default)")
|
||||
parser.add_argument('-t', '--top-level-directory', dest='top',
|
||||
help='Top level directory of project (defaults to '
|
||||
'start directory)')
|
||||
for arg in ('start', 'pattern', 'top'):
|
||||
parser.add_argument(arg, nargs='?',
|
||||
default=argparse.SUPPRESS,
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
return parser
|
||||
|
||||
def _do_discovery(self, argv, Loader=None):
|
||||
self.start = '.'
|
||||
self.pattern = 'test*.py'
|
||||
self.top = None
|
||||
if argv is not None:
|
||||
# handle command line args for test discovery
|
||||
if self._discovery_parser is None:
|
||||
# for testing
|
||||
self._initArgParsers()
|
||||
self._discovery_parser.parse_args(argv, self)
|
||||
|
||||
loader = self.testLoader if Loader is None else Loader()
|
||||
self.test = loader.discover(self.start, self.pattern, self.top)
|
||||
|
||||
def runTests(self):
|
||||
if self.catchbreak:
|
||||
installHandler()
|
||||
if self.testRunner is None:
|
||||
self.testRunner = runner.TextTestRunner
|
||||
if isinstance(self.testRunner, type):
|
||||
try:
|
||||
try:
|
||||
testRunner = self.testRunner(verbosity=self.verbosity,
|
||||
failfast=self.failfast,
|
||||
buffer=self.buffer,
|
||||
warnings=self.warnings,
|
||||
tb_locals=self.tb_locals)
|
||||
except TypeError:
|
||||
# didn't accept the tb_locals argument
|
||||
testRunner = self.testRunner(verbosity=self.verbosity,
|
||||
failfast=self.failfast,
|
||||
buffer=self.buffer,
|
||||
warnings=self.warnings)
|
||||
except TypeError:
|
||||
# didn't accept the verbosity, buffer or failfast arguments
|
||||
testRunner = self.testRunner()
|
||||
else:
|
||||
# it is assumed to be a TestRunner instance
|
||||
testRunner = self.testRunner
|
||||
self.result = testRunner.run(self.test)
|
||||
if self.exit:
|
||||
sys.exit(not self.result.wasSuccessful())
|
||||
|
||||
main = TestProgram
|
2415
third_party/python/Lib/unittest/mock.py
vendored
Normal file
2415
third_party/python/Lib/unittest/mock.py
vendored
Normal file
File diff suppressed because it is too large
Load diff
216
third_party/python/Lib/unittest/result.py
vendored
Normal file
216
third_party/python/Lib/unittest/result.py
vendored
Normal file
|
@ -0,0 +1,216 @@
|
|||
"""Test result object"""
|
||||
|
||||
import io
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from . import util
|
||||
from functools import wraps
|
||||
|
||||
__unittest = True
|
||||
|
||||
def failfast(method):
|
||||
@wraps(method)
|
||||
def inner(self, *args, **kw):
|
||||
if getattr(self, 'failfast', False):
|
||||
self.stop()
|
||||
return method(self, *args, **kw)
|
||||
return inner
|
||||
|
||||
STDOUT_LINE = '\nStdout:\n%s'
|
||||
STDERR_LINE = '\nStderr:\n%s'
|
||||
|
||||
|
||||
class TestResult(object):
|
||||
"""Holder for test result information.
|
||||
|
||||
Test results are automatically managed by the TestCase and TestSuite
|
||||
classes, and do not need to be explicitly manipulated by writers of tests.
|
||||
|
||||
Each instance holds the total number of tests run, and collections of
|
||||
failures and errors that occurred among those test runs. The collections
|
||||
contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
|
||||
formatted traceback of the error that occurred.
|
||||
"""
|
||||
_previousTestClass = None
|
||||
_testRunEntered = False
|
||||
_moduleSetUpFailed = False
|
||||
def __init__(self, stream=None, descriptions=None, verbosity=None):
|
||||
self.failfast = False
|
||||
self.failures = []
|
||||
self.errors = []
|
||||
self.testsRun = 0
|
||||
self.skipped = []
|
||||
self.expectedFailures = []
|
||||
self.unexpectedSuccesses = []
|
||||
self.shouldStop = False
|
||||
self.buffer = False
|
||||
self.tb_locals = False
|
||||
self._stdout_buffer = None
|
||||
self._stderr_buffer = None
|
||||
self._original_stdout = sys.stdout
|
||||
self._original_stderr = sys.stderr
|
||||
self._mirrorOutput = False
|
||||
|
||||
def printErrors(self):
|
||||
"Called by TestRunner after test run"
|
||||
|
||||
def startTest(self, test):
|
||||
"Called when the given test is about to be run"
|
||||
self.testsRun += 1
|
||||
self._mirrorOutput = False
|
||||
self._setupStdout()
|
||||
|
||||
def _setupStdout(self):
|
||||
if self.buffer:
|
||||
if self._stderr_buffer is None:
|
||||
self._stderr_buffer = io.StringIO()
|
||||
self._stdout_buffer = io.StringIO()
|
||||
sys.stdout = self._stdout_buffer
|
||||
sys.stderr = self._stderr_buffer
|
||||
|
||||
def startTestRun(self):
|
||||
"""Called once before any tests are executed.
|
||||
|
||||
See startTest for a method called before each test.
|
||||
"""
|
||||
|
||||
def stopTest(self, test):
|
||||
"""Called when the given test has been run"""
|
||||
self._restoreStdout()
|
||||
self._mirrorOutput = False
|
||||
|
||||
def _restoreStdout(self):
|
||||
if self.buffer:
|
||||
if self._mirrorOutput:
|
||||
output = sys.stdout.getvalue()
|
||||
error = sys.stderr.getvalue()
|
||||
if output:
|
||||
if not output.endswith('\n'):
|
||||
output += '\n'
|
||||
self._original_stdout.write(STDOUT_LINE % output)
|
||||
if error:
|
||||
if not error.endswith('\n'):
|
||||
error += '\n'
|
||||
self._original_stderr.write(STDERR_LINE % error)
|
||||
|
||||
sys.stdout = self._original_stdout
|
||||
sys.stderr = self._original_stderr
|
||||
self._stdout_buffer.seek(0)
|
||||
self._stdout_buffer.truncate()
|
||||
self._stderr_buffer.seek(0)
|
||||
self._stderr_buffer.truncate()
|
||||
|
||||
def stopTestRun(self):
|
||||
"""Called once after all tests are executed.
|
||||
|
||||
See stopTest for a method called after each test.
|
||||
"""
|
||||
|
||||
@failfast
|
||||
def addError(self, test, err):
|
||||
"""Called when an error has occurred. 'err' is a tuple of values as
|
||||
returned by sys.exc_info().
|
||||
"""
|
||||
self.errors.append((test, self._exc_info_to_string(err, test)))
|
||||
self._mirrorOutput = True
|
||||
|
||||
@failfast
|
||||
def addFailure(self, test, err):
|
||||
"""Called when an error has occurred. 'err' is a tuple of values as
|
||||
returned by sys.exc_info()."""
|
||||
self.failures.append((test, self._exc_info_to_string(err, test)))
|
||||
self._mirrorOutput = True
|
||||
|
||||
def addSubTest(self, test, subtest, err):
|
||||
"""Called at the end of a subtest.
|
||||
'err' is None if the subtest ended successfully, otherwise it's a
|
||||
tuple of values as returned by sys.exc_info().
|
||||
"""
|
||||
# By default, we don't do anything with successful subtests, but
|
||||
# more sophisticated test results might want to record them.
|
||||
if err is not None:
|
||||
if getattr(self, 'failfast', False):
|
||||
self.stop()
|
||||
if issubclass(err[0], test.failureException):
|
||||
errors = self.failures
|
||||
else:
|
||||
errors = self.errors
|
||||
errors.append((subtest, self._exc_info_to_string(err, test)))
|
||||
self._mirrorOutput = True
|
||||
|
||||
def addSuccess(self, test):
|
||||
"Called when a test has completed successfully"
|
||||
pass
|
||||
|
||||
def addSkip(self, test, reason):
|
||||
"""Called when a test is skipped."""
|
||||
self.skipped.append((test, reason))
|
||||
|
||||
def addExpectedFailure(self, test, err):
|
||||
"""Called when an expected failure/error occurred."""
|
||||
self.expectedFailures.append(
|
||||
(test, self._exc_info_to_string(err, test)))
|
||||
|
||||
@failfast
|
||||
def addUnexpectedSuccess(self, test):
|
||||
"""Called when a test was expected to fail, but succeed."""
|
||||
self.unexpectedSuccesses.append(test)
|
||||
|
||||
def wasSuccessful(self):
|
||||
"""Tells whether or not this result was a success."""
|
||||
# The hasattr check is for test_result's OldResult test. That
|
||||
# way this method works on objects that lack the attribute.
|
||||
# (where would such result intances come from? old stored pickles?)
|
||||
return ((len(self.failures) == len(self.errors) == 0) and
|
||||
(not hasattr(self, 'unexpectedSuccesses') or
|
||||
len(self.unexpectedSuccesses) == 0))
|
||||
|
||||
def stop(self):
|
||||
"""Indicates that the tests should be aborted."""
|
||||
self.shouldStop = True
|
||||
|
||||
def _exc_info_to_string(self, err, test):
|
||||
"""Converts a sys.exc_info()-style tuple of values into a string."""
|
||||
exctype, value, tb = err
|
||||
# Skip test runner traceback levels
|
||||
while tb and self._is_relevant_tb_level(tb):
|
||||
tb = tb.tb_next
|
||||
|
||||
if exctype is test.failureException:
|
||||
# Skip assert*() traceback levels
|
||||
length = self._count_relevant_tb_levels(tb)
|
||||
else:
|
||||
length = None
|
||||
tb_e = traceback.TracebackException(
|
||||
exctype, value, tb, limit=length, capture_locals=self.tb_locals)
|
||||
msgLines = list(tb_e.format())
|
||||
|
||||
if self.buffer:
|
||||
output = sys.stdout.getvalue()
|
||||
error = sys.stderr.getvalue()
|
||||
if output:
|
||||
if not output.endswith('\n'):
|
||||
output += '\n'
|
||||
msgLines.append(STDOUT_LINE % output)
|
||||
if error:
|
||||
if not error.endswith('\n'):
|
||||
error += '\n'
|
||||
msgLines.append(STDERR_LINE % error)
|
||||
return ''.join(msgLines)
|
||||
|
||||
|
||||
def _is_relevant_tb_level(self, tb):
|
||||
return '__unittest' in tb.tb_frame.f_globals
|
||||
|
||||
def _count_relevant_tb_levels(self, tb):
|
||||
length = 0
|
||||
while tb and not self._is_relevant_tb_level(tb):
|
||||
length += 1
|
||||
tb = tb.tb_next
|
||||
return length
|
||||
|
||||
def __repr__(self):
|
||||
return ("<%s run=%i errors=%i failures=%i>" %
|
||||
(util.strclass(self.__class__), self.testsRun, len(self.errors),
|
||||
len(self.failures)))
|
221
third_party/python/Lib/unittest/runner.py
vendored
Normal file
221
third_party/python/Lib/unittest/runner.py
vendored
Normal file
|
@ -0,0 +1,221 @@
|
|||
"""Running tests"""
|
||||
|
||||
import sys
|
||||
import time
|
||||
import warnings
|
||||
|
||||
from . import result
|
||||
from .signals import registerResult
|
||||
|
||||
__unittest = True
|
||||
|
||||
|
||||
class _WritelnDecorator(object):
|
||||
"""Used to decorate file-like objects with a handy 'writeln' method"""
|
||||
def __init__(self,stream):
|
||||
self.stream = stream
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr in ('stream', '__getstate__'):
|
||||
raise AttributeError(attr)
|
||||
return getattr(self.stream,attr)
|
||||
|
||||
def writeln(self, arg=None):
|
||||
if arg:
|
||||
self.write(arg)
|
||||
self.write('\n') # text-mode streams translate to \r\n if needed
|
||||
|
||||
|
||||
class TextTestResult(result.TestResult):
|
||||
"""A test result class that can print formatted text results to a stream.
|
||||
|
||||
Used by TextTestRunner.
|
||||
"""
|
||||
separator1 = '=' * 70
|
||||
separator2 = '-' * 70
|
||||
|
||||
def __init__(self, stream, descriptions, verbosity):
|
||||
super(TextTestResult, self).__init__(stream, descriptions, verbosity)
|
||||
self.stream = stream
|
||||
self.showAll = verbosity > 1
|
||||
self.dots = verbosity == 1
|
||||
self.descriptions = descriptions
|
||||
|
||||
def getDescription(self, test):
|
||||
doc_first_line = test.shortDescription()
|
||||
if self.descriptions and doc_first_line:
|
||||
return '\n'.join((str(test), doc_first_line))
|
||||
else:
|
||||
return str(test)
|
||||
|
||||
def startTest(self, test):
|
||||
super(TextTestResult, self).startTest(test)
|
||||
if self.showAll:
|
||||
self.stream.write(self.getDescription(test))
|
||||
self.stream.write(" ... ")
|
||||
self.stream.flush()
|
||||
|
||||
def addSuccess(self, test):
|
||||
super(TextTestResult, self).addSuccess(test)
|
||||
if self.showAll:
|
||||
self.stream.writeln("ok")
|
||||
elif self.dots:
|
||||
self.stream.write('.')
|
||||
self.stream.flush()
|
||||
|
||||
def addError(self, test, err):
|
||||
super(TextTestResult, self).addError(test, err)
|
||||
if self.showAll:
|
||||
self.stream.writeln("ERROR")
|
||||
elif self.dots:
|
||||
self.stream.write('E')
|
||||
self.stream.flush()
|
||||
|
||||
def addFailure(self, test, err):
|
||||
super(TextTestResult, self).addFailure(test, err)
|
||||
if self.showAll:
|
||||
self.stream.writeln("FAIL")
|
||||
elif self.dots:
|
||||
self.stream.write('F')
|
||||
self.stream.flush()
|
||||
|
||||
def addSkip(self, test, reason):
|
||||
super(TextTestResult, self).addSkip(test, reason)
|
||||
if self.showAll:
|
||||
self.stream.writeln("skipped {0!r}".format(reason))
|
||||
elif self.dots:
|
||||
self.stream.write("s")
|
||||
self.stream.flush()
|
||||
|
||||
def addExpectedFailure(self, test, err):
|
||||
super(TextTestResult, self).addExpectedFailure(test, err)
|
||||
if self.showAll:
|
||||
self.stream.writeln("expected failure")
|
||||
elif self.dots:
|
||||
self.stream.write("x")
|
||||
self.stream.flush()
|
||||
|
||||
def addUnexpectedSuccess(self, test):
|
||||
super(TextTestResult, self).addUnexpectedSuccess(test)
|
||||
if self.showAll:
|
||||
self.stream.writeln("unexpected success")
|
||||
elif self.dots:
|
||||
self.stream.write("u")
|
||||
self.stream.flush()
|
||||
|
||||
def printErrors(self):
|
||||
if self.dots or self.showAll:
|
||||
self.stream.writeln()
|
||||
self.printErrorList('ERROR', self.errors)
|
||||
self.printErrorList('FAIL', self.failures)
|
||||
|
||||
def printErrorList(self, flavour, errors):
|
||||
for test, err in errors:
|
||||
self.stream.writeln(self.separator1)
|
||||
self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
|
||||
self.stream.writeln(self.separator2)
|
||||
self.stream.writeln("%s" % err)
|
||||
|
||||
|
||||
class TextTestRunner(object):
|
||||
"""A test runner class that displays results in textual form.
|
||||
|
||||
It prints out the names of tests as they are run, errors as they
|
||||
occur, and a summary of the results at the end of the test run.
|
||||
"""
|
||||
resultclass = TextTestResult
|
||||
|
||||
def __init__(self, stream=None, descriptions=True, verbosity=1,
|
||||
failfast=False, buffer=False, resultclass=None, warnings=None,
|
||||
*, tb_locals=False):
|
||||
"""Construct a TextTestRunner.
|
||||
|
||||
Subclasses should accept **kwargs to ensure compatibility as the
|
||||
interface changes.
|
||||
"""
|
||||
if stream is None:
|
||||
stream = sys.stderr
|
||||
self.stream = _WritelnDecorator(stream)
|
||||
self.descriptions = descriptions
|
||||
self.verbosity = verbosity
|
||||
self.failfast = failfast
|
||||
self.buffer = buffer
|
||||
self.tb_locals = tb_locals
|
||||
self.warnings = warnings
|
||||
if resultclass is not None:
|
||||
self.resultclass = resultclass
|
||||
|
||||
def _makeResult(self):
|
||||
return self.resultclass(self.stream, self.descriptions, self.verbosity)
|
||||
|
||||
def run(self, test):
|
||||
"Run the given test case or test suite."
|
||||
result = self._makeResult()
|
||||
registerResult(result)
|
||||
result.failfast = self.failfast
|
||||
result.buffer = self.buffer
|
||||
result.tb_locals = self.tb_locals
|
||||
with warnings.catch_warnings():
|
||||
if self.warnings:
|
||||
# if self.warnings is set, use it to filter all the warnings
|
||||
warnings.simplefilter(self.warnings)
|
||||
# if the filter is 'default' or 'always', special-case the
|
||||
# warnings from the deprecated unittest methods to show them
|
||||
# no more than once per module, because they can be fairly
|
||||
# noisy. The -Wd and -Wa flags can be used to bypass this
|
||||
# only when self.warnings is None.
|
||||
if self.warnings in ['default', 'always']:
|
||||
warnings.filterwarnings('module',
|
||||
category=DeprecationWarning,
|
||||
message=r'Please use assert\w+ instead.')
|
||||
startTime = time.time()
|
||||
startTestRun = getattr(result, 'startTestRun', None)
|
||||
if startTestRun is not None:
|
||||
startTestRun()
|
||||
try:
|
||||
test(result)
|
||||
finally:
|
||||
stopTestRun = getattr(result, 'stopTestRun', None)
|
||||
if stopTestRun is not None:
|
||||
stopTestRun()
|
||||
stopTime = time.time()
|
||||
timeTaken = stopTime - startTime
|
||||
result.printErrors()
|
||||
if hasattr(result, 'separator2'):
|
||||
self.stream.writeln(result.separator2)
|
||||
run = result.testsRun
|
||||
self.stream.writeln("Ran %d test%s in %.3fs" %
|
||||
(run, run != 1 and "s" or "", timeTaken))
|
||||
self.stream.writeln()
|
||||
|
||||
expectedFails = unexpectedSuccesses = skipped = 0
|
||||
try:
|
||||
results = map(len, (result.expectedFailures,
|
||||
result.unexpectedSuccesses,
|
||||
result.skipped))
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
expectedFails, unexpectedSuccesses, skipped = results
|
||||
|
||||
infos = []
|
||||
if not result.wasSuccessful():
|
||||
self.stream.write("FAILED")
|
||||
failed, errored = len(result.failures), len(result.errors)
|
||||
if failed:
|
||||
infos.append("failures=%d" % failed)
|
||||
if errored:
|
||||
infos.append("errors=%d" % errored)
|
||||
else:
|
||||
self.stream.write("OK")
|
||||
if skipped:
|
||||
infos.append("skipped=%d" % skipped)
|
||||
if expectedFails:
|
||||
infos.append("expected failures=%d" % expectedFails)
|
||||
if unexpectedSuccesses:
|
||||
infos.append("unexpected successes=%d" % unexpectedSuccesses)
|
||||
if infos:
|
||||
self.stream.writeln(" (%s)" % (", ".join(infos),))
|
||||
else:
|
||||
self.stream.write("\n")
|
||||
return result
|
71
third_party/python/Lib/unittest/signals.py
vendored
Normal file
71
third_party/python/Lib/unittest/signals.py
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
import signal
|
||||
import weakref
|
||||
|
||||
from functools import wraps
|
||||
|
||||
__unittest = True
|
||||
|
||||
|
||||
class _InterruptHandler(object):
|
||||
def __init__(self, default_handler):
|
||||
self.called = False
|
||||
self.original_handler = default_handler
|
||||
if isinstance(default_handler, int):
|
||||
if default_handler == signal.SIG_DFL:
|
||||
# Pretend it's signal.default_int_handler instead.
|
||||
default_handler = signal.default_int_handler
|
||||
elif default_handler == signal.SIG_IGN:
|
||||
# Not quite the same thing as SIG_IGN, but the closest we
|
||||
# can make it: do nothing.
|
||||
def default_handler(unused_signum, unused_frame):
|
||||
pass
|
||||
else:
|
||||
raise TypeError("expected SIGINT signal handler to be "
|
||||
"signal.SIG_IGN, signal.SIG_DFL, or a "
|
||||
"callable object")
|
||||
self.default_handler = default_handler
|
||||
|
||||
def __call__(self, signum, frame):
|
||||
installed_handler = signal.getsignal(signal.SIGINT)
|
||||
if installed_handler is not self:
|
||||
# if we aren't the installed handler, then delegate immediately
|
||||
# to the default handler
|
||||
self.default_handler(signum, frame)
|
||||
|
||||
if self.called:
|
||||
self.default_handler(signum, frame)
|
||||
self.called = True
|
||||
for result in _results.keys():
|
||||
result.stop()
|
||||
|
||||
_results = weakref.WeakKeyDictionary()
|
||||
def registerResult(result):
|
||||
_results[result] = 1
|
||||
|
||||
def removeResult(result):
|
||||
return bool(_results.pop(result, None))
|
||||
|
||||
_interrupt_handler = None
|
||||
def installHandler():
|
||||
global _interrupt_handler
|
||||
if _interrupt_handler is None:
|
||||
default_handler = signal.getsignal(signal.SIGINT)
|
||||
_interrupt_handler = _InterruptHandler(default_handler)
|
||||
signal.signal(signal.SIGINT, _interrupt_handler)
|
||||
|
||||
|
||||
def removeHandler(method=None):
|
||||
if method is not None:
|
||||
@wraps(method)
|
||||
def inner(*args, **kwargs):
|
||||
initial = signal.getsignal(signal.SIGINT)
|
||||
removeHandler()
|
||||
try:
|
||||
return method(*args, **kwargs)
|
||||
finally:
|
||||
signal.signal(signal.SIGINT, initial)
|
||||
return inner
|
||||
|
||||
global _interrupt_handler
|
||||
if _interrupt_handler is not None:
|
||||
signal.signal(signal.SIGINT, _interrupt_handler.original_handler)
|
321
third_party/python/Lib/unittest/suite.py
vendored
Normal file
321
third_party/python/Lib/unittest/suite.py
vendored
Normal file
|
@ -0,0 +1,321 @@
|
|||
"""TestSuite"""
|
||||
|
||||
import sys
|
||||
|
||||
from . import case
|
||||
from . import util
|
||||
|
||||
__unittest = True
|
||||
|
||||
|
||||
def _call_if_exists(parent, attr):
|
||||
func = getattr(parent, attr, lambda: None)
|
||||
func()
|
||||
|
||||
|
||||
class BaseTestSuite(object):
|
||||
"""A simple test suite that doesn't provide class or module shared fixtures.
|
||||
"""
|
||||
_cleanup = True
|
||||
|
||||
def __init__(self, tests=()):
|
||||
self._tests = []
|
||||
self._removed_tests = 0
|
||||
self.addTests(tests)
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s tests=%s>" % (util.strclass(self.__class__), list(self))
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, self.__class__):
|
||||
return NotImplemented
|
||||
return list(self) == list(other)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._tests)
|
||||
|
||||
def countTestCases(self):
|
||||
cases = self._removed_tests
|
||||
for test in self:
|
||||
if test:
|
||||
cases += test.countTestCases()
|
||||
return cases
|
||||
|
||||
def addTest(self, test):
|
||||
# sanity checks
|
||||
if not callable(test):
|
||||
raise TypeError("{} is not callable".format(repr(test)))
|
||||
if isinstance(test, type) and issubclass(test,
|
||||
(case.TestCase, TestSuite)):
|
||||
raise TypeError("TestCases and TestSuites must be instantiated "
|
||||
"before passing them to addTest()")
|
||||
self._tests.append(test)
|
||||
|
||||
def addTests(self, tests):
|
||||
if isinstance(tests, str):
|
||||
raise TypeError("tests must be an iterable of tests, not a string")
|
||||
for test in tests:
|
||||
self.addTest(test)
|
||||
|
||||
def run(self, result):
|
||||
for index, test in enumerate(self):
|
||||
if result.shouldStop:
|
||||
break
|
||||
test(result)
|
||||
if self._cleanup:
|
||||
self._removeTestAtIndex(index)
|
||||
return result
|
||||
|
||||
def _removeTestAtIndex(self, index):
|
||||
"""Stop holding a reference to the TestCase at index."""
|
||||
try:
|
||||
test = self._tests[index]
|
||||
except TypeError:
|
||||
# support for suite implementations that have overridden self._tests
|
||||
pass
|
||||
else:
|
||||
# Some unittest tests add non TestCase/TestSuite objects to
|
||||
# the suite.
|
||||
if hasattr(test, 'countTestCases'):
|
||||
self._removed_tests += test.countTestCases()
|
||||
self._tests[index] = None
|
||||
|
||||
def __call__(self, *args, **kwds):
|
||||
return self.run(*args, **kwds)
|
||||
|
||||
def debug(self):
|
||||
"""Run the tests without collecting errors in a TestResult"""
|
||||
for test in self:
|
||||
test.debug()
|
||||
|
||||
|
||||
class TestSuite(BaseTestSuite):
|
||||
"""A test suite is a composite test consisting of a number of TestCases.
|
||||
|
||||
For use, create an instance of TestSuite, then add test case instances.
|
||||
When all tests have been added, the suite can be passed to a test
|
||||
runner, such as TextTestRunner. It will run the individual test cases
|
||||
in the order in which they were added, aggregating the results. When
|
||||
subclassing, do not forget to call the base class constructor.
|
||||
"""
|
||||
|
||||
def run(self, result, debug=False):
|
||||
topLevel = False
|
||||
if getattr(result, '_testRunEntered', False) is False:
|
||||
result._testRunEntered = topLevel = True
|
||||
|
||||
for index, test in enumerate(self):
|
||||
if result.shouldStop:
|
||||
break
|
||||
|
||||
if _isnotsuite(test):
|
||||
self._tearDownPreviousClass(test, result)
|
||||
self._handleModuleFixture(test, result)
|
||||
self._handleClassSetUp(test, result)
|
||||
result._previousTestClass = test.__class__
|
||||
|
||||
if (getattr(test.__class__, '_classSetupFailed', False) or
|
||||
getattr(result, '_moduleSetUpFailed', False)):
|
||||
continue
|
||||
|
||||
if not debug:
|
||||
test(result)
|
||||
else:
|
||||
test.debug()
|
||||
|
||||
if self._cleanup:
|
||||
self._removeTestAtIndex(index)
|
||||
|
||||
if topLevel:
|
||||
self._tearDownPreviousClass(None, result)
|
||||
self._handleModuleTearDown(result)
|
||||
result._testRunEntered = False
|
||||
return result
|
||||
|
||||
def debug(self):
|
||||
"""Run the tests without collecting errors in a TestResult"""
|
||||
debug = _DebugResult()
|
||||
self.run(debug, True)
|
||||
|
||||
################################
|
||||
|
||||
def _handleClassSetUp(self, test, result):
|
||||
previousClass = getattr(result, '_previousTestClass', None)
|
||||
currentClass = test.__class__
|
||||
if currentClass == previousClass:
|
||||
return
|
||||
if result._moduleSetUpFailed:
|
||||
return
|
||||
if getattr(currentClass, "__unittest_skip__", False):
|
||||
return
|
||||
|
||||
try:
|
||||
currentClass._classSetupFailed = False
|
||||
except TypeError:
|
||||
# test may actually be a function
|
||||
# so its class will be a builtin-type
|
||||
pass
|
||||
|
||||
setUpClass = getattr(currentClass, 'setUpClass', None)
|
||||
if setUpClass is not None:
|
||||
_call_if_exists(result, '_setupStdout')
|
||||
try:
|
||||
setUpClass()
|
||||
except Exception as e:
|
||||
if isinstance(result, _DebugResult):
|
||||
raise
|
||||
currentClass._classSetupFailed = True
|
||||
className = util.strclass(currentClass)
|
||||
errorName = 'setUpClass (%s)' % className
|
||||
self._addClassOrModuleLevelException(result, e, errorName)
|
||||
finally:
|
||||
_call_if_exists(result, '_restoreStdout')
|
||||
|
||||
def _get_previous_module(self, result):
|
||||
previousModule = None
|
||||
previousClass = getattr(result, '_previousTestClass', None)
|
||||
if previousClass is not None:
|
||||
previousModule = previousClass.__module__
|
||||
return previousModule
|
||||
|
||||
|
||||
def _handleModuleFixture(self, test, result):
|
||||
previousModule = self._get_previous_module(result)
|
||||
currentModule = test.__class__.__module__
|
||||
if currentModule == previousModule:
|
||||
return
|
||||
|
||||
self._handleModuleTearDown(result)
|
||||
|
||||
|
||||
result._moduleSetUpFailed = False
|
||||
try:
|
||||
module = sys.modules[currentModule]
|
||||
except KeyError:
|
||||
return
|
||||
setUpModule = getattr(module, 'setUpModule', None)
|
||||
if setUpModule is not None:
|
||||
_call_if_exists(result, '_setupStdout')
|
||||
try:
|
||||
setUpModule()
|
||||
except Exception as e:
|
||||
if isinstance(result, _DebugResult):
|
||||
raise
|
||||
result._moduleSetUpFailed = True
|
||||
errorName = 'setUpModule (%s)' % currentModule
|
||||
self._addClassOrModuleLevelException(result, e, errorName)
|
||||
finally:
|
||||
_call_if_exists(result, '_restoreStdout')
|
||||
|
||||
def _addClassOrModuleLevelException(self, result, exception, errorName):
|
||||
error = _ErrorHolder(errorName)
|
||||
addSkip = getattr(result, 'addSkip', None)
|
||||
if addSkip is not None and isinstance(exception, case.SkipTest):
|
||||
addSkip(error, str(exception))
|
||||
else:
|
||||
result.addError(error, sys.exc_info())
|
||||
|
||||
def _handleModuleTearDown(self, result):
|
||||
previousModule = self._get_previous_module(result)
|
||||
if previousModule is None:
|
||||
return
|
||||
if result._moduleSetUpFailed:
|
||||
return
|
||||
|
||||
try:
|
||||
module = sys.modules[previousModule]
|
||||
except KeyError:
|
||||
return
|
||||
|
||||
tearDownModule = getattr(module, 'tearDownModule', None)
|
||||
if tearDownModule is not None:
|
||||
_call_if_exists(result, '_setupStdout')
|
||||
try:
|
||||
tearDownModule()
|
||||
except Exception as e:
|
||||
if isinstance(result, _DebugResult):
|
||||
raise
|
||||
errorName = 'tearDownModule (%s)' % previousModule
|
||||
self._addClassOrModuleLevelException(result, e, errorName)
|
||||
finally:
|
||||
_call_if_exists(result, '_restoreStdout')
|
||||
|
||||
def _tearDownPreviousClass(self, test, result):
|
||||
previousClass = getattr(result, '_previousTestClass', None)
|
||||
currentClass = test.__class__
|
||||
if currentClass == previousClass:
|
||||
return
|
||||
if getattr(previousClass, '_classSetupFailed', False):
|
||||
return
|
||||
if getattr(result, '_moduleSetUpFailed', False):
|
||||
return
|
||||
if getattr(previousClass, "__unittest_skip__", False):
|
||||
return
|
||||
|
||||
tearDownClass = getattr(previousClass, 'tearDownClass', None)
|
||||
if tearDownClass is not None:
|
||||
_call_if_exists(result, '_setupStdout')
|
||||
try:
|
||||
tearDownClass()
|
||||
except Exception as e:
|
||||
if isinstance(result, _DebugResult):
|
||||
raise
|
||||
className = util.strclass(previousClass)
|
||||
errorName = 'tearDownClass (%s)' % className
|
||||
self._addClassOrModuleLevelException(result, e, errorName)
|
||||
finally:
|
||||
_call_if_exists(result, '_restoreStdout')
|
||||
|
||||
|
||||
class _ErrorHolder(object):
|
||||
"""
|
||||
Placeholder for a TestCase inside a result. As far as a TestResult
|
||||
is concerned, this looks exactly like a unit test. Used to insert
|
||||
arbitrary errors into a test suite run.
|
||||
"""
|
||||
# Inspired by the ErrorHolder from Twisted:
|
||||
# http://twistedmatrix.com/trac/browser/trunk/twisted/trial/runner.py
|
||||
|
||||
# attribute used by TestResult._exc_info_to_string
|
||||
failureException = None
|
||||
|
||||
def __init__(self, description):
|
||||
self.description = description
|
||||
|
||||
def id(self):
|
||||
return self.description
|
||||
|
||||
def shortDescription(self):
|
||||
return None
|
||||
|
||||
def __repr__(self):
|
||||
return "<ErrorHolder description=%r>" % (self.description,)
|
||||
|
||||
def __str__(self):
|
||||
return self.id()
|
||||
|
||||
def run(self, result):
|
||||
# could call result.addError(...) - but this test-like object
|
||||
# shouldn't be run anyway
|
||||
pass
|
||||
|
||||
def __call__(self, result):
|
||||
return self.run(result)
|
||||
|
||||
def countTestCases(self):
|
||||
return 0
|
||||
|
||||
def _isnotsuite(test):
|
||||
"A crude way to tell apart testcases and suites with duck-typing"
|
||||
try:
|
||||
iter(test)
|
||||
except TypeError:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class _DebugResult(object):
|
||||
"Used by the TestSuite to hold previous class when running in debug."
|
||||
_previousTestClass = None
|
||||
_moduleSetUpFailed = False
|
||||
shouldStop = False
|
22
third_party/python/Lib/unittest/test/__init__.py
vendored
Normal file
22
third_party/python/Lib/unittest/test/__init__.py
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
|
||||
here = os.path.dirname(__file__)
|
||||
loader = unittest.defaultTestLoader
|
||||
|
||||
def suite():
|
||||
suite = unittest.TestSuite()
|
||||
for fn in os.listdir(here):
|
||||
if fn.startswith("test") and fn.endswith(".py"):
|
||||
modname = "unittest.test." + fn[:-3]
|
||||
__import__(modname)
|
||||
module = sys.modules[modname]
|
||||
suite.addTest(loader.loadTestsFromModule(module))
|
||||
suite.addTest(loader.loadTestsFromName('unittest.test.testmock'))
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(defaultTest="suite")
|
18
third_party/python/Lib/unittest/test/__main__.py
vendored
Normal file
18
third_party/python/Lib/unittest/test/__main__.py
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
import os
|
||||
import unittest
|
||||
|
||||
|
||||
def load_tests(loader, standard_tests, pattern):
|
||||
# top level directory cached on loader instance
|
||||
this_dir = os.path.dirname(__file__)
|
||||
pattern = pattern or "test_*.py"
|
||||
# We are inside unittest.test, so the top-level is two notches up
|
||||
top_level_dir = os.path.dirname(os.path.dirname(this_dir))
|
||||
package_tests = loader.discover(start_dir=this_dir, pattern=pattern,
|
||||
top_level_dir=top_level_dir)
|
||||
standard_tests.addTests(package_tests)
|
||||
return standard_tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
73
third_party/python/Lib/unittest/test/_test_warnings.py
vendored
Normal file
73
third_party/python/Lib/unittest/test/_test_warnings.py
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
# helper module for test_runner.Test_TextTestRunner.test_warnings
|
||||
|
||||
"""
|
||||
This module has a number of tests that raise different kinds of warnings.
|
||||
When the tests are run, the warnings are caught and their messages are printed
|
||||
to stdout. This module also accepts an arg that is then passed to
|
||||
unittest.main to affect the behavior of warnings.
|
||||
Test_TextTestRunner.test_warnings executes this script with different
|
||||
combinations of warnings args and -W flags and check that the output is correct.
|
||||
See #10535.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
def warnfun():
|
||||
warnings.warn('rw', RuntimeWarning)
|
||||
|
||||
class TestWarnings(unittest.TestCase):
|
||||
# unittest warnings will be printed at most once per type (max one message
|
||||
# for the fail* methods, and one for the assert* methods)
|
||||
def test_assert(self):
|
||||
self.assertEquals(2+2, 4)
|
||||
self.assertEquals(2*2, 4)
|
||||
self.assertEquals(2**2, 4)
|
||||
|
||||
def test_fail(self):
|
||||
self.failUnless(1)
|
||||
self.failUnless(True)
|
||||
|
||||
def test_other_unittest(self):
|
||||
self.assertAlmostEqual(2+2, 4)
|
||||
self.assertNotAlmostEqual(4+4, 2)
|
||||
|
||||
# these warnings are normally silenced, but they are printed in unittest
|
||||
def test_deprecation(self):
|
||||
warnings.warn('dw', DeprecationWarning)
|
||||
warnings.warn('dw', DeprecationWarning)
|
||||
warnings.warn('dw', DeprecationWarning)
|
||||
|
||||
def test_import(self):
|
||||
warnings.warn('iw', ImportWarning)
|
||||
warnings.warn('iw', ImportWarning)
|
||||
warnings.warn('iw', ImportWarning)
|
||||
|
||||
# user warnings should always be printed
|
||||
def test_warning(self):
|
||||
warnings.warn('uw')
|
||||
warnings.warn('uw')
|
||||
warnings.warn('uw')
|
||||
|
||||
# these warnings come from the same place; they will be printed
|
||||
# only once by default or three times if the 'always' filter is used
|
||||
def test_function(self):
|
||||
|
||||
warnfun()
|
||||
warnfun()
|
||||
warnfun()
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
with warnings.catch_warnings(record=True) as ws:
|
||||
# if an arg is provided pass it to unittest.main as 'warnings'
|
||||
if len(sys.argv) == 2:
|
||||
unittest.main(exit=False, warnings=sys.argv.pop())
|
||||
else:
|
||||
unittest.main(exit=False)
|
||||
|
||||
# print all the warning messages collected
|
||||
for w in ws:
|
||||
print(w.message)
|
1
third_party/python/Lib/unittest/test/dummy.py
vendored
Normal file
1
third_party/python/Lib/unittest/test/dummy.py
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
# Empty module for testing the loading of modules
|
138
third_party/python/Lib/unittest/test/support.py
vendored
Normal file
138
third_party/python/Lib/unittest/test/support.py
vendored
Normal file
|
@ -0,0 +1,138 @@
|
|||
import unittest
|
||||
|
||||
|
||||
class TestEquality(object):
|
||||
"""Used as a mixin for TestCase"""
|
||||
|
||||
# Check for a valid __eq__ implementation
|
||||
def test_eq(self):
|
||||
for obj_1, obj_2 in self.eq_pairs:
|
||||
self.assertEqual(obj_1, obj_2)
|
||||
self.assertEqual(obj_2, obj_1)
|
||||
|
||||
# Check for a valid __ne__ implementation
|
||||
def test_ne(self):
|
||||
for obj_1, obj_2 in self.ne_pairs:
|
||||
self.assertNotEqual(obj_1, obj_2)
|
||||
self.assertNotEqual(obj_2, obj_1)
|
||||
|
||||
class TestHashing(object):
|
||||
"""Used as a mixin for TestCase"""
|
||||
|
||||
# Check for a valid __hash__ implementation
|
||||
def test_hash(self):
|
||||
for obj_1, obj_2 in self.eq_pairs:
|
||||
try:
|
||||
if not hash(obj_1) == hash(obj_2):
|
||||
self.fail("%r and %r do not hash equal" % (obj_1, obj_2))
|
||||
except Exception as e:
|
||||
self.fail("Problem hashing %r and %r: %s" % (obj_1, obj_2, e))
|
||||
|
||||
for obj_1, obj_2 in self.ne_pairs:
|
||||
try:
|
||||
if hash(obj_1) == hash(obj_2):
|
||||
self.fail("%s and %s hash equal, but shouldn't" %
|
||||
(obj_1, obj_2))
|
||||
except Exception as e:
|
||||
self.fail("Problem hashing %s and %s: %s" % (obj_1, obj_2, e))
|
||||
|
||||
|
||||
class _BaseLoggingResult(unittest.TestResult):
|
||||
def __init__(self, log):
|
||||
self._events = log
|
||||
super().__init__()
|
||||
|
||||
def startTest(self, test):
|
||||
self._events.append('startTest')
|
||||
super().startTest(test)
|
||||
|
||||
def startTestRun(self):
|
||||
self._events.append('startTestRun')
|
||||
super().startTestRun()
|
||||
|
||||
def stopTest(self, test):
|
||||
self._events.append('stopTest')
|
||||
super().stopTest(test)
|
||||
|
||||
def stopTestRun(self):
|
||||
self._events.append('stopTestRun')
|
||||
super().stopTestRun()
|
||||
|
||||
def addFailure(self, *args):
|
||||
self._events.append('addFailure')
|
||||
super().addFailure(*args)
|
||||
|
||||
def addSuccess(self, *args):
|
||||
self._events.append('addSuccess')
|
||||
super().addSuccess(*args)
|
||||
|
||||
def addError(self, *args):
|
||||
self._events.append('addError')
|
||||
super().addError(*args)
|
||||
|
||||
def addSkip(self, *args):
|
||||
self._events.append('addSkip')
|
||||
super().addSkip(*args)
|
||||
|
||||
def addExpectedFailure(self, *args):
|
||||
self._events.append('addExpectedFailure')
|
||||
super().addExpectedFailure(*args)
|
||||
|
||||
def addUnexpectedSuccess(self, *args):
|
||||
self._events.append('addUnexpectedSuccess')
|
||||
super().addUnexpectedSuccess(*args)
|
||||
|
||||
|
||||
class LegacyLoggingResult(_BaseLoggingResult):
|
||||
"""
|
||||
A legacy TestResult implementation, without an addSubTest method,
|
||||
which records its method calls.
|
||||
"""
|
||||
|
||||
@property
|
||||
def addSubTest(self):
|
||||
raise AttributeError
|
||||
|
||||
|
||||
class LoggingResult(_BaseLoggingResult):
|
||||
"""
|
||||
A TestResult implementation which records its method calls.
|
||||
"""
|
||||
|
||||
def addSubTest(self, test, subtest, err):
|
||||
if err is None:
|
||||
self._events.append('addSubTestSuccess')
|
||||
else:
|
||||
self._events.append('addSubTestFailure')
|
||||
super().addSubTest(test, subtest, err)
|
||||
|
||||
|
||||
class ResultWithNoStartTestRunStopTestRun(object):
|
||||
"""An object honouring TestResult before startTestRun/stopTestRun."""
|
||||
|
||||
def __init__(self):
|
||||
self.failures = []
|
||||
self.errors = []
|
||||
self.testsRun = 0
|
||||
self.skipped = []
|
||||
self.expectedFailures = []
|
||||
self.unexpectedSuccesses = []
|
||||
self.shouldStop = False
|
||||
|
||||
def startTest(self, test):
|
||||
pass
|
||||
|
||||
def stopTest(self, test):
|
||||
pass
|
||||
|
||||
def addError(self, test):
|
||||
pass
|
||||
|
||||
def addFailure(self, test):
|
||||
pass
|
||||
|
||||
def addSuccess(self, test):
|
||||
pass
|
||||
|
||||
def wasSuccessful(self):
|
||||
return True
|
411
third_party/python/Lib/unittest/test/test_assertions.py
vendored
Normal file
411
third_party/python/Lib/unittest/test/test_assertions.py
vendored
Normal file
|
@ -0,0 +1,411 @@
|
|||
import datetime
|
||||
import warnings
|
||||
import weakref
|
||||
import unittest
|
||||
from itertools import product
|
||||
|
||||
|
||||
class Test_Assertions(unittest.TestCase):
|
||||
def test_AlmostEqual(self):
|
||||
self.assertAlmostEqual(1.00000001, 1.0)
|
||||
self.assertNotAlmostEqual(1.0000001, 1.0)
|
||||
self.assertRaises(self.failureException,
|
||||
self.assertAlmostEqual, 1.0000001, 1.0)
|
||||
self.assertRaises(self.failureException,
|
||||
self.assertNotAlmostEqual, 1.00000001, 1.0)
|
||||
|
||||
self.assertAlmostEqual(1.1, 1.0, places=0)
|
||||
self.assertRaises(self.failureException,
|
||||
self.assertAlmostEqual, 1.1, 1.0, places=1)
|
||||
|
||||
self.assertAlmostEqual(0, .1+.1j, places=0)
|
||||
self.assertNotAlmostEqual(0, .1+.1j, places=1)
|
||||
self.assertRaises(self.failureException,
|
||||
self.assertAlmostEqual, 0, .1+.1j, places=1)
|
||||
self.assertRaises(self.failureException,
|
||||
self.assertNotAlmostEqual, 0, .1+.1j, places=0)
|
||||
|
||||
self.assertAlmostEqual(float('inf'), float('inf'))
|
||||
self.assertRaises(self.failureException, self.assertNotAlmostEqual,
|
||||
float('inf'), float('inf'))
|
||||
|
||||
def test_AmostEqualWithDelta(self):
|
||||
self.assertAlmostEqual(1.1, 1.0, delta=0.5)
|
||||
self.assertAlmostEqual(1.0, 1.1, delta=0.5)
|
||||
self.assertNotAlmostEqual(1.1, 1.0, delta=0.05)
|
||||
self.assertNotAlmostEqual(1.0, 1.1, delta=0.05)
|
||||
|
||||
self.assertAlmostEqual(1.0, 1.0, delta=0.5)
|
||||
self.assertRaises(self.failureException, self.assertNotAlmostEqual,
|
||||
1.0, 1.0, delta=0.5)
|
||||
|
||||
self.assertRaises(self.failureException, self.assertAlmostEqual,
|
||||
1.1, 1.0, delta=0.05)
|
||||
self.assertRaises(self.failureException, self.assertNotAlmostEqual,
|
||||
1.1, 1.0, delta=0.5)
|
||||
|
||||
self.assertRaises(TypeError, self.assertAlmostEqual,
|
||||
1.1, 1.0, places=2, delta=2)
|
||||
self.assertRaises(TypeError, self.assertNotAlmostEqual,
|
||||
1.1, 1.0, places=2, delta=2)
|
||||
|
||||
first = datetime.datetime.now()
|
||||
second = first + datetime.timedelta(seconds=10)
|
||||
self.assertAlmostEqual(first, second,
|
||||
delta=datetime.timedelta(seconds=20))
|
||||
self.assertNotAlmostEqual(first, second,
|
||||
delta=datetime.timedelta(seconds=5))
|
||||
|
||||
def test_assertRaises(self):
|
||||
def _raise(e):
|
||||
raise e
|
||||
self.assertRaises(KeyError, _raise, KeyError)
|
||||
self.assertRaises(KeyError, _raise, KeyError("key"))
|
||||
try:
|
||||
self.assertRaises(KeyError, lambda: None)
|
||||
except self.failureException as e:
|
||||
self.assertIn("KeyError not raised", str(e))
|
||||
else:
|
||||
self.fail("assertRaises() didn't fail")
|
||||
try:
|
||||
self.assertRaises(KeyError, _raise, ValueError)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.fail("assertRaises() didn't let exception pass through")
|
||||
with self.assertRaises(KeyError) as cm:
|
||||
try:
|
||||
raise KeyError
|
||||
except Exception as e:
|
||||
exc = e
|
||||
raise
|
||||
self.assertIs(cm.exception, exc)
|
||||
|
||||
with self.assertRaises(KeyError):
|
||||
raise KeyError("key")
|
||||
try:
|
||||
with self.assertRaises(KeyError):
|
||||
pass
|
||||
except self.failureException as e:
|
||||
self.assertIn("KeyError not raised", str(e))
|
||||
else:
|
||||
self.fail("assertRaises() didn't fail")
|
||||
try:
|
||||
with self.assertRaises(KeyError):
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.fail("assertRaises() didn't let exception pass through")
|
||||
|
||||
def test_assertRaises_frames_survival(self):
|
||||
# Issue #9815: assertRaises should avoid keeping local variables
|
||||
# in a traceback alive.
|
||||
class A:
|
||||
pass
|
||||
wr = None
|
||||
|
||||
class Foo(unittest.TestCase):
|
||||
|
||||
def foo(self):
|
||||
nonlocal wr
|
||||
a = A()
|
||||
wr = weakref.ref(a)
|
||||
try:
|
||||
raise IOError
|
||||
except IOError:
|
||||
raise ValueError
|
||||
|
||||
def test_functional(self):
|
||||
self.assertRaises(ValueError, self.foo)
|
||||
|
||||
def test_with(self):
|
||||
with self.assertRaises(ValueError):
|
||||
self.foo()
|
||||
|
||||
Foo("test_functional").run()
|
||||
self.assertIsNone(wr())
|
||||
Foo("test_with").run()
|
||||
self.assertIsNone(wr())
|
||||
|
||||
def testAssertNotRegex(self):
|
||||
self.assertNotRegex('Ala ma kota', r'r+')
|
||||
try:
|
||||
self.assertNotRegex('Ala ma kota', r'k.t', 'Message')
|
||||
except self.failureException as e:
|
||||
self.assertIn('Message', e.args[0])
|
||||
else:
|
||||
self.fail('assertNotRegex should have failed.')
|
||||
|
||||
|
||||
class TestLongMessage(unittest.TestCase):
|
||||
"""Test that the individual asserts honour longMessage.
|
||||
This actually tests all the message behaviour for
|
||||
asserts that use longMessage."""
|
||||
|
||||
def setUp(self):
|
||||
class TestableTestFalse(unittest.TestCase):
|
||||
longMessage = False
|
||||
failureException = self.failureException
|
||||
|
||||
def testTest(self):
|
||||
pass
|
||||
|
||||
class TestableTestTrue(unittest.TestCase):
|
||||
longMessage = True
|
||||
failureException = self.failureException
|
||||
|
||||
def testTest(self):
|
||||
pass
|
||||
|
||||
self.testableTrue = TestableTestTrue('testTest')
|
||||
self.testableFalse = TestableTestFalse('testTest')
|
||||
|
||||
def testDefault(self):
|
||||
self.assertTrue(unittest.TestCase.longMessage)
|
||||
|
||||
def test_formatMsg(self):
|
||||
self.assertEqual(self.testableFalse._formatMessage(None, "foo"), "foo")
|
||||
self.assertEqual(self.testableFalse._formatMessage("foo", "bar"), "foo")
|
||||
|
||||
self.assertEqual(self.testableTrue._formatMessage(None, "foo"), "foo")
|
||||
self.assertEqual(self.testableTrue._formatMessage("foo", "bar"), "bar : foo")
|
||||
|
||||
# This blows up if _formatMessage uses string concatenation
|
||||
self.testableTrue._formatMessage(object(), 'foo')
|
||||
|
||||
def test_formatMessage_unicode_error(self):
|
||||
one = ''.join(chr(i) for i in range(255))
|
||||
# this used to cause a UnicodeDecodeError constructing msg
|
||||
self.testableTrue._formatMessage(one, '\uFFFD')
|
||||
|
||||
def assertMessages(self, methodName, args, errors):
|
||||
"""
|
||||
Check that methodName(*args) raises the correct error messages.
|
||||
errors should be a list of 4 regex that match the error when:
|
||||
1) longMessage = False and no msg passed;
|
||||
2) longMessage = False and msg passed;
|
||||
3) longMessage = True and no msg passed;
|
||||
4) longMessage = True and msg passed;
|
||||
"""
|
||||
def getMethod(i):
|
||||
useTestableFalse = i < 2
|
||||
if useTestableFalse:
|
||||
test = self.testableFalse
|
||||
else:
|
||||
test = self.testableTrue
|
||||
return getattr(test, methodName)
|
||||
|
||||
for i, expected_regex in enumerate(errors):
|
||||
testMethod = getMethod(i)
|
||||
kwargs = {}
|
||||
withMsg = i % 2
|
||||
if withMsg:
|
||||
kwargs = {"msg": "oops"}
|
||||
|
||||
with self.assertRaisesRegex(self.failureException,
|
||||
expected_regex=expected_regex):
|
||||
testMethod(*args, **kwargs)
|
||||
|
||||
def testAssertTrue(self):
|
||||
self.assertMessages('assertTrue', (False,),
|
||||
["^False is not true$", "^oops$", "^False is not true$",
|
||||
"^False is not true : oops$"])
|
||||
|
||||
def testAssertFalse(self):
|
||||
self.assertMessages('assertFalse', (True,),
|
||||
["^True is not false$", "^oops$", "^True is not false$",
|
||||
"^True is not false : oops$"])
|
||||
|
||||
def testNotEqual(self):
|
||||
self.assertMessages('assertNotEqual', (1, 1),
|
||||
["^1 == 1$", "^oops$", "^1 == 1$",
|
||||
"^1 == 1 : oops$"])
|
||||
|
||||
def testAlmostEqual(self):
|
||||
self.assertMessages('assertAlmostEqual', (1, 2),
|
||||
["^1 != 2 within 7 places$", "^oops$",
|
||||
"^1 != 2 within 7 places$", "^1 != 2 within 7 places : oops$"])
|
||||
|
||||
def testNotAlmostEqual(self):
|
||||
self.assertMessages('assertNotAlmostEqual', (1, 1),
|
||||
["^1 == 1 within 7 places$", "^oops$",
|
||||
"^1 == 1 within 7 places$", "^1 == 1 within 7 places : oops$"])
|
||||
|
||||
def test_baseAssertEqual(self):
|
||||
self.assertMessages('_baseAssertEqual', (1, 2),
|
||||
["^1 != 2$", "^oops$", "^1 != 2$", "^1 != 2 : oops$"])
|
||||
|
||||
def testAssertSequenceEqual(self):
|
||||
# Error messages are multiline so not testing on full message
|
||||
# assertTupleEqual and assertListEqual delegate to this method
|
||||
self.assertMessages('assertSequenceEqual', ([], [None]),
|
||||
[r"\+ \[None\]$", "^oops$", r"\+ \[None\]$",
|
||||
r"\+ \[None\] : oops$"])
|
||||
|
||||
def testAssertSetEqual(self):
|
||||
self.assertMessages('assertSetEqual', (set(), set([None])),
|
||||
["None$", "^oops$", "None$",
|
||||
"None : oops$"])
|
||||
|
||||
def testAssertIn(self):
|
||||
self.assertMessages('assertIn', (None, []),
|
||||
[r'^None not found in \[\]$', "^oops$",
|
||||
r'^None not found in \[\]$',
|
||||
r'^None not found in \[\] : oops$'])
|
||||
|
||||
def testAssertNotIn(self):
|
||||
self.assertMessages('assertNotIn', (None, [None]),
|
||||
[r'^None unexpectedly found in \[None\]$', "^oops$",
|
||||
r'^None unexpectedly found in \[None\]$',
|
||||
r'^None unexpectedly found in \[None\] : oops$'])
|
||||
|
||||
def testAssertDictEqual(self):
|
||||
self.assertMessages('assertDictEqual', ({}, {'key': 'value'}),
|
||||
[r"\+ \{'key': 'value'\}$", "^oops$",
|
||||
r"\+ \{'key': 'value'\}$",
|
||||
r"\+ \{'key': 'value'\} : oops$"])
|
||||
|
||||
def testAssertDictContainsSubset(self):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
|
||||
self.assertMessages('assertDictContainsSubset', ({'key': 'value'}, {}),
|
||||
["^Missing: 'key'$", "^oops$",
|
||||
"^Missing: 'key'$",
|
||||
"^Missing: 'key' : oops$"])
|
||||
|
||||
def testAssertMultiLineEqual(self):
|
||||
self.assertMessages('assertMultiLineEqual', ("", "foo"),
|
||||
[r"\+ foo$", "^oops$",
|
||||
r"\+ foo$",
|
||||
r"\+ foo : oops$"])
|
||||
|
||||
def testAssertLess(self):
|
||||
self.assertMessages('assertLess', (2, 1),
|
||||
["^2 not less than 1$", "^oops$",
|
||||
"^2 not less than 1$", "^2 not less than 1 : oops$"])
|
||||
|
||||
def testAssertLessEqual(self):
|
||||
self.assertMessages('assertLessEqual', (2, 1),
|
||||
["^2 not less than or equal to 1$", "^oops$",
|
||||
"^2 not less than or equal to 1$",
|
||||
"^2 not less than or equal to 1 : oops$"])
|
||||
|
||||
def testAssertGreater(self):
|
||||
self.assertMessages('assertGreater', (1, 2),
|
||||
["^1 not greater than 2$", "^oops$",
|
||||
"^1 not greater than 2$",
|
||||
"^1 not greater than 2 : oops$"])
|
||||
|
||||
def testAssertGreaterEqual(self):
|
||||
self.assertMessages('assertGreaterEqual', (1, 2),
|
||||
["^1 not greater than or equal to 2$", "^oops$",
|
||||
"^1 not greater than or equal to 2$",
|
||||
"^1 not greater than or equal to 2 : oops$"])
|
||||
|
||||
def testAssertIsNone(self):
|
||||
self.assertMessages('assertIsNone', ('not None',),
|
||||
["^'not None' is not None$", "^oops$",
|
||||
"^'not None' is not None$",
|
||||
"^'not None' is not None : oops$"])
|
||||
|
||||
def testAssertIsNotNone(self):
|
||||
self.assertMessages('assertIsNotNone', (None,),
|
||||
["^unexpectedly None$", "^oops$",
|
||||
"^unexpectedly None$",
|
||||
"^unexpectedly None : oops$"])
|
||||
|
||||
def testAssertIs(self):
|
||||
self.assertMessages('assertIs', (None, 'foo'),
|
||||
["^None is not 'foo'$", "^oops$",
|
||||
"^None is not 'foo'$",
|
||||
"^None is not 'foo' : oops$"])
|
||||
|
||||
def testAssertIsNot(self):
|
||||
self.assertMessages('assertIsNot', (None, None),
|
||||
["^unexpectedly identical: None$", "^oops$",
|
||||
"^unexpectedly identical: None$",
|
||||
"^unexpectedly identical: None : oops$"])
|
||||
|
||||
def testAssertRegex(self):
|
||||
self.assertMessages('assertRegex', ('foo', 'bar'),
|
||||
["^Regex didn't match:",
|
||||
"^oops$",
|
||||
"^Regex didn't match:",
|
||||
"^Regex didn't match: (.*) : oops$"])
|
||||
|
||||
def testAssertNotRegex(self):
|
||||
self.assertMessages('assertNotRegex', ('foo', 'foo'),
|
||||
["^Regex matched:",
|
||||
"^oops$",
|
||||
"^Regex matched:",
|
||||
"^Regex matched: (.*) : oops$"])
|
||||
|
||||
|
||||
def assertMessagesCM(self, methodName, args, func, errors):
|
||||
"""
|
||||
Check that the correct error messages are raised while executing:
|
||||
with method(*args):
|
||||
func()
|
||||
*errors* should be a list of 4 regex that match the error when:
|
||||
1) longMessage = False and no msg passed;
|
||||
2) longMessage = False and msg passed;
|
||||
3) longMessage = True and no msg passed;
|
||||
4) longMessage = True and msg passed;
|
||||
"""
|
||||
p = product((self.testableFalse, self.testableTrue),
|
||||
({}, {"msg": "oops"}))
|
||||
for (cls, kwargs), err in zip(p, errors):
|
||||
method = getattr(cls, methodName)
|
||||
with self.assertRaisesRegex(cls.failureException, err):
|
||||
with method(*args, **kwargs) as cm:
|
||||
func()
|
||||
|
||||
def testAssertRaises(self):
|
||||
self.assertMessagesCM('assertRaises', (TypeError,), lambda: None,
|
||||
['^TypeError not raised$', '^oops$',
|
||||
'^TypeError not raised$',
|
||||
'^TypeError not raised : oops$'])
|
||||
|
||||
def testAssertRaisesRegex(self):
|
||||
# test error not raised
|
||||
self.assertMessagesCM('assertRaisesRegex', (TypeError, 'unused regex'),
|
||||
lambda: None,
|
||||
['^TypeError not raised$', '^oops$',
|
||||
'^TypeError not raised$',
|
||||
'^TypeError not raised : oops$'])
|
||||
# test error raised but with wrong message
|
||||
def raise_wrong_message():
|
||||
raise TypeError('foo')
|
||||
self.assertMessagesCM('assertRaisesRegex', (TypeError, 'regex'),
|
||||
raise_wrong_message,
|
||||
['^"regex" does not match "foo"$', '^oops$',
|
||||
'^"regex" does not match "foo"$',
|
||||
'^"regex" does not match "foo" : oops$'])
|
||||
|
||||
def testAssertWarns(self):
|
||||
self.assertMessagesCM('assertWarns', (UserWarning,), lambda: None,
|
||||
['^UserWarning not triggered$', '^oops$',
|
||||
'^UserWarning not triggered$',
|
||||
'^UserWarning not triggered : oops$'])
|
||||
|
||||
def testAssertWarnsRegex(self):
|
||||
# test error not raised
|
||||
self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'unused regex'),
|
||||
lambda: None,
|
||||
['^UserWarning not triggered$', '^oops$',
|
||||
'^UserWarning not triggered$',
|
||||
'^UserWarning not triggered : oops$'])
|
||||
# test warning raised but with wrong message
|
||||
def raise_wrong_message():
|
||||
warnings.warn('foo')
|
||||
self.assertMessagesCM('assertWarnsRegex', (UserWarning, 'regex'),
|
||||
raise_wrong_message,
|
||||
['^"regex" does not match "foo"$', '^oops$',
|
||||
'^"regex" does not match "foo"$',
|
||||
'^"regex" does not match "foo" : oops$'])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
288
third_party/python/Lib/unittest/test/test_break.py
vendored
Normal file
288
third_party/python/Lib/unittest/test/test_break.py
vendored
Normal file
|
@ -0,0 +1,288 @@
|
|||
import gc
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
import signal
|
||||
import weakref
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
@unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
|
||||
@unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
|
||||
@unittest.skipIf(sys.platform == 'freebsd6', "Test kills regrtest on freebsd6 "
|
||||
"if threads have been used")
|
||||
class TestBreak(unittest.TestCase):
|
||||
int_handler = None
|
||||
|
||||
def setUp(self):
|
||||
self._default_handler = signal.getsignal(signal.SIGINT)
|
||||
if self.int_handler is not None:
|
||||
signal.signal(signal.SIGINT, self.int_handler)
|
||||
|
||||
def tearDown(self):
|
||||
signal.signal(signal.SIGINT, self._default_handler)
|
||||
unittest.signals._results = weakref.WeakKeyDictionary()
|
||||
unittest.signals._interrupt_handler = None
|
||||
|
||||
|
||||
def testInstallHandler(self):
|
||||
default_handler = signal.getsignal(signal.SIGINT)
|
||||
unittest.installHandler()
|
||||
self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler)
|
||||
|
||||
try:
|
||||
pid = os.getpid()
|
||||
os.kill(pid, signal.SIGINT)
|
||||
except KeyboardInterrupt:
|
||||
self.fail("KeyboardInterrupt not handled")
|
||||
|
||||
self.assertTrue(unittest.signals._interrupt_handler.called)
|
||||
|
||||
def testRegisterResult(self):
|
||||
result = unittest.TestResult()
|
||||
self.assertNotIn(result, unittest.signals._results)
|
||||
|
||||
unittest.registerResult(result)
|
||||
try:
|
||||
self.assertIn(result, unittest.signals._results)
|
||||
finally:
|
||||
unittest.removeResult(result)
|
||||
|
||||
def testInterruptCaught(self):
|
||||
default_handler = signal.getsignal(signal.SIGINT)
|
||||
|
||||
result = unittest.TestResult()
|
||||
unittest.installHandler()
|
||||
unittest.registerResult(result)
|
||||
|
||||
self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler)
|
||||
|
||||
def test(result):
|
||||
pid = os.getpid()
|
||||
os.kill(pid, signal.SIGINT)
|
||||
result.breakCaught = True
|
||||
self.assertTrue(result.shouldStop)
|
||||
|
||||
try:
|
||||
test(result)
|
||||
except KeyboardInterrupt:
|
||||
self.fail("KeyboardInterrupt not handled")
|
||||
self.assertTrue(result.breakCaught)
|
||||
|
||||
|
||||
def testSecondInterrupt(self):
|
||||
# Can't use skipIf decorator because the signal handler may have
|
||||
# been changed after defining this method.
|
||||
if signal.getsignal(signal.SIGINT) == signal.SIG_IGN:
|
||||
self.skipTest("test requires SIGINT to not be ignored")
|
||||
result = unittest.TestResult()
|
||||
unittest.installHandler()
|
||||
unittest.registerResult(result)
|
||||
|
||||
def test(result):
|
||||
pid = os.getpid()
|
||||
os.kill(pid, signal.SIGINT)
|
||||
result.breakCaught = True
|
||||
self.assertTrue(result.shouldStop)
|
||||
os.kill(pid, signal.SIGINT)
|
||||
self.fail("Second KeyboardInterrupt not raised")
|
||||
|
||||
try:
|
||||
test(result)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
else:
|
||||
self.fail("Second KeyboardInterrupt not raised")
|
||||
self.assertTrue(result.breakCaught)
|
||||
|
||||
|
||||
def testTwoResults(self):
|
||||
unittest.installHandler()
|
||||
|
||||
result = unittest.TestResult()
|
||||
unittest.registerResult(result)
|
||||
new_handler = signal.getsignal(signal.SIGINT)
|
||||
|
||||
result2 = unittest.TestResult()
|
||||
unittest.registerResult(result2)
|
||||
self.assertEqual(signal.getsignal(signal.SIGINT), new_handler)
|
||||
|
||||
result3 = unittest.TestResult()
|
||||
|
||||
def test(result):
|
||||
pid = os.getpid()
|
||||
os.kill(pid, signal.SIGINT)
|
||||
|
||||
try:
|
||||
test(result)
|
||||
except KeyboardInterrupt:
|
||||
self.fail("KeyboardInterrupt not handled")
|
||||
|
||||
self.assertTrue(result.shouldStop)
|
||||
self.assertTrue(result2.shouldStop)
|
||||
self.assertFalse(result3.shouldStop)
|
||||
|
||||
|
||||
def testHandlerReplacedButCalled(self):
|
||||
# Can't use skipIf decorator because the signal handler may have
|
||||
# been changed after defining this method.
|
||||
if signal.getsignal(signal.SIGINT) == signal.SIG_IGN:
|
||||
self.skipTest("test requires SIGINT to not be ignored")
|
||||
# If our handler has been replaced (is no longer installed) but is
|
||||
# called by the *new* handler, then it isn't safe to delay the
|
||||
# SIGINT and we should immediately delegate to the default handler
|
||||
unittest.installHandler()
|
||||
|
||||
handler = signal.getsignal(signal.SIGINT)
|
||||
def new_handler(frame, signum):
|
||||
handler(frame, signum)
|
||||
signal.signal(signal.SIGINT, new_handler)
|
||||
|
||||
try:
|
||||
pid = os.getpid()
|
||||
os.kill(pid, signal.SIGINT)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
else:
|
||||
self.fail("replaced but delegated handler doesn't raise interrupt")
|
||||
|
||||
def testRunner(self):
|
||||
# Creating a TextTestRunner with the appropriate argument should
|
||||
# register the TextTestResult it creates
|
||||
runner = unittest.TextTestRunner(stream=io.StringIO())
|
||||
|
||||
result = runner.run(unittest.TestSuite())
|
||||
self.assertIn(result, unittest.signals._results)
|
||||
|
||||
def testWeakReferences(self):
|
||||
# Calling registerResult on a result should not keep it alive
|
||||
result = unittest.TestResult()
|
||||
unittest.registerResult(result)
|
||||
|
||||
ref = weakref.ref(result)
|
||||
del result
|
||||
|
||||
# For non-reference counting implementations
|
||||
gc.collect();gc.collect()
|
||||
self.assertIsNone(ref())
|
||||
|
||||
|
||||
def testRemoveResult(self):
|
||||
result = unittest.TestResult()
|
||||
unittest.registerResult(result)
|
||||
|
||||
unittest.installHandler()
|
||||
self.assertTrue(unittest.removeResult(result))
|
||||
|
||||
# Should this raise an error instead?
|
||||
self.assertFalse(unittest.removeResult(unittest.TestResult()))
|
||||
|
||||
try:
|
||||
pid = os.getpid()
|
||||
os.kill(pid, signal.SIGINT)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
self.assertFalse(result.shouldStop)
|
||||
|
||||
def testMainInstallsHandler(self):
|
||||
failfast = object()
|
||||
test = object()
|
||||
verbosity = object()
|
||||
result = object()
|
||||
default_handler = signal.getsignal(signal.SIGINT)
|
||||
|
||||
class FakeRunner(object):
|
||||
initArgs = []
|
||||
runArgs = []
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.initArgs.append((args, kwargs))
|
||||
def run(self, test):
|
||||
self.runArgs.append(test)
|
||||
return result
|
||||
|
||||
class Program(unittest.TestProgram):
|
||||
def __init__(self, catchbreak):
|
||||
self.exit = False
|
||||
self.verbosity = verbosity
|
||||
self.failfast = failfast
|
||||
self.catchbreak = catchbreak
|
||||
self.tb_locals = False
|
||||
self.testRunner = FakeRunner
|
||||
self.test = test
|
||||
self.result = None
|
||||
|
||||
p = Program(False)
|
||||
p.runTests()
|
||||
|
||||
self.assertEqual(FakeRunner.initArgs, [((), {'buffer': None,
|
||||
'verbosity': verbosity,
|
||||
'failfast': failfast,
|
||||
'tb_locals': False,
|
||||
'warnings': None})])
|
||||
self.assertEqual(FakeRunner.runArgs, [test])
|
||||
self.assertEqual(p.result, result)
|
||||
|
||||
self.assertEqual(signal.getsignal(signal.SIGINT), default_handler)
|
||||
|
||||
FakeRunner.initArgs = []
|
||||
FakeRunner.runArgs = []
|
||||
p = Program(True)
|
||||
p.runTests()
|
||||
|
||||
self.assertEqual(FakeRunner.initArgs, [((), {'buffer': None,
|
||||
'verbosity': verbosity,
|
||||
'failfast': failfast,
|
||||
'tb_locals': False,
|
||||
'warnings': None})])
|
||||
self.assertEqual(FakeRunner.runArgs, [test])
|
||||
self.assertEqual(p.result, result)
|
||||
|
||||
self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler)
|
||||
|
||||
def testRemoveHandler(self):
|
||||
default_handler = signal.getsignal(signal.SIGINT)
|
||||
unittest.installHandler()
|
||||
unittest.removeHandler()
|
||||
self.assertEqual(signal.getsignal(signal.SIGINT), default_handler)
|
||||
|
||||
# check that calling removeHandler multiple times has no ill-effect
|
||||
unittest.removeHandler()
|
||||
self.assertEqual(signal.getsignal(signal.SIGINT), default_handler)
|
||||
|
||||
def testRemoveHandlerAsDecorator(self):
|
||||
default_handler = signal.getsignal(signal.SIGINT)
|
||||
unittest.installHandler()
|
||||
|
||||
@unittest.removeHandler
|
||||
def test():
|
||||
self.assertEqual(signal.getsignal(signal.SIGINT), default_handler)
|
||||
|
||||
test()
|
||||
self.assertNotEqual(signal.getsignal(signal.SIGINT), default_handler)
|
||||
|
||||
@unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
|
||||
@unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
|
||||
@unittest.skipIf(sys.platform == 'freebsd6', "Test kills regrtest on freebsd6 "
|
||||
"if threads have been used")
|
||||
class TestBreakDefaultIntHandler(TestBreak):
|
||||
int_handler = signal.default_int_handler
|
||||
|
||||
@unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
|
||||
@unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
|
||||
@unittest.skipIf(sys.platform == 'freebsd6', "Test kills regrtest on freebsd6 "
|
||||
"if threads have been used")
|
||||
class TestBreakSignalIgnored(TestBreak):
|
||||
int_handler = signal.SIG_IGN
|
||||
|
||||
@unittest.skipUnless(hasattr(os, 'kill'), "Test requires os.kill")
|
||||
@unittest.skipIf(sys.platform =="win32", "Test cannot run on Windows")
|
||||
@unittest.skipIf(sys.platform == 'freebsd6', "Test kills regrtest on freebsd6 "
|
||||
"if threads have been used")
|
||||
class TestBreakSignalDefault(TestBreak):
|
||||
int_handler = signal.SIG_DFL
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
1847
third_party/python/Lib/unittest/test/test_case.py
vendored
Normal file
1847
third_party/python/Lib/unittest/test/test_case.py
vendored
Normal file
File diff suppressed because it is too large
Load diff
873
third_party/python/Lib/unittest/test/test_discovery.py
vendored
Normal file
873
third_party/python/Lib/unittest/test/test_discovery.py
vendored
Normal file
|
@ -0,0 +1,873 @@
|
|||
import os.path
|
||||
from os.path import abspath
|
||||
import re
|
||||
import sys
|
||||
import types
|
||||
import pickle
|
||||
from test import support
|
||||
import test.test_importlib.util
|
||||
|
||||
import unittest
|
||||
import unittest.mock
|
||||
import unittest.test
|
||||
|
||||
|
||||
class TestableTestProgram(unittest.TestProgram):
|
||||
module = None
|
||||
exit = True
|
||||
defaultTest = failfast = catchbreak = buffer = None
|
||||
verbosity = 1
|
||||
progName = ''
|
||||
testRunner = testLoader = None
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestDiscovery(unittest.TestCase):
|
||||
|
||||
# Heavily mocked tests so I can avoid hitting the filesystem
|
||||
def test_get_name_from_path(self):
|
||||
loader = unittest.TestLoader()
|
||||
loader._top_level_dir = '/foo'
|
||||
name = loader._get_name_from_path('/foo/bar/baz.py')
|
||||
self.assertEqual(name, 'bar.baz')
|
||||
|
||||
if not __debug__:
|
||||
# asserts are off
|
||||
return
|
||||
|
||||
with self.assertRaises(AssertionError):
|
||||
loader._get_name_from_path('/bar/baz.py')
|
||||
|
||||
def test_find_tests(self):
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
original_listdir = os.listdir
|
||||
def restore_listdir():
|
||||
os.listdir = original_listdir
|
||||
original_isfile = os.path.isfile
|
||||
def restore_isfile():
|
||||
os.path.isfile = original_isfile
|
||||
original_isdir = os.path.isdir
|
||||
def restore_isdir():
|
||||
os.path.isdir = original_isdir
|
||||
|
||||
path_lists = [['test2.py', 'test1.py', 'not_a_test.py', 'test_dir',
|
||||
'test.foo', 'test-not-a-module.py', 'another_dir'],
|
||||
['test4.py', 'test3.py', ]]
|
||||
os.listdir = lambda path: path_lists.pop(0)
|
||||
self.addCleanup(restore_listdir)
|
||||
|
||||
def isdir(path):
|
||||
return path.endswith('dir')
|
||||
os.path.isdir = isdir
|
||||
self.addCleanup(restore_isdir)
|
||||
|
||||
def isfile(path):
|
||||
# another_dir is not a package and so shouldn't be recursed into
|
||||
return not path.endswith('dir') and not 'another_dir' in path
|
||||
os.path.isfile = isfile
|
||||
self.addCleanup(restore_isfile)
|
||||
|
||||
loader._get_module_from_name = lambda path: path + ' module'
|
||||
orig_load_tests = loader.loadTestsFromModule
|
||||
def loadTestsFromModule(module, pattern=None):
|
||||
# This is where load_tests is called.
|
||||
base = orig_load_tests(module, pattern=pattern)
|
||||
return base + [module + ' tests']
|
||||
loader.loadTestsFromModule = loadTestsFromModule
|
||||
loader.suiteClass = lambda thing: thing
|
||||
|
||||
top_level = os.path.abspath('/foo')
|
||||
loader._top_level_dir = top_level
|
||||
suite = list(loader._find_tests(top_level, 'test*.py'))
|
||||
|
||||
# The test suites found should be sorted alphabetically for reliable
|
||||
# execution order.
|
||||
expected = [[name + ' module tests'] for name in
|
||||
('test1', 'test2', 'test_dir')]
|
||||
expected.extend([[('test_dir.%s' % name) + ' module tests'] for name in
|
||||
('test3', 'test4')])
|
||||
self.assertEqual(suite, expected)
|
||||
|
||||
def test_find_tests_socket(self):
|
||||
# A socket is neither a directory nor a regular file.
|
||||
# https://bugs.python.org/issue25320
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
original_listdir = os.listdir
|
||||
def restore_listdir():
|
||||
os.listdir = original_listdir
|
||||
original_isfile = os.path.isfile
|
||||
def restore_isfile():
|
||||
os.path.isfile = original_isfile
|
||||
original_isdir = os.path.isdir
|
||||
def restore_isdir():
|
||||
os.path.isdir = original_isdir
|
||||
|
||||
path_lists = [['socket']]
|
||||
os.listdir = lambda path: path_lists.pop(0)
|
||||
self.addCleanup(restore_listdir)
|
||||
|
||||
os.path.isdir = lambda path: False
|
||||
self.addCleanup(restore_isdir)
|
||||
|
||||
os.path.isfile = lambda path: False
|
||||
self.addCleanup(restore_isfile)
|
||||
|
||||
loader._get_module_from_name = lambda path: path + ' module'
|
||||
orig_load_tests = loader.loadTestsFromModule
|
||||
def loadTestsFromModule(module, pattern=None):
|
||||
# This is where load_tests is called.
|
||||
base = orig_load_tests(module, pattern=pattern)
|
||||
return base + [module + ' tests']
|
||||
loader.loadTestsFromModule = loadTestsFromModule
|
||||
loader.suiteClass = lambda thing: thing
|
||||
|
||||
top_level = os.path.abspath('/foo')
|
||||
loader._top_level_dir = top_level
|
||||
suite = list(loader._find_tests(top_level, 'test*.py'))
|
||||
|
||||
self.assertEqual(suite, [])
|
||||
|
||||
def test_find_tests_with_package(self):
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
original_listdir = os.listdir
|
||||
def restore_listdir():
|
||||
os.listdir = original_listdir
|
||||
original_isfile = os.path.isfile
|
||||
def restore_isfile():
|
||||
os.path.isfile = original_isfile
|
||||
original_isdir = os.path.isdir
|
||||
def restore_isdir():
|
||||
os.path.isdir = original_isdir
|
||||
|
||||
directories = ['a_directory', 'test_directory', 'test_directory2']
|
||||
path_lists = [directories, [], [], []]
|
||||
os.listdir = lambda path: path_lists.pop(0)
|
||||
self.addCleanup(restore_listdir)
|
||||
|
||||
os.path.isdir = lambda path: True
|
||||
self.addCleanup(restore_isdir)
|
||||
|
||||
os.path.isfile = lambda path: os.path.basename(path) not in directories
|
||||
self.addCleanup(restore_isfile)
|
||||
|
||||
class Module(object):
|
||||
paths = []
|
||||
load_tests_args = []
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
self.paths.append(path)
|
||||
if os.path.basename(path) == 'test_directory':
|
||||
def load_tests(loader, tests, pattern):
|
||||
self.load_tests_args.append((loader, tests, pattern))
|
||||
return [self.path + ' load_tests']
|
||||
self.load_tests = load_tests
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.path == other.path
|
||||
|
||||
loader._get_module_from_name = lambda name: Module(name)
|
||||
orig_load_tests = loader.loadTestsFromModule
|
||||
def loadTestsFromModule(module, pattern=None):
|
||||
# This is where load_tests is called.
|
||||
base = orig_load_tests(module, pattern=pattern)
|
||||
return base + [module.path + ' module tests']
|
||||
loader.loadTestsFromModule = loadTestsFromModule
|
||||
loader.suiteClass = lambda thing: thing
|
||||
|
||||
loader._top_level_dir = '/foo'
|
||||
# this time no '.py' on the pattern so that it can match
|
||||
# a test package
|
||||
suite = list(loader._find_tests('/foo', 'test*'))
|
||||
|
||||
# We should have loaded tests from the a_directory and test_directory2
|
||||
# directly and via load_tests for the test_directory package, which
|
||||
# still calls the baseline module loader.
|
||||
self.assertEqual(suite,
|
||||
[['a_directory module tests'],
|
||||
['test_directory load_tests',
|
||||
'test_directory module tests'],
|
||||
['test_directory2 module tests']])
|
||||
|
||||
|
||||
# The test module paths should be sorted for reliable execution order
|
||||
self.assertEqual(Module.paths,
|
||||
['a_directory', 'test_directory', 'test_directory2'])
|
||||
|
||||
# load_tests should have been called once with loader, tests and pattern
|
||||
# (but there are no tests in our stub module itself, so that is [] at
|
||||
# the time of call).
|
||||
self.assertEqual(Module.load_tests_args,
|
||||
[(loader, [], 'test*')])
|
||||
|
||||
def test_find_tests_default_calls_package_load_tests(self):
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
original_listdir = os.listdir
|
||||
def restore_listdir():
|
||||
os.listdir = original_listdir
|
||||
original_isfile = os.path.isfile
|
||||
def restore_isfile():
|
||||
os.path.isfile = original_isfile
|
||||
original_isdir = os.path.isdir
|
||||
def restore_isdir():
|
||||
os.path.isdir = original_isdir
|
||||
|
||||
directories = ['a_directory', 'test_directory', 'test_directory2']
|
||||
path_lists = [directories, [], [], []]
|
||||
os.listdir = lambda path: path_lists.pop(0)
|
||||
self.addCleanup(restore_listdir)
|
||||
|
||||
os.path.isdir = lambda path: True
|
||||
self.addCleanup(restore_isdir)
|
||||
|
||||
os.path.isfile = lambda path: os.path.basename(path) not in directories
|
||||
self.addCleanup(restore_isfile)
|
||||
|
||||
class Module(object):
|
||||
paths = []
|
||||
load_tests_args = []
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
self.paths.append(path)
|
||||
if os.path.basename(path) == 'test_directory':
|
||||
def load_tests(loader, tests, pattern):
|
||||
self.load_tests_args.append((loader, tests, pattern))
|
||||
return [self.path + ' load_tests']
|
||||
self.load_tests = load_tests
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.path == other.path
|
||||
|
||||
loader._get_module_from_name = lambda name: Module(name)
|
||||
orig_load_tests = loader.loadTestsFromModule
|
||||
def loadTestsFromModule(module, pattern=None):
|
||||
# This is where load_tests is called.
|
||||
base = orig_load_tests(module, pattern=pattern)
|
||||
return base + [module.path + ' module tests']
|
||||
loader.loadTestsFromModule = loadTestsFromModule
|
||||
loader.suiteClass = lambda thing: thing
|
||||
|
||||
loader._top_level_dir = '/foo'
|
||||
# this time no '.py' on the pattern so that it can match
|
||||
# a test package
|
||||
suite = list(loader._find_tests('/foo', 'test*.py'))
|
||||
|
||||
# We should have loaded tests from the a_directory and test_directory2
|
||||
# directly and via load_tests for the test_directory package, which
|
||||
# still calls the baseline module loader.
|
||||
self.assertEqual(suite,
|
||||
[['a_directory module tests'],
|
||||
['test_directory load_tests',
|
||||
'test_directory module tests'],
|
||||
['test_directory2 module tests']])
|
||||
# The test module paths should be sorted for reliable execution order
|
||||
self.assertEqual(Module.paths,
|
||||
['a_directory', 'test_directory', 'test_directory2'])
|
||||
|
||||
|
||||
# load_tests should have been called once with loader, tests and pattern
|
||||
self.assertEqual(Module.load_tests_args,
|
||||
[(loader, [], 'test*.py')])
|
||||
|
||||
def test_find_tests_customize_via_package_pattern(self):
|
||||
# This test uses the example 'do-nothing' load_tests from
|
||||
# https://docs.python.org/3/library/unittest.html#load-tests-protocol
|
||||
# to make sure that that actually works.
|
||||
# Housekeeping
|
||||
original_listdir = os.listdir
|
||||
def restore_listdir():
|
||||
os.listdir = original_listdir
|
||||
self.addCleanup(restore_listdir)
|
||||
original_isfile = os.path.isfile
|
||||
def restore_isfile():
|
||||
os.path.isfile = original_isfile
|
||||
self.addCleanup(restore_isfile)
|
||||
original_isdir = os.path.isdir
|
||||
def restore_isdir():
|
||||
os.path.isdir = original_isdir
|
||||
self.addCleanup(restore_isdir)
|
||||
self.addCleanup(sys.path.remove, abspath('/foo'))
|
||||
|
||||
# Test data: we expect the following:
|
||||
# a listdir to find our package, and isfile and isdir checks on it.
|
||||
# a module-from-name call to turn that into a module
|
||||
# followed by load_tests.
|
||||
# then our load_tests will call discover() which is messy
|
||||
# but that finally chains into find_tests again for the child dir -
|
||||
# which is why we don't have an infinite loop.
|
||||
# We expect to see:
|
||||
# the module load tests for both package and plain module called,
|
||||
# and the plain module result nested by the package module load_tests
|
||||
# indicating that it was processed and could have been mutated.
|
||||
vfs = {abspath('/foo'): ['my_package'],
|
||||
abspath('/foo/my_package'): ['__init__.py', 'test_module.py']}
|
||||
def list_dir(path):
|
||||
return list(vfs[path])
|
||||
os.listdir = list_dir
|
||||
os.path.isdir = lambda path: not path.endswith('.py')
|
||||
os.path.isfile = lambda path: path.endswith('.py')
|
||||
|
||||
class Module(object):
|
||||
paths = []
|
||||
load_tests_args = []
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
self.paths.append(path)
|
||||
if path.endswith('test_module'):
|
||||
def load_tests(loader, tests, pattern):
|
||||
self.load_tests_args.append((loader, tests, pattern))
|
||||
return [self.path + ' load_tests']
|
||||
else:
|
||||
def load_tests(loader, tests, pattern):
|
||||
self.load_tests_args.append((loader, tests, pattern))
|
||||
# top level directory cached on loader instance
|
||||
__file__ = '/foo/my_package/__init__.py'
|
||||
this_dir = os.path.dirname(__file__)
|
||||
pkg_tests = loader.discover(
|
||||
start_dir=this_dir, pattern=pattern)
|
||||
return [self.path + ' load_tests', tests
|
||||
] + pkg_tests
|
||||
self.load_tests = load_tests
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.path == other.path
|
||||
|
||||
loader = unittest.TestLoader()
|
||||
loader._get_module_from_name = lambda name: Module(name)
|
||||
loader.suiteClass = lambda thing: thing
|
||||
|
||||
loader._top_level_dir = abspath('/foo')
|
||||
# this time no '.py' on the pattern so that it can match
|
||||
# a test package
|
||||
suite = list(loader._find_tests(abspath('/foo'), 'test*.py'))
|
||||
|
||||
# We should have loaded tests from both my_package and
|
||||
# my_package.test_module, and also run the load_tests hook in both.
|
||||
# (normally this would be nested TestSuites.)
|
||||
self.assertEqual(suite,
|
||||
[['my_package load_tests', [],
|
||||
['my_package.test_module load_tests']]])
|
||||
# Parents before children.
|
||||
self.assertEqual(Module.paths,
|
||||
['my_package', 'my_package.test_module'])
|
||||
|
||||
# load_tests should have been called twice with loader, tests and pattern
|
||||
self.assertEqual(Module.load_tests_args,
|
||||
[(loader, [], 'test*.py'),
|
||||
(loader, [], 'test*.py')])
|
||||
|
||||
def test_discover(self):
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
original_isfile = os.path.isfile
|
||||
original_isdir = os.path.isdir
|
||||
def restore_isfile():
|
||||
os.path.isfile = original_isfile
|
||||
|
||||
os.path.isfile = lambda path: False
|
||||
self.addCleanup(restore_isfile)
|
||||
|
||||
orig_sys_path = sys.path[:]
|
||||
def restore_path():
|
||||
sys.path[:] = orig_sys_path
|
||||
self.addCleanup(restore_path)
|
||||
|
||||
full_path = os.path.abspath(os.path.normpath('/foo'))
|
||||
with self.assertRaises(ImportError):
|
||||
loader.discover('/foo/bar', top_level_dir='/foo')
|
||||
|
||||
self.assertEqual(loader._top_level_dir, full_path)
|
||||
self.assertIn(full_path, sys.path)
|
||||
|
||||
os.path.isfile = lambda path: True
|
||||
os.path.isdir = lambda path: True
|
||||
|
||||
def restore_isdir():
|
||||
os.path.isdir = original_isdir
|
||||
self.addCleanup(restore_isdir)
|
||||
|
||||
_find_tests_args = []
|
||||
def _find_tests(start_dir, pattern, namespace=None):
|
||||
_find_tests_args.append((start_dir, pattern))
|
||||
return ['tests']
|
||||
loader._find_tests = _find_tests
|
||||
loader.suiteClass = str
|
||||
|
||||
suite = loader.discover('/foo/bar/baz', 'pattern', '/foo/bar')
|
||||
|
||||
top_level_dir = os.path.abspath('/foo/bar')
|
||||
start_dir = os.path.abspath('/foo/bar/baz')
|
||||
self.assertEqual(suite, "['tests']")
|
||||
self.assertEqual(loader._top_level_dir, top_level_dir)
|
||||
self.assertEqual(_find_tests_args, [(start_dir, 'pattern')])
|
||||
self.assertIn(top_level_dir, sys.path)
|
||||
|
||||
def test_discover_start_dir_is_package_calls_package_load_tests(self):
|
||||
# This test verifies that the package load_tests in a package is indeed
|
||||
# invoked when the start_dir is a package (and not the top level).
|
||||
# http://bugs.python.org/issue22457
|
||||
|
||||
# Test data: we expect the following:
|
||||
# an isfile to verify the package, then importing and scanning
|
||||
# as per _find_tests' normal behaviour.
|
||||
# We expect to see our load_tests hook called once.
|
||||
vfs = {abspath('/toplevel'): ['startdir'],
|
||||
abspath('/toplevel/startdir'): ['__init__.py']}
|
||||
def list_dir(path):
|
||||
return list(vfs[path])
|
||||
self.addCleanup(setattr, os, 'listdir', os.listdir)
|
||||
os.listdir = list_dir
|
||||
self.addCleanup(setattr, os.path, 'isfile', os.path.isfile)
|
||||
os.path.isfile = lambda path: path.endswith('.py')
|
||||
self.addCleanup(setattr, os.path, 'isdir', os.path.isdir)
|
||||
os.path.isdir = lambda path: not path.endswith('.py')
|
||||
self.addCleanup(sys.path.remove, abspath('/toplevel'))
|
||||
|
||||
class Module(object):
|
||||
paths = []
|
||||
load_tests_args = []
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
|
||||
def load_tests(self, loader, tests, pattern):
|
||||
return ['load_tests called ' + self.path]
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.path == other.path
|
||||
|
||||
loader = unittest.TestLoader()
|
||||
loader._get_module_from_name = lambda name: Module(name)
|
||||
loader.suiteClass = lambda thing: thing
|
||||
|
||||
suite = loader.discover('/toplevel/startdir', top_level_dir='/toplevel')
|
||||
|
||||
# We should have loaded tests from the package __init__.
|
||||
# (normally this would be nested TestSuites.)
|
||||
self.assertEqual(suite,
|
||||
[['load_tests called startdir']])
|
||||
|
||||
def setup_import_issue_tests(self, fakefile):
|
||||
listdir = os.listdir
|
||||
os.listdir = lambda _: [fakefile]
|
||||
isfile = os.path.isfile
|
||||
os.path.isfile = lambda _: True
|
||||
orig_sys_path = sys.path[:]
|
||||
def restore():
|
||||
os.path.isfile = isfile
|
||||
os.listdir = listdir
|
||||
sys.path[:] = orig_sys_path
|
||||
self.addCleanup(restore)
|
||||
|
||||
def setup_import_issue_package_tests(self, vfs):
|
||||
self.addCleanup(setattr, os, 'listdir', os.listdir)
|
||||
self.addCleanup(setattr, os.path, 'isfile', os.path.isfile)
|
||||
self.addCleanup(setattr, os.path, 'isdir', os.path.isdir)
|
||||
self.addCleanup(sys.path.__setitem__, slice(None), list(sys.path))
|
||||
def list_dir(path):
|
||||
return list(vfs[path])
|
||||
os.listdir = list_dir
|
||||
os.path.isdir = lambda path: not path.endswith('.py')
|
||||
os.path.isfile = lambda path: path.endswith('.py')
|
||||
|
||||
def test_discover_with_modules_that_fail_to_import(self):
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
self.setup_import_issue_tests('test_this_does_not_exist.py')
|
||||
|
||||
suite = loader.discover('.')
|
||||
self.assertIn(os.getcwd(), sys.path)
|
||||
self.assertEqual(suite.countTestCases(), 1)
|
||||
# Errors loading the suite are also captured for introspection.
|
||||
self.assertNotEqual([], loader.errors)
|
||||
self.assertEqual(1, len(loader.errors))
|
||||
error = loader.errors[0]
|
||||
self.assertTrue(
|
||||
'Failed to import test module: test_this_does_not_exist' in error,
|
||||
'missing error string in %r' % error)
|
||||
test = list(list(suite)[0])[0] # extract test from suite
|
||||
|
||||
with self.assertRaises(ImportError):
|
||||
test.test_this_does_not_exist()
|
||||
|
||||
def test_discover_with_init_modules_that_fail_to_import(self):
|
||||
vfs = {abspath('/foo'): ['my_package'],
|
||||
abspath('/foo/my_package'): ['__init__.py', 'test_module.py']}
|
||||
self.setup_import_issue_package_tests(vfs)
|
||||
import_calls = []
|
||||
def _get_module_from_name(name):
|
||||
import_calls.append(name)
|
||||
raise ImportError("Cannot import Name")
|
||||
loader = unittest.TestLoader()
|
||||
loader._get_module_from_name = _get_module_from_name
|
||||
suite = loader.discover(abspath('/foo'))
|
||||
|
||||
self.assertIn(abspath('/foo'), sys.path)
|
||||
self.assertEqual(suite.countTestCases(), 1)
|
||||
# Errors loading the suite are also captured for introspection.
|
||||
self.assertNotEqual([], loader.errors)
|
||||
self.assertEqual(1, len(loader.errors))
|
||||
error = loader.errors[0]
|
||||
self.assertTrue(
|
||||
'Failed to import test module: my_package' in error,
|
||||
'missing error string in %r' % error)
|
||||
test = list(list(suite)[0])[0] # extract test from suite
|
||||
with self.assertRaises(ImportError):
|
||||
test.my_package()
|
||||
self.assertEqual(import_calls, ['my_package'])
|
||||
|
||||
# Check picklability
|
||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||
pickle.loads(pickle.dumps(test, proto))
|
||||
|
||||
def test_discover_with_module_that_raises_SkipTest_on_import(self):
|
||||
if not unittest.BaseTestSuite._cleanup:
|
||||
raise unittest.SkipTest("Suite cleanup is disabled")
|
||||
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
def _get_module_from_name(name):
|
||||
raise unittest.SkipTest('skipperoo')
|
||||
loader._get_module_from_name = _get_module_from_name
|
||||
|
||||
self.setup_import_issue_tests('test_skip_dummy.py')
|
||||
|
||||
suite = loader.discover('.')
|
||||
self.assertEqual(suite.countTestCases(), 1)
|
||||
|
||||
result = unittest.TestResult()
|
||||
suite.run(result)
|
||||
self.assertEqual(len(result.skipped), 1)
|
||||
|
||||
# Check picklability
|
||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||
pickle.loads(pickle.dumps(suite, proto))
|
||||
|
||||
def test_discover_with_init_module_that_raises_SkipTest_on_import(self):
|
||||
if not unittest.BaseTestSuite._cleanup:
|
||||
raise unittest.SkipTest("Suite cleanup is disabled")
|
||||
|
||||
vfs = {abspath('/foo'): ['my_package'],
|
||||
abspath('/foo/my_package'): ['__init__.py', 'test_module.py']}
|
||||
self.setup_import_issue_package_tests(vfs)
|
||||
import_calls = []
|
||||
def _get_module_from_name(name):
|
||||
import_calls.append(name)
|
||||
raise unittest.SkipTest('skipperoo')
|
||||
loader = unittest.TestLoader()
|
||||
loader._get_module_from_name = _get_module_from_name
|
||||
suite = loader.discover(abspath('/foo'))
|
||||
|
||||
self.assertIn(abspath('/foo'), sys.path)
|
||||
self.assertEqual(suite.countTestCases(), 1)
|
||||
result = unittest.TestResult()
|
||||
suite.run(result)
|
||||
self.assertEqual(len(result.skipped), 1)
|
||||
self.assertEqual(result.testsRun, 1)
|
||||
self.assertEqual(import_calls, ['my_package'])
|
||||
|
||||
# Check picklability
|
||||
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
|
||||
pickle.loads(pickle.dumps(suite, proto))
|
||||
|
||||
def test_command_line_handling_parseArgs(self):
|
||||
program = TestableTestProgram()
|
||||
|
||||
args = []
|
||||
program._do_discovery = args.append
|
||||
program.parseArgs(['something', 'discover'])
|
||||
self.assertEqual(args, [[]])
|
||||
|
||||
args[:] = []
|
||||
program.parseArgs(['something', 'discover', 'foo', 'bar'])
|
||||
self.assertEqual(args, [['foo', 'bar']])
|
||||
|
||||
def test_command_line_handling_discover_by_default(self):
|
||||
program = TestableTestProgram()
|
||||
|
||||
args = []
|
||||
program._do_discovery = args.append
|
||||
program.parseArgs(['something'])
|
||||
self.assertEqual(args, [[]])
|
||||
self.assertEqual(program.verbosity, 1)
|
||||
self.assertIs(program.buffer, False)
|
||||
self.assertIs(program.catchbreak, False)
|
||||
self.assertIs(program.failfast, False)
|
||||
|
||||
def test_command_line_handling_discover_by_default_with_options(self):
|
||||
program = TestableTestProgram()
|
||||
|
||||
args = []
|
||||
program._do_discovery = args.append
|
||||
program.parseArgs(['something', '-v', '-b', '-v', '-c', '-f'])
|
||||
self.assertEqual(args, [[]])
|
||||
self.assertEqual(program.verbosity, 2)
|
||||
self.assertIs(program.buffer, True)
|
||||
self.assertIs(program.catchbreak, True)
|
||||
self.assertIs(program.failfast, True)
|
||||
|
||||
|
||||
def test_command_line_handling_do_discovery_too_many_arguments(self):
|
||||
program = TestableTestProgram()
|
||||
program.testLoader = None
|
||||
|
||||
with support.captured_stderr() as stderr, \
|
||||
self.assertRaises(SystemExit) as cm:
|
||||
# too many args
|
||||
program._do_discovery(['one', 'two', 'three', 'four'])
|
||||
self.assertEqual(cm.exception.args, (2,))
|
||||
self.assertIn('usage:', stderr.getvalue())
|
||||
|
||||
|
||||
def test_command_line_handling_do_discovery_uses_default_loader(self):
|
||||
program = object.__new__(unittest.TestProgram)
|
||||
program._initArgParsers()
|
||||
|
||||
class Loader(object):
|
||||
args = []
|
||||
def discover(self, start_dir, pattern, top_level_dir):
|
||||
self.args.append((start_dir, pattern, top_level_dir))
|
||||
return 'tests'
|
||||
|
||||
program.testLoader = Loader()
|
||||
program._do_discovery(['-v'])
|
||||
self.assertEqual(Loader.args, [('.', 'test*.py', None)])
|
||||
|
||||
def test_command_line_handling_do_discovery_calls_loader(self):
|
||||
program = TestableTestProgram()
|
||||
|
||||
class Loader(object):
|
||||
args = []
|
||||
def discover(self, start_dir, pattern, top_level_dir):
|
||||
self.args.append((start_dir, pattern, top_level_dir))
|
||||
return 'tests'
|
||||
|
||||
program._do_discovery(['-v'], Loader=Loader)
|
||||
self.assertEqual(program.verbosity, 2)
|
||||
self.assertEqual(program.test, 'tests')
|
||||
self.assertEqual(Loader.args, [('.', 'test*.py', None)])
|
||||
|
||||
Loader.args = []
|
||||
program = TestableTestProgram()
|
||||
program._do_discovery(['--verbose'], Loader=Loader)
|
||||
self.assertEqual(program.test, 'tests')
|
||||
self.assertEqual(Loader.args, [('.', 'test*.py', None)])
|
||||
|
||||
Loader.args = []
|
||||
program = TestableTestProgram()
|
||||
program._do_discovery([], Loader=Loader)
|
||||
self.assertEqual(program.test, 'tests')
|
||||
self.assertEqual(Loader.args, [('.', 'test*.py', None)])
|
||||
|
||||
Loader.args = []
|
||||
program = TestableTestProgram()
|
||||
program._do_discovery(['fish'], Loader=Loader)
|
||||
self.assertEqual(program.test, 'tests')
|
||||
self.assertEqual(Loader.args, [('fish', 'test*.py', None)])
|
||||
|
||||
Loader.args = []
|
||||
program = TestableTestProgram()
|
||||
program._do_discovery(['fish', 'eggs'], Loader=Loader)
|
||||
self.assertEqual(program.test, 'tests')
|
||||
self.assertEqual(Loader.args, [('fish', 'eggs', None)])
|
||||
|
||||
Loader.args = []
|
||||
program = TestableTestProgram()
|
||||
program._do_discovery(['fish', 'eggs', 'ham'], Loader=Loader)
|
||||
self.assertEqual(program.test, 'tests')
|
||||
self.assertEqual(Loader.args, [('fish', 'eggs', 'ham')])
|
||||
|
||||
Loader.args = []
|
||||
program = TestableTestProgram()
|
||||
program._do_discovery(['-s', 'fish'], Loader=Loader)
|
||||
self.assertEqual(program.test, 'tests')
|
||||
self.assertEqual(Loader.args, [('fish', 'test*.py', None)])
|
||||
|
||||
Loader.args = []
|
||||
program = TestableTestProgram()
|
||||
program._do_discovery(['-t', 'fish'], Loader=Loader)
|
||||
self.assertEqual(program.test, 'tests')
|
||||
self.assertEqual(Loader.args, [('.', 'test*.py', 'fish')])
|
||||
|
||||
Loader.args = []
|
||||
program = TestableTestProgram()
|
||||
program._do_discovery(['-p', 'fish'], Loader=Loader)
|
||||
self.assertEqual(program.test, 'tests')
|
||||
self.assertEqual(Loader.args, [('.', 'fish', None)])
|
||||
self.assertFalse(program.failfast)
|
||||
self.assertFalse(program.catchbreak)
|
||||
|
||||
Loader.args = []
|
||||
program = TestableTestProgram()
|
||||
program._do_discovery(['-p', 'eggs', '-s', 'fish', '-v', '-f', '-c'],
|
||||
Loader=Loader)
|
||||
self.assertEqual(program.test, 'tests')
|
||||
self.assertEqual(Loader.args, [('fish', 'eggs', None)])
|
||||
self.assertEqual(program.verbosity, 2)
|
||||
self.assertTrue(program.failfast)
|
||||
self.assertTrue(program.catchbreak)
|
||||
|
||||
def setup_module_clash(self):
|
||||
class Module(object):
|
||||
__file__ = 'bar/foo.py'
|
||||
sys.modules['foo'] = Module
|
||||
full_path = os.path.abspath('foo')
|
||||
original_listdir = os.listdir
|
||||
original_isfile = os.path.isfile
|
||||
original_isdir = os.path.isdir
|
||||
|
||||
def cleanup():
|
||||
os.listdir = original_listdir
|
||||
os.path.isfile = original_isfile
|
||||
os.path.isdir = original_isdir
|
||||
del sys.modules['foo']
|
||||
if full_path in sys.path:
|
||||
sys.path.remove(full_path)
|
||||
self.addCleanup(cleanup)
|
||||
|
||||
def listdir(_):
|
||||
return ['foo.py']
|
||||
def isfile(_):
|
||||
return True
|
||||
def isdir(_):
|
||||
return True
|
||||
os.listdir = listdir
|
||||
os.path.isfile = isfile
|
||||
os.path.isdir = isdir
|
||||
return full_path
|
||||
|
||||
def test_detect_module_clash(self):
|
||||
full_path = self.setup_module_clash()
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
mod_dir = os.path.abspath('bar')
|
||||
expected_dir = os.path.abspath('foo')
|
||||
msg = re.escape(r"'foo' module incorrectly imported from %r. Expected %r. "
|
||||
"Is this module globally installed?" % (mod_dir, expected_dir))
|
||||
self.assertRaisesRegex(
|
||||
ImportError, '^%s$' % msg, loader.discover,
|
||||
start_dir='foo', pattern='foo.py'
|
||||
)
|
||||
self.assertEqual(sys.path[0], full_path)
|
||||
|
||||
def test_module_symlink_ok(self):
|
||||
full_path = self.setup_module_clash()
|
||||
|
||||
original_realpath = os.path.realpath
|
||||
|
||||
mod_dir = os.path.abspath('bar')
|
||||
expected_dir = os.path.abspath('foo')
|
||||
|
||||
def cleanup():
|
||||
os.path.realpath = original_realpath
|
||||
self.addCleanup(cleanup)
|
||||
|
||||
def realpath(path):
|
||||
if path == os.path.join(mod_dir, 'foo.py'):
|
||||
return os.path.join(expected_dir, 'foo.py')
|
||||
return path
|
||||
os.path.realpath = realpath
|
||||
loader = unittest.TestLoader()
|
||||
loader.discover(start_dir='foo', pattern='foo.py')
|
||||
|
||||
def test_discovery_from_dotted_path(self):
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
tests = [self]
|
||||
expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__))
|
||||
|
||||
self.wasRun = False
|
||||
def _find_tests(start_dir, pattern, namespace=None):
|
||||
self.wasRun = True
|
||||
self.assertEqual(start_dir, expectedPath)
|
||||
return tests
|
||||
loader._find_tests = _find_tests
|
||||
suite = loader.discover('unittest.test')
|
||||
self.assertTrue(self.wasRun)
|
||||
self.assertEqual(suite._tests, tests)
|
||||
|
||||
|
||||
def test_discovery_from_dotted_path_builtin_modules(self):
|
||||
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
listdir = os.listdir
|
||||
os.listdir = lambda _: ['test_this_does_not_exist.py']
|
||||
isfile = os.path.isfile
|
||||
isdir = os.path.isdir
|
||||
os.path.isdir = lambda _: False
|
||||
orig_sys_path = sys.path[:]
|
||||
def restore():
|
||||
os.path.isfile = isfile
|
||||
os.path.isdir = isdir
|
||||
os.listdir = listdir
|
||||
sys.path[:] = orig_sys_path
|
||||
self.addCleanup(restore)
|
||||
|
||||
with self.assertRaises(TypeError) as cm:
|
||||
loader.discover('sys')
|
||||
self.assertEqual(str(cm.exception),
|
||||
'Can not use builtin modules '
|
||||
'as dotted module names')
|
||||
|
||||
def test_discovery_from_dotted_namespace_packages(self):
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
package = types.ModuleType('package')
|
||||
package.__path__ = ['/a', '/b']
|
||||
package.__spec__ = types.SimpleNamespace(
|
||||
loader=None,
|
||||
submodule_search_locations=['/a', '/b']
|
||||
)
|
||||
|
||||
def _import(packagename, *args, **kwargs):
|
||||
sys.modules[packagename] = package
|
||||
return package
|
||||
|
||||
_find_tests_args = []
|
||||
def _find_tests(start_dir, pattern, namespace=None):
|
||||
_find_tests_args.append((start_dir, pattern))
|
||||
return ['%s/tests' % start_dir]
|
||||
|
||||
loader._find_tests = _find_tests
|
||||
loader.suiteClass = list
|
||||
|
||||
with unittest.mock.patch('builtins.__import__', _import):
|
||||
# Since loader.discover() can modify sys.path, restore it when done.
|
||||
with support.DirsOnSysPath():
|
||||
# Make sure to remove 'package' from sys.modules when done.
|
||||
with test.test_importlib.util.uncache('package'):
|
||||
suite = loader.discover('package')
|
||||
|
||||
self.assertEqual(suite, ['/a/tests', '/b/tests'])
|
||||
|
||||
def test_discovery_failed_discovery(self):
|
||||
loader = unittest.TestLoader()
|
||||
package = types.ModuleType('package')
|
||||
|
||||
def _import(packagename, *args, **kwargs):
|
||||
sys.modules[packagename] = package
|
||||
return package
|
||||
|
||||
with unittest.mock.patch('builtins.__import__', _import):
|
||||
# Since loader.discover() can modify sys.path, restore it when done.
|
||||
with support.DirsOnSysPath():
|
||||
# Make sure to remove 'package' from sys.modules when done.
|
||||
with test.test_importlib.util.uncache('package'):
|
||||
with self.assertRaises(TypeError) as cm:
|
||||
loader.discover('package')
|
||||
self.assertEqual(str(cm.exception),
|
||||
'don\'t know how to discover from {!r}'
|
||||
.format(package))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
148
third_party/python/Lib/unittest/test/test_functiontestcase.py
vendored
Normal file
148
third_party/python/Lib/unittest/test/test_functiontestcase.py
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
import unittest
|
||||
|
||||
from unittest.test.support import LoggingResult
|
||||
|
||||
|
||||
class Test_FunctionTestCase(unittest.TestCase):
|
||||
|
||||
# "Return the number of tests represented by the this test object. For
|
||||
# TestCase instances, this will always be 1"
|
||||
def test_countTestCases(self):
|
||||
test = unittest.FunctionTestCase(lambda: None)
|
||||
|
||||
self.assertEqual(test.countTestCases(), 1)
|
||||
|
||||
# "When a setUp() method is defined, the test runner will run that method
|
||||
# prior to each test. Likewise, if a tearDown() method is defined, the
|
||||
# test runner will invoke that method after each test. In the example,
|
||||
# setUp() was used to create a fresh sequence for each test."
|
||||
#
|
||||
# Make sure the proper call order is maintained, even if setUp() raises
|
||||
# an exception.
|
||||
def test_run_call_order__error_in_setUp(self):
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
|
||||
def setUp():
|
||||
events.append('setUp')
|
||||
raise RuntimeError('raised by setUp')
|
||||
|
||||
def test():
|
||||
events.append('test')
|
||||
|
||||
def tearDown():
|
||||
events.append('tearDown')
|
||||
|
||||
expected = ['startTest', 'setUp', 'addError', 'stopTest']
|
||||
unittest.FunctionTestCase(test, setUp, tearDown).run(result)
|
||||
self.assertEqual(events, expected)
|
||||
|
||||
# "When a setUp() method is defined, the test runner will run that method
|
||||
# prior to each test. Likewise, if a tearDown() method is defined, the
|
||||
# test runner will invoke that method after each test. In the example,
|
||||
# setUp() was used to create a fresh sequence for each test."
|
||||
#
|
||||
# Make sure the proper call order is maintained, even if the test raises
|
||||
# an error (as opposed to a failure).
|
||||
def test_run_call_order__error_in_test(self):
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
|
||||
def setUp():
|
||||
events.append('setUp')
|
||||
|
||||
def test():
|
||||
events.append('test')
|
||||
raise RuntimeError('raised by test')
|
||||
|
||||
def tearDown():
|
||||
events.append('tearDown')
|
||||
|
||||
expected = ['startTest', 'setUp', 'test', 'tearDown',
|
||||
'addError', 'stopTest']
|
||||
unittest.FunctionTestCase(test, setUp, tearDown).run(result)
|
||||
self.assertEqual(events, expected)
|
||||
|
||||
# "When a setUp() method is defined, the test runner will run that method
|
||||
# prior to each test. Likewise, if a tearDown() method is defined, the
|
||||
# test runner will invoke that method after each test. In the example,
|
||||
# setUp() was used to create a fresh sequence for each test."
|
||||
#
|
||||
# Make sure the proper call order is maintained, even if the test signals
|
||||
# a failure (as opposed to an error).
|
||||
def test_run_call_order__failure_in_test(self):
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
|
||||
def setUp():
|
||||
events.append('setUp')
|
||||
|
||||
def test():
|
||||
events.append('test')
|
||||
self.fail('raised by test')
|
||||
|
||||
def tearDown():
|
||||
events.append('tearDown')
|
||||
|
||||
expected = ['startTest', 'setUp', 'test', 'tearDown',
|
||||
'addFailure', 'stopTest']
|
||||
unittest.FunctionTestCase(test, setUp, tearDown).run(result)
|
||||
self.assertEqual(events, expected)
|
||||
|
||||
# "When a setUp() method is defined, the test runner will run that method
|
||||
# prior to each test. Likewise, if a tearDown() method is defined, the
|
||||
# test runner will invoke that method after each test. In the example,
|
||||
# setUp() was used to create a fresh sequence for each test."
|
||||
#
|
||||
# Make sure the proper call order is maintained, even if tearDown() raises
|
||||
# an exception.
|
||||
def test_run_call_order__error_in_tearDown(self):
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
|
||||
def setUp():
|
||||
events.append('setUp')
|
||||
|
||||
def test():
|
||||
events.append('test')
|
||||
|
||||
def tearDown():
|
||||
events.append('tearDown')
|
||||
raise RuntimeError('raised by tearDown')
|
||||
|
||||
expected = ['startTest', 'setUp', 'test', 'tearDown', 'addError',
|
||||
'stopTest']
|
||||
unittest.FunctionTestCase(test, setUp, tearDown).run(result)
|
||||
self.assertEqual(events, expected)
|
||||
|
||||
# "Return a string identifying the specific test case."
|
||||
#
|
||||
# Because of the vague nature of the docs, I'm not going to lock this
|
||||
# test down too much. Really all that can be asserted is that the id()
|
||||
# will be a string (either 8-byte or unicode -- again, because the docs
|
||||
# just say "string")
|
||||
def test_id(self):
|
||||
test = unittest.FunctionTestCase(lambda: None)
|
||||
|
||||
self.assertIsInstance(test.id(), str)
|
||||
|
||||
# "Returns a one-line description of the test, or None if no description
|
||||
# has been provided. The default implementation of this method returns
|
||||
# the first line of the test method's docstring, if available, or None."
|
||||
def test_shortDescription__no_docstring(self):
|
||||
test = unittest.FunctionTestCase(lambda: None)
|
||||
|
||||
self.assertEqual(test.shortDescription(), None)
|
||||
|
||||
# "Returns a one-line description of the test, or None if no description
|
||||
# has been provided. The default implementation of this method returns
|
||||
# the first line of the test method's docstring, if available, or None."
|
||||
def test_shortDescription__singleline_docstring(self):
|
||||
desc = "this tests foo"
|
||||
test = unittest.FunctionTestCase(lambda: None, description=desc)
|
||||
|
||||
self.assertEqual(test.shortDescription(), "this tests foo")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
1529
third_party/python/Lib/unittest/test/test_loader.py
vendored
Normal file
1529
third_party/python/Lib/unittest/test/test_loader.py
vendored
Normal file
File diff suppressed because it is too large
Load diff
414
third_party/python/Lib/unittest/test/test_program.py
vendored
Normal file
414
third_party/python/Lib/unittest/test/test_program.py
vendored
Normal file
|
@ -0,0 +1,414 @@
|
|||
import io
|
||||
|
||||
import os
|
||||
import sys
|
||||
from test import support
|
||||
import unittest
|
||||
import unittest.test
|
||||
|
||||
|
||||
class Test_TestProgram(unittest.TestCase):
|
||||
|
||||
def test_discovery_from_dotted_path(self):
|
||||
loader = unittest.TestLoader()
|
||||
|
||||
tests = [self]
|
||||
expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__))
|
||||
|
||||
self.wasRun = False
|
||||
def _find_tests(start_dir, pattern):
|
||||
self.wasRun = True
|
||||
self.assertEqual(start_dir, expectedPath)
|
||||
return tests
|
||||
loader._find_tests = _find_tests
|
||||
suite = loader.discover('unittest.test')
|
||||
self.assertTrue(self.wasRun)
|
||||
self.assertEqual(suite._tests, tests)
|
||||
|
||||
# Horrible white box test
|
||||
def testNoExit(self):
|
||||
result = object()
|
||||
test = object()
|
||||
|
||||
class FakeRunner(object):
|
||||
def run(self, test):
|
||||
self.test = test
|
||||
return result
|
||||
|
||||
runner = FakeRunner()
|
||||
|
||||
oldParseArgs = unittest.TestProgram.parseArgs
|
||||
def restoreParseArgs():
|
||||
unittest.TestProgram.parseArgs = oldParseArgs
|
||||
unittest.TestProgram.parseArgs = lambda *args: None
|
||||
self.addCleanup(restoreParseArgs)
|
||||
|
||||
def removeTest():
|
||||
del unittest.TestProgram.test
|
||||
unittest.TestProgram.test = test
|
||||
self.addCleanup(removeTest)
|
||||
|
||||
program = unittest.TestProgram(testRunner=runner, exit=False, verbosity=2)
|
||||
|
||||
self.assertEqual(program.result, result)
|
||||
self.assertEqual(runner.test, test)
|
||||
self.assertEqual(program.verbosity, 2)
|
||||
|
||||
class FooBar(unittest.TestCase):
|
||||
def testPass(self):
|
||||
assert True
|
||||
def testFail(self):
|
||||
assert False
|
||||
|
||||
class FooBarLoader(unittest.TestLoader):
|
||||
"""Test loader that returns a suite containing FooBar."""
|
||||
def loadTestsFromModule(self, module):
|
||||
return self.suiteClass(
|
||||
[self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
|
||||
|
||||
def loadTestsFromNames(self, names, module):
|
||||
return self.suiteClass(
|
||||
[self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
|
||||
|
||||
def test_defaultTest_with_string(self):
|
||||
class FakeRunner(object):
|
||||
def run(self, test):
|
||||
self.test = test
|
||||
return True
|
||||
|
||||
old_argv = sys.argv
|
||||
sys.argv = ['faketest']
|
||||
runner = FakeRunner()
|
||||
program = unittest.TestProgram(testRunner=runner, exit=False,
|
||||
defaultTest='unittest.test',
|
||||
testLoader=self.FooBarLoader())
|
||||
sys.argv = old_argv
|
||||
self.assertEqual(('unittest.test',), program.testNames)
|
||||
|
||||
def test_defaultTest_with_iterable(self):
|
||||
class FakeRunner(object):
|
||||
def run(self, test):
|
||||
self.test = test
|
||||
return True
|
||||
|
||||
old_argv = sys.argv
|
||||
sys.argv = ['faketest']
|
||||
runner = FakeRunner()
|
||||
program = unittest.TestProgram(
|
||||
testRunner=runner, exit=False,
|
||||
defaultTest=['unittest.test', 'unittest.test2'],
|
||||
testLoader=self.FooBarLoader())
|
||||
sys.argv = old_argv
|
||||
self.assertEqual(['unittest.test', 'unittest.test2'],
|
||||
program.testNames)
|
||||
|
||||
def test_NonExit(self):
|
||||
program = unittest.main(exit=False,
|
||||
argv=["foobar"],
|
||||
testRunner=unittest.TextTestRunner(stream=io.StringIO()),
|
||||
testLoader=self.FooBarLoader())
|
||||
self.assertTrue(hasattr(program, 'result'))
|
||||
|
||||
|
||||
def test_Exit(self):
|
||||
self.assertRaises(
|
||||
SystemExit,
|
||||
unittest.main,
|
||||
argv=["foobar"],
|
||||
testRunner=unittest.TextTestRunner(stream=io.StringIO()),
|
||||
exit=True,
|
||||
testLoader=self.FooBarLoader())
|
||||
|
||||
|
||||
def test_ExitAsDefault(self):
|
||||
self.assertRaises(
|
||||
SystemExit,
|
||||
unittest.main,
|
||||
argv=["foobar"],
|
||||
testRunner=unittest.TextTestRunner(stream=io.StringIO()),
|
||||
testLoader=self.FooBarLoader())
|
||||
|
||||
|
||||
class InitialisableProgram(unittest.TestProgram):
|
||||
exit = False
|
||||
result = None
|
||||
verbosity = 1
|
||||
defaultTest = None
|
||||
tb_locals = False
|
||||
testRunner = None
|
||||
testLoader = unittest.defaultTestLoader
|
||||
module = '__main__'
|
||||
progName = 'test'
|
||||
test = 'test'
|
||||
def __init__(self, *args):
|
||||
pass
|
||||
|
||||
RESULT = object()
|
||||
|
||||
class FakeRunner(object):
|
||||
initArgs = None
|
||||
test = None
|
||||
raiseError = 0
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
FakeRunner.initArgs = kwargs
|
||||
if FakeRunner.raiseError:
|
||||
FakeRunner.raiseError -= 1
|
||||
raise TypeError
|
||||
|
||||
def run(self, test):
|
||||
FakeRunner.test = test
|
||||
return RESULT
|
||||
|
||||
|
||||
class TestCommandLineArgs(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.program = InitialisableProgram()
|
||||
self.program.createTests = lambda: None
|
||||
FakeRunner.initArgs = None
|
||||
FakeRunner.test = None
|
||||
FakeRunner.raiseError = 0
|
||||
|
||||
def testVerbosity(self):
|
||||
program = self.program
|
||||
|
||||
for opt in '-q', '--quiet':
|
||||
program.verbosity = 1
|
||||
program.parseArgs([None, opt])
|
||||
self.assertEqual(program.verbosity, 0)
|
||||
|
||||
for opt in '-v', '--verbose':
|
||||
program.verbosity = 1
|
||||
program.parseArgs([None, opt])
|
||||
self.assertEqual(program.verbosity, 2)
|
||||
|
||||
def testBufferCatchFailfast(self):
|
||||
program = self.program
|
||||
for arg, attr in (('buffer', 'buffer'), ('failfast', 'failfast'),
|
||||
('catch', 'catchbreak')):
|
||||
if attr == 'catch' and not hasInstallHandler:
|
||||
continue
|
||||
|
||||
setattr(program, attr, None)
|
||||
program.parseArgs([None])
|
||||
self.assertIs(getattr(program, attr), False)
|
||||
|
||||
false = []
|
||||
setattr(program, attr, false)
|
||||
program.parseArgs([None])
|
||||
self.assertIs(getattr(program, attr), false)
|
||||
|
||||
true = [42]
|
||||
setattr(program, attr, true)
|
||||
program.parseArgs([None])
|
||||
self.assertIs(getattr(program, attr), true)
|
||||
|
||||
short_opt = '-%s' % arg[0]
|
||||
long_opt = '--%s' % arg
|
||||
for opt in short_opt, long_opt:
|
||||
setattr(program, attr, None)
|
||||
program.parseArgs([None, opt])
|
||||
self.assertIs(getattr(program, attr), True)
|
||||
|
||||
setattr(program, attr, False)
|
||||
with support.captured_stderr() as stderr, \
|
||||
self.assertRaises(SystemExit) as cm:
|
||||
program.parseArgs([None, opt])
|
||||
self.assertEqual(cm.exception.args, (2,))
|
||||
|
||||
setattr(program, attr, True)
|
||||
with support.captured_stderr() as stderr, \
|
||||
self.assertRaises(SystemExit) as cm:
|
||||
program.parseArgs([None, opt])
|
||||
self.assertEqual(cm.exception.args, (2,))
|
||||
|
||||
def testWarning(self):
|
||||
"""Test the warnings argument"""
|
||||
# see #10535
|
||||
class FakeTP(unittest.TestProgram):
|
||||
def parseArgs(self, *args, **kw): pass
|
||||
def runTests(self, *args, **kw): pass
|
||||
warnoptions = sys.warnoptions[:]
|
||||
try:
|
||||
sys.warnoptions[:] = []
|
||||
# no warn options, no arg -> default
|
||||
self.assertEqual(FakeTP().warnings, 'default')
|
||||
# no warn options, w/ arg -> arg value
|
||||
self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
|
||||
sys.warnoptions[:] = ['somevalue']
|
||||
# warn options, no arg -> None
|
||||
# warn options, w/ arg -> arg value
|
||||
self.assertEqual(FakeTP().warnings, None)
|
||||
self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
|
||||
finally:
|
||||
sys.warnoptions[:] = warnoptions
|
||||
|
||||
def testRunTestsRunnerClass(self):
|
||||
program = self.program
|
||||
|
||||
program.testRunner = FakeRunner
|
||||
program.verbosity = 'verbosity'
|
||||
program.failfast = 'failfast'
|
||||
program.buffer = 'buffer'
|
||||
program.warnings = 'warnings'
|
||||
|
||||
program.runTests()
|
||||
|
||||
self.assertEqual(FakeRunner.initArgs, {'verbosity': 'verbosity',
|
||||
'failfast': 'failfast',
|
||||
'buffer': 'buffer',
|
||||
'tb_locals': False,
|
||||
'warnings': 'warnings'})
|
||||
self.assertEqual(FakeRunner.test, 'test')
|
||||
self.assertIs(program.result, RESULT)
|
||||
|
||||
def testRunTestsRunnerInstance(self):
|
||||
program = self.program
|
||||
|
||||
program.testRunner = FakeRunner()
|
||||
FakeRunner.initArgs = None
|
||||
|
||||
program.runTests()
|
||||
|
||||
# A new FakeRunner should not have been instantiated
|
||||
self.assertIsNone(FakeRunner.initArgs)
|
||||
|
||||
self.assertEqual(FakeRunner.test, 'test')
|
||||
self.assertIs(program.result, RESULT)
|
||||
|
||||
def test_locals(self):
|
||||
program = self.program
|
||||
|
||||
program.testRunner = FakeRunner
|
||||
program.parseArgs([None, '--locals'])
|
||||
self.assertEqual(True, program.tb_locals)
|
||||
program.runTests()
|
||||
self.assertEqual(FakeRunner.initArgs, {'buffer': False,
|
||||
'failfast': False,
|
||||
'tb_locals': True,
|
||||
'verbosity': 1,
|
||||
'warnings': None})
|
||||
|
||||
def testRunTestsOldRunnerClass(self):
|
||||
program = self.program
|
||||
|
||||
# Two TypeErrors are needed to fall all the way back to old-style
|
||||
# runners - one to fail tb_locals, one to fail buffer etc.
|
||||
FakeRunner.raiseError = 2
|
||||
program.testRunner = FakeRunner
|
||||
program.verbosity = 'verbosity'
|
||||
program.failfast = 'failfast'
|
||||
program.buffer = 'buffer'
|
||||
program.test = 'test'
|
||||
|
||||
program.runTests()
|
||||
|
||||
# If initialising raises a type error it should be retried
|
||||
# without the new keyword arguments
|
||||
self.assertEqual(FakeRunner.initArgs, {})
|
||||
self.assertEqual(FakeRunner.test, 'test')
|
||||
self.assertIs(program.result, RESULT)
|
||||
|
||||
def testCatchBreakInstallsHandler(self):
|
||||
module = sys.modules['unittest.main']
|
||||
original = module.installHandler
|
||||
def restore():
|
||||
module.installHandler = original
|
||||
self.addCleanup(restore)
|
||||
|
||||
self.installed = False
|
||||
def fakeInstallHandler():
|
||||
self.installed = True
|
||||
module.installHandler = fakeInstallHandler
|
||||
|
||||
program = self.program
|
||||
program.catchbreak = True
|
||||
|
||||
program.testRunner = FakeRunner
|
||||
|
||||
program.runTests()
|
||||
self.assertTrue(self.installed)
|
||||
|
||||
def _patch_isfile(self, names, exists=True):
|
||||
def isfile(path):
|
||||
return path in names
|
||||
original = os.path.isfile
|
||||
os.path.isfile = isfile
|
||||
def restore():
|
||||
os.path.isfile = original
|
||||
self.addCleanup(restore)
|
||||
|
||||
|
||||
def testParseArgsFileNames(self):
|
||||
# running tests with filenames instead of module names
|
||||
program = self.program
|
||||
argv = ['progname', 'foo.py', 'bar.Py', 'baz.PY', 'wing.txt']
|
||||
self._patch_isfile(argv)
|
||||
|
||||
program.createTests = lambda: None
|
||||
program.parseArgs(argv)
|
||||
|
||||
# note that 'wing.txt' is not a Python file so the name should
|
||||
# *not* be converted to a module name
|
||||
expected = ['foo', 'bar', 'baz', 'wing.txt']
|
||||
self.assertEqual(program.testNames, expected)
|
||||
|
||||
|
||||
def testParseArgsFilePaths(self):
|
||||
program = self.program
|
||||
argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
|
||||
self._patch_isfile(argv)
|
||||
|
||||
program.createTests = lambda: None
|
||||
program.parseArgs(argv)
|
||||
|
||||
expected = ['foo.bar.baz', 'green.red']
|
||||
self.assertEqual(program.testNames, expected)
|
||||
|
||||
|
||||
def testParseArgsNonExistentFiles(self):
|
||||
program = self.program
|
||||
argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
|
||||
self._patch_isfile([])
|
||||
|
||||
program.createTests = lambda: None
|
||||
program.parseArgs(argv)
|
||||
|
||||
self.assertEqual(program.testNames, argv[1:])
|
||||
|
||||
def testParseArgsAbsolutePathsThatCanBeConverted(self):
|
||||
cur_dir = os.getcwd()
|
||||
program = self.program
|
||||
def _join(name):
|
||||
return os.path.join(cur_dir, name)
|
||||
argv = ['progname', _join('foo/bar/baz.py'), _join('green\\red.py')]
|
||||
self._patch_isfile(argv)
|
||||
|
||||
program.createTests = lambda: None
|
||||
program.parseArgs(argv)
|
||||
|
||||
expected = ['foo.bar.baz', 'green.red']
|
||||
self.assertEqual(program.testNames, expected)
|
||||
|
||||
def testParseArgsAbsolutePathsThatCannotBeConverted(self):
|
||||
program = self.program
|
||||
# even on Windows '/...' is considered absolute by os.path.abspath
|
||||
argv = ['progname', '/foo/bar/baz.py', '/green/red.py']
|
||||
self._patch_isfile(argv)
|
||||
|
||||
program.createTests = lambda: None
|
||||
program.parseArgs(argv)
|
||||
|
||||
self.assertEqual(program.testNames, argv[1:])
|
||||
|
||||
# it may be better to use platform specific functions to normalise paths
|
||||
# rather than accepting '.PY' and '\' as file separator on Linux / Mac
|
||||
# it would also be better to check that a filename is a valid module
|
||||
# identifier (we have a regex for this in loader.py)
|
||||
# for invalid filenames should we raise a useful error rather than
|
||||
# leaving the current error message (import of filename fails) in place?
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
695
third_party/python/Lib/unittest/test/test_result.py
vendored
Normal file
695
third_party/python/Lib/unittest/test/test_result.py
vendored
Normal file
|
@ -0,0 +1,695 @@
|
|||
import io
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
from test import support
|
||||
|
||||
import traceback
|
||||
import unittest
|
||||
|
||||
|
||||
class MockTraceback(object):
|
||||
class TracebackException:
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.capture_locals = kwargs.get('capture_locals', False)
|
||||
def format(self):
|
||||
result = ['A traceback']
|
||||
if self.capture_locals:
|
||||
result.append('locals')
|
||||
return result
|
||||
|
||||
def restore_traceback():
|
||||
unittest.result.traceback = traceback
|
||||
|
||||
|
||||
class Test_TestResult(unittest.TestCase):
|
||||
# Note: there are not separate tests for TestResult.wasSuccessful(),
|
||||
# TestResult.errors, TestResult.failures, TestResult.testsRun or
|
||||
# TestResult.shouldStop because these only have meaning in terms of
|
||||
# other TestResult methods.
|
||||
#
|
||||
# Accordingly, tests for the aforenamed attributes are incorporated
|
||||
# in with the tests for the defining methods.
|
||||
################################################################
|
||||
|
||||
def test_init(self):
|
||||
result = unittest.TestResult()
|
||||
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
self.assertEqual(len(result.failures), 0)
|
||||
self.assertEqual(result.testsRun, 0)
|
||||
self.assertEqual(result.shouldStop, False)
|
||||
self.assertIsNone(result._stdout_buffer)
|
||||
self.assertIsNone(result._stderr_buffer)
|
||||
|
||||
# "This method can be called to signal that the set of tests being
|
||||
# run should be aborted by setting the TestResult's shouldStop
|
||||
# attribute to True."
|
||||
def test_stop(self):
|
||||
result = unittest.TestResult()
|
||||
|
||||
result.stop()
|
||||
|
||||
self.assertEqual(result.shouldStop, True)
|
||||
|
||||
# "Called when the test case test is about to be run. The default
|
||||
# implementation simply increments the instance's testsRun counter."
|
||||
def test_startTest(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self):
|
||||
pass
|
||||
|
||||
test = Foo('test_1')
|
||||
|
||||
result = unittest.TestResult()
|
||||
|
||||
result.startTest(test)
|
||||
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
self.assertEqual(len(result.failures), 0)
|
||||
self.assertEqual(result.testsRun, 1)
|
||||
self.assertEqual(result.shouldStop, False)
|
||||
|
||||
result.stopTest(test)
|
||||
|
||||
# "Called after the test case test has been executed, regardless of
|
||||
# the outcome. The default implementation does nothing."
|
||||
def test_stopTest(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self):
|
||||
pass
|
||||
|
||||
test = Foo('test_1')
|
||||
|
||||
result = unittest.TestResult()
|
||||
|
||||
result.startTest(test)
|
||||
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
self.assertEqual(len(result.failures), 0)
|
||||
self.assertEqual(result.testsRun, 1)
|
||||
self.assertEqual(result.shouldStop, False)
|
||||
|
||||
result.stopTest(test)
|
||||
|
||||
# Same tests as above; make sure nothing has changed
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
self.assertEqual(len(result.failures), 0)
|
||||
self.assertEqual(result.testsRun, 1)
|
||||
self.assertEqual(result.shouldStop, False)
|
||||
|
||||
# "Called before and after tests are run. The default implementation does nothing."
|
||||
def test_startTestRun_stopTestRun(self):
|
||||
result = unittest.TestResult()
|
||||
result.startTestRun()
|
||||
result.stopTestRun()
|
||||
|
||||
# "addSuccess(test)"
|
||||
# ...
|
||||
# "Called when the test case test succeeds"
|
||||
# ...
|
||||
# "wasSuccessful() - Returns True if all tests run so far have passed,
|
||||
# otherwise returns False"
|
||||
# ...
|
||||
# "testsRun - The total number of tests run so far."
|
||||
# ...
|
||||
# "errors - A list containing 2-tuples of TestCase instances and
|
||||
# formatted tracebacks. Each tuple represents a test which raised an
|
||||
# unexpected exception. Contains formatted
|
||||
# tracebacks instead of sys.exc_info() results."
|
||||
# ...
|
||||
# "failures - A list containing 2-tuples of TestCase instances and
|
||||
# formatted tracebacks. Each tuple represents a test where a failure was
|
||||
# explicitly signalled using the TestCase.fail*() or TestCase.assert*()
|
||||
# methods. Contains formatted tracebacks instead
|
||||
# of sys.exc_info() results."
|
||||
def test_addSuccess(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self):
|
||||
pass
|
||||
|
||||
test = Foo('test_1')
|
||||
|
||||
result = unittest.TestResult()
|
||||
|
||||
result.startTest(test)
|
||||
result.addSuccess(test)
|
||||
result.stopTest(test)
|
||||
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
self.assertEqual(len(result.failures), 0)
|
||||
self.assertEqual(result.testsRun, 1)
|
||||
self.assertEqual(result.shouldStop, False)
|
||||
|
||||
# "addFailure(test, err)"
|
||||
# ...
|
||||
# "Called when the test case test signals a failure. err is a tuple of
|
||||
# the form returned by sys.exc_info(): (type, value, traceback)"
|
||||
# ...
|
||||
# "wasSuccessful() - Returns True if all tests run so far have passed,
|
||||
# otherwise returns False"
|
||||
# ...
|
||||
# "testsRun - The total number of tests run so far."
|
||||
# ...
|
||||
# "errors - A list containing 2-tuples of TestCase instances and
|
||||
# formatted tracebacks. Each tuple represents a test which raised an
|
||||
# unexpected exception. Contains formatted
|
||||
# tracebacks instead of sys.exc_info() results."
|
||||
# ...
|
||||
# "failures - A list containing 2-tuples of TestCase instances and
|
||||
# formatted tracebacks. Each tuple represents a test where a failure was
|
||||
# explicitly signalled using the TestCase.fail*() or TestCase.assert*()
|
||||
# methods. Contains formatted tracebacks instead
|
||||
# of sys.exc_info() results."
|
||||
def test_addFailure(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self):
|
||||
pass
|
||||
|
||||
test = Foo('test_1')
|
||||
try:
|
||||
test.fail("foo")
|
||||
except:
|
||||
exc_info_tuple = sys.exc_info()
|
||||
|
||||
result = unittest.TestResult()
|
||||
|
||||
result.startTest(test)
|
||||
result.addFailure(test, exc_info_tuple)
|
||||
result.stopTest(test)
|
||||
|
||||
self.assertFalse(result.wasSuccessful())
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
self.assertEqual(len(result.failures), 1)
|
||||
self.assertEqual(result.testsRun, 1)
|
||||
self.assertEqual(result.shouldStop, False)
|
||||
|
||||
test_case, formatted_exc = result.failures[0]
|
||||
self.assertIs(test_case, test)
|
||||
self.assertIsInstance(formatted_exc, str)
|
||||
|
||||
# "addError(test, err)"
|
||||
# ...
|
||||
# "Called when the test case test raises an unexpected exception err
|
||||
# is a tuple of the form returned by sys.exc_info():
|
||||
# (type, value, traceback)"
|
||||
# ...
|
||||
# "wasSuccessful() - Returns True if all tests run so far have passed,
|
||||
# otherwise returns False"
|
||||
# ...
|
||||
# "testsRun - The total number of tests run so far."
|
||||
# ...
|
||||
# "errors - A list containing 2-tuples of TestCase instances and
|
||||
# formatted tracebacks. Each tuple represents a test which raised an
|
||||
# unexpected exception. Contains formatted
|
||||
# tracebacks instead of sys.exc_info() results."
|
||||
# ...
|
||||
# "failures - A list containing 2-tuples of TestCase instances and
|
||||
# formatted tracebacks. Each tuple represents a test where a failure was
|
||||
# explicitly signalled using the TestCase.fail*() or TestCase.assert*()
|
||||
# methods. Contains formatted tracebacks instead
|
||||
# of sys.exc_info() results."
|
||||
def test_addError(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self):
|
||||
pass
|
||||
|
||||
test = Foo('test_1')
|
||||
try:
|
||||
raise TypeError()
|
||||
except:
|
||||
exc_info_tuple = sys.exc_info()
|
||||
|
||||
result = unittest.TestResult()
|
||||
|
||||
result.startTest(test)
|
||||
result.addError(test, exc_info_tuple)
|
||||
result.stopTest(test)
|
||||
|
||||
self.assertFalse(result.wasSuccessful())
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
self.assertEqual(len(result.failures), 0)
|
||||
self.assertEqual(result.testsRun, 1)
|
||||
self.assertEqual(result.shouldStop, False)
|
||||
|
||||
test_case, formatted_exc = result.errors[0]
|
||||
self.assertIs(test_case, test)
|
||||
self.assertIsInstance(formatted_exc, str)
|
||||
|
||||
def test_addError_locals(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self):
|
||||
1/0
|
||||
|
||||
test = Foo('test_1')
|
||||
result = unittest.TestResult()
|
||||
result.tb_locals = True
|
||||
|
||||
unittest.result.traceback = MockTraceback
|
||||
self.addCleanup(restore_traceback)
|
||||
result.startTestRun()
|
||||
test.run(result)
|
||||
result.stopTestRun()
|
||||
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
test_case, formatted_exc = result.errors[0]
|
||||
self.assertEqual('A tracebacklocals', formatted_exc)
|
||||
|
||||
def test_addSubTest(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self):
|
||||
nonlocal subtest
|
||||
with self.subTest(foo=1):
|
||||
subtest = self._subtest
|
||||
try:
|
||||
1/0
|
||||
except ZeroDivisionError:
|
||||
exc_info_tuple = sys.exc_info()
|
||||
# Register an error by hand (to check the API)
|
||||
result.addSubTest(test, subtest, exc_info_tuple)
|
||||
# Now trigger a failure
|
||||
self.fail("some recognizable failure")
|
||||
|
||||
subtest = None
|
||||
test = Foo('test_1')
|
||||
result = unittest.TestResult()
|
||||
|
||||
test.run(result)
|
||||
|
||||
self.assertFalse(result.wasSuccessful())
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
self.assertEqual(len(result.failures), 1)
|
||||
self.assertEqual(result.testsRun, 1)
|
||||
self.assertEqual(result.shouldStop, False)
|
||||
|
||||
test_case, formatted_exc = result.errors[0]
|
||||
self.assertIs(test_case, subtest)
|
||||
self.assertIn("ZeroDivisionError", formatted_exc)
|
||||
test_case, formatted_exc = result.failures[0]
|
||||
self.assertIs(test_case, subtest)
|
||||
self.assertIn("some recognizable failure", formatted_exc)
|
||||
|
||||
def testGetDescriptionWithoutDocstring(self):
|
||||
result = unittest.TextTestResult(None, True, 1)
|
||||
self.assertEqual(
|
||||
result.getDescription(self),
|
||||
'testGetDescriptionWithoutDocstring (' + __name__ +
|
||||
'.Test_TestResult)')
|
||||
|
||||
def testGetSubTestDescriptionWithoutDocstring(self):
|
||||
with self.subTest(foo=1, bar=2):
|
||||
result = unittest.TextTestResult(None, True, 1)
|
||||
self.assertEqual(
|
||||
result.getDescription(self._subtest),
|
||||
'testGetSubTestDescriptionWithoutDocstring (' + __name__ +
|
||||
'.Test_TestResult) (bar=2, foo=1)')
|
||||
with self.subTest('some message'):
|
||||
result = unittest.TextTestResult(None, True, 1)
|
||||
self.assertEqual(
|
||||
result.getDescription(self._subtest),
|
||||
'testGetSubTestDescriptionWithoutDocstring (' + __name__ +
|
||||
'.Test_TestResult) [some message]')
|
||||
|
||||
def testGetSubTestDescriptionWithoutDocstringAndParams(self):
|
||||
with self.subTest():
|
||||
result = unittest.TextTestResult(None, True, 1)
|
||||
self.assertEqual(
|
||||
result.getDescription(self._subtest),
|
||||
'testGetSubTestDescriptionWithoutDocstringAndParams '
|
||||
'(' + __name__ + '.Test_TestResult) (<subtest>)')
|
||||
|
||||
def testGetSubTestDescriptionForFalsyValues(self):
|
||||
expected = 'testGetSubTestDescriptionForFalsyValues (%s.Test_TestResult) [%s]'
|
||||
result = unittest.TextTestResult(None, True, 1)
|
||||
for arg in [0, None, []]:
|
||||
with self.subTest(arg):
|
||||
self.assertEqual(
|
||||
result.getDescription(self._subtest),
|
||||
expected % (__name__, arg)
|
||||
)
|
||||
|
||||
def testGetNestedSubTestDescriptionWithoutDocstring(self):
|
||||
with self.subTest(foo=1):
|
||||
with self.subTest(bar=2):
|
||||
result = unittest.TextTestResult(None, True, 1)
|
||||
self.assertEqual(
|
||||
result.getDescription(self._subtest),
|
||||
'testGetNestedSubTestDescriptionWithoutDocstring '
|
||||
'(' + __name__ + '.Test_TestResult) (bar=2, foo=1)')
|
||||
|
||||
@unittest.skipIf(sys.flags.optimize >= 2,
|
||||
"Docstrings are omitted with -O2 and above")
|
||||
def testGetDescriptionWithOneLineDocstring(self):
|
||||
"""Tests getDescription() for a method with a docstring."""
|
||||
result = unittest.TextTestResult(None, True, 1)
|
||||
self.assertEqual(
|
||||
result.getDescription(self),
|
||||
('testGetDescriptionWithOneLineDocstring '
|
||||
'(' + __name__ + '.Test_TestResult)\n'
|
||||
'Tests getDescription() for a method with a docstring.'))
|
||||
|
||||
@unittest.skipIf(sys.flags.optimize >= 2,
|
||||
"Docstrings are omitted with -O2 and above")
|
||||
def testGetSubTestDescriptionWithOneLineDocstring(self):
|
||||
"""Tests getDescription() for a method with a docstring."""
|
||||
result = unittest.TextTestResult(None, True, 1)
|
||||
with self.subTest(foo=1, bar=2):
|
||||
self.assertEqual(
|
||||
result.getDescription(self._subtest),
|
||||
('testGetSubTestDescriptionWithOneLineDocstring '
|
||||
'(' + __name__ + '.Test_TestResult) (bar=2, foo=1)\n'
|
||||
'Tests getDescription() for a method with a docstring.'))
|
||||
|
||||
@unittest.skipIf(sys.flags.optimize >= 2,
|
||||
"Docstrings are omitted with -O2 and above")
|
||||
def testGetDescriptionWithMultiLineDocstring(self):
|
||||
"""Tests getDescription() for a method with a longer docstring.
|
||||
The second line of the docstring.
|
||||
"""
|
||||
result = unittest.TextTestResult(None, True, 1)
|
||||
self.assertEqual(
|
||||
result.getDescription(self),
|
||||
('testGetDescriptionWithMultiLineDocstring '
|
||||
'(' + __name__ + '.Test_TestResult)\n'
|
||||
'Tests getDescription() for a method with a longer '
|
||||
'docstring.'))
|
||||
|
||||
@unittest.skipIf(sys.flags.optimize >= 2,
|
||||
"Docstrings are omitted with -O2 and above")
|
||||
def testGetSubTestDescriptionWithMultiLineDocstring(self):
|
||||
"""Tests getDescription() for a method with a longer docstring.
|
||||
The second line of the docstring.
|
||||
"""
|
||||
result = unittest.TextTestResult(None, True, 1)
|
||||
with self.subTest(foo=1, bar=2):
|
||||
self.assertEqual(
|
||||
result.getDescription(self._subtest),
|
||||
('testGetSubTestDescriptionWithMultiLineDocstring '
|
||||
'(' + __name__ + '.Test_TestResult) (bar=2, foo=1)\n'
|
||||
'Tests getDescription() for a method with a longer '
|
||||
'docstring.'))
|
||||
|
||||
def testStackFrameTrimming(self):
|
||||
class Frame(object):
|
||||
class tb_frame(object):
|
||||
f_globals = {}
|
||||
result = unittest.TestResult()
|
||||
self.assertFalse(result._is_relevant_tb_level(Frame))
|
||||
|
||||
Frame.tb_frame.f_globals['__unittest'] = True
|
||||
self.assertTrue(result._is_relevant_tb_level(Frame))
|
||||
|
||||
def testFailFast(self):
|
||||
result = unittest.TestResult()
|
||||
result._exc_info_to_string = lambda *_: ''
|
||||
result.failfast = True
|
||||
result.addError(None, None)
|
||||
self.assertTrue(result.shouldStop)
|
||||
|
||||
result = unittest.TestResult()
|
||||
result._exc_info_to_string = lambda *_: ''
|
||||
result.failfast = True
|
||||
result.addFailure(None, None)
|
||||
self.assertTrue(result.shouldStop)
|
||||
|
||||
result = unittest.TestResult()
|
||||
result._exc_info_to_string = lambda *_: ''
|
||||
result.failfast = True
|
||||
result.addUnexpectedSuccess(None)
|
||||
self.assertTrue(result.shouldStop)
|
||||
|
||||
def testFailFastSetByRunner(self):
|
||||
runner = unittest.TextTestRunner(stream=io.StringIO(), failfast=True)
|
||||
def test(result):
|
||||
self.assertTrue(result.failfast)
|
||||
result = runner.run(test)
|
||||
|
||||
|
||||
classDict = dict(unittest.TestResult.__dict__)
|
||||
for m in ('addSkip', 'addExpectedFailure', 'addUnexpectedSuccess',
|
||||
'__init__'):
|
||||
del classDict[m]
|
||||
|
||||
def __init__(self, stream=None, descriptions=None, verbosity=None):
|
||||
self.failures = []
|
||||
self.errors = []
|
||||
self.testsRun = 0
|
||||
self.shouldStop = False
|
||||
self.buffer = False
|
||||
self.tb_locals = False
|
||||
|
||||
classDict['__init__'] = __init__
|
||||
OldResult = type('OldResult', (object,), classDict)
|
||||
|
||||
class Test_OldTestResult(unittest.TestCase):
|
||||
|
||||
def assertOldResultWarning(self, test, failures):
|
||||
with support.check_warnings(("TestResult has no add.+ method,",
|
||||
RuntimeWarning)):
|
||||
result = OldResult()
|
||||
test.run(result)
|
||||
self.assertEqual(len(result.failures), failures)
|
||||
|
||||
def testOldTestResult(self):
|
||||
class Test(unittest.TestCase):
|
||||
def testSkip(self):
|
||||
self.skipTest('foobar')
|
||||
@unittest.expectedFailure
|
||||
def testExpectedFail(self):
|
||||
raise TypeError
|
||||
@unittest.expectedFailure
|
||||
def testUnexpectedSuccess(self):
|
||||
pass
|
||||
|
||||
for test_name, should_pass in (('testSkip', True),
|
||||
('testExpectedFail', True),
|
||||
('testUnexpectedSuccess', False)):
|
||||
test = Test(test_name)
|
||||
self.assertOldResultWarning(test, int(not should_pass))
|
||||
|
||||
def testOldTestTesultSetup(self):
|
||||
class Test(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest('no reason')
|
||||
def testFoo(self):
|
||||
pass
|
||||
self.assertOldResultWarning(Test('testFoo'), 0)
|
||||
|
||||
def testOldTestResultClass(self):
|
||||
@unittest.skip('no reason')
|
||||
class Test(unittest.TestCase):
|
||||
def testFoo(self):
|
||||
pass
|
||||
self.assertOldResultWarning(Test('testFoo'), 0)
|
||||
|
||||
def testOldResultWithRunner(self):
|
||||
class Test(unittest.TestCase):
|
||||
def testFoo(self):
|
||||
pass
|
||||
runner = unittest.TextTestRunner(resultclass=OldResult,
|
||||
stream=io.StringIO())
|
||||
# This will raise an exception if TextTestRunner can't handle old
|
||||
# test result objects
|
||||
runner.run(Test('testFoo'))
|
||||
|
||||
|
||||
class TestOutputBuffering(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self._real_out = sys.stdout
|
||||
self._real_err = sys.stderr
|
||||
|
||||
def tearDown(self):
|
||||
sys.stdout = self._real_out
|
||||
sys.stderr = self._real_err
|
||||
|
||||
def testBufferOutputOff(self):
|
||||
real_out = self._real_out
|
||||
real_err = self._real_err
|
||||
|
||||
result = unittest.TestResult()
|
||||
self.assertFalse(result.buffer)
|
||||
|
||||
self.assertIs(real_out, sys.stdout)
|
||||
self.assertIs(real_err, sys.stderr)
|
||||
|
||||
result.startTest(self)
|
||||
|
||||
self.assertIs(real_out, sys.stdout)
|
||||
self.assertIs(real_err, sys.stderr)
|
||||
|
||||
def testBufferOutputStartTestAddSuccess(self):
|
||||
real_out = self._real_out
|
||||
real_err = self._real_err
|
||||
|
||||
result = unittest.TestResult()
|
||||
self.assertFalse(result.buffer)
|
||||
|
||||
result.buffer = True
|
||||
|
||||
self.assertIs(real_out, sys.stdout)
|
||||
self.assertIs(real_err, sys.stderr)
|
||||
|
||||
result.startTest(self)
|
||||
|
||||
self.assertIsNot(real_out, sys.stdout)
|
||||
self.assertIsNot(real_err, sys.stderr)
|
||||
self.assertIsInstance(sys.stdout, io.StringIO)
|
||||
self.assertIsInstance(sys.stderr, io.StringIO)
|
||||
self.assertIsNot(sys.stdout, sys.stderr)
|
||||
|
||||
out_stream = sys.stdout
|
||||
err_stream = sys.stderr
|
||||
|
||||
result._original_stdout = io.StringIO()
|
||||
result._original_stderr = io.StringIO()
|
||||
|
||||
print('foo')
|
||||
print('bar', file=sys.stderr)
|
||||
|
||||
self.assertEqual(out_stream.getvalue(), 'foo\n')
|
||||
self.assertEqual(err_stream.getvalue(), 'bar\n')
|
||||
|
||||
self.assertEqual(result._original_stdout.getvalue(), '')
|
||||
self.assertEqual(result._original_stderr.getvalue(), '')
|
||||
|
||||
result.addSuccess(self)
|
||||
result.stopTest(self)
|
||||
|
||||
self.assertIs(sys.stdout, result._original_stdout)
|
||||
self.assertIs(sys.stderr, result._original_stderr)
|
||||
|
||||
self.assertEqual(result._original_stdout.getvalue(), '')
|
||||
self.assertEqual(result._original_stderr.getvalue(), '')
|
||||
|
||||
self.assertEqual(out_stream.getvalue(), '')
|
||||
self.assertEqual(err_stream.getvalue(), '')
|
||||
|
||||
|
||||
def getStartedResult(self):
|
||||
result = unittest.TestResult()
|
||||
result.buffer = True
|
||||
result.startTest(self)
|
||||
return result
|
||||
|
||||
def testBufferOutputAddErrorOrFailure(self):
|
||||
unittest.result.traceback = MockTraceback
|
||||
self.addCleanup(restore_traceback)
|
||||
|
||||
for message_attr, add_attr, include_error in [
|
||||
('errors', 'addError', True),
|
||||
('failures', 'addFailure', False),
|
||||
('errors', 'addError', True),
|
||||
('failures', 'addFailure', False)
|
||||
]:
|
||||
result = self.getStartedResult()
|
||||
buffered_out = sys.stdout
|
||||
buffered_err = sys.stderr
|
||||
result._original_stdout = io.StringIO()
|
||||
result._original_stderr = io.StringIO()
|
||||
|
||||
print('foo', file=sys.stdout)
|
||||
if include_error:
|
||||
print('bar', file=sys.stderr)
|
||||
|
||||
|
||||
addFunction = getattr(result, add_attr)
|
||||
addFunction(self, (None, None, None))
|
||||
result.stopTest(self)
|
||||
|
||||
result_list = getattr(result, message_attr)
|
||||
self.assertEqual(len(result_list), 1)
|
||||
|
||||
test, message = result_list[0]
|
||||
expectedOutMessage = textwrap.dedent("""
|
||||
Stdout:
|
||||
foo
|
||||
""")
|
||||
expectedErrMessage = ''
|
||||
if include_error:
|
||||
expectedErrMessage = textwrap.dedent("""
|
||||
Stderr:
|
||||
bar
|
||||
""")
|
||||
|
||||
expectedFullMessage = 'A traceback%s%s' % (expectedOutMessage, expectedErrMessage)
|
||||
|
||||
self.assertIs(test, self)
|
||||
self.assertEqual(result._original_stdout.getvalue(), expectedOutMessage)
|
||||
self.assertEqual(result._original_stderr.getvalue(), expectedErrMessage)
|
||||
self.assertMultiLineEqual(message, expectedFullMessage)
|
||||
|
||||
def testBufferSetupClass(self):
|
||||
result = unittest.TestResult()
|
||||
result.buffer = True
|
||||
|
||||
class Foo(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
1/0
|
||||
def test_foo(self):
|
||||
pass
|
||||
suite = unittest.TestSuite([Foo('test_foo')])
|
||||
suite(result)
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
|
||||
def testBufferTearDownClass(self):
|
||||
result = unittest.TestResult()
|
||||
result.buffer = True
|
||||
|
||||
class Foo(unittest.TestCase):
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
1/0
|
||||
def test_foo(self):
|
||||
pass
|
||||
suite = unittest.TestSuite([Foo('test_foo')])
|
||||
suite(result)
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
|
||||
def testBufferSetUpModule(self):
|
||||
result = unittest.TestResult()
|
||||
result.buffer = True
|
||||
|
||||
class Foo(unittest.TestCase):
|
||||
def test_foo(self):
|
||||
pass
|
||||
class Module(object):
|
||||
@staticmethod
|
||||
def setUpModule():
|
||||
1/0
|
||||
|
||||
Foo.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
self.addCleanup(sys.modules.pop, 'Module')
|
||||
suite = unittest.TestSuite([Foo('test_foo')])
|
||||
suite(result)
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
|
||||
def testBufferTearDownModule(self):
|
||||
result = unittest.TestResult()
|
||||
result.buffer = True
|
||||
|
||||
class Foo(unittest.TestCase):
|
||||
def test_foo(self):
|
||||
pass
|
||||
class Module(object):
|
||||
@staticmethod
|
||||
def tearDownModule():
|
||||
1/0
|
||||
|
||||
Foo.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
self.addCleanup(sys.modules.pop, 'Module')
|
||||
suite = unittest.TestSuite([Foo('test_foo')])
|
||||
suite(result)
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
353
third_party/python/Lib/unittest/test/test_runner.py
vendored
Normal file
353
third_party/python/Lib/unittest/test/test_runner.py
vendored
Normal file
|
@ -0,0 +1,353 @@
|
|||
import io
|
||||
import os
|
||||
import sys
|
||||
import pickle
|
||||
import subprocess
|
||||
|
||||
import unittest
|
||||
from unittest.case import _Outcome
|
||||
|
||||
from unittest.test.support import (LoggingResult,
|
||||
ResultWithNoStartTestRunStopTestRun)
|
||||
|
||||
|
||||
class TestCleanUp(unittest.TestCase):
|
||||
|
||||
def testCleanUp(self):
|
||||
class TestableTest(unittest.TestCase):
|
||||
def testNothing(self):
|
||||
pass
|
||||
|
||||
test = TestableTest('testNothing')
|
||||
self.assertEqual(test._cleanups, [])
|
||||
|
||||
cleanups = []
|
||||
|
||||
def cleanup1(*args, **kwargs):
|
||||
cleanups.append((1, args, kwargs))
|
||||
|
||||
def cleanup2(*args, **kwargs):
|
||||
cleanups.append((2, args, kwargs))
|
||||
|
||||
test.addCleanup(cleanup1, 1, 2, 3, four='hello', five='goodbye')
|
||||
test.addCleanup(cleanup2)
|
||||
|
||||
self.assertEqual(test._cleanups,
|
||||
[(cleanup1, (1, 2, 3), dict(four='hello', five='goodbye')),
|
||||
(cleanup2, (), {})])
|
||||
|
||||
self.assertTrue(test.doCleanups())
|
||||
self.assertEqual(cleanups, [(2, (), {}), (1, (1, 2, 3), dict(four='hello', five='goodbye'))])
|
||||
|
||||
def testCleanUpWithErrors(self):
|
||||
class TestableTest(unittest.TestCase):
|
||||
def testNothing(self):
|
||||
pass
|
||||
|
||||
test = TestableTest('testNothing')
|
||||
outcome = test._outcome = _Outcome()
|
||||
|
||||
exc1 = Exception('foo')
|
||||
exc2 = Exception('bar')
|
||||
def cleanup1():
|
||||
raise exc1
|
||||
|
||||
def cleanup2():
|
||||
raise exc2
|
||||
|
||||
test.addCleanup(cleanup1)
|
||||
test.addCleanup(cleanup2)
|
||||
|
||||
self.assertFalse(test.doCleanups())
|
||||
self.assertFalse(outcome.success)
|
||||
|
||||
((_, (Type1, instance1, _)),
|
||||
(_, (Type2, instance2, _))) = reversed(outcome.errors)
|
||||
self.assertEqual((Type1, instance1), (Exception, exc1))
|
||||
self.assertEqual((Type2, instance2), (Exception, exc2))
|
||||
|
||||
def testCleanupInRun(self):
|
||||
blowUp = False
|
||||
ordering = []
|
||||
|
||||
class TestableTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
ordering.append('setUp')
|
||||
if blowUp:
|
||||
raise Exception('foo')
|
||||
|
||||
def testNothing(self):
|
||||
ordering.append('test')
|
||||
|
||||
def tearDown(self):
|
||||
ordering.append('tearDown')
|
||||
|
||||
test = TestableTest('testNothing')
|
||||
|
||||
def cleanup1():
|
||||
ordering.append('cleanup1')
|
||||
def cleanup2():
|
||||
ordering.append('cleanup2')
|
||||
test.addCleanup(cleanup1)
|
||||
test.addCleanup(cleanup2)
|
||||
|
||||
def success(some_test):
|
||||
self.assertEqual(some_test, test)
|
||||
ordering.append('success')
|
||||
|
||||
result = unittest.TestResult()
|
||||
result.addSuccess = success
|
||||
|
||||
test.run(result)
|
||||
self.assertEqual(ordering, ['setUp', 'test', 'tearDown',
|
||||
'cleanup2', 'cleanup1', 'success'])
|
||||
|
||||
blowUp = True
|
||||
ordering = []
|
||||
test = TestableTest('testNothing')
|
||||
test.addCleanup(cleanup1)
|
||||
test.run(result)
|
||||
self.assertEqual(ordering, ['setUp', 'cleanup1'])
|
||||
|
||||
def testTestCaseDebugExecutesCleanups(self):
|
||||
ordering = []
|
||||
|
||||
class TestableTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
ordering.append('setUp')
|
||||
self.addCleanup(cleanup1)
|
||||
|
||||
def testNothing(self):
|
||||
ordering.append('test')
|
||||
|
||||
def tearDown(self):
|
||||
ordering.append('tearDown')
|
||||
|
||||
test = TestableTest('testNothing')
|
||||
|
||||
def cleanup1():
|
||||
ordering.append('cleanup1')
|
||||
test.addCleanup(cleanup2)
|
||||
def cleanup2():
|
||||
ordering.append('cleanup2')
|
||||
|
||||
test.debug()
|
||||
self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2'])
|
||||
|
||||
|
||||
class Test_TextTestRunner(unittest.TestCase):
|
||||
"""Tests for TextTestRunner."""
|
||||
|
||||
def setUp(self):
|
||||
# clean the environment from pre-existing PYTHONWARNINGS to make
|
||||
# test_warnings results consistent
|
||||
self.pythonwarnings = os.environ.get('PYTHONWARNINGS')
|
||||
if self.pythonwarnings:
|
||||
del os.environ['PYTHONWARNINGS']
|
||||
|
||||
def tearDown(self):
|
||||
# bring back pre-existing PYTHONWARNINGS if present
|
||||
if self.pythonwarnings:
|
||||
os.environ['PYTHONWARNINGS'] = self.pythonwarnings
|
||||
|
||||
def test_init(self):
|
||||
runner = unittest.TextTestRunner()
|
||||
self.assertFalse(runner.failfast)
|
||||
self.assertFalse(runner.buffer)
|
||||
self.assertEqual(runner.verbosity, 1)
|
||||
self.assertEqual(runner.warnings, None)
|
||||
self.assertTrue(runner.descriptions)
|
||||
self.assertEqual(runner.resultclass, unittest.TextTestResult)
|
||||
self.assertFalse(runner.tb_locals)
|
||||
|
||||
def test_multiple_inheritance(self):
|
||||
class AResult(unittest.TestResult):
|
||||
def __init__(self, stream, descriptions, verbosity):
|
||||
super(AResult, self).__init__(stream, descriptions, verbosity)
|
||||
|
||||
class ATextResult(unittest.TextTestResult, AResult):
|
||||
pass
|
||||
|
||||
# This used to raise an exception due to TextTestResult not passing
|
||||
# on arguments in its __init__ super call
|
||||
ATextResult(None, None, 1)
|
||||
|
||||
def testBufferAndFailfast(self):
|
||||
class Test(unittest.TestCase):
|
||||
def testFoo(self):
|
||||
pass
|
||||
result = unittest.TestResult()
|
||||
runner = unittest.TextTestRunner(stream=io.StringIO(), failfast=True,
|
||||
buffer=True)
|
||||
# Use our result object
|
||||
runner._makeResult = lambda: result
|
||||
runner.run(Test('testFoo'))
|
||||
|
||||
self.assertTrue(result.failfast)
|
||||
self.assertTrue(result.buffer)
|
||||
|
||||
def test_locals(self):
|
||||
runner = unittest.TextTestRunner(stream=io.StringIO(), tb_locals=True)
|
||||
result = runner.run(unittest.TestSuite())
|
||||
self.assertEqual(True, result.tb_locals)
|
||||
|
||||
def testRunnerRegistersResult(self):
|
||||
class Test(unittest.TestCase):
|
||||
def testFoo(self):
|
||||
pass
|
||||
originalRegisterResult = unittest.runner.registerResult
|
||||
def cleanup():
|
||||
unittest.runner.registerResult = originalRegisterResult
|
||||
self.addCleanup(cleanup)
|
||||
|
||||
result = unittest.TestResult()
|
||||
runner = unittest.TextTestRunner(stream=io.StringIO())
|
||||
# Use our result object
|
||||
runner._makeResult = lambda: result
|
||||
|
||||
self.wasRegistered = 0
|
||||
def fakeRegisterResult(thisResult):
|
||||
self.wasRegistered += 1
|
||||
self.assertEqual(thisResult, result)
|
||||
unittest.runner.registerResult = fakeRegisterResult
|
||||
|
||||
runner.run(unittest.TestSuite())
|
||||
self.assertEqual(self.wasRegistered, 1)
|
||||
|
||||
def test_works_with_result_without_startTestRun_stopTestRun(self):
|
||||
class OldTextResult(ResultWithNoStartTestRunStopTestRun):
|
||||
separator2 = ''
|
||||
def printErrors(self):
|
||||
pass
|
||||
|
||||
class Runner(unittest.TextTestRunner):
|
||||
def __init__(self):
|
||||
super(Runner, self).__init__(io.StringIO())
|
||||
|
||||
def _makeResult(self):
|
||||
return OldTextResult()
|
||||
|
||||
runner = Runner()
|
||||
runner.run(unittest.TestSuite())
|
||||
|
||||
def test_startTestRun_stopTestRun_called(self):
|
||||
class LoggingTextResult(LoggingResult):
|
||||
separator2 = ''
|
||||
def printErrors(self):
|
||||
pass
|
||||
|
||||
class LoggingRunner(unittest.TextTestRunner):
|
||||
def __init__(self, events):
|
||||
super(LoggingRunner, self).__init__(io.StringIO())
|
||||
self._events = events
|
||||
|
||||
def _makeResult(self):
|
||||
return LoggingTextResult(self._events)
|
||||
|
||||
events = []
|
||||
runner = LoggingRunner(events)
|
||||
runner.run(unittest.TestSuite())
|
||||
expected = ['startTestRun', 'stopTestRun']
|
||||
self.assertEqual(events, expected)
|
||||
|
||||
def test_pickle_unpickle(self):
|
||||
# Issue #7197: a TextTestRunner should be (un)pickleable. This is
|
||||
# required by test_multiprocessing under Windows (in verbose mode).
|
||||
stream = io.StringIO("foo")
|
||||
runner = unittest.TextTestRunner(stream)
|
||||
for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1):
|
||||
s = pickle.dumps(runner, protocol)
|
||||
obj = pickle.loads(s)
|
||||
# StringIO objects never compare equal, a cheap test instead.
|
||||
self.assertEqual(obj.stream.getvalue(), stream.getvalue())
|
||||
|
||||
def test_resultclass(self):
|
||||
def MockResultClass(*args):
|
||||
return args
|
||||
STREAM = object()
|
||||
DESCRIPTIONS = object()
|
||||
VERBOSITY = object()
|
||||
runner = unittest.TextTestRunner(STREAM, DESCRIPTIONS, VERBOSITY,
|
||||
resultclass=MockResultClass)
|
||||
self.assertEqual(runner.resultclass, MockResultClass)
|
||||
|
||||
expectedresult = (runner.stream, DESCRIPTIONS, VERBOSITY)
|
||||
self.assertEqual(runner._makeResult(), expectedresult)
|
||||
|
||||
def test_warnings(self):
|
||||
"""
|
||||
Check that warnings argument of TextTestRunner correctly affects the
|
||||
behavior of the warnings.
|
||||
"""
|
||||
# see #10535 and the _test_warnings file for more information
|
||||
|
||||
def get_parse_out_err(p):
|
||||
return [b.splitlines() for b in p.communicate()]
|
||||
opts = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
cwd=os.path.dirname(__file__))
|
||||
ae_msg = b'Please use assertEqual instead.'
|
||||
at_msg = b'Please use assertTrue instead.'
|
||||
|
||||
# no args -> all the warnings are printed, unittest warnings only once
|
||||
p = subprocess.Popen([sys.executable, '_test_warnings.py'], **opts)
|
||||
with p:
|
||||
out, err = get_parse_out_err(p)
|
||||
self.assertIn(b'OK', err)
|
||||
# check that the total number of warnings in the output is correct
|
||||
self.assertEqual(len(out), 12)
|
||||
# check that the numbers of the different kind of warnings is correct
|
||||
for msg in [b'dw', b'iw', b'uw']:
|
||||
self.assertEqual(out.count(msg), 3)
|
||||
for msg in [ae_msg, at_msg, b'rw']:
|
||||
self.assertEqual(out.count(msg), 1)
|
||||
|
||||
args_list = (
|
||||
# passing 'ignore' as warnings arg -> no warnings
|
||||
[sys.executable, '_test_warnings.py', 'ignore'],
|
||||
# -W doesn't affect the result if the arg is passed
|
||||
[sys.executable, '-Wa', '_test_warnings.py', 'ignore'],
|
||||
# -W affects the result if the arg is not passed
|
||||
[sys.executable, '-Wi', '_test_warnings.py']
|
||||
)
|
||||
# in all these cases no warnings are printed
|
||||
for args in args_list:
|
||||
p = subprocess.Popen(args, **opts)
|
||||
with p:
|
||||
out, err = get_parse_out_err(p)
|
||||
self.assertIn(b'OK', err)
|
||||
self.assertEqual(len(out), 0)
|
||||
|
||||
|
||||
# passing 'always' as warnings arg -> all the warnings printed,
|
||||
# unittest warnings only once
|
||||
p = subprocess.Popen([sys.executable, '_test_warnings.py', 'always'],
|
||||
**opts)
|
||||
with p:
|
||||
out, err = get_parse_out_err(p)
|
||||
self.assertIn(b'OK', err)
|
||||
self.assertEqual(len(out), 14)
|
||||
for msg in [b'dw', b'iw', b'uw', b'rw']:
|
||||
self.assertEqual(out.count(msg), 3)
|
||||
for msg in [ae_msg, at_msg]:
|
||||
self.assertEqual(out.count(msg), 1)
|
||||
|
||||
def testStdErrLookedUpAtInstantiationTime(self):
|
||||
# see issue 10786
|
||||
old_stderr = sys.stderr
|
||||
f = io.StringIO()
|
||||
sys.stderr = f
|
||||
try:
|
||||
runner = unittest.TextTestRunner()
|
||||
self.assertTrue(runner.stream.stream is f)
|
||||
finally:
|
||||
sys.stderr = old_stderr
|
||||
|
||||
def testSpecifiedStreamUsed(self):
|
||||
# see issue 10786
|
||||
f = io.StringIO()
|
||||
runner = unittest.TextTestRunner(f)
|
||||
self.assertTrue(runner.stream.stream is f)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
507
third_party/python/Lib/unittest/test/test_setups.py
vendored
Normal file
507
third_party/python/Lib/unittest/test/test_setups.py
vendored
Normal file
|
@ -0,0 +1,507 @@
|
|||
import io
|
||||
import sys
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
def resultFactory(*_):
|
||||
return unittest.TestResult()
|
||||
|
||||
|
||||
class TestSetups(unittest.TestCase):
|
||||
|
||||
def getRunner(self):
|
||||
return unittest.TextTestRunner(resultclass=resultFactory,
|
||||
stream=io.StringIO())
|
||||
def runTests(self, *cases):
|
||||
suite = unittest.TestSuite()
|
||||
for case in cases:
|
||||
tests = unittest.defaultTestLoader.loadTestsFromTestCase(case)
|
||||
suite.addTests(tests)
|
||||
|
||||
runner = self.getRunner()
|
||||
|
||||
# creating a nested suite exposes some potential bugs
|
||||
realSuite = unittest.TestSuite()
|
||||
realSuite.addTest(suite)
|
||||
# adding empty suites to the end exposes potential bugs
|
||||
suite.addTest(unittest.TestSuite())
|
||||
realSuite.addTest(unittest.TestSuite())
|
||||
return runner.run(realSuite)
|
||||
|
||||
def test_setup_class(self):
|
||||
class Test(unittest.TestCase):
|
||||
setUpCalled = 0
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
Test.setUpCalled += 1
|
||||
unittest.TestCase.setUpClass()
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
|
||||
result = self.runTests(Test)
|
||||
|
||||
self.assertEqual(Test.setUpCalled, 1)
|
||||
self.assertEqual(result.testsRun, 2)
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
|
||||
def test_teardown_class(self):
|
||||
class Test(unittest.TestCase):
|
||||
tearDownCalled = 0
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
Test.tearDownCalled += 1
|
||||
unittest.TestCase.tearDownClass()
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
|
||||
result = self.runTests(Test)
|
||||
|
||||
self.assertEqual(Test.tearDownCalled, 1)
|
||||
self.assertEqual(result.testsRun, 2)
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
|
||||
def test_teardown_class_two_classes(self):
|
||||
class Test(unittest.TestCase):
|
||||
tearDownCalled = 0
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
Test.tearDownCalled += 1
|
||||
unittest.TestCase.tearDownClass()
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
|
||||
class Test2(unittest.TestCase):
|
||||
tearDownCalled = 0
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
Test2.tearDownCalled += 1
|
||||
unittest.TestCase.tearDownClass()
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
|
||||
result = self.runTests(Test, Test2)
|
||||
|
||||
self.assertEqual(Test.tearDownCalled, 1)
|
||||
self.assertEqual(Test2.tearDownCalled, 1)
|
||||
self.assertEqual(result.testsRun, 4)
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
|
||||
def test_error_in_setupclass(self):
|
||||
class BrokenTest(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
raise TypeError('foo')
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
|
||||
result = self.runTests(BrokenTest)
|
||||
|
||||
self.assertEqual(result.testsRun, 0)
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
error, _ = result.errors[0]
|
||||
self.assertEqual(str(error),
|
||||
'setUpClass (%s.%s)' % (__name__, BrokenTest.__qualname__))
|
||||
|
||||
def test_error_in_teardown_class(self):
|
||||
class Test(unittest.TestCase):
|
||||
tornDown = 0
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
Test.tornDown += 1
|
||||
raise TypeError('foo')
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
|
||||
class Test2(unittest.TestCase):
|
||||
tornDown = 0
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
Test2.tornDown += 1
|
||||
raise TypeError('foo')
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
|
||||
result = self.runTests(Test, Test2)
|
||||
self.assertEqual(result.testsRun, 4)
|
||||
self.assertEqual(len(result.errors), 2)
|
||||
self.assertEqual(Test.tornDown, 1)
|
||||
self.assertEqual(Test2.tornDown, 1)
|
||||
|
||||
error, _ = result.errors[0]
|
||||
self.assertEqual(str(error),
|
||||
'tearDownClass (%s.%s)' % (__name__, Test.__qualname__))
|
||||
|
||||
def test_class_not_torndown_when_setup_fails(self):
|
||||
class Test(unittest.TestCase):
|
||||
tornDown = False
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
raise TypeError
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
Test.tornDown = True
|
||||
raise TypeError('foo')
|
||||
def test_one(self):
|
||||
pass
|
||||
|
||||
self.runTests(Test)
|
||||
self.assertFalse(Test.tornDown)
|
||||
|
||||
def test_class_not_setup_or_torndown_when_skipped(self):
|
||||
class Test(unittest.TestCase):
|
||||
classSetUp = False
|
||||
tornDown = False
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
Test.classSetUp = True
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
Test.tornDown = True
|
||||
def test_one(self):
|
||||
pass
|
||||
|
||||
Test = unittest.skip("hop")(Test)
|
||||
self.runTests(Test)
|
||||
self.assertFalse(Test.classSetUp)
|
||||
self.assertFalse(Test.tornDown)
|
||||
|
||||
def test_setup_teardown_order_with_pathological_suite(self):
|
||||
results = []
|
||||
|
||||
class Module1(object):
|
||||
@staticmethod
|
||||
def setUpModule():
|
||||
results.append('Module1.setUpModule')
|
||||
@staticmethod
|
||||
def tearDownModule():
|
||||
results.append('Module1.tearDownModule')
|
||||
|
||||
class Module2(object):
|
||||
@staticmethod
|
||||
def setUpModule():
|
||||
results.append('Module2.setUpModule')
|
||||
@staticmethod
|
||||
def tearDownModule():
|
||||
results.append('Module2.tearDownModule')
|
||||
|
||||
class Test1(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
results.append('setup 1')
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
results.append('teardown 1')
|
||||
def testOne(self):
|
||||
results.append('Test1.testOne')
|
||||
def testTwo(self):
|
||||
results.append('Test1.testTwo')
|
||||
|
||||
class Test2(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
results.append('setup 2')
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
results.append('teardown 2')
|
||||
def testOne(self):
|
||||
results.append('Test2.testOne')
|
||||
def testTwo(self):
|
||||
results.append('Test2.testTwo')
|
||||
|
||||
class Test3(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
results.append('setup 3')
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
results.append('teardown 3')
|
||||
def testOne(self):
|
||||
results.append('Test3.testOne')
|
||||
def testTwo(self):
|
||||
results.append('Test3.testTwo')
|
||||
|
||||
Test1.__module__ = Test2.__module__ = 'Module'
|
||||
Test3.__module__ = 'Module2'
|
||||
sys.modules['Module'] = Module1
|
||||
sys.modules['Module2'] = Module2
|
||||
|
||||
first = unittest.TestSuite((Test1('testOne'),))
|
||||
second = unittest.TestSuite((Test1('testTwo'),))
|
||||
third = unittest.TestSuite((Test2('testOne'),))
|
||||
fourth = unittest.TestSuite((Test2('testTwo'),))
|
||||
fifth = unittest.TestSuite((Test3('testOne'),))
|
||||
sixth = unittest.TestSuite((Test3('testTwo'),))
|
||||
suite = unittest.TestSuite((first, second, third, fourth, fifth, sixth))
|
||||
|
||||
runner = self.getRunner()
|
||||
result = runner.run(suite)
|
||||
self.assertEqual(result.testsRun, 6)
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
|
||||
self.assertEqual(results,
|
||||
['Module1.setUpModule', 'setup 1',
|
||||
'Test1.testOne', 'Test1.testTwo', 'teardown 1',
|
||||
'setup 2', 'Test2.testOne', 'Test2.testTwo',
|
||||
'teardown 2', 'Module1.tearDownModule',
|
||||
'Module2.setUpModule', 'setup 3',
|
||||
'Test3.testOne', 'Test3.testTwo',
|
||||
'teardown 3', 'Module2.tearDownModule'])
|
||||
|
||||
def test_setup_module(self):
|
||||
class Module(object):
|
||||
moduleSetup = 0
|
||||
@staticmethod
|
||||
def setUpModule():
|
||||
Module.moduleSetup += 1
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
Test.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
|
||||
result = self.runTests(Test)
|
||||
self.assertEqual(Module.moduleSetup, 1)
|
||||
self.assertEqual(result.testsRun, 2)
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
|
||||
def test_error_in_setup_module(self):
|
||||
class Module(object):
|
||||
moduleSetup = 0
|
||||
moduleTornDown = 0
|
||||
@staticmethod
|
||||
def setUpModule():
|
||||
Module.moduleSetup += 1
|
||||
raise TypeError('foo')
|
||||
@staticmethod
|
||||
def tearDownModule():
|
||||
Module.moduleTornDown += 1
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
classSetUp = False
|
||||
classTornDown = False
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
Test.classSetUp = True
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
Test.classTornDown = True
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
|
||||
class Test2(unittest.TestCase):
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
Test.__module__ = 'Module'
|
||||
Test2.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
|
||||
result = self.runTests(Test, Test2)
|
||||
self.assertEqual(Module.moduleSetup, 1)
|
||||
self.assertEqual(Module.moduleTornDown, 0)
|
||||
self.assertEqual(result.testsRun, 0)
|
||||
self.assertFalse(Test.classSetUp)
|
||||
self.assertFalse(Test.classTornDown)
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
error, _ = result.errors[0]
|
||||
self.assertEqual(str(error), 'setUpModule (Module)')
|
||||
|
||||
def test_testcase_with_missing_module(self):
|
||||
class Test(unittest.TestCase):
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
Test.__module__ = 'Module'
|
||||
sys.modules.pop('Module', None)
|
||||
|
||||
result = self.runTests(Test)
|
||||
self.assertEqual(result.testsRun, 2)
|
||||
|
||||
def test_teardown_module(self):
|
||||
class Module(object):
|
||||
moduleTornDown = 0
|
||||
@staticmethod
|
||||
def tearDownModule():
|
||||
Module.moduleTornDown += 1
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
Test.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
|
||||
result = self.runTests(Test)
|
||||
self.assertEqual(Module.moduleTornDown, 1)
|
||||
self.assertEqual(result.testsRun, 2)
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
|
||||
def test_error_in_teardown_module(self):
|
||||
class Module(object):
|
||||
moduleTornDown = 0
|
||||
@staticmethod
|
||||
def tearDownModule():
|
||||
Module.moduleTornDown += 1
|
||||
raise TypeError('foo')
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
classSetUp = False
|
||||
classTornDown = False
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
Test.classSetUp = True
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
Test.classTornDown = True
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
|
||||
class Test2(unittest.TestCase):
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
Test.__module__ = 'Module'
|
||||
Test2.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
|
||||
result = self.runTests(Test, Test2)
|
||||
self.assertEqual(Module.moduleTornDown, 1)
|
||||
self.assertEqual(result.testsRun, 4)
|
||||
self.assertTrue(Test.classSetUp)
|
||||
self.assertTrue(Test.classTornDown)
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
error, _ = result.errors[0]
|
||||
self.assertEqual(str(error), 'tearDownModule (Module)')
|
||||
|
||||
def test_skiptest_in_setupclass(self):
|
||||
class Test(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
raise unittest.SkipTest('foo')
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
|
||||
result = self.runTests(Test)
|
||||
self.assertEqual(result.testsRun, 0)
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
self.assertEqual(len(result.skipped), 1)
|
||||
skipped = result.skipped[0][0]
|
||||
self.assertEqual(str(skipped),
|
||||
'setUpClass (%s.%s)' % (__name__, Test.__qualname__))
|
||||
|
||||
def test_skiptest_in_setupmodule(self):
|
||||
class Test(unittest.TestCase):
|
||||
def test_one(self):
|
||||
pass
|
||||
def test_two(self):
|
||||
pass
|
||||
|
||||
class Module(object):
|
||||
@staticmethod
|
||||
def setUpModule():
|
||||
raise unittest.SkipTest('foo')
|
||||
|
||||
Test.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
|
||||
result = self.runTests(Test)
|
||||
self.assertEqual(result.testsRun, 0)
|
||||
self.assertEqual(len(result.errors), 0)
|
||||
self.assertEqual(len(result.skipped), 1)
|
||||
skipped = result.skipped[0][0]
|
||||
self.assertEqual(str(skipped), 'setUpModule (Module)')
|
||||
|
||||
def test_suite_debug_executes_setups_and_teardowns(self):
|
||||
ordering = []
|
||||
|
||||
class Module(object):
|
||||
@staticmethod
|
||||
def setUpModule():
|
||||
ordering.append('setUpModule')
|
||||
@staticmethod
|
||||
def tearDownModule():
|
||||
ordering.append('tearDownModule')
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
ordering.append('setUpClass')
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
ordering.append('tearDownClass')
|
||||
def test_something(self):
|
||||
ordering.append('test_something')
|
||||
|
||||
Test.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
|
||||
suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test)
|
||||
suite.debug()
|
||||
expectedOrder = ['setUpModule', 'setUpClass', 'test_something', 'tearDownClass', 'tearDownModule']
|
||||
self.assertEqual(ordering, expectedOrder)
|
||||
|
||||
def test_suite_debug_propagates_exceptions(self):
|
||||
class Module(object):
|
||||
@staticmethod
|
||||
def setUpModule():
|
||||
if phase == 0:
|
||||
raise Exception('setUpModule')
|
||||
@staticmethod
|
||||
def tearDownModule():
|
||||
if phase == 1:
|
||||
raise Exception('tearDownModule')
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
if phase == 2:
|
||||
raise Exception('setUpClass')
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
if phase == 3:
|
||||
raise Exception('tearDownClass')
|
||||
def test_something(self):
|
||||
if phase == 4:
|
||||
raise Exception('test_something')
|
||||
|
||||
Test.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
|
||||
messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something')
|
||||
for phase, msg in enumerate(messages):
|
||||
_suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test)
|
||||
suite = unittest.TestSuite([_suite])
|
||||
with self.assertRaisesRegex(Exception, msg):
|
||||
suite.debug()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
260
third_party/python/Lib/unittest/test/test_skipping.py
vendored
Normal file
260
third_party/python/Lib/unittest/test/test_skipping.py
vendored
Normal file
|
@ -0,0 +1,260 @@
|
|||
import unittest
|
||||
|
||||
from unittest.test.support import LoggingResult
|
||||
|
||||
|
||||
class Test_TestSkipping(unittest.TestCase):
|
||||
|
||||
def test_skipping(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_skip_me(self):
|
||||
self.skipTest("skip")
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
test = Foo("test_skip_me")
|
||||
test.run(result)
|
||||
self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
|
||||
self.assertEqual(result.skipped, [(test, "skip")])
|
||||
|
||||
# Try letting setUp skip the test now.
|
||||
class Foo(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.skipTest("testing")
|
||||
def test_nothing(self): pass
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
test = Foo("test_nothing")
|
||||
test.run(result)
|
||||
self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
|
||||
self.assertEqual(result.skipped, [(test, "testing")])
|
||||
self.assertEqual(result.testsRun, 1)
|
||||
|
||||
def test_skipping_subtests(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_skip_me(self):
|
||||
with self.subTest(a=1):
|
||||
with self.subTest(b=2):
|
||||
self.skipTest("skip 1")
|
||||
self.skipTest("skip 2")
|
||||
self.skipTest("skip 3")
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
test = Foo("test_skip_me")
|
||||
test.run(result)
|
||||
self.assertEqual(events, ['startTest', 'addSkip', 'addSkip',
|
||||
'addSkip', 'stopTest'])
|
||||
self.assertEqual(len(result.skipped), 3)
|
||||
subtest, msg = result.skipped[0]
|
||||
self.assertEqual(msg, "skip 1")
|
||||
self.assertIsInstance(subtest, unittest.TestCase)
|
||||
self.assertIsNot(subtest, test)
|
||||
subtest, msg = result.skipped[1]
|
||||
self.assertEqual(msg, "skip 2")
|
||||
self.assertIsInstance(subtest, unittest.TestCase)
|
||||
self.assertIsNot(subtest, test)
|
||||
self.assertEqual(result.skipped[2], (test, "skip 3"))
|
||||
|
||||
def test_skipping_decorators(self):
|
||||
op_table = ((unittest.skipUnless, False, True),
|
||||
(unittest.skipIf, True, False))
|
||||
for deco, do_skip, dont_skip in op_table:
|
||||
class Foo(unittest.TestCase):
|
||||
@deco(do_skip, "testing")
|
||||
def test_skip(self): pass
|
||||
|
||||
@deco(dont_skip, "testing")
|
||||
def test_dont_skip(self): pass
|
||||
test_do_skip = Foo("test_skip")
|
||||
test_dont_skip = Foo("test_dont_skip")
|
||||
suite = unittest.TestSuite([test_do_skip, test_dont_skip])
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
suite.run(result)
|
||||
self.assertEqual(len(result.skipped), 1)
|
||||
expected = ['startTest', 'addSkip', 'stopTest',
|
||||
'startTest', 'addSuccess', 'stopTest']
|
||||
self.assertEqual(events, expected)
|
||||
self.assertEqual(result.testsRun, 2)
|
||||
self.assertEqual(result.skipped, [(test_do_skip, "testing")])
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
|
||||
def test_skip_class(self):
|
||||
@unittest.skip("testing")
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self):
|
||||
record.append(1)
|
||||
record = []
|
||||
result = unittest.TestResult()
|
||||
test = Foo("test_1")
|
||||
suite = unittest.TestSuite([test])
|
||||
suite.run(result)
|
||||
self.assertEqual(result.skipped, [(test, "testing")])
|
||||
self.assertEqual(record, [])
|
||||
|
||||
def test_skip_non_unittest_class(self):
|
||||
@unittest.skip("testing")
|
||||
class Mixin:
|
||||
def test_1(self):
|
||||
record.append(1)
|
||||
class Foo(Mixin, unittest.TestCase):
|
||||
pass
|
||||
record = []
|
||||
result = unittest.TestResult()
|
||||
test = Foo("test_1")
|
||||
suite = unittest.TestSuite([test])
|
||||
suite.run(result)
|
||||
self.assertEqual(result.skipped, [(test, "testing")])
|
||||
self.assertEqual(record, [])
|
||||
|
||||
def test_expected_failure(self):
|
||||
class Foo(unittest.TestCase):
|
||||
@unittest.expectedFailure
|
||||
def test_die(self):
|
||||
self.fail("help me!")
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
test = Foo("test_die")
|
||||
test.run(result)
|
||||
self.assertEqual(events,
|
||||
['startTest', 'addExpectedFailure', 'stopTest'])
|
||||
self.assertEqual(result.expectedFailures[0][0], test)
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
|
||||
def test_expected_failure_with_wrapped_class(self):
|
||||
@unittest.expectedFailure
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self):
|
||||
self.assertTrue(False)
|
||||
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
test = Foo("test_1")
|
||||
test.run(result)
|
||||
self.assertEqual(events,
|
||||
['startTest', 'addExpectedFailure', 'stopTest'])
|
||||
self.assertEqual(result.expectedFailures[0][0], test)
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
|
||||
def test_expected_failure_with_wrapped_subclass(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self):
|
||||
self.assertTrue(False)
|
||||
|
||||
@unittest.expectedFailure
|
||||
class Bar(Foo):
|
||||
pass
|
||||
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
test = Bar("test_1")
|
||||
test.run(result)
|
||||
self.assertEqual(events,
|
||||
['startTest', 'addExpectedFailure', 'stopTest'])
|
||||
self.assertEqual(result.expectedFailures[0][0], test)
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
|
||||
def test_expected_failure_subtests(self):
|
||||
# A failure in any subtest counts as the expected failure of the
|
||||
# whole test.
|
||||
class Foo(unittest.TestCase):
|
||||
@unittest.expectedFailure
|
||||
def test_die(self):
|
||||
with self.subTest():
|
||||
# This one succeeds
|
||||
pass
|
||||
with self.subTest():
|
||||
self.fail("help me!")
|
||||
with self.subTest():
|
||||
# This one doesn't get executed
|
||||
self.fail("shouldn't come here")
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
test = Foo("test_die")
|
||||
test.run(result)
|
||||
self.assertEqual(events,
|
||||
['startTest', 'addSubTestSuccess',
|
||||
'addExpectedFailure', 'stopTest'])
|
||||
self.assertEqual(len(result.expectedFailures), 1)
|
||||
self.assertIs(result.expectedFailures[0][0], test)
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
|
||||
def test_unexpected_success(self):
|
||||
class Foo(unittest.TestCase):
|
||||
@unittest.expectedFailure
|
||||
def test_die(self):
|
||||
pass
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
test = Foo("test_die")
|
||||
test.run(result)
|
||||
self.assertEqual(events,
|
||||
['startTest', 'addUnexpectedSuccess', 'stopTest'])
|
||||
self.assertFalse(result.failures)
|
||||
self.assertEqual(result.unexpectedSuccesses, [test])
|
||||
self.assertFalse(result.wasSuccessful())
|
||||
|
||||
def test_unexpected_success_subtests(self):
|
||||
# Success in all subtests counts as the unexpected success of
|
||||
# the whole test.
|
||||
class Foo(unittest.TestCase):
|
||||
@unittest.expectedFailure
|
||||
def test_die(self):
|
||||
with self.subTest():
|
||||
# This one succeeds
|
||||
pass
|
||||
with self.subTest():
|
||||
# So does this one
|
||||
pass
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
test = Foo("test_die")
|
||||
test.run(result)
|
||||
self.assertEqual(events,
|
||||
['startTest',
|
||||
'addSubTestSuccess', 'addSubTestSuccess',
|
||||
'addUnexpectedSuccess', 'stopTest'])
|
||||
self.assertFalse(result.failures)
|
||||
self.assertEqual(result.unexpectedSuccesses, [test])
|
||||
self.assertFalse(result.wasSuccessful())
|
||||
|
||||
def test_skip_doesnt_run_setup(self):
|
||||
class Foo(unittest.TestCase):
|
||||
wasSetUp = False
|
||||
wasTornDown = False
|
||||
def setUp(self):
|
||||
Foo.wasSetUp = True
|
||||
def tornDown(self):
|
||||
Foo.wasTornDown = True
|
||||
@unittest.skip('testing')
|
||||
def test_1(self):
|
||||
pass
|
||||
|
||||
result = unittest.TestResult()
|
||||
test = Foo("test_1")
|
||||
suite = unittest.TestSuite([test])
|
||||
suite.run(result)
|
||||
self.assertEqual(result.skipped, [(test, "testing")])
|
||||
self.assertFalse(Foo.wasSetUp)
|
||||
self.assertFalse(Foo.wasTornDown)
|
||||
|
||||
def test_decorated_skip(self):
|
||||
def decorator(func):
|
||||
def inner(*a):
|
||||
return func(*a)
|
||||
return inner
|
||||
|
||||
class Foo(unittest.TestCase):
|
||||
@decorator
|
||||
@unittest.skip('testing')
|
||||
def test_1(self):
|
||||
pass
|
||||
|
||||
result = unittest.TestResult()
|
||||
test = Foo("test_1")
|
||||
suite = unittest.TestSuite([test])
|
||||
suite.run(result)
|
||||
self.assertEqual(result.skipped, [(test, "testing")])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
447
third_party/python/Lib/unittest/test/test_suite.py
vendored
Normal file
447
third_party/python/Lib/unittest/test/test_suite.py
vendored
Normal file
|
@ -0,0 +1,447 @@
|
|||
import unittest
|
||||
|
||||
import gc
|
||||
import sys
|
||||
import weakref
|
||||
from unittest.test.support import LoggingResult, TestEquality
|
||||
|
||||
|
||||
### Support code for Test_TestSuite
|
||||
################################################################
|
||||
|
||||
class Test(object):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self): pass
|
||||
def test_2(self): pass
|
||||
def test_3(self): pass
|
||||
def runTest(self): pass
|
||||
|
||||
def _mk_TestSuite(*names):
|
||||
return unittest.TestSuite(Test.Foo(n) for n in names)
|
||||
|
||||
################################################################
|
||||
|
||||
|
||||
class Test_TestSuite(unittest.TestCase, TestEquality):
|
||||
|
||||
### Set up attributes needed by inherited tests
|
||||
################################################################
|
||||
|
||||
# Used by TestEquality.test_eq
|
||||
eq_pairs = [(unittest.TestSuite(), unittest.TestSuite())
|
||||
,(unittest.TestSuite(), unittest.TestSuite([]))
|
||||
,(_mk_TestSuite('test_1'), _mk_TestSuite('test_1'))]
|
||||
|
||||
# Used by TestEquality.test_ne
|
||||
ne_pairs = [(unittest.TestSuite(), _mk_TestSuite('test_1'))
|
||||
,(unittest.TestSuite([]), _mk_TestSuite('test_1'))
|
||||
,(_mk_TestSuite('test_1', 'test_2'), _mk_TestSuite('test_1', 'test_3'))
|
||||
,(_mk_TestSuite('test_1'), _mk_TestSuite('test_2'))]
|
||||
|
||||
################################################################
|
||||
### /Set up attributes needed by inherited tests
|
||||
|
||||
### Tests for TestSuite.__init__
|
||||
################################################################
|
||||
|
||||
# "class TestSuite([tests])"
|
||||
#
|
||||
# The tests iterable should be optional
|
||||
def test_init__tests_optional(self):
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
self.assertEqual(suite.countTestCases(), 0)
|
||||
# countTestCases() still works after tests are run
|
||||
suite.run(unittest.TestResult())
|
||||
self.assertEqual(suite.countTestCases(), 0)
|
||||
|
||||
# "class TestSuite([tests])"
|
||||
# ...
|
||||
# "If tests is given, it must be an iterable of individual test cases
|
||||
# or other test suites that will be used to build the suite initially"
|
||||
#
|
||||
# TestSuite should deal with empty tests iterables by allowing the
|
||||
# creation of an empty suite
|
||||
def test_init__empty_tests(self):
|
||||
suite = unittest.TestSuite([])
|
||||
|
||||
self.assertEqual(suite.countTestCases(), 0)
|
||||
# countTestCases() still works after tests are run
|
||||
suite.run(unittest.TestResult())
|
||||
self.assertEqual(suite.countTestCases(), 0)
|
||||
|
||||
# "class TestSuite([tests])"
|
||||
# ...
|
||||
# "If tests is given, it must be an iterable of individual test cases
|
||||
# or other test suites that will be used to build the suite initially"
|
||||
#
|
||||
# TestSuite should allow any iterable to provide tests
|
||||
def test_init__tests_from_any_iterable(self):
|
||||
def tests():
|
||||
yield unittest.FunctionTestCase(lambda: None)
|
||||
yield unittest.FunctionTestCase(lambda: None)
|
||||
|
||||
suite_1 = unittest.TestSuite(tests())
|
||||
self.assertEqual(suite_1.countTestCases(), 2)
|
||||
|
||||
suite_2 = unittest.TestSuite(suite_1)
|
||||
self.assertEqual(suite_2.countTestCases(), 2)
|
||||
|
||||
suite_3 = unittest.TestSuite(set(suite_1))
|
||||
self.assertEqual(suite_3.countTestCases(), 2)
|
||||
|
||||
# countTestCases() still works after tests are run
|
||||
suite_1.run(unittest.TestResult())
|
||||
self.assertEqual(suite_1.countTestCases(), 2)
|
||||
suite_2.run(unittest.TestResult())
|
||||
self.assertEqual(suite_2.countTestCases(), 2)
|
||||
suite_3.run(unittest.TestResult())
|
||||
self.assertEqual(suite_3.countTestCases(), 2)
|
||||
|
||||
# "class TestSuite([tests])"
|
||||
# ...
|
||||
# "If tests is given, it must be an iterable of individual test cases
|
||||
# or other test suites that will be used to build the suite initially"
|
||||
#
|
||||
# Does TestSuite() also allow other TestSuite() instances to be present
|
||||
# in the tests iterable?
|
||||
def test_init__TestSuite_instances_in_tests(self):
|
||||
def tests():
|
||||
ftc = unittest.FunctionTestCase(lambda: None)
|
||||
yield unittest.TestSuite([ftc])
|
||||
yield unittest.FunctionTestCase(lambda: None)
|
||||
|
||||
suite = unittest.TestSuite(tests())
|
||||
self.assertEqual(suite.countTestCases(), 2)
|
||||
# countTestCases() still works after tests are run
|
||||
suite.run(unittest.TestResult())
|
||||
self.assertEqual(suite.countTestCases(), 2)
|
||||
|
||||
################################################################
|
||||
### /Tests for TestSuite.__init__
|
||||
|
||||
# Container types should support the iter protocol
|
||||
def test_iter(self):
|
||||
test1 = unittest.FunctionTestCase(lambda: None)
|
||||
test2 = unittest.FunctionTestCase(lambda: None)
|
||||
suite = unittest.TestSuite((test1, test2))
|
||||
|
||||
self.assertEqual(list(suite), [test1, test2])
|
||||
|
||||
# "Return the number of tests represented by the this test object.
|
||||
# ...this method is also implemented by the TestSuite class, which can
|
||||
# return larger [greater than 1] values"
|
||||
#
|
||||
# Presumably an empty TestSuite returns 0?
|
||||
def test_countTestCases_zero_simple(self):
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
self.assertEqual(suite.countTestCases(), 0)
|
||||
|
||||
# "Return the number of tests represented by the this test object.
|
||||
# ...this method is also implemented by the TestSuite class, which can
|
||||
# return larger [greater than 1] values"
|
||||
#
|
||||
# Presumably an empty TestSuite (even if it contains other empty
|
||||
# TestSuite instances) returns 0?
|
||||
def test_countTestCases_zero_nested(self):
|
||||
class Test1(unittest.TestCase):
|
||||
def test(self):
|
||||
pass
|
||||
|
||||
suite = unittest.TestSuite([unittest.TestSuite()])
|
||||
|
||||
self.assertEqual(suite.countTestCases(), 0)
|
||||
|
||||
# "Return the number of tests represented by the this test object.
|
||||
# ...this method is also implemented by the TestSuite class, which can
|
||||
# return larger [greater than 1] values"
|
||||
def test_countTestCases_simple(self):
|
||||
test1 = unittest.FunctionTestCase(lambda: None)
|
||||
test2 = unittest.FunctionTestCase(lambda: None)
|
||||
suite = unittest.TestSuite((test1, test2))
|
||||
|
||||
self.assertEqual(suite.countTestCases(), 2)
|
||||
# countTestCases() still works after tests are run
|
||||
suite.run(unittest.TestResult())
|
||||
self.assertEqual(suite.countTestCases(), 2)
|
||||
|
||||
# "Return the number of tests represented by the this test object.
|
||||
# ...this method is also implemented by the TestSuite class, which can
|
||||
# return larger [greater than 1] values"
|
||||
#
|
||||
# Make sure this holds for nested TestSuite instances, too
|
||||
def test_countTestCases_nested(self):
|
||||
class Test1(unittest.TestCase):
|
||||
def test1(self): pass
|
||||
def test2(self): pass
|
||||
|
||||
test2 = unittest.FunctionTestCase(lambda: None)
|
||||
test3 = unittest.FunctionTestCase(lambda: None)
|
||||
child = unittest.TestSuite((Test1('test2'), test2))
|
||||
parent = unittest.TestSuite((test3, child, Test1('test1')))
|
||||
|
||||
self.assertEqual(parent.countTestCases(), 4)
|
||||
# countTestCases() still works after tests are run
|
||||
parent.run(unittest.TestResult())
|
||||
self.assertEqual(parent.countTestCases(), 4)
|
||||
self.assertEqual(child.countTestCases(), 2)
|
||||
|
||||
# "Run the tests associated with this suite, collecting the result into
|
||||
# the test result object passed as result."
|
||||
#
|
||||
# And if there are no tests? What then?
|
||||
def test_run__empty_suite(self):
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
suite.run(result)
|
||||
|
||||
self.assertEqual(events, [])
|
||||
|
||||
# "Note that unlike TestCase.run(), TestSuite.run() requires the
|
||||
# "result object to be passed in."
|
||||
def test_run__requires_result(self):
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
try:
|
||||
suite.run()
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("Failed to raise TypeError")
|
||||
|
||||
# "Run the tests associated with this suite, collecting the result into
|
||||
# the test result object passed as result."
|
||||
def test_run(self):
|
||||
events = []
|
||||
result = LoggingResult(events)
|
||||
|
||||
class LoggingCase(unittest.TestCase):
|
||||
def run(self, result):
|
||||
events.append('run %s' % self._testMethodName)
|
||||
|
||||
def test1(self): pass
|
||||
def test2(self): pass
|
||||
|
||||
tests = [LoggingCase('test1'), LoggingCase('test2')]
|
||||
|
||||
unittest.TestSuite(tests).run(result)
|
||||
|
||||
self.assertEqual(events, ['run test1', 'run test2'])
|
||||
|
||||
# "Add a TestCase ... to the suite"
|
||||
def test_addTest__TestCase(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test(self): pass
|
||||
|
||||
test = Foo('test')
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
suite.addTest(test)
|
||||
|
||||
self.assertEqual(suite.countTestCases(), 1)
|
||||
self.assertEqual(list(suite), [test])
|
||||
# countTestCases() still works after tests are run
|
||||
suite.run(unittest.TestResult())
|
||||
self.assertEqual(suite.countTestCases(), 1)
|
||||
|
||||
# "Add a ... TestSuite to the suite"
|
||||
def test_addTest__TestSuite(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test(self): pass
|
||||
|
||||
suite_2 = unittest.TestSuite([Foo('test')])
|
||||
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(suite_2)
|
||||
|
||||
self.assertEqual(suite.countTestCases(), 1)
|
||||
self.assertEqual(list(suite), [suite_2])
|
||||
# countTestCases() still works after tests are run
|
||||
suite.run(unittest.TestResult())
|
||||
self.assertEqual(suite.countTestCases(), 1)
|
||||
|
||||
# "Add all the tests from an iterable of TestCase and TestSuite
|
||||
# instances to this test suite."
|
||||
#
|
||||
# "This is equivalent to iterating over tests, calling addTest() for
|
||||
# each element"
|
||||
def test_addTests(self):
|
||||
class Foo(unittest.TestCase):
|
||||
def test_1(self): pass
|
||||
def test_2(self): pass
|
||||
|
||||
test_1 = Foo('test_1')
|
||||
test_2 = Foo('test_2')
|
||||
inner_suite = unittest.TestSuite([test_2])
|
||||
|
||||
def gen():
|
||||
yield test_1
|
||||
yield test_2
|
||||
yield inner_suite
|
||||
|
||||
suite_1 = unittest.TestSuite()
|
||||
suite_1.addTests(gen())
|
||||
|
||||
self.assertEqual(list(suite_1), list(gen()))
|
||||
|
||||
# "This is equivalent to iterating over tests, calling addTest() for
|
||||
# each element"
|
||||
suite_2 = unittest.TestSuite()
|
||||
for t in gen():
|
||||
suite_2.addTest(t)
|
||||
|
||||
self.assertEqual(suite_1, suite_2)
|
||||
|
||||
# "Add all the tests from an iterable of TestCase and TestSuite
|
||||
# instances to this test suite."
|
||||
#
|
||||
# What happens if it doesn't get an iterable?
|
||||
def test_addTest__noniterable(self):
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
try:
|
||||
suite.addTests(5)
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("Failed to raise TypeError")
|
||||
|
||||
def test_addTest__noncallable(self):
|
||||
suite = unittest.TestSuite()
|
||||
self.assertRaises(TypeError, suite.addTest, 5)
|
||||
|
||||
def test_addTest__casesuiteclass(self):
|
||||
suite = unittest.TestSuite()
|
||||
self.assertRaises(TypeError, suite.addTest, Test_TestSuite)
|
||||
self.assertRaises(TypeError, suite.addTest, unittest.TestSuite)
|
||||
|
||||
def test_addTests__string(self):
|
||||
suite = unittest.TestSuite()
|
||||
self.assertRaises(TypeError, suite.addTests, "foo")
|
||||
|
||||
def test_function_in_suite(self):
|
||||
def f(_):
|
||||
pass
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(f)
|
||||
|
||||
# when the bug is fixed this line will not crash
|
||||
suite.run(unittest.TestResult())
|
||||
|
||||
def test_remove_test_at_index(self):
|
||||
if not unittest.BaseTestSuite._cleanup:
|
||||
raise unittest.SkipTest("Suite cleanup is disabled")
|
||||
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
suite._tests = [1, 2, 3]
|
||||
suite._removeTestAtIndex(1)
|
||||
|
||||
self.assertEqual([1, None, 3], suite._tests)
|
||||
|
||||
def test_remove_test_at_index_not_indexable(self):
|
||||
if not unittest.BaseTestSuite._cleanup:
|
||||
raise unittest.SkipTest("Suite cleanup is disabled")
|
||||
|
||||
suite = unittest.TestSuite()
|
||||
suite._tests = None
|
||||
|
||||
# if _removeAtIndex raises for noniterables this next line will break
|
||||
suite._removeTestAtIndex(2)
|
||||
|
||||
def assert_garbage_collect_test_after_run(self, TestSuiteClass):
|
||||
if not unittest.BaseTestSuite._cleanup:
|
||||
raise unittest.SkipTest("Suite cleanup is disabled")
|
||||
|
||||
class Foo(unittest.TestCase):
|
||||
def test_nothing(self):
|
||||
pass
|
||||
|
||||
test = Foo('test_nothing')
|
||||
wref = weakref.ref(test)
|
||||
|
||||
suite = TestSuiteClass([wref()])
|
||||
suite.run(unittest.TestResult())
|
||||
|
||||
del test
|
||||
|
||||
# for the benefit of non-reference counting implementations
|
||||
gc.collect()
|
||||
|
||||
self.assertEqual(suite._tests, [None])
|
||||
self.assertIsNone(wref())
|
||||
|
||||
def test_garbage_collect_test_after_run_BaseTestSuite(self):
|
||||
self.assert_garbage_collect_test_after_run(unittest.BaseTestSuite)
|
||||
|
||||
def test_garbage_collect_test_after_run_TestSuite(self):
|
||||
self.assert_garbage_collect_test_after_run(unittest.TestSuite)
|
||||
|
||||
def test_basetestsuite(self):
|
||||
class Test(unittest.TestCase):
|
||||
wasSetUp = False
|
||||
wasTornDown = False
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.wasSetUp = True
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.wasTornDown = True
|
||||
def testPass(self):
|
||||
pass
|
||||
def testFail(self):
|
||||
fail
|
||||
class Module(object):
|
||||
wasSetUp = False
|
||||
wasTornDown = False
|
||||
@staticmethod
|
||||
def setUpModule():
|
||||
Module.wasSetUp = True
|
||||
@staticmethod
|
||||
def tearDownModule():
|
||||
Module.wasTornDown = True
|
||||
|
||||
Test.__module__ = 'Module'
|
||||
sys.modules['Module'] = Module
|
||||
self.addCleanup(sys.modules.pop, 'Module')
|
||||
|
||||
suite = unittest.BaseTestSuite()
|
||||
suite.addTests([Test('testPass'), Test('testFail')])
|
||||
self.assertEqual(suite.countTestCases(), 2)
|
||||
|
||||
result = unittest.TestResult()
|
||||
suite.run(result)
|
||||
self.assertFalse(Module.wasSetUp)
|
||||
self.assertFalse(Module.wasTornDown)
|
||||
self.assertFalse(Test.wasSetUp)
|
||||
self.assertFalse(Test.wasTornDown)
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
self.assertEqual(len(result.failures), 0)
|
||||
self.assertEqual(result.testsRun, 2)
|
||||
self.assertEqual(suite.countTestCases(), 2)
|
||||
|
||||
|
||||
def test_overriding_call(self):
|
||||
class MySuite(unittest.TestSuite):
|
||||
called = False
|
||||
def __call__(self, *args, **kw):
|
||||
self.called = True
|
||||
unittest.TestSuite.__call__(self, *args, **kw)
|
||||
|
||||
suite = MySuite()
|
||||
result = unittest.TestResult()
|
||||
wrapper = unittest.TestSuite()
|
||||
wrapper.addTest(suite)
|
||||
wrapper(result)
|
||||
self.assertTrue(suite.called)
|
||||
|
||||
# reusing results should be permitted even if abominable
|
||||
self.assertFalse(result._testRunEntered)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
17
third_party/python/Lib/unittest/test/testmock/__init__.py
vendored
Normal file
17
third_party/python/Lib/unittest/test/testmock/__init__.py
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
|
||||
here = os.path.dirname(__file__)
|
||||
loader = unittest.defaultTestLoader
|
||||
|
||||
def load_tests(*args):
|
||||
suite = unittest.TestSuite()
|
||||
for fn in os.listdir(here):
|
||||
if fn.startswith("test") and fn.endswith(".py"):
|
||||
modname = "unittest.test.testmock." + fn[:-3]
|
||||
__import__(modname)
|
||||
module = sys.modules[modname]
|
||||
suite.addTest(loader.loadTestsFromModule(module))
|
||||
return suite
|
18
third_party/python/Lib/unittest/test/testmock/__main__.py
vendored
Normal file
18
third_party/python/Lib/unittest/test/testmock/__main__.py
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
import os
|
||||
import unittest
|
||||
|
||||
|
||||
def load_tests(loader, standard_tests, pattern):
|
||||
# top level directory cached on loader instance
|
||||
this_dir = os.path.dirname(__file__)
|
||||
pattern = pattern or "test*.py"
|
||||
# We are inside unittest.test.testmock, so the top-level is three notches up
|
||||
top_level_dir = os.path.dirname(os.path.dirname(os.path.dirname(this_dir)))
|
||||
package_tests = loader.discover(start_dir=this_dir, pattern=pattern,
|
||||
top_level_dir=top_level_dir)
|
||||
standard_tests.addTests(package_tests)
|
||||
return standard_tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
21
third_party/python/Lib/unittest/test/testmock/support.py
vendored
Normal file
21
third_party/python/Lib/unittest/test/testmock/support.py
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
def is_instance(obj, klass):
|
||||
"""Version of is_instance that doesn't access __class__"""
|
||||
return issubclass(type(obj), klass)
|
||||
|
||||
|
||||
class SomeClass(object):
|
||||
class_attribute = None
|
||||
|
||||
def wibble(self):
|
||||
pass
|
||||
|
||||
|
||||
class X(object):
|
||||
pass
|
||||
|
||||
|
||||
def examine_warnings(func):
|
||||
def wrapper():
|
||||
with catch_warnings(record=True) as ws:
|
||||
func(ws)
|
||||
return wrapper
|
151
third_party/python/Lib/unittest/test/testmock/testcallable.py
vendored
Normal file
151
third_party/python/Lib/unittest/test/testmock/testcallable.py
vendored
Normal file
|
@ -0,0 +1,151 @@
|
|||
# Copyright (C) 2007-2012 Michael Foord & the mock team
|
||||
# E-mail: fuzzyman AT voidspace DOT org DOT uk
|
||||
# http://www.voidspace.org.uk/python/mock/
|
||||
|
||||
import unittest
|
||||
from unittest.test.testmock.support import is_instance, X, SomeClass
|
||||
|
||||
from unittest.mock import (
|
||||
Mock, MagicMock, NonCallableMagicMock,
|
||||
NonCallableMock, patch, create_autospec,
|
||||
CallableMixin
|
||||
)
|
||||
|
||||
|
||||
|
||||
class TestCallable(unittest.TestCase):
|
||||
|
||||
def assertNotCallable(self, mock):
|
||||
self.assertTrue(is_instance(mock, NonCallableMagicMock))
|
||||
self.assertFalse(is_instance(mock, CallableMixin))
|
||||
|
||||
|
||||
def test_non_callable(self):
|
||||
for mock in NonCallableMagicMock(), NonCallableMock():
|
||||
self.assertRaises(TypeError, mock)
|
||||
self.assertFalse(hasattr(mock, '__call__'))
|
||||
self.assertIn(mock.__class__.__name__, repr(mock))
|
||||
|
||||
|
||||
def test_hierarchy(self):
|
||||
self.assertTrue(issubclass(MagicMock, Mock))
|
||||
self.assertTrue(issubclass(NonCallableMagicMock, NonCallableMock))
|
||||
|
||||
|
||||
def test_attributes(self):
|
||||
one = NonCallableMock()
|
||||
self.assertTrue(issubclass(type(one.one), Mock))
|
||||
|
||||
two = NonCallableMagicMock()
|
||||
self.assertTrue(issubclass(type(two.two), MagicMock))
|
||||
|
||||
|
||||
def test_subclasses(self):
|
||||
class MockSub(Mock):
|
||||
pass
|
||||
|
||||
one = MockSub()
|
||||
self.assertTrue(issubclass(type(one.one), MockSub))
|
||||
|
||||
class MagicSub(MagicMock):
|
||||
pass
|
||||
|
||||
two = MagicSub()
|
||||
self.assertTrue(issubclass(type(two.two), MagicSub))
|
||||
|
||||
|
||||
def test_patch_spec(self):
|
||||
patcher = patch('%s.X' % __name__, spec=True)
|
||||
mock = patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
|
||||
instance = mock()
|
||||
mock.assert_called_once_with()
|
||||
|
||||
self.assertNotCallable(instance)
|
||||
self.assertRaises(TypeError, instance)
|
||||
|
||||
|
||||
def test_patch_spec_set(self):
|
||||
patcher = patch('%s.X' % __name__, spec_set=True)
|
||||
mock = patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
|
||||
instance = mock()
|
||||
mock.assert_called_once_with()
|
||||
|
||||
self.assertNotCallable(instance)
|
||||
self.assertRaises(TypeError, instance)
|
||||
|
||||
|
||||
def test_patch_spec_instance(self):
|
||||
patcher = patch('%s.X' % __name__, spec=X())
|
||||
mock = patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
|
||||
self.assertNotCallable(mock)
|
||||
self.assertRaises(TypeError, mock)
|
||||
|
||||
|
||||
def test_patch_spec_set_instance(self):
|
||||
patcher = patch('%s.X' % __name__, spec_set=X())
|
||||
mock = patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
|
||||
self.assertNotCallable(mock)
|
||||
self.assertRaises(TypeError, mock)
|
||||
|
||||
|
||||
def test_patch_spec_callable_class(self):
|
||||
class CallableX(X):
|
||||
def __call__(self):
|
||||
pass
|
||||
|
||||
class Sub(CallableX):
|
||||
pass
|
||||
|
||||
class Multi(SomeClass, Sub):
|
||||
pass
|
||||
|
||||
for arg in 'spec', 'spec_set':
|
||||
for Klass in CallableX, Sub, Multi:
|
||||
with patch('%s.X' % __name__, **{arg: Klass}) as mock:
|
||||
instance = mock()
|
||||
mock.assert_called_once_with()
|
||||
|
||||
self.assertTrue(is_instance(instance, MagicMock))
|
||||
# inherited spec
|
||||
self.assertRaises(AttributeError, getattr, instance,
|
||||
'foobarbaz')
|
||||
|
||||
result = instance()
|
||||
# instance is callable, result has no spec
|
||||
instance.assert_called_once_with()
|
||||
|
||||
result(3, 2, 1)
|
||||
result.assert_called_once_with(3, 2, 1)
|
||||
result.foo(3, 2, 1)
|
||||
result.foo.assert_called_once_with(3, 2, 1)
|
||||
|
||||
|
||||
def test_create_autospec(self):
|
||||
mock = create_autospec(X)
|
||||
instance = mock()
|
||||
self.assertRaises(TypeError, instance)
|
||||
|
||||
mock = create_autospec(X())
|
||||
self.assertRaises(TypeError, mock)
|
||||
|
||||
|
||||
def test_create_autospec_instance(self):
|
||||
mock = create_autospec(SomeClass, instance=True)
|
||||
|
||||
self.assertRaises(TypeError, mock)
|
||||
mock.wibble()
|
||||
mock.wibble.assert_called_once_with()
|
||||
|
||||
self.assertRaises(TypeError, mock.wibble, 'some', 'args')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
962
third_party/python/Lib/unittest/test/testmock/testhelpers.py
vendored
Normal file
962
third_party/python/Lib/unittest/test/testmock/testhelpers.py
vendored
Normal file
|
@ -0,0 +1,962 @@
|
|||
import time
|
||||
import types
|
||||
import unittest
|
||||
|
||||
from unittest.mock import (
|
||||
call, _Call, create_autospec, MagicMock,
|
||||
Mock, ANY, _CallList, patch, PropertyMock
|
||||
)
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
class SomeClass(object):
|
||||
def one(self, a, b):
|
||||
pass
|
||||
def two(self):
|
||||
pass
|
||||
def three(self, a=None):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class AnyTest(unittest.TestCase):
|
||||
|
||||
def test_any(self):
|
||||
self.assertEqual(ANY, object())
|
||||
|
||||
mock = Mock()
|
||||
mock(ANY)
|
||||
mock.assert_called_with(ANY)
|
||||
|
||||
mock = Mock()
|
||||
mock(foo=ANY)
|
||||
mock.assert_called_with(foo=ANY)
|
||||
|
||||
def test_repr(self):
|
||||
self.assertEqual(repr(ANY), '<ANY>')
|
||||
self.assertEqual(str(ANY), '<ANY>')
|
||||
|
||||
|
||||
def test_any_and_datetime(self):
|
||||
mock = Mock()
|
||||
mock(datetime.now(), foo=datetime.now())
|
||||
|
||||
mock.assert_called_with(ANY, foo=ANY)
|
||||
|
||||
|
||||
def test_any_mock_calls_comparison_order(self):
|
||||
mock = Mock()
|
||||
d = datetime.now()
|
||||
class Foo(object):
|
||||
def __eq__(self, other):
|
||||
return False
|
||||
def __ne__(self, other):
|
||||
return True
|
||||
|
||||
for d in datetime.now(), Foo():
|
||||
mock.reset_mock()
|
||||
|
||||
mock(d, foo=d, bar=d)
|
||||
mock.method(d, zinga=d, alpha=d)
|
||||
mock().method(a1=d, z99=d)
|
||||
|
||||
expected = [
|
||||
call(ANY, foo=ANY, bar=ANY),
|
||||
call.method(ANY, zinga=ANY, alpha=ANY),
|
||||
call(), call().method(a1=ANY, z99=ANY)
|
||||
]
|
||||
self.assertEqual(expected, mock.mock_calls)
|
||||
self.assertEqual(mock.mock_calls, expected)
|
||||
|
||||
|
||||
|
||||
class CallTest(unittest.TestCase):
|
||||
|
||||
def test_call_with_call(self):
|
||||
kall = _Call()
|
||||
self.assertEqual(kall, _Call())
|
||||
self.assertEqual(kall, _Call(('',)))
|
||||
self.assertEqual(kall, _Call(((),)))
|
||||
self.assertEqual(kall, _Call(({},)))
|
||||
self.assertEqual(kall, _Call(('', ())))
|
||||
self.assertEqual(kall, _Call(('', {})))
|
||||
self.assertEqual(kall, _Call(('', (), {})))
|
||||
self.assertEqual(kall, _Call(('foo',)))
|
||||
self.assertEqual(kall, _Call(('bar', ())))
|
||||
self.assertEqual(kall, _Call(('baz', {})))
|
||||
self.assertEqual(kall, _Call(('spam', (), {})))
|
||||
|
||||
kall = _Call(((1, 2, 3),))
|
||||
self.assertEqual(kall, _Call(((1, 2, 3),)))
|
||||
self.assertEqual(kall, _Call(('', (1, 2, 3))))
|
||||
self.assertEqual(kall, _Call(((1, 2, 3), {})))
|
||||
self.assertEqual(kall, _Call(('', (1, 2, 3), {})))
|
||||
|
||||
kall = _Call(((1, 2, 4),))
|
||||
self.assertNotEqual(kall, _Call(('', (1, 2, 3))))
|
||||
self.assertNotEqual(kall, _Call(('', (1, 2, 3), {})))
|
||||
|
||||
kall = _Call(('foo', (1, 2, 4),))
|
||||
self.assertNotEqual(kall, _Call(('', (1, 2, 4))))
|
||||
self.assertNotEqual(kall, _Call(('', (1, 2, 4), {})))
|
||||
self.assertNotEqual(kall, _Call(('bar', (1, 2, 4))))
|
||||
self.assertNotEqual(kall, _Call(('bar', (1, 2, 4), {})))
|
||||
|
||||
kall = _Call(({'a': 3},))
|
||||
self.assertEqual(kall, _Call(('', (), {'a': 3})))
|
||||
self.assertEqual(kall, _Call(('', {'a': 3})))
|
||||
self.assertEqual(kall, _Call(((), {'a': 3})))
|
||||
self.assertEqual(kall, _Call(({'a': 3},)))
|
||||
|
||||
|
||||
def test_empty__Call(self):
|
||||
args = _Call()
|
||||
|
||||
self.assertEqual(args, ())
|
||||
self.assertEqual(args, ('foo',))
|
||||
self.assertEqual(args, ((),))
|
||||
self.assertEqual(args, ('foo', ()))
|
||||
self.assertEqual(args, ('foo',(), {}))
|
||||
self.assertEqual(args, ('foo', {}))
|
||||
self.assertEqual(args, ({},))
|
||||
|
||||
|
||||
def test_named_empty_call(self):
|
||||
args = _Call(('foo', (), {}))
|
||||
|
||||
self.assertEqual(args, ('foo',))
|
||||
self.assertEqual(args, ('foo', ()))
|
||||
self.assertEqual(args, ('foo',(), {}))
|
||||
self.assertEqual(args, ('foo', {}))
|
||||
|
||||
self.assertNotEqual(args, ((),))
|
||||
self.assertNotEqual(args, ())
|
||||
self.assertNotEqual(args, ({},))
|
||||
self.assertNotEqual(args, ('bar',))
|
||||
self.assertNotEqual(args, ('bar', ()))
|
||||
self.assertNotEqual(args, ('bar', {}))
|
||||
|
||||
|
||||
def test_call_with_args(self):
|
||||
args = _Call(((1, 2, 3), {}))
|
||||
|
||||
self.assertEqual(args, ((1, 2, 3),))
|
||||
self.assertEqual(args, ('foo', (1, 2, 3)))
|
||||
self.assertEqual(args, ('foo', (1, 2, 3), {}))
|
||||
self.assertEqual(args, ((1, 2, 3), {}))
|
||||
|
||||
|
||||
def test_named_call_with_args(self):
|
||||
args = _Call(('foo', (1, 2, 3), {}))
|
||||
|
||||
self.assertEqual(args, ('foo', (1, 2, 3)))
|
||||
self.assertEqual(args, ('foo', (1, 2, 3), {}))
|
||||
|
||||
self.assertNotEqual(args, ((1, 2, 3),))
|
||||
self.assertNotEqual(args, ((1, 2, 3), {}))
|
||||
|
||||
|
||||
def test_call_with_kwargs(self):
|
||||
args = _Call(((), dict(a=3, b=4)))
|
||||
|
||||
self.assertEqual(args, (dict(a=3, b=4),))
|
||||
self.assertEqual(args, ('foo', dict(a=3, b=4)))
|
||||
self.assertEqual(args, ('foo', (), dict(a=3, b=4)))
|
||||
self.assertEqual(args, ((), dict(a=3, b=4)))
|
||||
|
||||
|
||||
def test_named_call_with_kwargs(self):
|
||||
args = _Call(('foo', (), dict(a=3, b=4)))
|
||||
|
||||
self.assertEqual(args, ('foo', dict(a=3, b=4)))
|
||||
self.assertEqual(args, ('foo', (), dict(a=3, b=4)))
|
||||
|
||||
self.assertNotEqual(args, (dict(a=3, b=4),))
|
||||
self.assertNotEqual(args, ((), dict(a=3, b=4)))
|
||||
|
||||
|
||||
def test_call_with_args_call_empty_name(self):
|
||||
args = _Call(((1, 2, 3), {}))
|
||||
self.assertEqual(args, call(1, 2, 3))
|
||||
self.assertEqual(call(1, 2, 3), args)
|
||||
self.assertIn(call(1, 2, 3), [args])
|
||||
|
||||
|
||||
def test_call_ne(self):
|
||||
self.assertNotEqual(_Call(((1, 2, 3),)), call(1, 2))
|
||||
self.assertFalse(_Call(((1, 2, 3),)) != call(1, 2, 3))
|
||||
self.assertTrue(_Call(((1, 2), {})) != call(1, 2, 3))
|
||||
|
||||
|
||||
def test_call_non_tuples(self):
|
||||
kall = _Call(((1, 2, 3),))
|
||||
for value in 1, None, self, int:
|
||||
self.assertNotEqual(kall, value)
|
||||
self.assertFalse(kall == value)
|
||||
|
||||
|
||||
def test_repr(self):
|
||||
self.assertEqual(repr(_Call()), 'call()')
|
||||
self.assertEqual(repr(_Call(('foo',))), 'call.foo()')
|
||||
|
||||
self.assertEqual(repr(_Call(((1, 2, 3), {'a': 'b'}))),
|
||||
"call(1, 2, 3, a='b')")
|
||||
self.assertEqual(repr(_Call(('bar', (1, 2, 3), {'a': 'b'}))),
|
||||
"call.bar(1, 2, 3, a='b')")
|
||||
|
||||
self.assertEqual(repr(call), 'call')
|
||||
self.assertEqual(str(call), 'call')
|
||||
|
||||
self.assertEqual(repr(call()), 'call()')
|
||||
self.assertEqual(repr(call(1)), 'call(1)')
|
||||
self.assertEqual(repr(call(zz='thing')), "call(zz='thing')")
|
||||
|
||||
self.assertEqual(repr(call().foo), 'call().foo')
|
||||
self.assertEqual(repr(call(1).foo.bar(a=3).bing),
|
||||
'call().foo.bar().bing')
|
||||
self.assertEqual(
|
||||
repr(call().foo(1, 2, a=3)),
|
||||
"call().foo(1, 2, a=3)"
|
||||
)
|
||||
self.assertEqual(repr(call()()), "call()()")
|
||||
self.assertEqual(repr(call(1)(2)), "call()(2)")
|
||||
self.assertEqual(
|
||||
repr(call()().bar().baz.beep(1)),
|
||||
"call()().bar().baz.beep(1)"
|
||||
)
|
||||
|
||||
|
||||
def test_call(self):
|
||||
self.assertEqual(call(), ('', (), {}))
|
||||
self.assertEqual(call('foo', 'bar', one=3, two=4),
|
||||
('', ('foo', 'bar'), {'one': 3, 'two': 4}))
|
||||
|
||||
mock = Mock()
|
||||
mock(1, 2, 3)
|
||||
mock(a=3, b=6)
|
||||
self.assertEqual(mock.call_args_list,
|
||||
[call(1, 2, 3), call(a=3, b=6)])
|
||||
|
||||
def test_attribute_call(self):
|
||||
self.assertEqual(call.foo(1), ('foo', (1,), {}))
|
||||
self.assertEqual(call.bar.baz(fish='eggs'),
|
||||
('bar.baz', (), {'fish': 'eggs'}))
|
||||
|
||||
mock = Mock()
|
||||
mock.foo(1, 2 ,3)
|
||||
mock.bar.baz(a=3, b=6)
|
||||
self.assertEqual(mock.method_calls,
|
||||
[call.foo(1, 2, 3), call.bar.baz(a=3, b=6)])
|
||||
|
||||
|
||||
def test_extended_call(self):
|
||||
result = call(1).foo(2).bar(3, a=4)
|
||||
self.assertEqual(result, ('().foo().bar', (3,), dict(a=4)))
|
||||
|
||||
mock = MagicMock()
|
||||
mock(1, 2, a=3, b=4)
|
||||
self.assertEqual(mock.call_args, call(1, 2, a=3, b=4))
|
||||
self.assertNotEqual(mock.call_args, call(1, 2, 3))
|
||||
|
||||
self.assertEqual(mock.call_args_list, [call(1, 2, a=3, b=4)])
|
||||
self.assertEqual(mock.mock_calls, [call(1, 2, a=3, b=4)])
|
||||
|
||||
mock = MagicMock()
|
||||
mock.foo(1).bar()().baz.beep(a=6)
|
||||
|
||||
last_call = call.foo(1).bar()().baz.beep(a=6)
|
||||
self.assertEqual(mock.mock_calls[-1], last_call)
|
||||
self.assertEqual(mock.mock_calls, last_call.call_list())
|
||||
|
||||
|
||||
def test_extended_not_equal(self):
|
||||
a = call(x=1).foo
|
||||
b = call(x=2).foo
|
||||
self.assertEqual(a, a)
|
||||
self.assertEqual(b, b)
|
||||
self.assertNotEqual(a, b)
|
||||
|
||||
|
||||
def test_nested_calls_not_equal(self):
|
||||
a = call(x=1).foo().bar
|
||||
b = call(x=2).foo().bar
|
||||
self.assertEqual(a, a)
|
||||
self.assertEqual(b, b)
|
||||
self.assertNotEqual(a, b)
|
||||
|
||||
|
||||
def test_call_list(self):
|
||||
mock = MagicMock()
|
||||
mock(1)
|
||||
self.assertEqual(call(1).call_list(), mock.mock_calls)
|
||||
|
||||
mock = MagicMock()
|
||||
mock(1).method(2)
|
||||
self.assertEqual(call(1).method(2).call_list(),
|
||||
mock.mock_calls)
|
||||
|
||||
mock = MagicMock()
|
||||
mock(1).method(2)(3)
|
||||
self.assertEqual(call(1).method(2)(3).call_list(),
|
||||
mock.mock_calls)
|
||||
|
||||
mock = MagicMock()
|
||||
int(mock(1).method(2)(3).foo.bar.baz(4)(5))
|
||||
kall = call(1).method(2)(3).foo.bar.baz(4)(5).__int__()
|
||||
self.assertEqual(kall.call_list(), mock.mock_calls)
|
||||
|
||||
|
||||
def test_call_any(self):
|
||||
self.assertEqual(call, ANY)
|
||||
|
||||
m = MagicMock()
|
||||
int(m)
|
||||
self.assertEqual(m.mock_calls, [ANY])
|
||||
self.assertEqual([ANY], m.mock_calls)
|
||||
|
||||
|
||||
def test_two_args_call(self):
|
||||
args = _Call(((1, 2), {'a': 3}), two=True)
|
||||
self.assertEqual(len(args), 2)
|
||||
self.assertEqual(args[0], (1, 2))
|
||||
self.assertEqual(args[1], {'a': 3})
|
||||
|
||||
other_args = _Call(((1, 2), {'a': 3}))
|
||||
self.assertEqual(args, other_args)
|
||||
|
||||
def test_call_with_name(self):
|
||||
self.assertEqual(_Call((), 'foo')[0], 'foo')
|
||||
self.assertEqual(_Call((('bar', 'barz'),),)[0], '')
|
||||
self.assertEqual(_Call((('bar', 'barz'), {'hello': 'world'}),)[0], '')
|
||||
|
||||
|
||||
class SpecSignatureTest(unittest.TestCase):
|
||||
|
||||
def _check_someclass_mock(self, mock):
|
||||
self.assertRaises(AttributeError, getattr, mock, 'foo')
|
||||
mock.one(1, 2)
|
||||
mock.one.assert_called_with(1, 2)
|
||||
self.assertRaises(AssertionError,
|
||||
mock.one.assert_called_with, 3, 4)
|
||||
self.assertRaises(TypeError, mock.one, 1)
|
||||
|
||||
mock.two()
|
||||
mock.two.assert_called_with()
|
||||
self.assertRaises(AssertionError,
|
||||
mock.two.assert_called_with, 3)
|
||||
self.assertRaises(TypeError, mock.two, 1)
|
||||
|
||||
mock.three()
|
||||
mock.three.assert_called_with()
|
||||
self.assertRaises(AssertionError,
|
||||
mock.three.assert_called_with, 3)
|
||||
self.assertRaises(TypeError, mock.three, 3, 2)
|
||||
|
||||
mock.three(1)
|
||||
mock.three.assert_called_with(1)
|
||||
|
||||
mock.three(a=1)
|
||||
mock.three.assert_called_with(a=1)
|
||||
|
||||
|
||||
def test_basic(self):
|
||||
mock = create_autospec(SomeClass)
|
||||
self._check_someclass_mock(mock)
|
||||
mock = create_autospec(SomeClass())
|
||||
self._check_someclass_mock(mock)
|
||||
|
||||
|
||||
def test_create_autospec_return_value(self):
|
||||
def f():
|
||||
pass
|
||||
mock = create_autospec(f, return_value='foo')
|
||||
self.assertEqual(mock(), 'foo')
|
||||
|
||||
class Foo(object):
|
||||
pass
|
||||
|
||||
mock = create_autospec(Foo, return_value='foo')
|
||||
self.assertEqual(mock(), 'foo')
|
||||
|
||||
|
||||
def test_autospec_reset_mock(self):
|
||||
m = create_autospec(int)
|
||||
int(m)
|
||||
m.reset_mock()
|
||||
self.assertEqual(m.__int__.call_count, 0)
|
||||
|
||||
|
||||
def test_mocking_unbound_methods(self):
|
||||
class Foo(object):
|
||||
def foo(self, foo):
|
||||
pass
|
||||
p = patch.object(Foo, 'foo')
|
||||
mock_foo = p.start()
|
||||
Foo().foo(1)
|
||||
|
||||
mock_foo.assert_called_with(1)
|
||||
|
||||
|
||||
def test_create_autospec_unbound_methods(self):
|
||||
# see mock issue 128
|
||||
# this is expected to fail until the issue is fixed
|
||||
return
|
||||
class Foo(object):
|
||||
def foo(self):
|
||||
pass
|
||||
|
||||
klass = create_autospec(Foo)
|
||||
instance = klass()
|
||||
self.assertRaises(TypeError, instance.foo, 1)
|
||||
|
||||
# Note: no type checking on the "self" parameter
|
||||
klass.foo(1)
|
||||
klass.foo.assert_called_with(1)
|
||||
self.assertRaises(TypeError, klass.foo)
|
||||
|
||||
|
||||
def test_create_autospec_keyword_arguments(self):
|
||||
class Foo(object):
|
||||
a = 3
|
||||
m = create_autospec(Foo, a='3')
|
||||
self.assertEqual(m.a, '3')
|
||||
|
||||
|
||||
def test_create_autospec_keyword_only_arguments(self):
|
||||
def foo(a, *, b=None):
|
||||
pass
|
||||
|
||||
m = create_autospec(foo)
|
||||
m(1)
|
||||
m.assert_called_with(1)
|
||||
self.assertRaises(TypeError, m, 1, 2)
|
||||
|
||||
m(2, b=3)
|
||||
m.assert_called_with(2, b=3)
|
||||
|
||||
|
||||
def test_function_as_instance_attribute(self):
|
||||
obj = SomeClass()
|
||||
def f(a):
|
||||
pass
|
||||
obj.f = f
|
||||
|
||||
mock = create_autospec(obj)
|
||||
mock.f('bing')
|
||||
mock.f.assert_called_with('bing')
|
||||
|
||||
|
||||
def test_spec_as_list(self):
|
||||
# because spec as a list of strings in the mock constructor means
|
||||
# something very different we treat a list instance as the type.
|
||||
mock = create_autospec([])
|
||||
mock.append('foo')
|
||||
mock.append.assert_called_with('foo')
|
||||
|
||||
self.assertRaises(AttributeError, getattr, mock, 'foo')
|
||||
|
||||
class Foo(object):
|
||||
foo = []
|
||||
|
||||
mock = create_autospec(Foo)
|
||||
mock.foo.append(3)
|
||||
mock.foo.append.assert_called_with(3)
|
||||
self.assertRaises(AttributeError, getattr, mock.foo, 'foo')
|
||||
|
||||
|
||||
def test_attributes(self):
|
||||
class Sub(SomeClass):
|
||||
attr = SomeClass()
|
||||
|
||||
sub_mock = create_autospec(Sub)
|
||||
|
||||
for mock in (sub_mock, sub_mock.attr):
|
||||
self._check_someclass_mock(mock)
|
||||
|
||||
|
||||
def test_builtin_functions_types(self):
|
||||
# we could replace builtin functions / methods with a function
|
||||
# with *args / **kwargs signature. Using the builtin method type
|
||||
# as a spec seems to work fairly well though.
|
||||
class BuiltinSubclass(list):
|
||||
def bar(self, arg):
|
||||
pass
|
||||
sorted = sorted
|
||||
attr = {}
|
||||
|
||||
mock = create_autospec(BuiltinSubclass)
|
||||
mock.append(3)
|
||||
mock.append.assert_called_with(3)
|
||||
self.assertRaises(AttributeError, getattr, mock.append, 'foo')
|
||||
|
||||
mock.bar('foo')
|
||||
mock.bar.assert_called_with('foo')
|
||||
self.assertRaises(TypeError, mock.bar, 'foo', 'bar')
|
||||
self.assertRaises(AttributeError, getattr, mock.bar, 'foo')
|
||||
|
||||
mock.sorted([1, 2])
|
||||
mock.sorted.assert_called_with([1, 2])
|
||||
self.assertRaises(AttributeError, getattr, mock.sorted, 'foo')
|
||||
|
||||
mock.attr.pop(3)
|
||||
mock.attr.pop.assert_called_with(3)
|
||||
self.assertRaises(AttributeError, getattr, mock.attr, 'foo')
|
||||
|
||||
|
||||
def test_method_calls(self):
|
||||
class Sub(SomeClass):
|
||||
attr = SomeClass()
|
||||
|
||||
mock = create_autospec(Sub)
|
||||
mock.one(1, 2)
|
||||
mock.two()
|
||||
mock.three(3)
|
||||
|
||||
expected = [call.one(1, 2), call.two(), call.three(3)]
|
||||
self.assertEqual(mock.method_calls, expected)
|
||||
|
||||
mock.attr.one(1, 2)
|
||||
mock.attr.two()
|
||||
mock.attr.three(3)
|
||||
|
||||
expected.extend(
|
||||
[call.attr.one(1, 2), call.attr.two(), call.attr.three(3)]
|
||||
)
|
||||
self.assertEqual(mock.method_calls, expected)
|
||||
|
||||
|
||||
def test_magic_methods(self):
|
||||
class BuiltinSubclass(list):
|
||||
attr = {}
|
||||
|
||||
mock = create_autospec(BuiltinSubclass)
|
||||
self.assertEqual(list(mock), [])
|
||||
self.assertRaises(TypeError, int, mock)
|
||||
self.assertRaises(TypeError, int, mock.attr)
|
||||
self.assertEqual(list(mock), [])
|
||||
|
||||
self.assertIsInstance(mock['foo'], MagicMock)
|
||||
self.assertIsInstance(mock.attr['foo'], MagicMock)
|
||||
|
||||
|
||||
def test_spec_set(self):
|
||||
class Sub(SomeClass):
|
||||
attr = SomeClass()
|
||||
|
||||
for spec in (Sub, Sub()):
|
||||
mock = create_autospec(spec, spec_set=True)
|
||||
self._check_someclass_mock(mock)
|
||||
|
||||
self.assertRaises(AttributeError, setattr, mock, 'foo', 'bar')
|
||||
self.assertRaises(AttributeError, setattr, mock.attr, 'foo', 'bar')
|
||||
|
||||
|
||||
def test_descriptors(self):
|
||||
class Foo(object):
|
||||
@classmethod
|
||||
def f(cls, a, b):
|
||||
pass
|
||||
@staticmethod
|
||||
def g(a, b):
|
||||
pass
|
||||
|
||||
class Bar(Foo):
|
||||
pass
|
||||
|
||||
class Baz(SomeClass, Bar):
|
||||
pass
|
||||
|
||||
for spec in (Foo, Foo(), Bar, Bar(), Baz, Baz()):
|
||||
mock = create_autospec(spec)
|
||||
mock.f(1, 2)
|
||||
mock.f.assert_called_once_with(1, 2)
|
||||
|
||||
mock.g(3, 4)
|
||||
mock.g.assert_called_once_with(3, 4)
|
||||
|
||||
|
||||
def test_recursive(self):
|
||||
class A(object):
|
||||
def a(self):
|
||||
pass
|
||||
foo = 'foo bar baz'
|
||||
bar = foo
|
||||
|
||||
A.B = A
|
||||
mock = create_autospec(A)
|
||||
|
||||
mock()
|
||||
self.assertFalse(mock.B.called)
|
||||
|
||||
mock.a()
|
||||
mock.B.a()
|
||||
self.assertEqual(mock.method_calls, [call.a(), call.B.a()])
|
||||
|
||||
self.assertIs(A.foo, A.bar)
|
||||
self.assertIsNot(mock.foo, mock.bar)
|
||||
mock.foo.lower()
|
||||
self.assertRaises(AssertionError, mock.bar.lower.assert_called_with)
|
||||
|
||||
|
||||
def test_spec_inheritance_for_classes(self):
|
||||
class Foo(object):
|
||||
def a(self, x):
|
||||
pass
|
||||
class Bar(object):
|
||||
def f(self, y):
|
||||
pass
|
||||
|
||||
class_mock = create_autospec(Foo)
|
||||
|
||||
self.assertIsNot(class_mock, class_mock())
|
||||
|
||||
for this_mock in class_mock, class_mock():
|
||||
this_mock.a(x=5)
|
||||
this_mock.a.assert_called_with(x=5)
|
||||
this_mock.a.assert_called_with(5)
|
||||
self.assertRaises(TypeError, this_mock.a, 'foo', 'bar')
|
||||
self.assertRaises(AttributeError, getattr, this_mock, 'b')
|
||||
|
||||
instance_mock = create_autospec(Foo())
|
||||
instance_mock.a(5)
|
||||
instance_mock.a.assert_called_with(5)
|
||||
instance_mock.a.assert_called_with(x=5)
|
||||
self.assertRaises(TypeError, instance_mock.a, 'foo', 'bar')
|
||||
self.assertRaises(AttributeError, getattr, instance_mock, 'b')
|
||||
|
||||
# The return value isn't isn't callable
|
||||
self.assertRaises(TypeError, instance_mock)
|
||||
|
||||
instance_mock.Bar.f(6)
|
||||
instance_mock.Bar.f.assert_called_with(6)
|
||||
instance_mock.Bar.f.assert_called_with(y=6)
|
||||
self.assertRaises(AttributeError, getattr, instance_mock.Bar, 'g')
|
||||
|
||||
instance_mock.Bar().f(6)
|
||||
instance_mock.Bar().f.assert_called_with(6)
|
||||
instance_mock.Bar().f.assert_called_with(y=6)
|
||||
self.assertRaises(AttributeError, getattr, instance_mock.Bar(), 'g')
|
||||
|
||||
|
||||
def test_inherit(self):
|
||||
class Foo(object):
|
||||
a = 3
|
||||
|
||||
Foo.Foo = Foo
|
||||
|
||||
# class
|
||||
mock = create_autospec(Foo)
|
||||
instance = mock()
|
||||
self.assertRaises(AttributeError, getattr, instance, 'b')
|
||||
|
||||
attr_instance = mock.Foo()
|
||||
self.assertRaises(AttributeError, getattr, attr_instance, 'b')
|
||||
|
||||
# instance
|
||||
mock = create_autospec(Foo())
|
||||
self.assertRaises(AttributeError, getattr, mock, 'b')
|
||||
self.assertRaises(TypeError, mock)
|
||||
|
||||
# attribute instance
|
||||
call_result = mock.Foo()
|
||||
self.assertRaises(AttributeError, getattr, call_result, 'b')
|
||||
|
||||
|
||||
def test_builtins(self):
|
||||
# used to fail with infinite recursion
|
||||
create_autospec(1)
|
||||
|
||||
create_autospec(int)
|
||||
create_autospec('foo')
|
||||
create_autospec(str)
|
||||
create_autospec({})
|
||||
create_autospec(dict)
|
||||
create_autospec([])
|
||||
create_autospec(list)
|
||||
create_autospec(set())
|
||||
create_autospec(set)
|
||||
create_autospec(1.0)
|
||||
create_autospec(float)
|
||||
create_autospec(1j)
|
||||
create_autospec(complex)
|
||||
create_autospec(False)
|
||||
create_autospec(True)
|
||||
|
||||
|
||||
def test_function(self):
|
||||
def f(a, b):
|
||||
pass
|
||||
|
||||
mock = create_autospec(f)
|
||||
self.assertRaises(TypeError, mock)
|
||||
mock(1, 2)
|
||||
mock.assert_called_with(1, 2)
|
||||
mock.assert_called_with(1, b=2)
|
||||
mock.assert_called_with(a=1, b=2)
|
||||
|
||||
f.f = f
|
||||
mock = create_autospec(f)
|
||||
self.assertRaises(TypeError, mock.f)
|
||||
mock.f(3, 4)
|
||||
mock.f.assert_called_with(3, 4)
|
||||
mock.f.assert_called_with(a=3, b=4)
|
||||
|
||||
|
||||
def test_skip_attributeerrors(self):
|
||||
class Raiser(object):
|
||||
def __get__(self, obj, type=None):
|
||||
if obj is None:
|
||||
raise AttributeError('Can only be accessed via an instance')
|
||||
|
||||
class RaiserClass(object):
|
||||
raiser = Raiser()
|
||||
|
||||
@staticmethod
|
||||
def existing(a, b):
|
||||
return a + b
|
||||
|
||||
s = create_autospec(RaiserClass)
|
||||
self.assertRaises(TypeError, lambda x: s.existing(1, 2, 3))
|
||||
s.existing(1, 2)
|
||||
self.assertRaises(AttributeError, lambda: s.nonexisting)
|
||||
|
||||
# check we can fetch the raiser attribute and it has no spec
|
||||
obj = s.raiser
|
||||
obj.foo, obj.bar
|
||||
|
||||
|
||||
def test_signature_class(self):
|
||||
class Foo(object):
|
||||
def __init__(self, a, b=3):
|
||||
pass
|
||||
|
||||
mock = create_autospec(Foo)
|
||||
|
||||
self.assertRaises(TypeError, mock)
|
||||
mock(1)
|
||||
mock.assert_called_once_with(1)
|
||||
mock.assert_called_once_with(a=1)
|
||||
self.assertRaises(AssertionError, mock.assert_called_once_with, 2)
|
||||
|
||||
mock(4, 5)
|
||||
mock.assert_called_with(4, 5)
|
||||
mock.assert_called_with(a=4, b=5)
|
||||
self.assertRaises(AssertionError, mock.assert_called_with, a=5, b=4)
|
||||
|
||||
|
||||
def test_class_with_no_init(self):
|
||||
# this used to raise an exception
|
||||
# due to trying to get a signature from object.__init__
|
||||
class Foo(object):
|
||||
pass
|
||||
create_autospec(Foo)
|
||||
|
||||
|
||||
def test_signature_callable(self):
|
||||
class Callable(object):
|
||||
def __init__(self, x, y):
|
||||
pass
|
||||
def __call__(self, a):
|
||||
pass
|
||||
|
||||
mock = create_autospec(Callable)
|
||||
mock(1, 2)
|
||||
mock.assert_called_once_with(1, 2)
|
||||
mock.assert_called_once_with(x=1, y=2)
|
||||
self.assertRaises(TypeError, mock, 'a')
|
||||
|
||||
instance = mock(1, 2)
|
||||
self.assertRaises(TypeError, instance)
|
||||
instance(a='a')
|
||||
instance.assert_called_once_with('a')
|
||||
instance.assert_called_once_with(a='a')
|
||||
instance('a')
|
||||
instance.assert_called_with('a')
|
||||
instance.assert_called_with(a='a')
|
||||
|
||||
mock = create_autospec(Callable(1, 2))
|
||||
mock(a='a')
|
||||
mock.assert_called_once_with(a='a')
|
||||
self.assertRaises(TypeError, mock)
|
||||
mock('a')
|
||||
mock.assert_called_with('a')
|
||||
|
||||
|
||||
def test_signature_noncallable(self):
|
||||
class NonCallable(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
mock = create_autospec(NonCallable)
|
||||
instance = mock()
|
||||
mock.assert_called_once_with()
|
||||
self.assertRaises(TypeError, mock, 'a')
|
||||
self.assertRaises(TypeError, instance)
|
||||
self.assertRaises(TypeError, instance, 'a')
|
||||
|
||||
mock = create_autospec(NonCallable())
|
||||
self.assertRaises(TypeError, mock)
|
||||
self.assertRaises(TypeError, mock, 'a')
|
||||
|
||||
|
||||
def test_create_autospec_none(self):
|
||||
class Foo(object):
|
||||
bar = None
|
||||
|
||||
mock = create_autospec(Foo)
|
||||
none = mock.bar
|
||||
self.assertNotIsInstance(none, type(None))
|
||||
|
||||
none.foo()
|
||||
none.foo.assert_called_once_with()
|
||||
|
||||
|
||||
def test_autospec_functions_with_self_in_odd_place(self):
|
||||
class Foo(object):
|
||||
def f(a, self):
|
||||
pass
|
||||
|
||||
a = create_autospec(Foo)
|
||||
a.f(10)
|
||||
a.f.assert_called_with(10)
|
||||
a.f.assert_called_with(self=10)
|
||||
a.f(self=10)
|
||||
a.f.assert_called_with(10)
|
||||
a.f.assert_called_with(self=10)
|
||||
|
||||
|
||||
def test_autospec_data_descriptor(self):
|
||||
class Descriptor(object):
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def __get__(self, obj, cls=None):
|
||||
if obj is None:
|
||||
return self
|
||||
return self.value
|
||||
|
||||
def __set__(self, obj, value):
|
||||
pass
|
||||
|
||||
class MyProperty(property):
|
||||
pass
|
||||
|
||||
class Foo(object):
|
||||
__slots__ = ['slot']
|
||||
|
||||
@property
|
||||
def prop(self):
|
||||
return 3
|
||||
|
||||
@MyProperty
|
||||
def subprop(self):
|
||||
return 4
|
||||
|
||||
desc = Descriptor(42)
|
||||
|
||||
foo = create_autospec(Foo)
|
||||
|
||||
def check_data_descriptor(mock_attr):
|
||||
# Data descriptors don't have a spec.
|
||||
self.assertIsInstance(mock_attr, MagicMock)
|
||||
mock_attr(1, 2, 3)
|
||||
mock_attr.abc(4, 5, 6)
|
||||
mock_attr.assert_called_once_with(1, 2, 3)
|
||||
mock_attr.abc.assert_called_once_with(4, 5, 6)
|
||||
|
||||
# property
|
||||
check_data_descriptor(foo.prop)
|
||||
# property subclass
|
||||
check_data_descriptor(foo.subprop)
|
||||
# class __slot__
|
||||
check_data_descriptor(foo.slot)
|
||||
# plain data descriptor
|
||||
check_data_descriptor(foo.desc)
|
||||
|
||||
|
||||
def test_autospec_on_bound_builtin_function(self):
|
||||
meth = types.MethodType(time.ctime, time.time())
|
||||
self.assertIsInstance(meth(), str)
|
||||
mocked = create_autospec(meth)
|
||||
|
||||
# no signature, so no spec to check against
|
||||
mocked()
|
||||
mocked.assert_called_once_with()
|
||||
mocked.reset_mock()
|
||||
mocked(4, 5, 6)
|
||||
mocked.assert_called_once_with(4, 5, 6)
|
||||
|
||||
|
||||
class TestCallList(unittest.TestCase):
|
||||
|
||||
def test_args_list_contains_call_list(self):
|
||||
mock = Mock()
|
||||
self.assertIsInstance(mock.call_args_list, _CallList)
|
||||
|
||||
mock(1, 2)
|
||||
mock(a=3)
|
||||
mock(3, 4)
|
||||
mock(b=6)
|
||||
|
||||
for kall in call(1, 2), call(a=3), call(3, 4), call(b=6):
|
||||
self.assertIn(kall, mock.call_args_list)
|
||||
|
||||
calls = [call(a=3), call(3, 4)]
|
||||
self.assertIn(calls, mock.call_args_list)
|
||||
calls = [call(1, 2), call(a=3)]
|
||||
self.assertIn(calls, mock.call_args_list)
|
||||
calls = [call(3, 4), call(b=6)]
|
||||
self.assertIn(calls, mock.call_args_list)
|
||||
calls = [call(3, 4)]
|
||||
self.assertIn(calls, mock.call_args_list)
|
||||
|
||||
self.assertNotIn(call('fish'), mock.call_args_list)
|
||||
self.assertNotIn([call('fish')], mock.call_args_list)
|
||||
|
||||
|
||||
def test_call_list_str(self):
|
||||
mock = Mock()
|
||||
mock(1, 2)
|
||||
mock.foo(a=3)
|
||||
mock.foo.bar().baz('fish', cat='dog')
|
||||
|
||||
expected = (
|
||||
"[call(1, 2),\n"
|
||||
" call.foo(a=3),\n"
|
||||
" call.foo.bar(),\n"
|
||||
" call.foo.bar().baz('fish', cat='dog')]"
|
||||
)
|
||||
self.assertEqual(str(mock.mock_calls), expected)
|
||||
|
||||
|
||||
def test_propertymock(self):
|
||||
p = patch('%s.SomeClass.one' % __name__, new_callable=PropertyMock)
|
||||
mock = p.start()
|
||||
try:
|
||||
SomeClass.one
|
||||
mock.assert_called_once_with()
|
||||
|
||||
s = SomeClass()
|
||||
s.one
|
||||
mock.assert_called_with()
|
||||
self.assertEqual(mock.mock_calls, [call(), call()])
|
||||
|
||||
s.one = 3
|
||||
self.assertEqual(mock.mock_calls, [call(), call(), call(3)])
|
||||
finally:
|
||||
p.stop()
|
||||
|
||||
|
||||
def test_propertymock_returnvalue(self):
|
||||
m = MagicMock()
|
||||
p = PropertyMock()
|
||||
type(m).foo = p
|
||||
|
||||
returned = m.foo
|
||||
p.assert_called_once_with()
|
||||
self.assertIsInstance(returned, MagicMock)
|
||||
self.assertNotIsInstance(returned, PropertyMock)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
468
third_party/python/Lib/unittest/test/testmock/testmagicmethods.py
vendored
Normal file
468
third_party/python/Lib/unittest/test/testmock/testmagicmethods.py
vendored
Normal file
|
@ -0,0 +1,468 @@
|
|||
import unittest
|
||||
import sys
|
||||
from unittest.mock import Mock, MagicMock, _magics
|
||||
|
||||
|
||||
|
||||
class TestMockingMagicMethods(unittest.TestCase):
|
||||
|
||||
def test_deleting_magic_methods(self):
|
||||
mock = Mock()
|
||||
self.assertFalse(hasattr(mock, '__getitem__'))
|
||||
|
||||
mock.__getitem__ = Mock()
|
||||
self.assertTrue(hasattr(mock, '__getitem__'))
|
||||
|
||||
del mock.__getitem__
|
||||
self.assertFalse(hasattr(mock, '__getitem__'))
|
||||
|
||||
|
||||
def test_magicmock_del(self):
|
||||
mock = MagicMock()
|
||||
# before using getitem
|
||||
del mock.__getitem__
|
||||
self.assertRaises(TypeError, lambda: mock['foo'])
|
||||
|
||||
mock = MagicMock()
|
||||
# this time use it first
|
||||
mock['foo']
|
||||
del mock.__getitem__
|
||||
self.assertRaises(TypeError, lambda: mock['foo'])
|
||||
|
||||
|
||||
def test_magic_method_wrapping(self):
|
||||
mock = Mock()
|
||||
def f(self, name):
|
||||
return self, 'fish'
|
||||
|
||||
mock.__getitem__ = f
|
||||
self.assertIsNot(mock.__getitem__, f)
|
||||
self.assertEqual(mock['foo'], (mock, 'fish'))
|
||||
self.assertEqual(mock.__getitem__('foo'), (mock, 'fish'))
|
||||
|
||||
mock.__getitem__ = mock
|
||||
self.assertIs(mock.__getitem__, mock)
|
||||
|
||||
|
||||
def test_magic_methods_isolated_between_mocks(self):
|
||||
mock1 = Mock()
|
||||
mock2 = Mock()
|
||||
|
||||
mock1.__iter__ = Mock(return_value=iter([]))
|
||||
self.assertEqual(list(mock1), [])
|
||||
self.assertRaises(TypeError, lambda: list(mock2))
|
||||
|
||||
|
||||
def test_repr(self):
|
||||
mock = Mock()
|
||||
self.assertEqual(repr(mock), "<Mock id='%s'>" % id(mock))
|
||||
mock.__repr__ = lambda s: 'foo'
|
||||
self.assertEqual(repr(mock), 'foo')
|
||||
|
||||
|
||||
def test_str(self):
|
||||
mock = Mock()
|
||||
self.assertEqual(str(mock), object.__str__(mock))
|
||||
mock.__str__ = lambda s: 'foo'
|
||||
self.assertEqual(str(mock), 'foo')
|
||||
|
||||
|
||||
def test_dict_methods(self):
|
||||
mock = Mock()
|
||||
|
||||
self.assertRaises(TypeError, lambda: mock['foo'])
|
||||
def _del():
|
||||
del mock['foo']
|
||||
def _set():
|
||||
mock['foo'] = 3
|
||||
self.assertRaises(TypeError, _del)
|
||||
self.assertRaises(TypeError, _set)
|
||||
|
||||
_dict = {}
|
||||
def getitem(s, name):
|
||||
return _dict[name]
|
||||
def setitem(s, name, value):
|
||||
_dict[name] = value
|
||||
def delitem(s, name):
|
||||
del _dict[name]
|
||||
|
||||
mock.__setitem__ = setitem
|
||||
mock.__getitem__ = getitem
|
||||
mock.__delitem__ = delitem
|
||||
|
||||
self.assertRaises(KeyError, lambda: mock['foo'])
|
||||
mock['foo'] = 'bar'
|
||||
self.assertEqual(_dict, {'foo': 'bar'})
|
||||
self.assertEqual(mock['foo'], 'bar')
|
||||
del mock['foo']
|
||||
self.assertEqual(_dict, {})
|
||||
|
||||
|
||||
def test_numeric(self):
|
||||
original = mock = Mock()
|
||||
mock.value = 0
|
||||
|
||||
self.assertRaises(TypeError, lambda: mock + 3)
|
||||
|
||||
def add(self, other):
|
||||
mock.value += other
|
||||
return self
|
||||
mock.__add__ = add
|
||||
self.assertEqual(mock + 3, mock)
|
||||
self.assertEqual(mock.value, 3)
|
||||
|
||||
del mock.__add__
|
||||
def iadd(mock):
|
||||
mock += 3
|
||||
self.assertRaises(TypeError, iadd, mock)
|
||||
mock.__iadd__ = add
|
||||
mock += 6
|
||||
self.assertEqual(mock, original)
|
||||
self.assertEqual(mock.value, 9)
|
||||
|
||||
self.assertRaises(TypeError, lambda: 3 + mock)
|
||||
mock.__radd__ = add
|
||||
self.assertEqual(7 + mock, mock)
|
||||
self.assertEqual(mock.value, 16)
|
||||
|
||||
def test_division(self):
|
||||
original = mock = Mock()
|
||||
mock.value = 32
|
||||
self.assertRaises(TypeError, lambda: mock / 2)
|
||||
|
||||
def truediv(self, other):
|
||||
mock.value /= other
|
||||
return self
|
||||
mock.__truediv__ = truediv
|
||||
self.assertEqual(mock / 2, mock)
|
||||
self.assertEqual(mock.value, 16)
|
||||
|
||||
del mock.__truediv__
|
||||
def itruediv(mock):
|
||||
mock /= 4
|
||||
self.assertRaises(TypeError, itruediv, mock)
|
||||
mock.__itruediv__ = truediv
|
||||
mock /= 8
|
||||
self.assertEqual(mock, original)
|
||||
self.assertEqual(mock.value, 2)
|
||||
|
||||
self.assertRaises(TypeError, lambda: 8 / mock)
|
||||
mock.__rtruediv__ = truediv
|
||||
self.assertEqual(0.5 / mock, mock)
|
||||
self.assertEqual(mock.value, 4)
|
||||
|
||||
def test_hash(self):
|
||||
mock = Mock()
|
||||
# test delegation
|
||||
self.assertEqual(hash(mock), Mock.__hash__(mock))
|
||||
|
||||
def _hash(s):
|
||||
return 3
|
||||
mock.__hash__ = _hash
|
||||
self.assertEqual(hash(mock), 3)
|
||||
|
||||
|
||||
def test_nonzero(self):
|
||||
m = Mock()
|
||||
self.assertTrue(bool(m))
|
||||
|
||||
m.__bool__ = lambda s: False
|
||||
self.assertFalse(bool(m))
|
||||
|
||||
|
||||
def test_comparison(self):
|
||||
mock = Mock()
|
||||
def comp(s, o):
|
||||
return True
|
||||
mock.__lt__ = mock.__gt__ = mock.__le__ = mock.__ge__ = comp
|
||||
self. assertTrue(mock < 3)
|
||||
self. assertTrue(mock > 3)
|
||||
self. assertTrue(mock <= 3)
|
||||
self. assertTrue(mock >= 3)
|
||||
|
||||
self.assertRaises(TypeError, lambda: MagicMock() < object())
|
||||
self.assertRaises(TypeError, lambda: object() < MagicMock())
|
||||
self.assertRaises(TypeError, lambda: MagicMock() < MagicMock())
|
||||
self.assertRaises(TypeError, lambda: MagicMock() > object())
|
||||
self.assertRaises(TypeError, lambda: object() > MagicMock())
|
||||
self.assertRaises(TypeError, lambda: MagicMock() > MagicMock())
|
||||
self.assertRaises(TypeError, lambda: MagicMock() <= object())
|
||||
self.assertRaises(TypeError, lambda: object() <= MagicMock())
|
||||
self.assertRaises(TypeError, lambda: MagicMock() <= MagicMock())
|
||||
self.assertRaises(TypeError, lambda: MagicMock() >= object())
|
||||
self.assertRaises(TypeError, lambda: object() >= MagicMock())
|
||||
self.assertRaises(TypeError, lambda: MagicMock() >= MagicMock())
|
||||
|
||||
|
||||
def test_equality(self):
|
||||
for mock in Mock(), MagicMock():
|
||||
self.assertEqual(mock == mock, True)
|
||||
self.assertIsInstance(mock == mock, bool)
|
||||
self.assertEqual(mock != mock, False)
|
||||
self.assertIsInstance(mock != mock, bool)
|
||||
self.assertEqual(mock == object(), False)
|
||||
self.assertEqual(mock != object(), True)
|
||||
|
||||
def eq(self, other):
|
||||
return other == 3
|
||||
mock.__eq__ = eq
|
||||
self.assertTrue(mock == 3)
|
||||
self.assertFalse(mock == 4)
|
||||
|
||||
def ne(self, other):
|
||||
return other == 3
|
||||
mock.__ne__ = ne
|
||||
self.assertTrue(mock != 3)
|
||||
self.assertFalse(mock != 4)
|
||||
|
||||
mock = MagicMock()
|
||||
mock.__eq__.return_value = True
|
||||
self.assertIsInstance(mock == 3, bool)
|
||||
self.assertEqual(mock == 3, True)
|
||||
|
||||
mock.__ne__.return_value = False
|
||||
self.assertIsInstance(mock != 3, bool)
|
||||
self.assertEqual(mock != 3, False)
|
||||
|
||||
|
||||
def test_len_contains_iter(self):
|
||||
mock = Mock()
|
||||
|
||||
self.assertRaises(TypeError, len, mock)
|
||||
self.assertRaises(TypeError, iter, mock)
|
||||
self.assertRaises(TypeError, lambda: 'foo' in mock)
|
||||
|
||||
mock.__len__ = lambda s: 6
|
||||
self.assertEqual(len(mock), 6)
|
||||
|
||||
mock.__contains__ = lambda s, o: o == 3
|
||||
self.assertIn(3, mock)
|
||||
self.assertNotIn(6, mock)
|
||||
|
||||
mock.__iter__ = lambda s: iter('foobarbaz')
|
||||
self.assertEqual(list(mock), list('foobarbaz'))
|
||||
|
||||
|
||||
def test_magicmock(self):
|
||||
mock = MagicMock()
|
||||
|
||||
mock.__iter__.return_value = iter([1, 2, 3])
|
||||
self.assertEqual(list(mock), [1, 2, 3])
|
||||
|
||||
getattr(mock, '__bool__').return_value = False
|
||||
self.assertFalse(hasattr(mock, '__nonzero__'))
|
||||
self.assertFalse(bool(mock))
|
||||
|
||||
for entry in _magics:
|
||||
self.assertTrue(hasattr(mock, entry))
|
||||
self.assertFalse(hasattr(mock, '__imaginery__'))
|
||||
|
||||
|
||||
def test_magic_mock_equality(self):
|
||||
mock = MagicMock()
|
||||
self.assertIsInstance(mock == object(), bool)
|
||||
self.assertIsInstance(mock != object(), bool)
|
||||
|
||||
self.assertEqual(mock == object(), False)
|
||||
self.assertEqual(mock != object(), True)
|
||||
self.assertEqual(mock == mock, True)
|
||||
self.assertEqual(mock != mock, False)
|
||||
|
||||
|
||||
def test_magicmock_defaults(self):
|
||||
mock = MagicMock()
|
||||
self.assertEqual(int(mock), 1)
|
||||
self.assertEqual(complex(mock), 1j)
|
||||
self.assertEqual(float(mock), 1.0)
|
||||
self.assertNotIn(object(), mock)
|
||||
self.assertEqual(len(mock), 0)
|
||||
self.assertEqual(list(mock), [])
|
||||
self.assertEqual(hash(mock), object.__hash__(mock))
|
||||
self.assertEqual(str(mock), object.__str__(mock))
|
||||
self.assertTrue(bool(mock))
|
||||
|
||||
# in Python 3 oct and hex use __index__
|
||||
# so these tests are for __index__ in py3k
|
||||
self.assertEqual(oct(mock), '0o1')
|
||||
self.assertEqual(hex(mock), '0x1')
|
||||
# how to test __sizeof__ ?
|
||||
|
||||
|
||||
def test_magic_methods_and_spec(self):
|
||||
class Iterable(object):
|
||||
def __iter__(self):
|
||||
pass
|
||||
|
||||
mock = Mock(spec=Iterable)
|
||||
self.assertRaises(AttributeError, lambda: mock.__iter__)
|
||||
|
||||
mock.__iter__ = Mock(return_value=iter([]))
|
||||
self.assertEqual(list(mock), [])
|
||||
|
||||
class NonIterable(object):
|
||||
pass
|
||||
mock = Mock(spec=NonIterable)
|
||||
self.assertRaises(AttributeError, lambda: mock.__iter__)
|
||||
|
||||
def set_int():
|
||||
mock.__int__ = Mock(return_value=iter([]))
|
||||
self.assertRaises(AttributeError, set_int)
|
||||
|
||||
mock = MagicMock(spec=Iterable)
|
||||
self.assertEqual(list(mock), [])
|
||||
self.assertRaises(AttributeError, set_int)
|
||||
|
||||
|
||||
def test_magic_methods_and_spec_set(self):
|
||||
class Iterable(object):
|
||||
def __iter__(self):
|
||||
pass
|
||||
|
||||
mock = Mock(spec_set=Iterable)
|
||||
self.assertRaises(AttributeError, lambda: mock.__iter__)
|
||||
|
||||
mock.__iter__ = Mock(return_value=iter([]))
|
||||
self.assertEqual(list(mock), [])
|
||||
|
||||
class NonIterable(object):
|
||||
pass
|
||||
mock = Mock(spec_set=NonIterable)
|
||||
self.assertRaises(AttributeError, lambda: mock.__iter__)
|
||||
|
||||
def set_int():
|
||||
mock.__int__ = Mock(return_value=iter([]))
|
||||
self.assertRaises(AttributeError, set_int)
|
||||
|
||||
mock = MagicMock(spec_set=Iterable)
|
||||
self.assertEqual(list(mock), [])
|
||||
self.assertRaises(AttributeError, set_int)
|
||||
|
||||
|
||||
def test_setting_unsupported_magic_method(self):
|
||||
mock = MagicMock()
|
||||
def set_setattr():
|
||||
mock.__setattr__ = lambda self, name: None
|
||||
self.assertRaisesRegex(AttributeError,
|
||||
"Attempting to set unsupported magic method '__setattr__'.",
|
||||
set_setattr
|
||||
)
|
||||
|
||||
|
||||
def test_attributes_and_return_value(self):
|
||||
mock = MagicMock()
|
||||
attr = mock.foo
|
||||
def _get_type(obj):
|
||||
# the type of every mock (or magicmock) is a custom subclass
|
||||
# so the real type is the second in the mro
|
||||
return type(obj).__mro__[1]
|
||||
self.assertEqual(_get_type(attr), MagicMock)
|
||||
|
||||
returned = mock()
|
||||
self.assertEqual(_get_type(returned), MagicMock)
|
||||
|
||||
|
||||
def test_magic_methods_are_magic_mocks(self):
|
||||
mock = MagicMock()
|
||||
self.assertIsInstance(mock.__getitem__, MagicMock)
|
||||
|
||||
mock[1][2].__getitem__.return_value = 3
|
||||
self.assertEqual(mock[1][2][3], 3)
|
||||
|
||||
|
||||
def test_magic_method_reset_mock(self):
|
||||
mock = MagicMock()
|
||||
str(mock)
|
||||
self.assertTrue(mock.__str__.called)
|
||||
mock.reset_mock()
|
||||
self.assertFalse(mock.__str__.called)
|
||||
|
||||
|
||||
def test_dir(self):
|
||||
# overriding the default implementation
|
||||
for mock in Mock(), MagicMock():
|
||||
def _dir(self):
|
||||
return ['foo']
|
||||
mock.__dir__ = _dir
|
||||
self.assertEqual(dir(mock), ['foo'])
|
||||
|
||||
|
||||
@unittest.skipIf('PyPy' in sys.version, "This fails differently on pypy")
|
||||
def test_bound_methods(self):
|
||||
m = Mock()
|
||||
|
||||
# XXXX should this be an expected failure instead?
|
||||
|
||||
# this seems like it should work, but is hard to do without introducing
|
||||
# other api inconsistencies. Failure message could be better though.
|
||||
m.__iter__ = [3].__iter__
|
||||
self.assertRaises(TypeError, iter, m)
|
||||
|
||||
|
||||
def test_magic_method_type(self):
|
||||
class Foo(MagicMock):
|
||||
pass
|
||||
|
||||
foo = Foo()
|
||||
self.assertIsInstance(foo.__int__, Foo)
|
||||
|
||||
|
||||
def test_descriptor_from_class(self):
|
||||
m = MagicMock()
|
||||
type(m).__str__.return_value = 'foo'
|
||||
self.assertEqual(str(m), 'foo')
|
||||
|
||||
|
||||
def test_iterable_as_iter_return_value(self):
|
||||
m = MagicMock()
|
||||
m.__iter__.return_value = [1, 2, 3]
|
||||
self.assertEqual(list(m), [1, 2, 3])
|
||||
self.assertEqual(list(m), [1, 2, 3])
|
||||
|
||||
m.__iter__.return_value = iter([4, 5, 6])
|
||||
self.assertEqual(list(m), [4, 5, 6])
|
||||
self.assertEqual(list(m), [])
|
||||
|
||||
|
||||
def test_matmul(self):
|
||||
m = MagicMock()
|
||||
self.assertIsInstance(m @ 1, MagicMock)
|
||||
m.__matmul__.return_value = 42
|
||||
m.__rmatmul__.return_value = 666
|
||||
m.__imatmul__.return_value = 24
|
||||
self.assertEqual(m @ 1, 42)
|
||||
self.assertEqual(1 @ m, 666)
|
||||
m @= 24
|
||||
self.assertEqual(m, 24)
|
||||
|
||||
def test_divmod_and_rdivmod(self):
|
||||
m = MagicMock()
|
||||
self.assertIsInstance(divmod(5, m), MagicMock)
|
||||
m.__divmod__.return_value = (2, 1)
|
||||
self.assertEqual(divmod(m, 2), (2, 1))
|
||||
m = MagicMock()
|
||||
foo = divmod(2, m)
|
||||
self.assertIsInstance(foo, MagicMock)
|
||||
foo_direct = m.__divmod__(2)
|
||||
self.assertIsInstance(foo_direct, MagicMock)
|
||||
bar = divmod(m, 2)
|
||||
self.assertIsInstance(bar, MagicMock)
|
||||
bar_direct = m.__rdivmod__(2)
|
||||
self.assertIsInstance(bar_direct, MagicMock)
|
||||
|
||||
# http://bugs.python.org/issue23310
|
||||
# Check if you can change behaviour of magic methods in MagicMock init
|
||||
def test_magic_in_initialization(self):
|
||||
m = MagicMock(**{'__str__.return_value': "12"})
|
||||
self.assertEqual(str(m), "12")
|
||||
|
||||
def test_changing_magic_set_in_initialization(self):
|
||||
m = MagicMock(**{'__str__.return_value': "12"})
|
||||
m.__str__.return_value = "13"
|
||||
self.assertEqual(str(m), "13")
|
||||
m = MagicMock(**{'__str__.return_value': "12"})
|
||||
m.configure_mock(**{'__str__.return_value': "14"})
|
||||
self.assertEqual(str(m), "14")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
1766
third_party/python/Lib/unittest/test/testmock/testmock.py
vendored
Normal file
1766
third_party/python/Lib/unittest/test/testmock/testmock.py
vendored
Normal file
File diff suppressed because it is too large
Load diff
1858
third_party/python/Lib/unittest/test/testmock/testpatch.py
vendored
Normal file
1858
third_party/python/Lib/unittest/test/testmock/testpatch.py
vendored
Normal file
File diff suppressed because it is too large
Load diff
28
third_party/python/Lib/unittest/test/testmock/testsentinel.py
vendored
Normal file
28
third_party/python/Lib/unittest/test/testmock/testsentinel.py
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
import unittest
|
||||
from unittest.mock import sentinel, DEFAULT
|
||||
|
||||
|
||||
class SentinelTest(unittest.TestCase):
|
||||
|
||||
def testSentinels(self):
|
||||
self.assertEqual(sentinel.whatever, sentinel.whatever,
|
||||
'sentinel not stored')
|
||||
self.assertNotEqual(sentinel.whatever, sentinel.whateverelse,
|
||||
'sentinel should be unique')
|
||||
|
||||
|
||||
def testSentinelName(self):
|
||||
self.assertEqual(str(sentinel.whatever), 'sentinel.whatever',
|
||||
'sentinel name incorrect')
|
||||
|
||||
|
||||
def testDEFAULT(self):
|
||||
self.assertIs(DEFAULT, sentinel.DEFAULT)
|
||||
|
||||
def testBases(self):
|
||||
# If this doesn't raise an AttributeError then help(mock) is broken
|
||||
self.assertRaises(AttributeError, lambda: sentinel.__bases__)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
301
third_party/python/Lib/unittest/test/testmock/testwith.py
vendored
Normal file
301
third_party/python/Lib/unittest/test/testmock/testwith.py
vendored
Normal file
|
@ -0,0 +1,301 @@
|
|||
import unittest
|
||||
from warnings import catch_warnings
|
||||
|
||||
from unittest.test.testmock.support import is_instance
|
||||
from unittest.mock import MagicMock, Mock, patch, sentinel, mock_open, call
|
||||
|
||||
|
||||
|
||||
something = sentinel.Something
|
||||
something_else = sentinel.SomethingElse
|
||||
|
||||
|
||||
|
||||
class WithTest(unittest.TestCase):
|
||||
|
||||
def test_with_statement(self):
|
||||
with patch('%s.something' % __name__, sentinel.Something2):
|
||||
self.assertEqual(something, sentinel.Something2, "unpatched")
|
||||
self.assertEqual(something, sentinel.Something)
|
||||
|
||||
|
||||
def test_with_statement_exception(self):
|
||||
try:
|
||||
with patch('%s.something' % __name__, sentinel.Something2):
|
||||
self.assertEqual(something, sentinel.Something2, "unpatched")
|
||||
raise Exception('pow')
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
self.fail("patch swallowed exception")
|
||||
self.assertEqual(something, sentinel.Something)
|
||||
|
||||
|
||||
def test_with_statement_as(self):
|
||||
with patch('%s.something' % __name__) as mock_something:
|
||||
self.assertEqual(something, mock_something, "unpatched")
|
||||
self.assertTrue(is_instance(mock_something, MagicMock),
|
||||
"patching wrong type")
|
||||
self.assertEqual(something, sentinel.Something)
|
||||
|
||||
|
||||
def test_patch_object_with_statement(self):
|
||||
class Foo(object):
|
||||
something = 'foo'
|
||||
original = Foo.something
|
||||
with patch.object(Foo, 'something'):
|
||||
self.assertNotEqual(Foo.something, original, "unpatched")
|
||||
self.assertEqual(Foo.something, original)
|
||||
|
||||
|
||||
def test_with_statement_nested(self):
|
||||
with catch_warnings(record=True):
|
||||
with patch('%s.something' % __name__) as mock_something, patch('%s.something_else' % __name__) as mock_something_else:
|
||||
self.assertEqual(something, mock_something, "unpatched")
|
||||
self.assertEqual(something_else, mock_something_else,
|
||||
"unpatched")
|
||||
|
||||
self.assertEqual(something, sentinel.Something)
|
||||
self.assertEqual(something_else, sentinel.SomethingElse)
|
||||
|
||||
|
||||
def test_with_statement_specified(self):
|
||||
with patch('%s.something' % __name__, sentinel.Patched) as mock_something:
|
||||
self.assertEqual(something, mock_something, "unpatched")
|
||||
self.assertEqual(mock_something, sentinel.Patched, "wrong patch")
|
||||
self.assertEqual(something, sentinel.Something)
|
||||
|
||||
|
||||
def testContextManagerMocking(self):
|
||||
mock = Mock()
|
||||
mock.__enter__ = Mock()
|
||||
mock.__exit__ = Mock()
|
||||
mock.__exit__.return_value = False
|
||||
|
||||
with mock as m:
|
||||
self.assertEqual(m, mock.__enter__.return_value)
|
||||
mock.__enter__.assert_called_with()
|
||||
mock.__exit__.assert_called_with(None, None, None)
|
||||
|
||||
|
||||
def test_context_manager_with_magic_mock(self):
|
||||
mock = MagicMock()
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
with mock:
|
||||
'foo' + 3
|
||||
mock.__enter__.assert_called_with()
|
||||
self.assertTrue(mock.__exit__.called)
|
||||
|
||||
|
||||
def test_with_statement_same_attribute(self):
|
||||
with patch('%s.something' % __name__, sentinel.Patched) as mock_something:
|
||||
self.assertEqual(something, mock_something, "unpatched")
|
||||
|
||||
with patch('%s.something' % __name__) as mock_again:
|
||||
self.assertEqual(something, mock_again, "unpatched")
|
||||
|
||||
self.assertEqual(something, mock_something,
|
||||
"restored with wrong instance")
|
||||
|
||||
self.assertEqual(something, sentinel.Something, "not restored")
|
||||
|
||||
|
||||
def test_with_statement_imbricated(self):
|
||||
with patch('%s.something' % __name__) as mock_something:
|
||||
self.assertEqual(something, mock_something, "unpatched")
|
||||
|
||||
with patch('%s.something_else' % __name__) as mock_something_else:
|
||||
self.assertEqual(something_else, mock_something_else,
|
||||
"unpatched")
|
||||
|
||||
self.assertEqual(something, sentinel.Something)
|
||||
self.assertEqual(something_else, sentinel.SomethingElse)
|
||||
|
||||
|
||||
def test_dict_context_manager(self):
|
||||
foo = {}
|
||||
with patch.dict(foo, {'a': 'b'}):
|
||||
self.assertEqual(foo, {'a': 'b'})
|
||||
self.assertEqual(foo, {})
|
||||
|
||||
with self.assertRaises(NameError):
|
||||
with patch.dict(foo, {'a': 'b'}):
|
||||
self.assertEqual(foo, {'a': 'b'})
|
||||
raise NameError('Konrad')
|
||||
|
||||
self.assertEqual(foo, {})
|
||||
|
||||
|
||||
|
||||
class TestMockOpen(unittest.TestCase):
|
||||
|
||||
def test_mock_open(self):
|
||||
mock = mock_open()
|
||||
with patch('%s.open' % __name__, mock, create=True) as patched:
|
||||
self.assertIs(patched, mock)
|
||||
open('foo')
|
||||
|
||||
mock.assert_called_once_with('foo')
|
||||
|
||||
|
||||
def test_mock_open_context_manager(self):
|
||||
mock = mock_open()
|
||||
handle = mock.return_value
|
||||
with patch('%s.open' % __name__, mock, create=True):
|
||||
with open('foo') as f:
|
||||
f.read()
|
||||
|
||||
expected_calls = [call('foo'), call().__enter__(), call().read(),
|
||||
call().__exit__(None, None, None)]
|
||||
self.assertEqual(mock.mock_calls, expected_calls)
|
||||
self.assertIs(f, handle)
|
||||
|
||||
def test_mock_open_context_manager_multiple_times(self):
|
||||
mock = mock_open()
|
||||
with patch('%s.open' % __name__, mock, create=True):
|
||||
with open('foo') as f:
|
||||
f.read()
|
||||
with open('bar') as f:
|
||||
f.read()
|
||||
|
||||
expected_calls = [
|
||||
call('foo'), call().__enter__(), call().read(),
|
||||
call().__exit__(None, None, None),
|
||||
call('bar'), call().__enter__(), call().read(),
|
||||
call().__exit__(None, None, None)]
|
||||
self.assertEqual(mock.mock_calls, expected_calls)
|
||||
|
||||
def test_explicit_mock(self):
|
||||
mock = MagicMock()
|
||||
mock_open(mock)
|
||||
|
||||
with patch('%s.open' % __name__, mock, create=True) as patched:
|
||||
self.assertIs(patched, mock)
|
||||
open('foo')
|
||||
|
||||
mock.assert_called_once_with('foo')
|
||||
|
||||
|
||||
def test_read_data(self):
|
||||
mock = mock_open(read_data='foo')
|
||||
with patch('%s.open' % __name__, mock, create=True):
|
||||
h = open('bar')
|
||||
result = h.read()
|
||||
|
||||
self.assertEqual(result, 'foo')
|
||||
|
||||
|
||||
def test_readline_data(self):
|
||||
# Check that readline will return all the lines from the fake file
|
||||
mock = mock_open(read_data='foo\nbar\nbaz\n')
|
||||
with patch('%s.open' % __name__, mock, create=True):
|
||||
h = open('bar')
|
||||
line1 = h.readline()
|
||||
line2 = h.readline()
|
||||
line3 = h.readline()
|
||||
self.assertEqual(line1, 'foo\n')
|
||||
self.assertEqual(line2, 'bar\n')
|
||||
self.assertEqual(line3, 'baz\n')
|
||||
|
||||
# Check that we properly emulate a file that doesn't end in a newline
|
||||
mock = mock_open(read_data='foo')
|
||||
with patch('%s.open' % __name__, mock, create=True):
|
||||
h = open('bar')
|
||||
result = h.readline()
|
||||
self.assertEqual(result, 'foo')
|
||||
|
||||
|
||||
def test_readlines_data(self):
|
||||
# Test that emulating a file that ends in a newline character works
|
||||
mock = mock_open(read_data='foo\nbar\nbaz\n')
|
||||
with patch('%s.open' % __name__, mock, create=True):
|
||||
h = open('bar')
|
||||
result = h.readlines()
|
||||
self.assertEqual(result, ['foo\n', 'bar\n', 'baz\n'])
|
||||
|
||||
# Test that files without a final newline will also be correctly
|
||||
# emulated
|
||||
mock = mock_open(read_data='foo\nbar\nbaz')
|
||||
with patch('%s.open' % __name__, mock, create=True):
|
||||
h = open('bar')
|
||||
result = h.readlines()
|
||||
|
||||
self.assertEqual(result, ['foo\n', 'bar\n', 'baz'])
|
||||
|
||||
|
||||
def test_read_bytes(self):
|
||||
mock = mock_open(read_data=b'\xc6')
|
||||
with patch('%s.open' % __name__, mock, create=True):
|
||||
with open('abc', 'rb') as f:
|
||||
result = f.read()
|
||||
self.assertEqual(result, b'\xc6')
|
||||
|
||||
|
||||
def test_readline_bytes(self):
|
||||
m = mock_open(read_data=b'abc\ndef\nghi\n')
|
||||
with patch('%s.open' % __name__, m, create=True):
|
||||
with open('abc', 'rb') as f:
|
||||
line1 = f.readline()
|
||||
line2 = f.readline()
|
||||
line3 = f.readline()
|
||||
self.assertEqual(line1, b'abc\n')
|
||||
self.assertEqual(line2, b'def\n')
|
||||
self.assertEqual(line3, b'ghi\n')
|
||||
|
||||
|
||||
def test_readlines_bytes(self):
|
||||
m = mock_open(read_data=b'abc\ndef\nghi\n')
|
||||
with patch('%s.open' % __name__, m, create=True):
|
||||
with open('abc', 'rb') as f:
|
||||
result = f.readlines()
|
||||
self.assertEqual(result, [b'abc\n', b'def\n', b'ghi\n'])
|
||||
|
||||
|
||||
def test_mock_open_read_with_argument(self):
|
||||
# At one point calling read with an argument was broken
|
||||
# for mocks returned by mock_open
|
||||
some_data = 'foo\nbar\nbaz'
|
||||
mock = mock_open(read_data=some_data)
|
||||
self.assertEqual(mock().read(10), some_data)
|
||||
|
||||
|
||||
def test_interleaved_reads(self):
|
||||
# Test that calling read, readline, and readlines pulls data
|
||||
# sequentially from the data we preload with
|
||||
mock = mock_open(read_data='foo\nbar\nbaz\n')
|
||||
with patch('%s.open' % __name__, mock, create=True):
|
||||
h = open('bar')
|
||||
line1 = h.readline()
|
||||
rest = h.readlines()
|
||||
self.assertEqual(line1, 'foo\n')
|
||||
self.assertEqual(rest, ['bar\n', 'baz\n'])
|
||||
|
||||
mock = mock_open(read_data='foo\nbar\nbaz\n')
|
||||
with patch('%s.open' % __name__, mock, create=True):
|
||||
h = open('bar')
|
||||
line1 = h.readline()
|
||||
rest = h.read()
|
||||
self.assertEqual(line1, 'foo\n')
|
||||
self.assertEqual(rest, 'bar\nbaz\n')
|
||||
|
||||
|
||||
def test_overriding_return_values(self):
|
||||
mock = mock_open(read_data='foo')
|
||||
handle = mock()
|
||||
|
||||
handle.read.return_value = 'bar'
|
||||
handle.readline.return_value = 'bar'
|
||||
handle.readlines.return_value = ['bar']
|
||||
|
||||
self.assertEqual(handle.read(), 'bar')
|
||||
self.assertEqual(handle.readline(), 'bar')
|
||||
self.assertEqual(handle.readlines(), ['bar'])
|
||||
|
||||
# call repeatedly to check that a StopIteration is not propagated
|
||||
self.assertEqual(handle.readline(), 'bar')
|
||||
self.assertEqual(handle.readline(), 'bar')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
177
third_party/python/Lib/unittest/util.py
vendored
Normal file
177
third_party/python/Lib/unittest/util.py
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
"""Various utility functions."""
|
||||
|
||||
from collections import namedtuple, OrderedDict
|
||||
from os.path import commonprefix
|
||||
|
||||
__unittest = True
|
||||
|
||||
_MAX_LENGTH = 80
|
||||
_PLACEHOLDER_LEN = 12
|
||||
_MIN_BEGIN_LEN = 5
|
||||
_MIN_END_LEN = 5
|
||||
_MIN_COMMON_LEN = 5
|
||||
_MIN_DIFF_LEN = _MAX_LENGTH - \
|
||||
(_MIN_BEGIN_LEN + _PLACEHOLDER_LEN + _MIN_COMMON_LEN +
|
||||
_PLACEHOLDER_LEN + _MIN_END_LEN)
|
||||
assert _MIN_DIFF_LEN >= 0
|
||||
|
||||
def _shorten(s, prefixlen, suffixlen):
|
||||
skip = len(s) - prefixlen - suffixlen
|
||||
if skip > _PLACEHOLDER_LEN:
|
||||
s = '%s[%d chars]%s' % (s[:prefixlen], skip, s[len(s) - suffixlen:])
|
||||
return s
|
||||
|
||||
def _common_shorten_repr(*args):
|
||||
args = tuple(map(safe_repr, args))
|
||||
maxlen = max(map(len, args))
|
||||
if maxlen <= _MAX_LENGTH:
|
||||
return args
|
||||
|
||||
prefix = commonprefix(args)
|
||||
prefixlen = len(prefix)
|
||||
|
||||
common_len = _MAX_LENGTH - \
|
||||
(maxlen - prefixlen + _MIN_BEGIN_LEN + _PLACEHOLDER_LEN)
|
||||
if common_len > _MIN_COMMON_LEN:
|
||||
assert _MIN_BEGIN_LEN + _PLACEHOLDER_LEN + _MIN_COMMON_LEN + \
|
||||
(maxlen - prefixlen) < _MAX_LENGTH
|
||||
prefix = _shorten(prefix, _MIN_BEGIN_LEN, common_len)
|
||||
return tuple(prefix + s[prefixlen:] for s in args)
|
||||
|
||||
prefix = _shorten(prefix, _MIN_BEGIN_LEN, _MIN_COMMON_LEN)
|
||||
return tuple(prefix + _shorten(s[prefixlen:], _MIN_DIFF_LEN, _MIN_END_LEN)
|
||||
for s in args)
|
||||
|
||||
def safe_repr(obj, short=False):
|
||||
try:
|
||||
result = repr(obj)
|
||||
except Exception:
|
||||
result = object.__repr__(obj)
|
||||
if not short or len(result) < _MAX_LENGTH:
|
||||
return result
|
||||
return result[:_MAX_LENGTH] + ' [truncated]...'
|
||||
|
||||
def strclass(cls):
|
||||
return "%s.%s" % (cls.__module__, cls.__qualname__)
|
||||
|
||||
def sorted_list_difference(expected, actual):
|
||||
"""Finds elements in only one or the other of two, sorted input lists.
|
||||
|
||||
Returns a two-element tuple of lists. The first list contains those
|
||||
elements in the "expected" list but not in the "actual" list, and the
|
||||
second contains those elements in the "actual" list but not in the
|
||||
"expected" list. Duplicate elements in either input list are ignored.
|
||||
"""
|
||||
i = j = 0
|
||||
missing = []
|
||||
unexpected = []
|
||||
while True:
|
||||
try:
|
||||
e = expected[i]
|
||||
a = actual[j]
|
||||
if e < a:
|
||||
missing.append(e)
|
||||
i += 1
|
||||
while expected[i] == e:
|
||||
i += 1
|
||||
elif e > a:
|
||||
unexpected.append(a)
|
||||
j += 1
|
||||
while actual[j] == a:
|
||||
j += 1
|
||||
else:
|
||||
i += 1
|
||||
try:
|
||||
while expected[i] == e:
|
||||
i += 1
|
||||
finally:
|
||||
j += 1
|
||||
while actual[j] == a:
|
||||
j += 1
|
||||
except IndexError:
|
||||
missing.extend(expected[i:])
|
||||
unexpected.extend(actual[j:])
|
||||
break
|
||||
return missing, unexpected
|
||||
|
||||
|
||||
def unorderable_list_difference(expected, actual):
|
||||
"""Same behavior as sorted_list_difference but
|
||||
for lists of unorderable items (like dicts).
|
||||
|
||||
As it does a linear search per item (remove) it
|
||||
has O(n*n) performance."""
|
||||
missing = []
|
||||
while expected:
|
||||
item = expected.pop()
|
||||
try:
|
||||
actual.remove(item)
|
||||
except ValueError:
|
||||
missing.append(item)
|
||||
|
||||
# anything left in actual is unexpected
|
||||
return missing, actual
|
||||
|
||||
def three_way_cmp(x, y):
|
||||
"""Return -1 if x < y, 0 if x == y and 1 if x > y"""
|
||||
return (x > y) - (x < y)
|
||||
|
||||
_Mismatch = namedtuple('Mismatch', 'actual expected value')
|
||||
|
||||
def _count_diff_all_purpose(actual, expected):
|
||||
'Returns list of (cnt_act, cnt_exp, elem) triples where the counts differ'
|
||||
# elements need not be hashable
|
||||
s, t = list(actual), list(expected)
|
||||
m, n = len(s), len(t)
|
||||
NULL = object()
|
||||
result = []
|
||||
for i, elem in enumerate(s):
|
||||
if elem is NULL:
|
||||
continue
|
||||
cnt_s = cnt_t = 0
|
||||
for j in range(i, m):
|
||||
if s[j] == elem:
|
||||
cnt_s += 1
|
||||
s[j] = NULL
|
||||
for j, other_elem in enumerate(t):
|
||||
if other_elem == elem:
|
||||
cnt_t += 1
|
||||
t[j] = NULL
|
||||
if cnt_s != cnt_t:
|
||||
diff = _Mismatch(cnt_s, cnt_t, elem)
|
||||
result.append(diff)
|
||||
|
||||
for i, elem in enumerate(t):
|
||||
if elem is NULL:
|
||||
continue
|
||||
cnt_t = 0
|
||||
for j in range(i, n):
|
||||
if t[j] == elem:
|
||||
cnt_t += 1
|
||||
t[j] = NULL
|
||||
diff = _Mismatch(0, cnt_t, elem)
|
||||
result.append(diff)
|
||||
return result
|
||||
|
||||
def _ordered_count(iterable):
|
||||
'Return dict of element counts, in the order they were first seen'
|
||||
c = OrderedDict()
|
||||
for elem in iterable:
|
||||
c[elem] = c.get(elem, 0) + 1
|
||||
return c
|
||||
|
||||
def _count_diff_hashable(actual, expected):
|
||||
'Returns list of (cnt_act, cnt_exp, elem) triples where the counts differ'
|
||||
# elements must be hashable
|
||||
s, t = _ordered_count(actual), _ordered_count(expected)
|
||||
result = []
|
||||
for elem, cnt_s in s.items():
|
||||
cnt_t = t.get(elem, 0)
|
||||
if cnt_s != cnt_t:
|
||||
diff = _Mismatch(cnt_s, cnt_t, elem)
|
||||
result.append(diff)
|
||||
for elem, cnt_t in t.items():
|
||||
if elem not in s:
|
||||
diff = _Mismatch(0, cnt_t, elem)
|
||||
result.append(diff)
|
||||
return result
|
Loading…
Add table
Add a link
Reference in a new issue