175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen"""Test case implementation"""
275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport sys
475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport difflib
575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport pprint
675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport re
775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport unittest
875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport warnings
975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
1075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenfrom unittest2 import result
1175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenfrom unittest2.util import (
1275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    safe_repr, safe_str, strclass,
1375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    unorderable_list_difference
1475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen)
1575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
1675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenfrom unittest2.compatibility import wraps
1775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
1875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen__unittest = True
1975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny ChenDIFF_OMITTED = ('\nDiff is %s characters long. '
2275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                 'Set self.maxDiff to None to see it.')
2375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass SkipTest(Exception):
2575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
2675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    Raise this exception in a test to skip it.
2775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
2875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    Usually you can use TestResult.skip() or one of the skipping decorators
2975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    instead of raising this directly.
3075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
3175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
3275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass _ExpectedFailure(Exception):
3375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
3475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    Raise this when a test is expected to fail.
3575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
3675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    This is an implementation detail.
3775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
3875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
3921416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata    def __init__(self, exc_info, bugnumber=None):
4075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # can't use super because Python 2.4 exceptions are old style
4175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Exception.__init__(self)
4275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.exc_info = exc_info
4321416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata        self.bugnumber = bugnumber
4475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
4575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass _UnexpectedSuccess(Exception):
4675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
4775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    The test was supposed to fail, but it didn't!
4875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
4975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
5021416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata    def __init__(self, exc_info, bugnumber=None):
5121416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata        # can't use super because Python 2.4 exceptions are old style
5221416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata        Exception.__init__(self)
5321416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata        self.exc_info = exc_info
5421416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata        self.bugnumber = bugnumber
5521416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata
5675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chendef _id(obj):
5775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    return obj
5875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
5975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chendef skip(reason):
6075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
6175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    Unconditionally skip a test.
6275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
6375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def decorator(test_item):
6475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
6575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            @wraps(test_item)
6675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            def skip_wrapper(*args, **kwargs):
6775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                raise SkipTest(reason)
6875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            test_item = skip_wrapper
6975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
7075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        test_item.__unittest_skip__ = True
7175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        test_item.__unittest_skip_why__ = reason
7275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return test_item
7375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    return decorator
7475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
7575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chendef skipIf(condition, reason):
7675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
7775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    Skip a test if the condition is true.
7875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
7975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    if condition:
8075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return skip(reason)
8175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    return _id
8275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
8375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chendef skipUnless(condition, reason):
8475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
8575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    Skip a test unless the condition is true.
8675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
8775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    if not condition:
8875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return skip(reason)
8975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    return _id
9075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
9121416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granatadef expectedFailure(bugnumber=None):
9221416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata     if callable(bugnumber):
9321416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata        @wraps(bugnumber)
9421416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata        def expectedFailure_easy_wrapper(*args, **kwargs):
9521416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata             try:
9621416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata                bugnumber(*args, **kwargs)
9721416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata             except Exception:
9821416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata                raise _ExpectedFailure(sys.exc_info(),None)
9921416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata             raise _UnexpectedSuccess(sys.exc_info(),None)
10021416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata        return expectedFailure_easy_wrapper
10121416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata     else:
10221416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata        def expectedFailure_impl(func):
10321416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata              @wraps(func)
10421416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata              def wrapper(*args, **kwargs):
10521416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata                   try:
10621416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata                      func(*args, **kwargs)
10721416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata                   except Exception:
10821416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata                      raise _ExpectedFailure(sys.exc_info(),bugnumber)
10921416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata                   raise _UnexpectedSuccess(sys.exc_info(),bugnumber)
11021416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata              return wrapper
11121416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata        return expectedFailure_impl
11275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
11375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass _AssertRaisesContext(object):
11475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """A context manager used to implement TestCase.assertRaises* methods."""
11575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
11675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __init__(self, expected, test_case, expected_regexp=None):
11775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.expected = expected
11875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.failureException = test_case.failureException
11975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.expected_regexp = expected_regexp
12075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
12175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __enter__(self):
12275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return self
12375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
12475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __exit__(self, exc_type, exc_value, tb):
12575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if exc_type is None:
12675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            try:
12775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                exc_name = self.expected.__name__
12875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            except AttributeError:
12975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                exc_name = str(self.expected)
13075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise self.failureException(
13175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                "%s not raised" % (exc_name,))
13275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not issubclass(exc_type, self.expected):
13375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            # let unexpected exceptions pass through
13475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return False
13575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.exception = exc_value # store for later retrieval
13675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if self.expected_regexp is None:
13775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return True
13875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
13975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        expected_regexp = self.expected_regexp
14075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if isinstance(expected_regexp, basestring):
14175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            expected_regexp = re.compile(expected_regexp)
14275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not expected_regexp.search(str(exc_value)):
14375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise self.failureException('"%s" does not match "%s"' %
14475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                     (expected_regexp.pattern, str(exc_value)))
14575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return True
14675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
14775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
14875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass _TypeEqualityDict(object):
14975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
15075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __init__(self, testcase):
15175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.testcase = testcase
15275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._store = {}
15375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
15475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __setitem__(self, key, value):
15575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._store[key] = value
15675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
15775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __getitem__(self, key):
15875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        value = self._store[key]
15975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if isinstance(value, basestring):
16075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return getattr(self.testcase, value)
16175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return value
16275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
16375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def get(self, key, default=None):
16475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if key in self._store:
16575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return self[key]
16675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return default
16775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
16875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
16975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass TestCase(unittest.TestCase):
17075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """A class whose instances are single test cases.
17175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
17275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    By default, the test code itself should be placed in a method named
17375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    'runTest'.
17475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
17575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    If the fixture may be used for many test cases, create as
17675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    many test methods as are needed. When instantiating such a TestCase
17775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    subclass, specify in the constructor arguments the name of the test method
17875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    that the instance is to execute.
17975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
18075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    Test authors should subclass TestCase for their own tests. Construction
18175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    and deconstruction of the test's environment ('fixture') can be
18275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    implemented by overriding the 'setUp' and 'tearDown' methods respectively.
18375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
18475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    If it is necessary to override the __init__ method, the base class
18575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    __init__ method must always be called. It is important that subclasses
18675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    should not change the signature of their __init__ method, since instances
18775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    of the classes are instantiated automatically by parts of the framework
18875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    in order to be run.
18975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
19075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
19175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # This attribute determines which exception will be raised when
19275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # the instance's assertion methods fail; test methods raising this
19375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # exception will be deemed to have 'failed' rather than 'errored'
19475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
19575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    failureException = AssertionError
19675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
19775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # This attribute sets the maximum length of a diff in failure messages
19875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # by assert methods using difflib. It is looked up as an instance attribute
19975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # so can be configured by individual tests if required.
20075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
20175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    maxDiff = 80*8
20275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
20375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # This attribute determines whether long messages (including repr of
20475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # objects used in assert methods) will be printed on failure in *addition*
20575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # to any explicit message passed.
20675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
20775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    longMessage = True
20875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
20975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # Attribute used by TestSuite for classSetUp
21075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
21175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    _classSetupFailed = False
21275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
21375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __init__(self, methodName='runTest'):
21475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Create an instance of the class that will use the named test
21575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           method when executed. Raises a ValueError if the instance does
21675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           not have a method with the specified name.
21775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
21875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._testMethodName = methodName
21975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._resultForDoCleanups = None
22075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
22175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            testMethod = getattr(self, methodName)
22275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except AttributeError:
22375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise ValueError("no such test method in %s: %s" % \
22475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                  (self.__class__, methodName))
22575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._testMethodDoc = testMethod.__doc__
22675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._cleanups = []
22775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
22875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # Map types to custom assertEqual functions that will compare
22975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # instances of said type in more detail to generate a more useful
23075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # error message.
23175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._type_equality_funcs = _TypeEqualityDict(self)
23275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addTypeEqualityFunc(dict, 'assertDictEqual')
23375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addTypeEqualityFunc(list, 'assertListEqual')
23475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
23575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addTypeEqualityFunc(set, 'assertSetEqual')
23675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
23775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual')
23875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
23975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def addTypeEqualityFunc(self, typeobj, function):
24075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Add a type specific assertEqual style function to compare a type.
24175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
24275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        This method is for use by TestCase subclasses that need to register
24375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        their own type equality functions to provide nicer error messages.
24475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
24575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Args:
24675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            typeobj: The data type to call this function on when both values
24775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    are of the same type in assertEqual().
24875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            function: The callable taking two arguments and an optional
24975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    msg= argument that raises self.failureException with a
25075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    useful error message when the two arguments are not equal.
25175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
25275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._type_equality_funcs[typeobj] = function
25375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
25475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def addCleanup(self, function, *args, **kwargs):
25575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Add a function, with arguments, to be called when the test is
25675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        completed. Functions added are called on a LIFO basis and are
25775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        called after tearDown on test failure or success.
25875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
25975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Cleanup items are called even if setUp fails (unlike tearDown)."""
26075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._cleanups.append((function, args, kwargs))
26175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
26275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def setUp(self):
26375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        "Hook method for setting up the test fixture before exercising it."
26475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
26575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    @classmethod
26675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def setUpClass(cls):
26775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        "Hook method for setting up class fixture before running tests in the class."
26875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
26975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    @classmethod
27075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def tearDownClass(cls):
27175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        "Hook method for deconstructing the class fixture after running all tests in the class."
27275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
27375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def tearDown(self):
27475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        "Hook method for deconstructing the test fixture after testing it."
27575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
27675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def countTestCases(self):
27775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return 1
27875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
27975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def defaultTestResult(self):
28075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return result.TestResult()
28175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
28275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def shortDescription(self):
28375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Returns a one-line description of the test, or None if no
28475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        description has been provided.
28575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
28675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        The default implementation of this method returns the first line of
28775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        the specified test method's docstring.
28875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
28975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        doc = self._testMethodDoc
29075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return doc and doc.split("\n")[0].strip() or None
29175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
29275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
29375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def id(self):
29475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return "%s.%s" % (strclass(self.__class__), self._testMethodName)
29575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
29675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __eq__(self, other):
29775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if type(self) is not type(other):
29875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return NotImplemented
29975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
30075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return self._testMethodName == other._testMethodName
30175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
30275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __ne__(self, other):
30375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return not self == other
30475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
30575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __hash__(self):
30675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return hash((type(self), self._testMethodName))
30775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
30875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __str__(self):
30975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
31075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
31175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __repr__(self):
31275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return "<%s testMethod=%s>" % \
31375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen               (strclass(self.__class__), self._testMethodName)
31475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
31575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _addSkip(self, result, reason):
31675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        addSkip = getattr(result, 'addSkip', None)
31775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if addSkip is not None:
31875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            addSkip(self, reason)
31975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        else:
32075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            warnings.warn("Use of a TestResult without an addSkip method is deprecated",
32175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                          DeprecationWarning, 2)
32275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            result.addSuccess(self)
32375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
32475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def run(self, result=None):
32575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        orig_result = result
32675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if result is None:
32775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            result = self.defaultTestResult()
32875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            startTestRun = getattr(result, 'startTestRun', None)
32975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if startTestRun is not None:
33075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                startTestRun()
33175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
33275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._resultForDoCleanups = result
33375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        result.startTest(self)
33475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
33575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        testMethod = getattr(self, self._testMethodName)
33675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
33775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if (getattr(self.__class__, "__unittest_skip__", False) or
33875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            getattr(testMethod, "__unittest_skip__", False)):
33975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            # If the class or method was skipped.
34075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            try:
34175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
34275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                            or getattr(testMethod, '__unittest_skip_why__', ''))
34375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self._addSkip(result, skip_why)
34475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            finally:
34575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                result.stopTest(self)
34675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
34775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
34875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            success = False
34975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            try:
35075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self.setUp()
35175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            except SkipTest, e:
35275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                self._addSkip(result, str(e))
35375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            except Exception:
35475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                result.addError(self, sys.exc_info())
35575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            else:
35675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                try:
35775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    testMethod()
35875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                except self.failureException:
35975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    result.addFailure(self, sys.exc_info())
36075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                except _ExpectedFailure, e:
36175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    addExpectedFailure = getattr(result, 'addExpectedFailure', None)
36275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    if addExpectedFailure is not None:
36321416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata                        addExpectedFailure(self, e.exc_info, e.bugnumber)
36475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    else:
36575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                        warnings.warn("Use of a TestResult without an addExpectedFailure method is deprecated",
36675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                      DeprecationWarning)
36775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                        result.addSuccess(self)
36821416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata                except _UnexpectedSuccess, x:
36975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
37075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    if addUnexpectedSuccess is not None:
37121416a1d09aad1e25401e54578c3343bb0f0c25fEnrico Granata                        addUnexpectedSuccess(self, x.bugnumber)
37275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    else:
37375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                        warnings.warn("Use of a TestResult without an addUnexpectedSuccess method is deprecated",
37475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                      DeprecationWarning)
37575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                        result.addFailure(self, sys.exc_info())
37675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                except SkipTest, e:
37775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    self._addSkip(result, str(e))
37875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                except Exception:
37975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    result.addError(self, sys.exc_info())
38075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                else:
38175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    success = True
38275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
38375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                try:
38475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    self.tearDown()
38575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                except Exception:
38675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    result.addError(self, sys.exc_info())
38775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    success = False
38875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
38975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            cleanUpSuccess = self.doCleanups()
39075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            success = success and cleanUpSuccess
39175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if success:
39275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                result.addSuccess(self)
39375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        finally:
39475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            result.stopTest(self)
39575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if orig_result is None:
39675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                stopTestRun = getattr(result, 'stopTestRun', None)
39775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                if stopTestRun is not None:
39875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    stopTestRun()
39975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
40075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def doCleanups(self):
40175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Execute all cleanup functions. Normally called for you after
40275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        tearDown."""
40375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        result = self._resultForDoCleanups
40475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        ok = True
40575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        while self._cleanups:
40675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            function, args, kwargs = self._cleanups.pop(-1)
40775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            try:
40875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                function(*args, **kwargs)
40975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            except Exception:
41075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                ok = False
41175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                result.addError(self, sys.exc_info())
41275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return ok
41375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
41475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __call__(self, *args, **kwds):
41575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return self.run(*args, **kwds)
41675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
41775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def debug(self):
41875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Run the test without collecting errors in a TestResult"""
41975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.setUp()
42075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        getattr(self, self._testMethodName)()
42175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.tearDown()
42275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        while self._cleanups:
42375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            function, args, kwargs = self._cleanups.pop(-1)
42475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            function(*args, **kwargs)
42575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
42675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def skipTest(self, reason):
42775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Skip this test."""
42875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        raise SkipTest(reason)
42975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
43075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def fail(self, msg=None):
43175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Fail immediately, with the given message."""
43275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        raise self.failureException(msg)
43375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
43475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertFalse(self, expr, msg=None):
43575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        "Fail the test if the expression is true."
43675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if expr:
43775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))
43875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise self.failureException(msg)
43975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
44075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertTrue(self, expr, msg=None):
44175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Fail the test unless the expression is true."""
44275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not expr:
44375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))
44475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise self.failureException(msg)
44575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
44675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _formatMessage(self, msg, standardMsg):
44775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Honour the longMessage attribute when generating failure messages.
44875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        If longMessage is False this means:
44975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        * Use only an explicit message if it is provided
45075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        * Otherwise use the standard message for the assert
45175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
45275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        If longMessage is True:
45375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        * Use the standard message
45475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        * If an explicit message is provided, plus ' : ' and the explicit message
45575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
45675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not self.longMessage:
45775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return msg or standardMsg
45875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if msg is None:
45975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return standardMsg
46075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
46175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return '%s : %s' % (standardMsg, msg)
46275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except UnicodeDecodeError:
46375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return '%s : %s' % (safe_str(standardMsg), safe_str(msg))
46475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
46575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
46675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
46775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Fail unless an exception of class excClass is thrown
46875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           by callableObj when invoked with arguments args and keyword
46975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           arguments kwargs. If a different type of exception is
47075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           thrown, it will not be caught, and the test case will be
47175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           deemed to have suffered an error, exactly as for an
47275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           unexpected exception.
47375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
47475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           If called with callableObj omitted or None, will return a
47575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           context object used like this::
47675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
47775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                with self.assertRaises(SomeException):
47875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    do_something()
47975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
48075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           The context manager keeps a reference to the exception as
48175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           the 'exception' attribute. This allows you to inspect the
48275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           exception after the assertion::
48375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
48475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen               with self.assertRaises(SomeException) as cm:
48575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                   do_something()
48675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen               the_exception = cm.exception
48775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen               self.assertEqual(the_exception.error_code, 3)
48875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
48975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if callableObj is None:
49075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return _AssertRaisesContext(excClass, self)
49175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
49275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            callableObj(*args, **kwargs)
49375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except excClass:
49475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
49575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
49675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if hasattr(excClass,'__name__'):
49775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            excName = excClass.__name__
49875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        else:
49975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            excName = str(excClass)
50075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        raise self.failureException, "%s not raised" % excName
50175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
50275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _getAssertEqualityFunc(self, first, second):
50375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Get a detailed comparison function for the types of the two args.
50475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
50575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Returns: A callable accepting (first, second, msg=None) that will
50675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        raise a failure exception if first != second with a useful human
50775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        readable error message for those types.
50875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
50975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        #
51075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
51175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # and vice versa.  I opted for the conservative approach in case
51275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # subclasses are not intended to be compared in detail to their super
51375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # class instances using a type equality func.  This means testing
51475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # subtypes won't automagically use the detailed comparison.  Callers
51575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # should use their type specific assertSpamEqual method to compare
51675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # subclasses if the detailed comparison is desired and appropriate.
51775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        # See the discussion in http://bugs.python.org/issue2578.
51875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        #
51975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if type(first) is type(second):
52075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            asserter = self._type_equality_funcs.get(type(first))
52175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if asserter is not None:
52275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                return asserter
52375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
52475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return self._baseAssertEqual
52575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
52675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _baseAssertEqual(self, first, second, msg=None):
52775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """The default assertEqual implementation, not type specific."""
52875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not first == second:
52975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
53075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg = self._formatMessage(msg, standardMsg)
53175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise self.failureException(msg)
53275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
53375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertEqual(self, first, second, msg=None):
53475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Fail if the two objects are unequal as determined by the '=='
53575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           operator.
53675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
53775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        assertion_func = self._getAssertEqualityFunc(first, second)
53875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        assertion_func(first, second, msg=msg)
53975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
54075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertNotEqual(self, first, second, msg=None):
54175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Fail if the two objects are equal as determined by the '=='
54275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           operator.
54375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
54475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not first != second:
54575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
54675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                           safe_repr(second)))
54775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise self.failureException(msg)
54875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
54975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None):
55075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Fail if the two objects are unequal as determined by their
55175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           difference rounded to the given number of decimal places
55275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           (default 7) and comparing to zero, or by comparing that the
55375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           between the two objects is more than the given delta.
55475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
55575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           Note that decimal places (from zero) are usually not the same
55675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           as significant digits (measured from the most signficant digit).
55775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
55875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           If the two objects compare equal then they will automatically
55975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           compare almost equal.
56075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
56175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if first == second:
56275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            # shortcut
56375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
56475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if delta is not None and places is not None:
56575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise TypeError("specify delta or places not both")
56675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
56775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if delta is not None:
56875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if abs(first - second) <= delta:
56975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                return
57075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
57175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s != %s within %s delta' % (safe_repr(first),
57275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                        safe_repr(second),
57375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                        safe_repr(delta))
57475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        else:
57575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if places is None:
57675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                places = 7
57775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
57875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if round(abs(second-first), places) == 0:
57975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                return
58075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
58175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s != %s within %r places' % (safe_repr(first),
58275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                          safe_repr(second),
58375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                          places)
58475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        msg = self._formatMessage(msg, standardMsg)
58575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        raise self.failureException(msg)
58675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
58775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None):
58875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Fail if the two objects are equal as determined by their
58975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           difference rounded to the given number of decimal places
59075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           (default 7) and comparing to zero, or by comparing that the
59175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           between the two objects is less than the given delta.
59275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
59375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           Note that decimal places (from zero) are usually not the same
59475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           as significant digits (measured from the most signficant digit).
59575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
59675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen           Objects that are equal automatically fail.
59775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
59875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if delta is not None and places is not None:
59975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise TypeError("specify delta or places not both")
60075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if delta is not None:
60175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if not (first == second) and abs(first - second) > delta:
60275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                return
60375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s == %s within %s delta' % (safe_repr(first),
60475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                        safe_repr(second),
60575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                        safe_repr(delta))
60675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        else:
60775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if places is None:
60875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                places = 7
60975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if not (first == second) and round(abs(second-first), places) != 0:
61075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                return
61175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s == %s within %r places' % (safe_repr(first),
61275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                         safe_repr(second),
61375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                         places)
61475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
61575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        msg = self._formatMessage(msg, standardMsg)
61675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        raise self.failureException(msg)
61775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
61875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # Synonyms for assertion methods
61975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
62075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # The plurals are undocumented.  Keep them that way to discourage use.
62175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # Do not add more.  Do not remove.
62275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # Going through a deprecation cycle on these would annoy many people.
62375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    assertEquals = assertEqual
62475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    assertNotEquals = assertNotEqual
62575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    assertAlmostEquals = assertAlmostEqual
62675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    assertNotAlmostEquals = assertNotAlmostEqual
62775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    assert_ = assertTrue
62875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
62975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # These fail* assertion method names are pending deprecation and will
63075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
63175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _deprecate(original_func):
63275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        def deprecated_func(*args, **kwargs):
63375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            warnings.warn(
63475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                ('Please use %s instead.' % original_func.__name__),
63575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                PendingDeprecationWarning, 2)
63675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return original_func(*args, **kwargs)
63775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return deprecated_func
63875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
63975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    failUnlessEqual = _deprecate(assertEqual)
64075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    failIfEqual = _deprecate(assertNotEqual)
64175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
64275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
64375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    failUnless = _deprecate(assertTrue)
64475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    failUnlessRaises = _deprecate(assertRaises)
64575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    failIf = _deprecate(assertFalse)
64675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
64775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertSequenceEqual(self, seq1, seq2,
64875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                            msg=None, seq_type=None, max_diff=80*8):
64975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """An equality assertion for ordered sequences (like lists and tuples).
65075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
65175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        For the purposes of this function, a valid ordered sequence type is one
65275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        which can be indexed, has a length, and has an equality operator.
65375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
65475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Args:
65575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            seq1: The first sequence to compare.
65675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            seq2: The second sequence to compare.
65775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            seq_type: The expected datatype of the sequences, or None if no
65875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    datatype should be enforced.
65975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg: Optional message to use on failure instead of a list of
66075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    differences.
66175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            max_diff: Maximum size off the diff, larger diffs are not shown
66275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
66375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if seq_type is not None:
66475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            seq_type_name = seq_type.__name__
66575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if not isinstance(seq1, seq_type):
66675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                raise self.failureException('First sequence is not a %s: %s'
66775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                            % (seq_type_name, safe_repr(seq1)))
66875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if not isinstance(seq2, seq_type):
66975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                raise self.failureException('Second sequence is not a %s: %s'
67075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                            % (seq_type_name, safe_repr(seq2)))
67175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        else:
67275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            seq_type_name = "sequence"
67375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
67475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        differing = None
67575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
67675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            len1 = len(seq1)
67775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except (TypeError, NotImplementedError):
67875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            differing = 'First %s has no length.    Non-sequence?' % (
67975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    seq_type_name)
68075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
68175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if differing is None:
68275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            try:
68375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                len2 = len(seq2)
68475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            except (TypeError, NotImplementedError):
68575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                differing = 'Second %s has no length.    Non-sequence?' % (
68675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                        seq_type_name)
68775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
68875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if differing is None:
68975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if seq1 == seq2:
69075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                return
69175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
69275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            seq1_repr = repr(seq1)
69375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            seq2_repr = repr(seq2)
69475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if len(seq1_repr) > 30:
69575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                seq1_repr = seq1_repr[:30] + '...'
69675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if len(seq2_repr) > 30:
69775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                seq2_repr = seq2_repr[:30] + '...'
69875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
69975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            differing = '%ss differ: %s != %s\n' % elements
70075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
70175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            for i in xrange(min(len1, len2)):
70275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                try:
70375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    item1 = seq1[i]
70475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                except (TypeError, IndexError, NotImplementedError):
70575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    differing += ('\nUnable to index element %d of first %s\n' %
70675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                 (i, seq_type_name))
70775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    break
70875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
70975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                try:
71075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    item2 = seq2[i]
71175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                except (TypeError, IndexError, NotImplementedError):
71275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    differing += ('\nUnable to index element %d of second %s\n' %
71375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                 (i, seq_type_name))
71475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    break
71575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
71675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                if item1 != item2:
71775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    differing += ('\nFirst differing element %d:\n%s\n%s\n' %
71875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                 (i, item1, item2))
71975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    break
72075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            else:
72175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                if (len1 == len2 and seq_type is None and
72275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    type(seq1) != type(seq2)):
72375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    # The sequences are the same, but have differing types.
72475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    return
72575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
72675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if len1 > len2:
72775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                differing += ('\nFirst %s contains %d additional '
72875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                             'elements.\n' % (seq_type_name, len1 - len2))
72975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                try:
73075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    differing += ('First extra element %d:\n%s\n' %
73175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                  (len2, seq1[len2]))
73275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                except (TypeError, IndexError, NotImplementedError):
73375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    differing += ('Unable to index element %d '
73475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                  'of first %s\n' % (len2, seq_type_name))
73575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            elif len1 < len2:
73675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                differing += ('\nSecond %s contains %d additional '
73775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                             'elements.\n' % (seq_type_name, len2 - len1))
73875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                try:
73975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    differing += ('First extra element %d:\n%s\n' %
74075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                  (len1, seq2[len1]))
74175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                except (TypeError, IndexError, NotImplementedError):
74275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    differing += ('Unable to index element %d '
74375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                  'of second %s\n' % (len1, seq_type_name))
74475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        standardMsg = differing
74575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        diffMsg = '\n' + '\n'.join(
74675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            difflib.ndiff(pprint.pformat(seq1).splitlines(),
74775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                          pprint.pformat(seq2).splitlines()))
74875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
74975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        standardMsg = self._truncateMessage(standardMsg, diffMsg)
75075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        msg = self._formatMessage(msg, standardMsg)
75175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.fail(msg)
75275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
75375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def _truncateMessage(self, message, diff):
75475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        max_diff = self.maxDiff
75575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if max_diff is None or len(diff) <= max_diff:
75675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return message + diff
75775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return message + (DIFF_OMITTED % len(diff))
75875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
75975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertListEqual(self, list1, list2, msg=None):
76075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """A list-specific equality assertion.
76175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
76275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Args:
76375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            list1: The first list to compare.
76475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            list2: The second list to compare.
76575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg: Optional message to use on failure instead of a list of
76675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    differences.
76775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
76875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
76975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertSequenceEqual(list1, list2, msg, seq_type=list)
77075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
77175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertTupleEqual(self, tuple1, tuple2, msg=None):
77275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """A tuple-specific equality assertion.
77375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
77475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Args:
77575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            tuple1: The first tuple to compare.
77675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            tuple2: The second tuple to compare.
77775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg: Optional message to use on failure instead of a list of
77875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    differences.
77975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
78075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
78175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
78275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertSetEqual(self, set1, set2, msg=None):
78375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """A set-specific equality assertion.
78475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
78575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Args:
78675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            set1: The first set to compare.
78775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            set2: The second set to compare.
78875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg: Optional message to use on failure instead of a list of
78975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    differences.
79075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
79175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        assertSetEqual uses ducktyping to support
79275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        different types of sets, and is optimized for sets specifically
79375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        (parameters must support a difference method).
79475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
79575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
79675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            difference1 = set1.difference(set2)
79775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except TypeError, e:
79875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail('invalid type when attempting set difference: %s' % e)
79975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except AttributeError, e:
80075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail('first argument does not support set difference: %s' % e)
80175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
80275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
80375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            difference2 = set2.difference(set1)
80475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except TypeError, e:
80575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail('invalid type when attempting set difference: %s' % e)
80675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except AttributeError, e:
80775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail('second argument does not support set difference: %s' % e)
80875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
80975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not (difference1 or difference2):
81075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
81175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
81275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        lines = []
81375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if difference1:
81475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            lines.append('Items in the first set but not the second:')
81575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            for item in difference1:
81675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                lines.append(repr(item))
81775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if difference2:
81875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            lines.append('Items in the second set but not the first:')
81975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            for item in difference2:
82075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                lines.append(repr(item))
82175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
82275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        standardMsg = '\n'.join(lines)
82375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.fail(self._formatMessage(msg, standardMsg))
82475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
82575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertIn(self, member, container, msg=None):
82675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Just like self.assertTrue(a in b), but with a nicer default message."""
82775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if member not in container:
82875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s not found in %s' % (safe_repr(member),
82975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                   safe_repr(container))
83075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
83175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
83275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertNotIn(self, member, container, msg=None):
83375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Just like self.assertTrue(a not in b), but with a nicer default message."""
83475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if member in container:
83575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
83675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                            safe_repr(container))
83775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
83875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
83975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertIs(self, expr1, expr2, msg=None):
84075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Just like self.assertTrue(a is b), but with a nicer default message."""
84175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if expr1 is not expr2:
84275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s is not %s' % (safe_repr(expr1), safe_repr(expr2))
84375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
84475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
84575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertIsNot(self, expr1, expr2, msg=None):
84675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Just like self.assertTrue(a is not b), but with a nicer default message."""
84775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if expr1 is expr2:
84875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
84975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
85075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
85175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertDictEqual(self, d1, d2, msg=None):
85275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
85375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
85475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
85575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if d1 != d2:
85675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
85775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            diff = ('\n' + '\n'.join(difflib.ndiff(
85875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                           pprint.pformat(d1).splitlines(),
85975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                           pprint.pformat(d2).splitlines())))
86075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = self._truncateMessage(standardMsg, diff)
86175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
86275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
86375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertDictContainsSubset(self, expected, actual, msg=None):
86475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Checks whether actual is a superset of expected."""
86575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        missing = []
86675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        mismatched = []
86775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        for key, value in expected.iteritems():
86875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if key not in actual:
86975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                missing.append(key)
87075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            elif value != actual[key]:
87175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                mismatched.append('%s, expected: %s, actual: %s' %
87275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                  (safe_repr(key), safe_repr(value),
87375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                   safe_repr(actual[key])))
87475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
87575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not (missing or mismatched):
87675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return
87775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
87875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        standardMsg = ''
87975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if missing:
88075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
88175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                    missing)
88275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if mismatched:
88375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if standardMsg:
88475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                standardMsg += '; '
88575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
88675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
88775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.fail(self._formatMessage(msg, standardMsg))
88875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
88975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
89075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """An unordered sequence specific comparison. It asserts that
89175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        expected_seq and actual_seq contain the same elements. It is
89275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        the equivalent of::
89375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
89475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.assertEqual(sorted(expected_seq), sorted(actual_seq))
89575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
89675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Raises with an error message listing which elements of expected_seq
89775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        are missing from actual_seq and vice versa if any.
89875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
89975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Asserts that each element has the same count in both sequences.
90075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Example:
90175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            - [0, 1, 1] and [1, 0, 1] compare equal.
90275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            - [0, 0, 1] and [0, 1] compare unequal.
90375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
90475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
90575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            expected = sorted(expected_seq)
90675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            actual = sorted(actual_seq)
90775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except TypeError:
90875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            # Unsortable items (example: set(), complex(), ...)
90975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            expected = list(expected_seq)
91075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            actual = list(actual_seq)
91175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            missing, unexpected = unorderable_list_difference(
91275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                expected, actual, ignore_duplicate=False
91375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            )
91475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        else:
91575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return self.assertSequenceEqual(expected, actual, msg=msg)
91675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
91775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        errors = []
91875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if missing:
91975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            errors.append('Expected, but missing:\n    %s' %
92075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                           safe_repr(missing))
92175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if unexpected:
92275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            errors.append('Unexpected, but present:\n    %s' %
92375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                           safe_repr(unexpected))
92475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if errors:
92575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '\n'.join(errors)
92675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
92775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
92875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertMultiLineEqual(self, first, second, msg=None):
92975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Assert that two multi-line strings are equal."""
93075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assert_(isinstance(first, basestring), (
93175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                'First argument is not a string'))
93275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self.assert_(isinstance(second, basestring), (
93375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                'Second argument is not a string'))
93475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
93575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if first != second:
93675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s != %s' % (safe_repr(first, True), safe_repr(second, True))
93775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
93875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                                       second.splitlines(True)))
93975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = self._truncateMessage(standardMsg, diff)
94075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
94175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
94275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertLess(self, a, b, msg=None):
94375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Just like self.assertTrue(a < b), but with a nicer default message."""
94475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not a < b:
94575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
94675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
94775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
94875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertLessEqual(self, a, b, msg=None):
94975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Just like self.assertTrue(a <= b), but with a nicer default message."""
95075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not a <= b:
95175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
95275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
95375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
95475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertGreater(self, a, b, msg=None):
95575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Just like self.assertTrue(a > b), but with a nicer default message."""
95675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not a > b:
95775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
95875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
95975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
96075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertGreaterEqual(self, a, b, msg=None):
96175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Just like self.assertTrue(a >= b), but with a nicer default message."""
96275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not a >= b:
96375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
96475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
96575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
96675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertIsNone(self, obj, msg=None):
96775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Same as self.assertTrue(obj is None), with a nicer default message."""
96875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if obj is not None:
96975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s is not None' % (safe_repr(obj),)
97075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
97175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
97275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertIsNotNone(self, obj, msg=None):
97375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Included for symmetry with assertIsNone."""
97475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if obj is None:
97575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = 'unexpectedly None'
97675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
97775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
97875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertIsInstance(self, obj, cls, msg=None):
97975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
98075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        default message."""
98175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not isinstance(obj, cls):
98275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
98375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
98475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
98575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertNotIsInstance(self, obj, cls, msg=None):
98675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Included for symmetry with assertIsInstance."""
98775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if isinstance(obj, cls):
98875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
98975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self.fail(self._formatMessage(msg, standardMsg))
99075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
99175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertRaisesRegexp(self, expected_exception, expected_regexp,
99275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                           callable_obj=None, *args, **kwargs):
99375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Asserts that the message in a raised exception matches a regexp.
99475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
99575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        Args:
99675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            expected_exception: Exception class expected to be raised.
99775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            expected_regexp: Regexp (re pattern object or string) expected
99875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                    to be found in error message.
99975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            callable_obj: Function to be called.
100075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            args: Extra args.
100175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            kwargs: Extra kwargs.
100275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """
100375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if callable_obj is None:
100475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return _AssertRaisesContext(expected_exception, self, expected_regexp)
100575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        try:
100675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            callable_obj(*args, **kwargs)
100775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        except expected_exception, exc_value:
100875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if isinstance(expected_regexp, basestring):
100975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                expected_regexp = re.compile(expected_regexp)
101075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if not expected_regexp.search(str(exc_value)):
101175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                raise self.failureException('"%s" does not match "%s"' %
101275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                         (expected_regexp.pattern, str(exc_value)))
101375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        else:
101475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            if hasattr(expected_exception, '__name__'):
101575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                excName = expected_exception.__name__
101675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            else:
101775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                excName = str(expected_exception)
101875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise self.failureException, "%s not raised" % excName
101975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
102075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
102175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertRegexpMatches(self, text, expected_regexp, msg=None):
102275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Fail the test unless the text matches the regular expression."""
102375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if isinstance(expected_regexp, basestring):
102475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            expected_regexp = re.compile(expected_regexp)
102575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not expected_regexp.search(text):
102675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg = msg or "Regexp didn't match"
102775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
102875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise self.failureException(msg)
102975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
103075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
103175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        """Fail the test if the text matches the regular expression."""
103275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if isinstance(unexpected_regexp, basestring):
103375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            unexpected_regexp = re.compile(unexpected_regexp)
103475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        match = unexpected_regexp.search(text)
103575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if match:
103675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg = msg or "Regexp matched"
103775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            msg = '%s: %r matches %r in %r' % (msg,
103875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                               text[match.start():match.end()],
103975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                               unexpected_regexp.pattern,
104075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                               text)
104175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            raise self.failureException(msg)
104275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
104375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenclass FunctionTestCase(TestCase):
104475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """A test case that wraps a test function.
104575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
104675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    This is useful for slipping pre-existing test functions into the
104775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    unittest framework. Optionally, set-up and tidy-up functions can be
104875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    supplied. As with TestCase, the tidy-up ('tearDown') function will
104975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    always be called if the set-up ('setUp') function ran successfully.
105075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    """
105175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
105275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
105375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        super(FunctionTestCase, self).__init__()
105475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._setUpFunc = setUp
105575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._tearDownFunc = tearDown
105675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._testFunc = testFunc
105775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._description = description
105875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
105975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def setUp(self):
106075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if self._setUpFunc is not None:
106175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self._setUpFunc()
106275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
106375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def tearDown(self):
106475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if self._tearDownFunc is not None:
106575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            self._tearDownFunc()
106675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
106775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def runTest(self):
106875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        self._testFunc()
106975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
107075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def id(self):
107175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return self._testFunc.__name__
107275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
107375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __eq__(self, other):
107475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if not isinstance(other, self.__class__):
107575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return NotImplemented
107675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
107775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return self._setUpFunc == other._setUpFunc and \
107875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen               self._tearDownFunc == other._tearDownFunc and \
107975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen               self._testFunc == other._testFunc and \
108075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen               self._description == other._description
108175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
108275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __ne__(self, other):
108375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return not self == other
108475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
108575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __hash__(self):
108675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return hash((type(self), self._setUpFunc, self._tearDownFunc,
108775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                     self._testFunc, self._description))
108875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
108975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __str__(self):
109075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return "%s (%s)" % (strclass(self.__class__),
109175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                            self._testFunc.__name__)
109275e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
109375e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def __repr__(self):
109475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return "<%s testFunc=%s>" % (strclass(self.__class__),
109575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen                                     self._testFunc)
109675e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen
109775e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    def shortDescription(self):
109875e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        if self._description is not None:
109975e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen            return self._description
110075e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        doc = self._testFunc.__doc__
110175e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen        return doc and doc.split("\n")[0].strip() or None
1102