17db96d56Sopenharmony_ci"""Test case implementation"""
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ciimport sys
47db96d56Sopenharmony_ciimport functools
57db96d56Sopenharmony_ciimport difflib
67db96d56Sopenharmony_ciimport pprint
77db96d56Sopenharmony_ciimport re
87db96d56Sopenharmony_ciimport warnings
97db96d56Sopenharmony_ciimport collections
107db96d56Sopenharmony_ciimport contextlib
117db96d56Sopenharmony_ciimport traceback
127db96d56Sopenharmony_ciimport types
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_cifrom . import result
157db96d56Sopenharmony_cifrom .util import (strclass, safe_repr, _count_diff_all_purpose,
167db96d56Sopenharmony_ci                   _count_diff_hashable, _common_shorten_repr)
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci__unittest = True
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci_subtest_msg_sentinel = object()
217db96d56Sopenharmony_ci
227db96d56Sopenharmony_ciDIFF_OMITTED = ('\nDiff is %s characters long. '
237db96d56Sopenharmony_ci                 'Set self.maxDiff to None to see it.')
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ciclass SkipTest(Exception):
267db96d56Sopenharmony_ci    """
277db96d56Sopenharmony_ci    Raise this exception in a test to skip it.
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ci    Usually you can use TestCase.skipTest() or one of the skipping decorators
307db96d56Sopenharmony_ci    instead of raising this directly.
317db96d56Sopenharmony_ci    """
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ciclass _ShouldStop(Exception):
347db96d56Sopenharmony_ci    """
357db96d56Sopenharmony_ci    The test should stop.
367db96d56Sopenharmony_ci    """
377db96d56Sopenharmony_ci
387db96d56Sopenharmony_ciclass _UnexpectedSuccess(Exception):
397db96d56Sopenharmony_ci    """
407db96d56Sopenharmony_ci    The test was supposed to fail, but it didn't!
417db96d56Sopenharmony_ci    """
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ciclass _Outcome(object):
457db96d56Sopenharmony_ci    def __init__(self, result=None):
467db96d56Sopenharmony_ci        self.expecting_failure = False
477db96d56Sopenharmony_ci        self.result = result
487db96d56Sopenharmony_ci        self.result_supports_subtests = hasattr(result, "addSubTest")
497db96d56Sopenharmony_ci        self.success = True
507db96d56Sopenharmony_ci        self.expectedFailure = None
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ci    @contextlib.contextmanager
537db96d56Sopenharmony_ci    def testPartExecutor(self, test_case, subTest=False):
547db96d56Sopenharmony_ci        old_success = self.success
557db96d56Sopenharmony_ci        self.success = True
567db96d56Sopenharmony_ci        try:
577db96d56Sopenharmony_ci            yield
587db96d56Sopenharmony_ci        except KeyboardInterrupt:
597db96d56Sopenharmony_ci            raise
607db96d56Sopenharmony_ci        except SkipTest as e:
617db96d56Sopenharmony_ci            self.success = False
627db96d56Sopenharmony_ci            _addSkip(self.result, test_case, str(e))
637db96d56Sopenharmony_ci        except _ShouldStop:
647db96d56Sopenharmony_ci            pass
657db96d56Sopenharmony_ci        except:
667db96d56Sopenharmony_ci            exc_info = sys.exc_info()
677db96d56Sopenharmony_ci            if self.expecting_failure:
687db96d56Sopenharmony_ci                self.expectedFailure = exc_info
697db96d56Sopenharmony_ci            else:
707db96d56Sopenharmony_ci                self.success = False
717db96d56Sopenharmony_ci                if subTest:
727db96d56Sopenharmony_ci                    self.result.addSubTest(test_case.test_case, test_case, exc_info)
737db96d56Sopenharmony_ci                else:
747db96d56Sopenharmony_ci                    _addError(self.result, test_case, exc_info)
757db96d56Sopenharmony_ci            # explicitly break a reference cycle:
767db96d56Sopenharmony_ci            # exc_info -> frame -> exc_info
777db96d56Sopenharmony_ci            exc_info = None
787db96d56Sopenharmony_ci        else:
797db96d56Sopenharmony_ci            if subTest and self.success:
807db96d56Sopenharmony_ci                self.result.addSubTest(test_case.test_case, test_case, None)
817db96d56Sopenharmony_ci        finally:
827db96d56Sopenharmony_ci            self.success = self.success and old_success
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_cidef _addSkip(result, test_case, reason):
867db96d56Sopenharmony_ci    addSkip = getattr(result, 'addSkip', None)
877db96d56Sopenharmony_ci    if addSkip is not None:
887db96d56Sopenharmony_ci        addSkip(test_case, reason)
897db96d56Sopenharmony_ci    else:
907db96d56Sopenharmony_ci        warnings.warn("TestResult has no addSkip method, skips not reported",
917db96d56Sopenharmony_ci                      RuntimeWarning, 2)
927db96d56Sopenharmony_ci        result.addSuccess(test_case)
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_cidef _addError(result, test, exc_info):
957db96d56Sopenharmony_ci    if result is not None and exc_info is not None:
967db96d56Sopenharmony_ci        if issubclass(exc_info[0], test.failureException):
977db96d56Sopenharmony_ci            result.addFailure(test, exc_info)
987db96d56Sopenharmony_ci        else:
997db96d56Sopenharmony_ci            result.addError(test, exc_info)
1007db96d56Sopenharmony_ci
1017db96d56Sopenharmony_cidef _id(obj):
1027db96d56Sopenharmony_ci    return obj
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_cidef _enter_context(cm, addcleanup):
1067db96d56Sopenharmony_ci    # We look up the special methods on the type to match the with
1077db96d56Sopenharmony_ci    # statement.
1087db96d56Sopenharmony_ci    cls = type(cm)
1097db96d56Sopenharmony_ci    try:
1107db96d56Sopenharmony_ci        enter = cls.__enter__
1117db96d56Sopenharmony_ci        exit = cls.__exit__
1127db96d56Sopenharmony_ci    except AttributeError:
1137db96d56Sopenharmony_ci        raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does "
1147db96d56Sopenharmony_ci                        f"not support the context manager protocol") from None
1157db96d56Sopenharmony_ci    result = enter(cm)
1167db96d56Sopenharmony_ci    addcleanup(exit, cm, None, None, None)
1177db96d56Sopenharmony_ci    return result
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_ci_module_cleanups = []
1217db96d56Sopenharmony_cidef addModuleCleanup(function, /, *args, **kwargs):
1227db96d56Sopenharmony_ci    """Same as addCleanup, except the cleanup items are called even if
1237db96d56Sopenharmony_ci    setUpModule fails (unlike tearDownModule)."""
1247db96d56Sopenharmony_ci    _module_cleanups.append((function, args, kwargs))
1257db96d56Sopenharmony_ci
1267db96d56Sopenharmony_cidef enterModuleContext(cm):
1277db96d56Sopenharmony_ci    """Same as enterContext, but module-wide."""
1287db96d56Sopenharmony_ci    return _enter_context(cm, addModuleCleanup)
1297db96d56Sopenharmony_ci
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_cidef doModuleCleanups():
1327db96d56Sopenharmony_ci    """Execute all module cleanup functions. Normally called for you after
1337db96d56Sopenharmony_ci    tearDownModule."""
1347db96d56Sopenharmony_ci    exceptions = []
1357db96d56Sopenharmony_ci    while _module_cleanups:
1367db96d56Sopenharmony_ci        function, args, kwargs = _module_cleanups.pop()
1377db96d56Sopenharmony_ci        try:
1387db96d56Sopenharmony_ci            function(*args, **kwargs)
1397db96d56Sopenharmony_ci        except Exception as exc:
1407db96d56Sopenharmony_ci            exceptions.append(exc)
1417db96d56Sopenharmony_ci    if exceptions:
1427db96d56Sopenharmony_ci        # Swallows all but first exception. If a multi-exception handler
1437db96d56Sopenharmony_ci        # gets written we should use that here instead.
1447db96d56Sopenharmony_ci        raise exceptions[0]
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_cidef skip(reason):
1487db96d56Sopenharmony_ci    """
1497db96d56Sopenharmony_ci    Unconditionally skip a test.
1507db96d56Sopenharmony_ci    """
1517db96d56Sopenharmony_ci    def decorator(test_item):
1527db96d56Sopenharmony_ci        if not isinstance(test_item, type):
1537db96d56Sopenharmony_ci            @functools.wraps(test_item)
1547db96d56Sopenharmony_ci            def skip_wrapper(*args, **kwargs):
1557db96d56Sopenharmony_ci                raise SkipTest(reason)
1567db96d56Sopenharmony_ci            test_item = skip_wrapper
1577db96d56Sopenharmony_ci
1587db96d56Sopenharmony_ci        test_item.__unittest_skip__ = True
1597db96d56Sopenharmony_ci        test_item.__unittest_skip_why__ = reason
1607db96d56Sopenharmony_ci        return test_item
1617db96d56Sopenharmony_ci    if isinstance(reason, types.FunctionType):
1627db96d56Sopenharmony_ci        test_item = reason
1637db96d56Sopenharmony_ci        reason = ''
1647db96d56Sopenharmony_ci        return decorator(test_item)
1657db96d56Sopenharmony_ci    return decorator
1667db96d56Sopenharmony_ci
1677db96d56Sopenharmony_cidef skipIf(condition, reason):
1687db96d56Sopenharmony_ci    """
1697db96d56Sopenharmony_ci    Skip a test if the condition is true.
1707db96d56Sopenharmony_ci    """
1717db96d56Sopenharmony_ci    if condition:
1727db96d56Sopenharmony_ci        return skip(reason)
1737db96d56Sopenharmony_ci    return _id
1747db96d56Sopenharmony_ci
1757db96d56Sopenharmony_cidef skipUnless(condition, reason):
1767db96d56Sopenharmony_ci    """
1777db96d56Sopenharmony_ci    Skip a test unless the condition is true.
1787db96d56Sopenharmony_ci    """
1797db96d56Sopenharmony_ci    if not condition:
1807db96d56Sopenharmony_ci        return skip(reason)
1817db96d56Sopenharmony_ci    return _id
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_cidef expectedFailure(test_item):
1847db96d56Sopenharmony_ci    test_item.__unittest_expecting_failure__ = True
1857db96d56Sopenharmony_ci    return test_item
1867db96d56Sopenharmony_ci
1877db96d56Sopenharmony_cidef _is_subtype(expected, basetype):
1887db96d56Sopenharmony_ci    if isinstance(expected, tuple):
1897db96d56Sopenharmony_ci        return all(_is_subtype(e, basetype) for e in expected)
1907db96d56Sopenharmony_ci    return isinstance(expected, type) and issubclass(expected, basetype)
1917db96d56Sopenharmony_ci
1927db96d56Sopenharmony_ciclass _BaseTestCaseContext:
1937db96d56Sopenharmony_ci
1947db96d56Sopenharmony_ci    def __init__(self, test_case):
1957db96d56Sopenharmony_ci        self.test_case = test_case
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ci    def _raiseFailure(self, standardMsg):
1987db96d56Sopenharmony_ci        msg = self.test_case._formatMessage(self.msg, standardMsg)
1997db96d56Sopenharmony_ci        raise self.test_case.failureException(msg)
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ciclass _AssertRaisesBaseContext(_BaseTestCaseContext):
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_ci    def __init__(self, expected, test_case, expected_regex=None):
2047db96d56Sopenharmony_ci        _BaseTestCaseContext.__init__(self, test_case)
2057db96d56Sopenharmony_ci        self.expected = expected
2067db96d56Sopenharmony_ci        self.test_case = test_case
2077db96d56Sopenharmony_ci        if expected_regex is not None:
2087db96d56Sopenharmony_ci            expected_regex = re.compile(expected_regex)
2097db96d56Sopenharmony_ci        self.expected_regex = expected_regex
2107db96d56Sopenharmony_ci        self.obj_name = None
2117db96d56Sopenharmony_ci        self.msg = None
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_ci    def handle(self, name, args, kwargs):
2147db96d56Sopenharmony_ci        """
2157db96d56Sopenharmony_ci        If args is empty, assertRaises/Warns is being used as a
2167db96d56Sopenharmony_ci        context manager, so check for a 'msg' kwarg and return self.
2177db96d56Sopenharmony_ci        If args is not empty, call a callable passing positional and keyword
2187db96d56Sopenharmony_ci        arguments.
2197db96d56Sopenharmony_ci        """
2207db96d56Sopenharmony_ci        try:
2217db96d56Sopenharmony_ci            if not _is_subtype(self.expected, self._base_type):
2227db96d56Sopenharmony_ci                raise TypeError('%s() arg 1 must be %s' %
2237db96d56Sopenharmony_ci                                (name, self._base_type_str))
2247db96d56Sopenharmony_ci            if not args:
2257db96d56Sopenharmony_ci                self.msg = kwargs.pop('msg', None)
2267db96d56Sopenharmony_ci                if kwargs:
2277db96d56Sopenharmony_ci                    raise TypeError('%r is an invalid keyword argument for '
2287db96d56Sopenharmony_ci                                    'this function' % (next(iter(kwargs)),))
2297db96d56Sopenharmony_ci                return self
2307db96d56Sopenharmony_ci
2317db96d56Sopenharmony_ci            callable_obj, *args = args
2327db96d56Sopenharmony_ci            try:
2337db96d56Sopenharmony_ci                self.obj_name = callable_obj.__name__
2347db96d56Sopenharmony_ci            except AttributeError:
2357db96d56Sopenharmony_ci                self.obj_name = str(callable_obj)
2367db96d56Sopenharmony_ci            with self:
2377db96d56Sopenharmony_ci                callable_obj(*args, **kwargs)
2387db96d56Sopenharmony_ci        finally:
2397db96d56Sopenharmony_ci            # bpo-23890: manually break a reference cycle
2407db96d56Sopenharmony_ci            self = None
2417db96d56Sopenharmony_ci
2427db96d56Sopenharmony_ci
2437db96d56Sopenharmony_ciclass _AssertRaisesContext(_AssertRaisesBaseContext):
2447db96d56Sopenharmony_ci    """A context manager used to implement TestCase.assertRaises* methods."""
2457db96d56Sopenharmony_ci
2467db96d56Sopenharmony_ci    _base_type = BaseException
2477db96d56Sopenharmony_ci    _base_type_str = 'an exception type or tuple of exception types'
2487db96d56Sopenharmony_ci
2497db96d56Sopenharmony_ci    def __enter__(self):
2507db96d56Sopenharmony_ci        return self
2517db96d56Sopenharmony_ci
2527db96d56Sopenharmony_ci    def __exit__(self, exc_type, exc_value, tb):
2537db96d56Sopenharmony_ci        if exc_type is None:
2547db96d56Sopenharmony_ci            try:
2557db96d56Sopenharmony_ci                exc_name = self.expected.__name__
2567db96d56Sopenharmony_ci            except AttributeError:
2577db96d56Sopenharmony_ci                exc_name = str(self.expected)
2587db96d56Sopenharmony_ci            if self.obj_name:
2597db96d56Sopenharmony_ci                self._raiseFailure("{} not raised by {}".format(exc_name,
2607db96d56Sopenharmony_ci                                                                self.obj_name))
2617db96d56Sopenharmony_ci            else:
2627db96d56Sopenharmony_ci                self._raiseFailure("{} not raised".format(exc_name))
2637db96d56Sopenharmony_ci        else:
2647db96d56Sopenharmony_ci            traceback.clear_frames(tb)
2657db96d56Sopenharmony_ci        if not issubclass(exc_type, self.expected):
2667db96d56Sopenharmony_ci            # let unexpected exceptions pass through
2677db96d56Sopenharmony_ci            return False
2687db96d56Sopenharmony_ci        # store exception, without traceback, for later retrieval
2697db96d56Sopenharmony_ci        self.exception = exc_value.with_traceback(None)
2707db96d56Sopenharmony_ci        if self.expected_regex is None:
2717db96d56Sopenharmony_ci            return True
2727db96d56Sopenharmony_ci
2737db96d56Sopenharmony_ci        expected_regex = self.expected_regex
2747db96d56Sopenharmony_ci        if not expected_regex.search(str(exc_value)):
2757db96d56Sopenharmony_ci            self._raiseFailure('"{}" does not match "{}"'.format(
2767db96d56Sopenharmony_ci                     expected_regex.pattern, str(exc_value)))
2777db96d56Sopenharmony_ci        return True
2787db96d56Sopenharmony_ci
2797db96d56Sopenharmony_ci    __class_getitem__ = classmethod(types.GenericAlias)
2807db96d56Sopenharmony_ci
2817db96d56Sopenharmony_ci
2827db96d56Sopenharmony_ciclass _AssertWarnsContext(_AssertRaisesBaseContext):
2837db96d56Sopenharmony_ci    """A context manager used to implement TestCase.assertWarns* methods."""
2847db96d56Sopenharmony_ci
2857db96d56Sopenharmony_ci    _base_type = Warning
2867db96d56Sopenharmony_ci    _base_type_str = 'a warning type or tuple of warning types'
2877db96d56Sopenharmony_ci
2887db96d56Sopenharmony_ci    def __enter__(self):
2897db96d56Sopenharmony_ci        # The __warningregistry__'s need to be in a pristine state for tests
2907db96d56Sopenharmony_ci        # to work properly.
2917db96d56Sopenharmony_ci        for v in list(sys.modules.values()):
2927db96d56Sopenharmony_ci            if getattr(v, '__warningregistry__', None):
2937db96d56Sopenharmony_ci                v.__warningregistry__ = {}
2947db96d56Sopenharmony_ci        self.warnings_manager = warnings.catch_warnings(record=True)
2957db96d56Sopenharmony_ci        self.warnings = self.warnings_manager.__enter__()
2967db96d56Sopenharmony_ci        warnings.simplefilter("always", self.expected)
2977db96d56Sopenharmony_ci        return self
2987db96d56Sopenharmony_ci
2997db96d56Sopenharmony_ci    def __exit__(self, exc_type, exc_value, tb):
3007db96d56Sopenharmony_ci        self.warnings_manager.__exit__(exc_type, exc_value, tb)
3017db96d56Sopenharmony_ci        if exc_type is not None:
3027db96d56Sopenharmony_ci            # let unexpected exceptions pass through
3037db96d56Sopenharmony_ci            return
3047db96d56Sopenharmony_ci        try:
3057db96d56Sopenharmony_ci            exc_name = self.expected.__name__
3067db96d56Sopenharmony_ci        except AttributeError:
3077db96d56Sopenharmony_ci            exc_name = str(self.expected)
3087db96d56Sopenharmony_ci        first_matching = None
3097db96d56Sopenharmony_ci        for m in self.warnings:
3107db96d56Sopenharmony_ci            w = m.message
3117db96d56Sopenharmony_ci            if not isinstance(w, self.expected):
3127db96d56Sopenharmony_ci                continue
3137db96d56Sopenharmony_ci            if first_matching is None:
3147db96d56Sopenharmony_ci                first_matching = w
3157db96d56Sopenharmony_ci            if (self.expected_regex is not None and
3167db96d56Sopenharmony_ci                not self.expected_regex.search(str(w))):
3177db96d56Sopenharmony_ci                continue
3187db96d56Sopenharmony_ci            # store warning for later retrieval
3197db96d56Sopenharmony_ci            self.warning = w
3207db96d56Sopenharmony_ci            self.filename = m.filename
3217db96d56Sopenharmony_ci            self.lineno = m.lineno
3227db96d56Sopenharmony_ci            return
3237db96d56Sopenharmony_ci        # Now we simply try to choose a helpful failure message
3247db96d56Sopenharmony_ci        if first_matching is not None:
3257db96d56Sopenharmony_ci            self._raiseFailure('"{}" does not match "{}"'.format(
3267db96d56Sopenharmony_ci                     self.expected_regex.pattern, str(first_matching)))
3277db96d56Sopenharmony_ci        if self.obj_name:
3287db96d56Sopenharmony_ci            self._raiseFailure("{} not triggered by {}".format(exc_name,
3297db96d56Sopenharmony_ci                                                               self.obj_name))
3307db96d56Sopenharmony_ci        else:
3317db96d56Sopenharmony_ci            self._raiseFailure("{} not triggered".format(exc_name))
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci
3347db96d56Sopenharmony_ciclass _OrderedChainMap(collections.ChainMap):
3357db96d56Sopenharmony_ci    def __iter__(self):
3367db96d56Sopenharmony_ci        seen = set()
3377db96d56Sopenharmony_ci        for mapping in self.maps:
3387db96d56Sopenharmony_ci            for k in mapping:
3397db96d56Sopenharmony_ci                if k not in seen:
3407db96d56Sopenharmony_ci                    seen.add(k)
3417db96d56Sopenharmony_ci                    yield k
3427db96d56Sopenharmony_ci
3437db96d56Sopenharmony_ci
3447db96d56Sopenharmony_ciclass TestCase(object):
3457db96d56Sopenharmony_ci    """A class whose instances are single test cases.
3467db96d56Sopenharmony_ci
3477db96d56Sopenharmony_ci    By default, the test code itself should be placed in a method named
3487db96d56Sopenharmony_ci    'runTest'.
3497db96d56Sopenharmony_ci
3507db96d56Sopenharmony_ci    If the fixture may be used for many test cases, create as
3517db96d56Sopenharmony_ci    many test methods as are needed. When instantiating such a TestCase
3527db96d56Sopenharmony_ci    subclass, specify in the constructor arguments the name of the test method
3537db96d56Sopenharmony_ci    that the instance is to execute.
3547db96d56Sopenharmony_ci
3557db96d56Sopenharmony_ci    Test authors should subclass TestCase for their own tests. Construction
3567db96d56Sopenharmony_ci    and deconstruction of the test's environment ('fixture') can be
3577db96d56Sopenharmony_ci    implemented by overriding the 'setUp' and 'tearDown' methods respectively.
3587db96d56Sopenharmony_ci
3597db96d56Sopenharmony_ci    If it is necessary to override the __init__ method, the base class
3607db96d56Sopenharmony_ci    __init__ method must always be called. It is important that subclasses
3617db96d56Sopenharmony_ci    should not change the signature of their __init__ method, since instances
3627db96d56Sopenharmony_ci    of the classes are instantiated automatically by parts of the framework
3637db96d56Sopenharmony_ci    in order to be run.
3647db96d56Sopenharmony_ci
3657db96d56Sopenharmony_ci    When subclassing TestCase, you can set these attributes:
3667db96d56Sopenharmony_ci    * failureException: determines which exception will be raised when
3677db96d56Sopenharmony_ci        the instance's assertion methods fail; test methods raising this
3687db96d56Sopenharmony_ci        exception will be deemed to have 'failed' rather than 'errored'.
3697db96d56Sopenharmony_ci    * longMessage: determines whether long messages (including repr of
3707db96d56Sopenharmony_ci        objects used in assert methods) will be printed on failure in *addition*
3717db96d56Sopenharmony_ci        to any explicit message passed.
3727db96d56Sopenharmony_ci    * maxDiff: sets the maximum length of a diff in failure messages
3737db96d56Sopenharmony_ci        by assert methods using difflib. It is looked up as an instance
3747db96d56Sopenharmony_ci        attribute so can be configured by individual tests if required.
3757db96d56Sopenharmony_ci    """
3767db96d56Sopenharmony_ci
3777db96d56Sopenharmony_ci    failureException = AssertionError
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_ci    longMessage = True
3807db96d56Sopenharmony_ci
3817db96d56Sopenharmony_ci    maxDiff = 80*8
3827db96d56Sopenharmony_ci
3837db96d56Sopenharmony_ci    # If a string is longer than _diffThreshold, use normal comparison instead
3847db96d56Sopenharmony_ci    # of difflib.  See #11763.
3857db96d56Sopenharmony_ci    _diffThreshold = 2**16
3867db96d56Sopenharmony_ci
3877db96d56Sopenharmony_ci    def __init_subclass__(cls, *args, **kwargs):
3887db96d56Sopenharmony_ci        # Attribute used by TestSuite for classSetUp
3897db96d56Sopenharmony_ci        cls._classSetupFailed = False
3907db96d56Sopenharmony_ci        cls._class_cleanups = []
3917db96d56Sopenharmony_ci        super().__init_subclass__(*args, **kwargs)
3927db96d56Sopenharmony_ci
3937db96d56Sopenharmony_ci    def __init__(self, methodName='runTest'):
3947db96d56Sopenharmony_ci        """Create an instance of the class that will use the named test
3957db96d56Sopenharmony_ci           method when executed. Raises a ValueError if the instance does
3967db96d56Sopenharmony_ci           not have a method with the specified name.
3977db96d56Sopenharmony_ci        """
3987db96d56Sopenharmony_ci        self._testMethodName = methodName
3997db96d56Sopenharmony_ci        self._outcome = None
4007db96d56Sopenharmony_ci        self._testMethodDoc = 'No test'
4017db96d56Sopenharmony_ci        try:
4027db96d56Sopenharmony_ci            testMethod = getattr(self, methodName)
4037db96d56Sopenharmony_ci        except AttributeError:
4047db96d56Sopenharmony_ci            if methodName != 'runTest':
4057db96d56Sopenharmony_ci                # we allow instantiation with no explicit method name
4067db96d56Sopenharmony_ci                # but not an *incorrect* or missing method name
4077db96d56Sopenharmony_ci                raise ValueError("no such test method in %s: %s" %
4087db96d56Sopenharmony_ci                      (self.__class__, methodName))
4097db96d56Sopenharmony_ci        else:
4107db96d56Sopenharmony_ci            self._testMethodDoc = testMethod.__doc__
4117db96d56Sopenharmony_ci        self._cleanups = []
4127db96d56Sopenharmony_ci        self._subtest = None
4137db96d56Sopenharmony_ci
4147db96d56Sopenharmony_ci        # Map types to custom assertEqual functions that will compare
4157db96d56Sopenharmony_ci        # instances of said type in more detail to generate a more useful
4167db96d56Sopenharmony_ci        # error message.
4177db96d56Sopenharmony_ci        self._type_equality_funcs = {}
4187db96d56Sopenharmony_ci        self.addTypeEqualityFunc(dict, 'assertDictEqual')
4197db96d56Sopenharmony_ci        self.addTypeEqualityFunc(list, 'assertListEqual')
4207db96d56Sopenharmony_ci        self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
4217db96d56Sopenharmony_ci        self.addTypeEqualityFunc(set, 'assertSetEqual')
4227db96d56Sopenharmony_ci        self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
4237db96d56Sopenharmony_ci        self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
4247db96d56Sopenharmony_ci
4257db96d56Sopenharmony_ci    def addTypeEqualityFunc(self, typeobj, function):
4267db96d56Sopenharmony_ci        """Add a type specific assertEqual style function to compare a type.
4277db96d56Sopenharmony_ci
4287db96d56Sopenharmony_ci        This method is for use by TestCase subclasses that need to register
4297db96d56Sopenharmony_ci        their own type equality functions to provide nicer error messages.
4307db96d56Sopenharmony_ci
4317db96d56Sopenharmony_ci        Args:
4327db96d56Sopenharmony_ci            typeobj: The data type to call this function on when both values
4337db96d56Sopenharmony_ci                    are of the same type in assertEqual().
4347db96d56Sopenharmony_ci            function: The callable taking two arguments and an optional
4357db96d56Sopenharmony_ci                    msg= argument that raises self.failureException with a
4367db96d56Sopenharmony_ci                    useful error message when the two arguments are not equal.
4377db96d56Sopenharmony_ci        """
4387db96d56Sopenharmony_ci        self._type_equality_funcs[typeobj] = function
4397db96d56Sopenharmony_ci
4407db96d56Sopenharmony_ci    def addCleanup(self, function, /, *args, **kwargs):
4417db96d56Sopenharmony_ci        """Add a function, with arguments, to be called when the test is
4427db96d56Sopenharmony_ci        completed. Functions added are called on a LIFO basis and are
4437db96d56Sopenharmony_ci        called after tearDown on test failure or success.
4447db96d56Sopenharmony_ci
4457db96d56Sopenharmony_ci        Cleanup items are called even if setUp fails (unlike tearDown)."""
4467db96d56Sopenharmony_ci        self._cleanups.append((function, args, kwargs))
4477db96d56Sopenharmony_ci
4487db96d56Sopenharmony_ci    def enterContext(self, cm):
4497db96d56Sopenharmony_ci        """Enters the supplied context manager.
4507db96d56Sopenharmony_ci
4517db96d56Sopenharmony_ci        If successful, also adds its __exit__ method as a cleanup
4527db96d56Sopenharmony_ci        function and returns the result of the __enter__ method.
4537db96d56Sopenharmony_ci        """
4547db96d56Sopenharmony_ci        return _enter_context(cm, self.addCleanup)
4557db96d56Sopenharmony_ci
4567db96d56Sopenharmony_ci    @classmethod
4577db96d56Sopenharmony_ci    def addClassCleanup(cls, function, /, *args, **kwargs):
4587db96d56Sopenharmony_ci        """Same as addCleanup, except the cleanup items are called even if
4597db96d56Sopenharmony_ci        setUpClass fails (unlike tearDownClass)."""
4607db96d56Sopenharmony_ci        cls._class_cleanups.append((function, args, kwargs))
4617db96d56Sopenharmony_ci
4627db96d56Sopenharmony_ci    @classmethod
4637db96d56Sopenharmony_ci    def enterClassContext(cls, cm):
4647db96d56Sopenharmony_ci        """Same as enterContext, but class-wide."""
4657db96d56Sopenharmony_ci        return _enter_context(cm, cls.addClassCleanup)
4667db96d56Sopenharmony_ci
4677db96d56Sopenharmony_ci    def setUp(self):
4687db96d56Sopenharmony_ci        "Hook method for setting up the test fixture before exercising it."
4697db96d56Sopenharmony_ci        pass
4707db96d56Sopenharmony_ci
4717db96d56Sopenharmony_ci    def tearDown(self):
4727db96d56Sopenharmony_ci        "Hook method for deconstructing the test fixture after testing it."
4737db96d56Sopenharmony_ci        pass
4747db96d56Sopenharmony_ci
4757db96d56Sopenharmony_ci    @classmethod
4767db96d56Sopenharmony_ci    def setUpClass(cls):
4777db96d56Sopenharmony_ci        "Hook method for setting up class fixture before running tests in the class."
4787db96d56Sopenharmony_ci
4797db96d56Sopenharmony_ci    @classmethod
4807db96d56Sopenharmony_ci    def tearDownClass(cls):
4817db96d56Sopenharmony_ci        "Hook method for deconstructing the class fixture after running all tests in the class."
4827db96d56Sopenharmony_ci
4837db96d56Sopenharmony_ci    def countTestCases(self):
4847db96d56Sopenharmony_ci        return 1
4857db96d56Sopenharmony_ci
4867db96d56Sopenharmony_ci    def defaultTestResult(self):
4877db96d56Sopenharmony_ci        return result.TestResult()
4887db96d56Sopenharmony_ci
4897db96d56Sopenharmony_ci    def shortDescription(self):
4907db96d56Sopenharmony_ci        """Returns a one-line description of the test, or None if no
4917db96d56Sopenharmony_ci        description has been provided.
4927db96d56Sopenharmony_ci
4937db96d56Sopenharmony_ci        The default implementation of this method returns the first line of
4947db96d56Sopenharmony_ci        the specified test method's docstring.
4957db96d56Sopenharmony_ci        """
4967db96d56Sopenharmony_ci        doc = self._testMethodDoc
4977db96d56Sopenharmony_ci        return doc.strip().split("\n")[0].strip() if doc else None
4987db96d56Sopenharmony_ci
4997db96d56Sopenharmony_ci
5007db96d56Sopenharmony_ci    def id(self):
5017db96d56Sopenharmony_ci        return "%s.%s" % (strclass(self.__class__), self._testMethodName)
5027db96d56Sopenharmony_ci
5037db96d56Sopenharmony_ci    def __eq__(self, other):
5047db96d56Sopenharmony_ci        if type(self) is not type(other):
5057db96d56Sopenharmony_ci            return NotImplemented
5067db96d56Sopenharmony_ci
5077db96d56Sopenharmony_ci        return self._testMethodName == other._testMethodName
5087db96d56Sopenharmony_ci
5097db96d56Sopenharmony_ci    def __hash__(self):
5107db96d56Sopenharmony_ci        return hash((type(self), self._testMethodName))
5117db96d56Sopenharmony_ci
5127db96d56Sopenharmony_ci    def __str__(self):
5137db96d56Sopenharmony_ci        return "%s (%s.%s)" % (self._testMethodName, strclass(self.__class__), self._testMethodName)
5147db96d56Sopenharmony_ci
5157db96d56Sopenharmony_ci    def __repr__(self):
5167db96d56Sopenharmony_ci        return "<%s testMethod=%s>" % \
5177db96d56Sopenharmony_ci               (strclass(self.__class__), self._testMethodName)
5187db96d56Sopenharmony_ci
5197db96d56Sopenharmony_ci    @contextlib.contextmanager
5207db96d56Sopenharmony_ci    def subTest(self, msg=_subtest_msg_sentinel, **params):
5217db96d56Sopenharmony_ci        """Return a context manager that will return the enclosed block
5227db96d56Sopenharmony_ci        of code in a subtest identified by the optional message and
5237db96d56Sopenharmony_ci        keyword parameters.  A failure in the subtest marks the test
5247db96d56Sopenharmony_ci        case as failed but resumes execution at the end of the enclosed
5257db96d56Sopenharmony_ci        block, allowing further test code to be executed.
5267db96d56Sopenharmony_ci        """
5277db96d56Sopenharmony_ci        if self._outcome is None or not self._outcome.result_supports_subtests:
5287db96d56Sopenharmony_ci            yield
5297db96d56Sopenharmony_ci            return
5307db96d56Sopenharmony_ci        parent = self._subtest
5317db96d56Sopenharmony_ci        if parent is None:
5327db96d56Sopenharmony_ci            params_map = _OrderedChainMap(params)
5337db96d56Sopenharmony_ci        else:
5347db96d56Sopenharmony_ci            params_map = parent.params.new_child(params)
5357db96d56Sopenharmony_ci        self._subtest = _SubTest(self, msg, params_map)
5367db96d56Sopenharmony_ci        try:
5377db96d56Sopenharmony_ci            with self._outcome.testPartExecutor(self._subtest, subTest=True):
5387db96d56Sopenharmony_ci                yield
5397db96d56Sopenharmony_ci            if not self._outcome.success:
5407db96d56Sopenharmony_ci                result = self._outcome.result
5417db96d56Sopenharmony_ci                if result is not None and result.failfast:
5427db96d56Sopenharmony_ci                    raise _ShouldStop
5437db96d56Sopenharmony_ci            elif self._outcome.expectedFailure:
5447db96d56Sopenharmony_ci                # If the test is expecting a failure, we really want to
5457db96d56Sopenharmony_ci                # stop now and register the expected failure.
5467db96d56Sopenharmony_ci                raise _ShouldStop
5477db96d56Sopenharmony_ci        finally:
5487db96d56Sopenharmony_ci            self._subtest = parent
5497db96d56Sopenharmony_ci
5507db96d56Sopenharmony_ci    def _addExpectedFailure(self, result, exc_info):
5517db96d56Sopenharmony_ci        try:
5527db96d56Sopenharmony_ci            addExpectedFailure = result.addExpectedFailure
5537db96d56Sopenharmony_ci        except AttributeError:
5547db96d56Sopenharmony_ci            warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
5557db96d56Sopenharmony_ci                          RuntimeWarning)
5567db96d56Sopenharmony_ci            result.addSuccess(self)
5577db96d56Sopenharmony_ci        else:
5587db96d56Sopenharmony_ci            addExpectedFailure(self, exc_info)
5597db96d56Sopenharmony_ci
5607db96d56Sopenharmony_ci    def _addUnexpectedSuccess(self, result):
5617db96d56Sopenharmony_ci        try:
5627db96d56Sopenharmony_ci            addUnexpectedSuccess = result.addUnexpectedSuccess
5637db96d56Sopenharmony_ci        except AttributeError:
5647db96d56Sopenharmony_ci            warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failure",
5657db96d56Sopenharmony_ci                          RuntimeWarning)
5667db96d56Sopenharmony_ci            # We need to pass an actual exception and traceback to addFailure,
5677db96d56Sopenharmony_ci            # otherwise the legacy result can choke.
5687db96d56Sopenharmony_ci            try:
5697db96d56Sopenharmony_ci                raise _UnexpectedSuccess from None
5707db96d56Sopenharmony_ci            except _UnexpectedSuccess:
5717db96d56Sopenharmony_ci                result.addFailure(self, sys.exc_info())
5727db96d56Sopenharmony_ci        else:
5737db96d56Sopenharmony_ci            addUnexpectedSuccess(self)
5747db96d56Sopenharmony_ci
5757db96d56Sopenharmony_ci    def _callSetUp(self):
5767db96d56Sopenharmony_ci        self.setUp()
5777db96d56Sopenharmony_ci
5787db96d56Sopenharmony_ci    def _callTestMethod(self, method):
5797db96d56Sopenharmony_ci        if method() is not None:
5807db96d56Sopenharmony_ci            warnings.warn(f'It is deprecated to return a value that is not None from a '
5817db96d56Sopenharmony_ci                          f'test case ({method})', DeprecationWarning, stacklevel=3)
5827db96d56Sopenharmony_ci
5837db96d56Sopenharmony_ci    def _callTearDown(self):
5847db96d56Sopenharmony_ci        self.tearDown()
5857db96d56Sopenharmony_ci
5867db96d56Sopenharmony_ci    def _callCleanup(self, function, /, *args, **kwargs):
5877db96d56Sopenharmony_ci        function(*args, **kwargs)
5887db96d56Sopenharmony_ci
5897db96d56Sopenharmony_ci    def run(self, result=None):
5907db96d56Sopenharmony_ci        if result is None:
5917db96d56Sopenharmony_ci            result = self.defaultTestResult()
5927db96d56Sopenharmony_ci            startTestRun = getattr(result, 'startTestRun', None)
5937db96d56Sopenharmony_ci            stopTestRun = getattr(result, 'stopTestRun', None)
5947db96d56Sopenharmony_ci            if startTestRun is not None:
5957db96d56Sopenharmony_ci                startTestRun()
5967db96d56Sopenharmony_ci        else:
5977db96d56Sopenharmony_ci            stopTestRun = None
5987db96d56Sopenharmony_ci
5997db96d56Sopenharmony_ci        result.startTest(self)
6007db96d56Sopenharmony_ci        try:
6017db96d56Sopenharmony_ci            testMethod = getattr(self, self._testMethodName)
6027db96d56Sopenharmony_ci            if (getattr(self.__class__, "__unittest_skip__", False) or
6037db96d56Sopenharmony_ci                getattr(testMethod, "__unittest_skip__", False)):
6047db96d56Sopenharmony_ci                # If the class or method was skipped.
6057db96d56Sopenharmony_ci                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
6067db96d56Sopenharmony_ci                            or getattr(testMethod, '__unittest_skip_why__', ''))
6077db96d56Sopenharmony_ci                _addSkip(result, self, skip_why)
6087db96d56Sopenharmony_ci                return result
6097db96d56Sopenharmony_ci
6107db96d56Sopenharmony_ci            expecting_failure = (
6117db96d56Sopenharmony_ci                getattr(self, "__unittest_expecting_failure__", False) or
6127db96d56Sopenharmony_ci                getattr(testMethod, "__unittest_expecting_failure__", False)
6137db96d56Sopenharmony_ci            )
6147db96d56Sopenharmony_ci            outcome = _Outcome(result)
6157db96d56Sopenharmony_ci            try:
6167db96d56Sopenharmony_ci                self._outcome = outcome
6177db96d56Sopenharmony_ci
6187db96d56Sopenharmony_ci                with outcome.testPartExecutor(self):
6197db96d56Sopenharmony_ci                    self._callSetUp()
6207db96d56Sopenharmony_ci                if outcome.success:
6217db96d56Sopenharmony_ci                    outcome.expecting_failure = expecting_failure
6227db96d56Sopenharmony_ci                    with outcome.testPartExecutor(self):
6237db96d56Sopenharmony_ci                        self._callTestMethod(testMethod)
6247db96d56Sopenharmony_ci                    outcome.expecting_failure = False
6257db96d56Sopenharmony_ci                    with outcome.testPartExecutor(self):
6267db96d56Sopenharmony_ci                        self._callTearDown()
6277db96d56Sopenharmony_ci                self.doCleanups()
6287db96d56Sopenharmony_ci
6297db96d56Sopenharmony_ci                if outcome.success:
6307db96d56Sopenharmony_ci                    if expecting_failure:
6317db96d56Sopenharmony_ci                        if outcome.expectedFailure:
6327db96d56Sopenharmony_ci                            self._addExpectedFailure(result, outcome.expectedFailure)
6337db96d56Sopenharmony_ci                        else:
6347db96d56Sopenharmony_ci                            self._addUnexpectedSuccess(result)
6357db96d56Sopenharmony_ci                    else:
6367db96d56Sopenharmony_ci                        result.addSuccess(self)
6377db96d56Sopenharmony_ci                return result
6387db96d56Sopenharmony_ci            finally:
6397db96d56Sopenharmony_ci                # explicitly break reference cycle:
6407db96d56Sopenharmony_ci                # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure
6417db96d56Sopenharmony_ci                outcome.expectedFailure = None
6427db96d56Sopenharmony_ci                outcome = None
6437db96d56Sopenharmony_ci
6447db96d56Sopenharmony_ci                # clear the outcome, no more needed
6457db96d56Sopenharmony_ci                self._outcome = None
6467db96d56Sopenharmony_ci
6477db96d56Sopenharmony_ci        finally:
6487db96d56Sopenharmony_ci            result.stopTest(self)
6497db96d56Sopenharmony_ci            if stopTestRun is not None:
6507db96d56Sopenharmony_ci                stopTestRun()
6517db96d56Sopenharmony_ci
6527db96d56Sopenharmony_ci    def doCleanups(self):
6537db96d56Sopenharmony_ci        """Execute all cleanup functions. Normally called for you after
6547db96d56Sopenharmony_ci        tearDown."""
6557db96d56Sopenharmony_ci        outcome = self._outcome or _Outcome()
6567db96d56Sopenharmony_ci        while self._cleanups:
6577db96d56Sopenharmony_ci            function, args, kwargs = self._cleanups.pop()
6587db96d56Sopenharmony_ci            with outcome.testPartExecutor(self):
6597db96d56Sopenharmony_ci                self._callCleanup(function, *args, **kwargs)
6607db96d56Sopenharmony_ci
6617db96d56Sopenharmony_ci        # return this for backwards compatibility
6627db96d56Sopenharmony_ci        # even though we no longer use it internally
6637db96d56Sopenharmony_ci        return outcome.success
6647db96d56Sopenharmony_ci
6657db96d56Sopenharmony_ci    @classmethod
6667db96d56Sopenharmony_ci    def doClassCleanups(cls):
6677db96d56Sopenharmony_ci        """Execute all class cleanup functions. Normally called for you after
6687db96d56Sopenharmony_ci        tearDownClass."""
6697db96d56Sopenharmony_ci        cls.tearDown_exceptions = []
6707db96d56Sopenharmony_ci        while cls._class_cleanups:
6717db96d56Sopenharmony_ci            function, args, kwargs = cls._class_cleanups.pop()
6727db96d56Sopenharmony_ci            try:
6737db96d56Sopenharmony_ci                function(*args, **kwargs)
6747db96d56Sopenharmony_ci            except Exception:
6757db96d56Sopenharmony_ci                cls.tearDown_exceptions.append(sys.exc_info())
6767db96d56Sopenharmony_ci
6777db96d56Sopenharmony_ci    def __call__(self, *args, **kwds):
6787db96d56Sopenharmony_ci        return self.run(*args, **kwds)
6797db96d56Sopenharmony_ci
6807db96d56Sopenharmony_ci    def debug(self):
6817db96d56Sopenharmony_ci        """Run the test without collecting errors in a TestResult"""
6827db96d56Sopenharmony_ci        testMethod = getattr(self, self._testMethodName)
6837db96d56Sopenharmony_ci        if (getattr(self.__class__, "__unittest_skip__", False) or
6847db96d56Sopenharmony_ci            getattr(testMethod, "__unittest_skip__", False)):
6857db96d56Sopenharmony_ci            # If the class or method was skipped.
6867db96d56Sopenharmony_ci            skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
6877db96d56Sopenharmony_ci                        or getattr(testMethod, '__unittest_skip_why__', ''))
6887db96d56Sopenharmony_ci            raise SkipTest(skip_why)
6897db96d56Sopenharmony_ci
6907db96d56Sopenharmony_ci        self._callSetUp()
6917db96d56Sopenharmony_ci        self._callTestMethod(testMethod)
6927db96d56Sopenharmony_ci        self._callTearDown()
6937db96d56Sopenharmony_ci        while self._cleanups:
6947db96d56Sopenharmony_ci            function, args, kwargs = self._cleanups.pop()
6957db96d56Sopenharmony_ci            self._callCleanup(function, *args, **kwargs)
6967db96d56Sopenharmony_ci
6977db96d56Sopenharmony_ci    def skipTest(self, reason):
6987db96d56Sopenharmony_ci        """Skip this test."""
6997db96d56Sopenharmony_ci        raise SkipTest(reason)
7007db96d56Sopenharmony_ci
7017db96d56Sopenharmony_ci    def fail(self, msg=None):
7027db96d56Sopenharmony_ci        """Fail immediately, with the given message."""
7037db96d56Sopenharmony_ci        raise self.failureException(msg)
7047db96d56Sopenharmony_ci
7057db96d56Sopenharmony_ci    def assertFalse(self, expr, msg=None):
7067db96d56Sopenharmony_ci        """Check that the expression is false."""
7077db96d56Sopenharmony_ci        if expr:
7087db96d56Sopenharmony_ci            msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
7097db96d56Sopenharmony_ci            raise self.failureException(msg)
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ci    def assertTrue(self, expr, msg=None):
7127db96d56Sopenharmony_ci        """Check that the expression is true."""
7137db96d56Sopenharmony_ci        if not expr:
7147db96d56Sopenharmony_ci            msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
7157db96d56Sopenharmony_ci            raise self.failureException(msg)
7167db96d56Sopenharmony_ci
7177db96d56Sopenharmony_ci    def _formatMessage(self, msg, standardMsg):
7187db96d56Sopenharmony_ci        """Honour the longMessage attribute when generating failure messages.
7197db96d56Sopenharmony_ci        If longMessage is False this means:
7207db96d56Sopenharmony_ci        * Use only an explicit message if it is provided
7217db96d56Sopenharmony_ci        * Otherwise use the standard message for the assert
7227db96d56Sopenharmony_ci
7237db96d56Sopenharmony_ci        If longMessage is True:
7247db96d56Sopenharmony_ci        * Use the standard message
7257db96d56Sopenharmony_ci        * If an explicit message is provided, plus ' : ' and the explicit message
7267db96d56Sopenharmony_ci        """
7277db96d56Sopenharmony_ci        if not self.longMessage:
7287db96d56Sopenharmony_ci            return msg or standardMsg
7297db96d56Sopenharmony_ci        if msg is None:
7307db96d56Sopenharmony_ci            return standardMsg
7317db96d56Sopenharmony_ci        try:
7327db96d56Sopenharmony_ci            # don't switch to '{}' formatting in Python 2.X
7337db96d56Sopenharmony_ci            # it changes the way unicode input is handled
7347db96d56Sopenharmony_ci            return '%s : %s' % (standardMsg, msg)
7357db96d56Sopenharmony_ci        except UnicodeDecodeError:
7367db96d56Sopenharmony_ci            return  '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
7377db96d56Sopenharmony_ci
7387db96d56Sopenharmony_ci    def assertRaises(self, expected_exception, *args, **kwargs):
7397db96d56Sopenharmony_ci        """Fail unless an exception of class expected_exception is raised
7407db96d56Sopenharmony_ci           by the callable when invoked with specified positional and
7417db96d56Sopenharmony_ci           keyword arguments. If a different type of exception is
7427db96d56Sopenharmony_ci           raised, it will not be caught, and the test case will be
7437db96d56Sopenharmony_ci           deemed to have suffered an error, exactly as for an
7447db96d56Sopenharmony_ci           unexpected exception.
7457db96d56Sopenharmony_ci
7467db96d56Sopenharmony_ci           If called with the callable and arguments omitted, will return a
7477db96d56Sopenharmony_ci           context object used like this::
7487db96d56Sopenharmony_ci
7497db96d56Sopenharmony_ci                with self.assertRaises(SomeException):
7507db96d56Sopenharmony_ci                    do_something()
7517db96d56Sopenharmony_ci
7527db96d56Sopenharmony_ci           An optional keyword argument 'msg' can be provided when assertRaises
7537db96d56Sopenharmony_ci           is used as a context object.
7547db96d56Sopenharmony_ci
7557db96d56Sopenharmony_ci           The context manager keeps a reference to the exception as
7567db96d56Sopenharmony_ci           the 'exception' attribute. This allows you to inspect the
7577db96d56Sopenharmony_ci           exception after the assertion::
7587db96d56Sopenharmony_ci
7597db96d56Sopenharmony_ci               with self.assertRaises(SomeException) as cm:
7607db96d56Sopenharmony_ci                   do_something()
7617db96d56Sopenharmony_ci               the_exception = cm.exception
7627db96d56Sopenharmony_ci               self.assertEqual(the_exception.error_code, 3)
7637db96d56Sopenharmony_ci        """
7647db96d56Sopenharmony_ci        context = _AssertRaisesContext(expected_exception, self)
7657db96d56Sopenharmony_ci        try:
7667db96d56Sopenharmony_ci            return context.handle('assertRaises', args, kwargs)
7677db96d56Sopenharmony_ci        finally:
7687db96d56Sopenharmony_ci            # bpo-23890: manually break a reference cycle
7697db96d56Sopenharmony_ci            context = None
7707db96d56Sopenharmony_ci
7717db96d56Sopenharmony_ci    def assertWarns(self, expected_warning, *args, **kwargs):
7727db96d56Sopenharmony_ci        """Fail unless a warning of class warnClass is triggered
7737db96d56Sopenharmony_ci           by the callable when invoked with specified positional and
7747db96d56Sopenharmony_ci           keyword arguments.  If a different type of warning is
7757db96d56Sopenharmony_ci           triggered, it will not be handled: depending on the other
7767db96d56Sopenharmony_ci           warning filtering rules in effect, it might be silenced, printed
7777db96d56Sopenharmony_ci           out, or raised as an exception.
7787db96d56Sopenharmony_ci
7797db96d56Sopenharmony_ci           If called with the callable and arguments omitted, will return a
7807db96d56Sopenharmony_ci           context object used like this::
7817db96d56Sopenharmony_ci
7827db96d56Sopenharmony_ci                with self.assertWarns(SomeWarning):
7837db96d56Sopenharmony_ci                    do_something()
7847db96d56Sopenharmony_ci
7857db96d56Sopenharmony_ci           An optional keyword argument 'msg' can be provided when assertWarns
7867db96d56Sopenharmony_ci           is used as a context object.
7877db96d56Sopenharmony_ci
7887db96d56Sopenharmony_ci           The context manager keeps a reference to the first matching
7897db96d56Sopenharmony_ci           warning as the 'warning' attribute; similarly, the 'filename'
7907db96d56Sopenharmony_ci           and 'lineno' attributes give you information about the line
7917db96d56Sopenharmony_ci           of Python code from which the warning was triggered.
7927db96d56Sopenharmony_ci           This allows you to inspect the warning after the assertion::
7937db96d56Sopenharmony_ci
7947db96d56Sopenharmony_ci               with self.assertWarns(SomeWarning) as cm:
7957db96d56Sopenharmony_ci                   do_something()
7967db96d56Sopenharmony_ci               the_warning = cm.warning
7977db96d56Sopenharmony_ci               self.assertEqual(the_warning.some_attribute, 147)
7987db96d56Sopenharmony_ci        """
7997db96d56Sopenharmony_ci        context = _AssertWarnsContext(expected_warning, self)
8007db96d56Sopenharmony_ci        return context.handle('assertWarns', args, kwargs)
8017db96d56Sopenharmony_ci
8027db96d56Sopenharmony_ci    def assertLogs(self, logger=None, level=None):
8037db96d56Sopenharmony_ci        """Fail unless a log message of level *level* or higher is emitted
8047db96d56Sopenharmony_ci        on *logger_name* or its children.  If omitted, *level* defaults to
8057db96d56Sopenharmony_ci        INFO and *logger* defaults to the root logger.
8067db96d56Sopenharmony_ci
8077db96d56Sopenharmony_ci        This method must be used as a context manager, and will yield
8087db96d56Sopenharmony_ci        a recording object with two attributes: `output` and `records`.
8097db96d56Sopenharmony_ci        At the end of the context manager, the `output` attribute will
8107db96d56Sopenharmony_ci        be a list of the matching formatted log messages and the
8117db96d56Sopenharmony_ci        `records` attribute will be a list of the corresponding LogRecord
8127db96d56Sopenharmony_ci        objects.
8137db96d56Sopenharmony_ci
8147db96d56Sopenharmony_ci        Example::
8157db96d56Sopenharmony_ci
8167db96d56Sopenharmony_ci            with self.assertLogs('foo', level='INFO') as cm:
8177db96d56Sopenharmony_ci                logging.getLogger('foo').info('first message')
8187db96d56Sopenharmony_ci                logging.getLogger('foo.bar').error('second message')
8197db96d56Sopenharmony_ci            self.assertEqual(cm.output, ['INFO:foo:first message',
8207db96d56Sopenharmony_ci                                         'ERROR:foo.bar:second message'])
8217db96d56Sopenharmony_ci        """
8227db96d56Sopenharmony_ci        # Lazy import to avoid importing logging if it is not needed.
8237db96d56Sopenharmony_ci        from ._log import _AssertLogsContext
8247db96d56Sopenharmony_ci        return _AssertLogsContext(self, logger, level, no_logs=False)
8257db96d56Sopenharmony_ci
8267db96d56Sopenharmony_ci    def assertNoLogs(self, logger=None, level=None):
8277db96d56Sopenharmony_ci        """ Fail unless no log messages of level *level* or higher are emitted
8287db96d56Sopenharmony_ci        on *logger_name* or its children.
8297db96d56Sopenharmony_ci
8307db96d56Sopenharmony_ci        This method must be used as a context manager.
8317db96d56Sopenharmony_ci        """
8327db96d56Sopenharmony_ci        from ._log import _AssertLogsContext
8337db96d56Sopenharmony_ci        return _AssertLogsContext(self, logger, level, no_logs=True)
8347db96d56Sopenharmony_ci
8357db96d56Sopenharmony_ci    def _getAssertEqualityFunc(self, first, second):
8367db96d56Sopenharmony_ci        """Get a detailed comparison function for the types of the two args.
8377db96d56Sopenharmony_ci
8387db96d56Sopenharmony_ci        Returns: A callable accepting (first, second, msg=None) that will
8397db96d56Sopenharmony_ci        raise a failure exception if first != second with a useful human
8407db96d56Sopenharmony_ci        readable error message for those types.
8417db96d56Sopenharmony_ci        """
8427db96d56Sopenharmony_ci        #
8437db96d56Sopenharmony_ci        # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
8447db96d56Sopenharmony_ci        # and vice versa.  I opted for the conservative approach in case
8457db96d56Sopenharmony_ci        # subclasses are not intended to be compared in detail to their super
8467db96d56Sopenharmony_ci        # class instances using a type equality func.  This means testing
8477db96d56Sopenharmony_ci        # subtypes won't automagically use the detailed comparison.  Callers
8487db96d56Sopenharmony_ci        # should use their type specific assertSpamEqual method to compare
8497db96d56Sopenharmony_ci        # subclasses if the detailed comparison is desired and appropriate.
8507db96d56Sopenharmony_ci        # See the discussion in http://bugs.python.org/issue2578.
8517db96d56Sopenharmony_ci        #
8527db96d56Sopenharmony_ci        if type(first) is type(second):
8537db96d56Sopenharmony_ci            asserter = self._type_equality_funcs.get(type(first))
8547db96d56Sopenharmony_ci            if asserter is not None:
8557db96d56Sopenharmony_ci                if isinstance(asserter, str):
8567db96d56Sopenharmony_ci                    asserter = getattr(self, asserter)
8577db96d56Sopenharmony_ci                return asserter
8587db96d56Sopenharmony_ci
8597db96d56Sopenharmony_ci        return self._baseAssertEqual
8607db96d56Sopenharmony_ci
8617db96d56Sopenharmony_ci    def _baseAssertEqual(self, first, second, msg=None):
8627db96d56Sopenharmony_ci        """The default assertEqual implementation, not type specific."""
8637db96d56Sopenharmony_ci        if not first == second:
8647db96d56Sopenharmony_ci            standardMsg = '%s != %s' % _common_shorten_repr(first, second)
8657db96d56Sopenharmony_ci            msg = self._formatMessage(msg, standardMsg)
8667db96d56Sopenharmony_ci            raise self.failureException(msg)
8677db96d56Sopenharmony_ci
8687db96d56Sopenharmony_ci    def assertEqual(self, first, second, msg=None):
8697db96d56Sopenharmony_ci        """Fail if the two objects are unequal as determined by the '=='
8707db96d56Sopenharmony_ci           operator.
8717db96d56Sopenharmony_ci        """
8727db96d56Sopenharmony_ci        assertion_func = self._getAssertEqualityFunc(first, second)
8737db96d56Sopenharmony_ci        assertion_func(first, second, msg=msg)
8747db96d56Sopenharmony_ci
8757db96d56Sopenharmony_ci    def assertNotEqual(self, first, second, msg=None):
8767db96d56Sopenharmony_ci        """Fail if the two objects are equal as determined by the '!='
8777db96d56Sopenharmony_ci           operator.
8787db96d56Sopenharmony_ci        """
8797db96d56Sopenharmony_ci        if not first != second:
8807db96d56Sopenharmony_ci            msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
8817db96d56Sopenharmony_ci                                                          safe_repr(second)))
8827db96d56Sopenharmony_ci            raise self.failureException(msg)
8837db96d56Sopenharmony_ci
8847db96d56Sopenharmony_ci    def assertAlmostEqual(self, first, second, places=None, msg=None,
8857db96d56Sopenharmony_ci                          delta=None):
8867db96d56Sopenharmony_ci        """Fail if the two objects are unequal as determined by their
8877db96d56Sopenharmony_ci           difference rounded to the given number of decimal places
8887db96d56Sopenharmony_ci           (default 7) and comparing to zero, or by comparing that the
8897db96d56Sopenharmony_ci           difference between the two objects is more than the given
8907db96d56Sopenharmony_ci           delta.
8917db96d56Sopenharmony_ci
8927db96d56Sopenharmony_ci           Note that decimal places (from zero) are usually not the same
8937db96d56Sopenharmony_ci           as significant digits (measured from the most significant digit).
8947db96d56Sopenharmony_ci
8957db96d56Sopenharmony_ci           If the two objects compare equal then they will automatically
8967db96d56Sopenharmony_ci           compare almost equal.
8977db96d56Sopenharmony_ci        """
8987db96d56Sopenharmony_ci        if first == second:
8997db96d56Sopenharmony_ci            # shortcut
9007db96d56Sopenharmony_ci            return
9017db96d56Sopenharmony_ci        if delta is not None and places is not None:
9027db96d56Sopenharmony_ci            raise TypeError("specify delta or places not both")
9037db96d56Sopenharmony_ci
9047db96d56Sopenharmony_ci        diff = abs(first - second)
9057db96d56Sopenharmony_ci        if delta is not None:
9067db96d56Sopenharmony_ci            if diff <= delta:
9077db96d56Sopenharmony_ci                return
9087db96d56Sopenharmony_ci
9097db96d56Sopenharmony_ci            standardMsg = '%s != %s within %s delta (%s difference)' % (
9107db96d56Sopenharmony_ci                safe_repr(first),
9117db96d56Sopenharmony_ci                safe_repr(second),
9127db96d56Sopenharmony_ci                safe_repr(delta),
9137db96d56Sopenharmony_ci                safe_repr(diff))
9147db96d56Sopenharmony_ci        else:
9157db96d56Sopenharmony_ci            if places is None:
9167db96d56Sopenharmony_ci                places = 7
9177db96d56Sopenharmony_ci
9187db96d56Sopenharmony_ci            if round(diff, places) == 0:
9197db96d56Sopenharmony_ci                return
9207db96d56Sopenharmony_ci
9217db96d56Sopenharmony_ci            standardMsg = '%s != %s within %r places (%s difference)' % (
9227db96d56Sopenharmony_ci                safe_repr(first),
9237db96d56Sopenharmony_ci                safe_repr(second),
9247db96d56Sopenharmony_ci                places,
9257db96d56Sopenharmony_ci                safe_repr(diff))
9267db96d56Sopenharmony_ci        msg = self._formatMessage(msg, standardMsg)
9277db96d56Sopenharmony_ci        raise self.failureException(msg)
9287db96d56Sopenharmony_ci
9297db96d56Sopenharmony_ci    def assertNotAlmostEqual(self, first, second, places=None, msg=None,
9307db96d56Sopenharmony_ci                             delta=None):
9317db96d56Sopenharmony_ci        """Fail if the two objects are equal as determined by their
9327db96d56Sopenharmony_ci           difference rounded to the given number of decimal places
9337db96d56Sopenharmony_ci           (default 7) and comparing to zero, or by comparing that the
9347db96d56Sopenharmony_ci           difference between the two objects is less than the given delta.
9357db96d56Sopenharmony_ci
9367db96d56Sopenharmony_ci           Note that decimal places (from zero) are usually not the same
9377db96d56Sopenharmony_ci           as significant digits (measured from the most significant digit).
9387db96d56Sopenharmony_ci
9397db96d56Sopenharmony_ci           Objects that are equal automatically fail.
9407db96d56Sopenharmony_ci        """
9417db96d56Sopenharmony_ci        if delta is not None and places is not None:
9427db96d56Sopenharmony_ci            raise TypeError("specify delta or places not both")
9437db96d56Sopenharmony_ci        diff = abs(first - second)
9447db96d56Sopenharmony_ci        if delta is not None:
9457db96d56Sopenharmony_ci            if not (first == second) and diff > delta:
9467db96d56Sopenharmony_ci                return
9477db96d56Sopenharmony_ci            standardMsg = '%s == %s within %s delta (%s difference)' % (
9487db96d56Sopenharmony_ci                safe_repr(first),
9497db96d56Sopenharmony_ci                safe_repr(second),
9507db96d56Sopenharmony_ci                safe_repr(delta),
9517db96d56Sopenharmony_ci                safe_repr(diff))
9527db96d56Sopenharmony_ci        else:
9537db96d56Sopenharmony_ci            if places is None:
9547db96d56Sopenharmony_ci                places = 7
9557db96d56Sopenharmony_ci            if not (first == second) and round(diff, places) != 0:
9567db96d56Sopenharmony_ci                return
9577db96d56Sopenharmony_ci            standardMsg = '%s == %s within %r places' % (safe_repr(first),
9587db96d56Sopenharmony_ci                                                         safe_repr(second),
9597db96d56Sopenharmony_ci                                                         places)
9607db96d56Sopenharmony_ci
9617db96d56Sopenharmony_ci        msg = self._formatMessage(msg, standardMsg)
9627db96d56Sopenharmony_ci        raise self.failureException(msg)
9637db96d56Sopenharmony_ci
9647db96d56Sopenharmony_ci    def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
9657db96d56Sopenharmony_ci        """An equality assertion for ordered sequences (like lists and tuples).
9667db96d56Sopenharmony_ci
9677db96d56Sopenharmony_ci        For the purposes of this function, a valid ordered sequence type is one
9687db96d56Sopenharmony_ci        which can be indexed, has a length, and has an equality operator.
9697db96d56Sopenharmony_ci
9707db96d56Sopenharmony_ci        Args:
9717db96d56Sopenharmony_ci            seq1: The first sequence to compare.
9727db96d56Sopenharmony_ci            seq2: The second sequence to compare.
9737db96d56Sopenharmony_ci            seq_type: The expected datatype of the sequences, or None if no
9747db96d56Sopenharmony_ci                    datatype should be enforced.
9757db96d56Sopenharmony_ci            msg: Optional message to use on failure instead of a list of
9767db96d56Sopenharmony_ci                    differences.
9777db96d56Sopenharmony_ci        """
9787db96d56Sopenharmony_ci        if seq_type is not None:
9797db96d56Sopenharmony_ci            seq_type_name = seq_type.__name__
9807db96d56Sopenharmony_ci            if not isinstance(seq1, seq_type):
9817db96d56Sopenharmony_ci                raise self.failureException('First sequence is not a %s: %s'
9827db96d56Sopenharmony_ci                                        % (seq_type_name, safe_repr(seq1)))
9837db96d56Sopenharmony_ci            if not isinstance(seq2, seq_type):
9847db96d56Sopenharmony_ci                raise self.failureException('Second sequence is not a %s: %s'
9857db96d56Sopenharmony_ci                                        % (seq_type_name, safe_repr(seq2)))
9867db96d56Sopenharmony_ci        else:
9877db96d56Sopenharmony_ci            seq_type_name = "sequence"
9887db96d56Sopenharmony_ci
9897db96d56Sopenharmony_ci        differing = None
9907db96d56Sopenharmony_ci        try:
9917db96d56Sopenharmony_ci            len1 = len(seq1)
9927db96d56Sopenharmony_ci        except (TypeError, NotImplementedError):
9937db96d56Sopenharmony_ci            differing = 'First %s has no length.    Non-sequence?' % (
9947db96d56Sopenharmony_ci                    seq_type_name)
9957db96d56Sopenharmony_ci
9967db96d56Sopenharmony_ci        if differing is None:
9977db96d56Sopenharmony_ci            try:
9987db96d56Sopenharmony_ci                len2 = len(seq2)
9997db96d56Sopenharmony_ci            except (TypeError, NotImplementedError):
10007db96d56Sopenharmony_ci                differing = 'Second %s has no length.    Non-sequence?' % (
10017db96d56Sopenharmony_ci                        seq_type_name)
10027db96d56Sopenharmony_ci
10037db96d56Sopenharmony_ci        if differing is None:
10047db96d56Sopenharmony_ci            if seq1 == seq2:
10057db96d56Sopenharmony_ci                return
10067db96d56Sopenharmony_ci
10077db96d56Sopenharmony_ci            differing = '%ss differ: %s != %s\n' % (
10087db96d56Sopenharmony_ci                    (seq_type_name.capitalize(),) +
10097db96d56Sopenharmony_ci                    _common_shorten_repr(seq1, seq2))
10107db96d56Sopenharmony_ci
10117db96d56Sopenharmony_ci            for i in range(min(len1, len2)):
10127db96d56Sopenharmony_ci                try:
10137db96d56Sopenharmony_ci                    item1 = seq1[i]
10147db96d56Sopenharmony_ci                except (TypeError, IndexError, NotImplementedError):
10157db96d56Sopenharmony_ci                    differing += ('\nUnable to index element %d of first %s\n' %
10167db96d56Sopenharmony_ci                                 (i, seq_type_name))
10177db96d56Sopenharmony_ci                    break
10187db96d56Sopenharmony_ci
10197db96d56Sopenharmony_ci                try:
10207db96d56Sopenharmony_ci                    item2 = seq2[i]
10217db96d56Sopenharmony_ci                except (TypeError, IndexError, NotImplementedError):
10227db96d56Sopenharmony_ci                    differing += ('\nUnable to index element %d of second %s\n' %
10237db96d56Sopenharmony_ci                                 (i, seq_type_name))
10247db96d56Sopenharmony_ci                    break
10257db96d56Sopenharmony_ci
10267db96d56Sopenharmony_ci                if item1 != item2:
10277db96d56Sopenharmony_ci                    differing += ('\nFirst differing element %d:\n%s\n%s\n' %
10287db96d56Sopenharmony_ci                                 ((i,) + _common_shorten_repr(item1, item2)))
10297db96d56Sopenharmony_ci                    break
10307db96d56Sopenharmony_ci            else:
10317db96d56Sopenharmony_ci                if (len1 == len2 and seq_type is None and
10327db96d56Sopenharmony_ci                    type(seq1) != type(seq2)):
10337db96d56Sopenharmony_ci                    # The sequences are the same, but have differing types.
10347db96d56Sopenharmony_ci                    return
10357db96d56Sopenharmony_ci
10367db96d56Sopenharmony_ci            if len1 > len2:
10377db96d56Sopenharmony_ci                differing += ('\nFirst %s contains %d additional '
10387db96d56Sopenharmony_ci                             'elements.\n' % (seq_type_name, len1 - len2))
10397db96d56Sopenharmony_ci                try:
10407db96d56Sopenharmony_ci                    differing += ('First extra element %d:\n%s\n' %
10417db96d56Sopenharmony_ci                                  (len2, safe_repr(seq1[len2])))
10427db96d56Sopenharmony_ci                except (TypeError, IndexError, NotImplementedError):
10437db96d56Sopenharmony_ci                    differing += ('Unable to index element %d '
10447db96d56Sopenharmony_ci                                  'of first %s\n' % (len2, seq_type_name))
10457db96d56Sopenharmony_ci            elif len1 < len2:
10467db96d56Sopenharmony_ci                differing += ('\nSecond %s contains %d additional '
10477db96d56Sopenharmony_ci                             'elements.\n' % (seq_type_name, len2 - len1))
10487db96d56Sopenharmony_ci                try:
10497db96d56Sopenharmony_ci                    differing += ('First extra element %d:\n%s\n' %
10507db96d56Sopenharmony_ci                                  (len1, safe_repr(seq2[len1])))
10517db96d56Sopenharmony_ci                except (TypeError, IndexError, NotImplementedError):
10527db96d56Sopenharmony_ci                    differing += ('Unable to index element %d '
10537db96d56Sopenharmony_ci                                  'of second %s\n' % (len1, seq_type_name))
10547db96d56Sopenharmony_ci        standardMsg = differing
10557db96d56Sopenharmony_ci        diffMsg = '\n' + '\n'.join(
10567db96d56Sopenharmony_ci            difflib.ndiff(pprint.pformat(seq1).splitlines(),
10577db96d56Sopenharmony_ci                          pprint.pformat(seq2).splitlines()))
10587db96d56Sopenharmony_ci
10597db96d56Sopenharmony_ci        standardMsg = self._truncateMessage(standardMsg, diffMsg)
10607db96d56Sopenharmony_ci        msg = self._formatMessage(msg, standardMsg)
10617db96d56Sopenharmony_ci        self.fail(msg)
10627db96d56Sopenharmony_ci
10637db96d56Sopenharmony_ci    def _truncateMessage(self, message, diff):
10647db96d56Sopenharmony_ci        max_diff = self.maxDiff
10657db96d56Sopenharmony_ci        if max_diff is None or len(diff) <= max_diff:
10667db96d56Sopenharmony_ci            return message + diff
10677db96d56Sopenharmony_ci        return message + (DIFF_OMITTED % len(diff))
10687db96d56Sopenharmony_ci
10697db96d56Sopenharmony_ci    def assertListEqual(self, list1, list2, msg=None):
10707db96d56Sopenharmony_ci        """A list-specific equality assertion.
10717db96d56Sopenharmony_ci
10727db96d56Sopenharmony_ci        Args:
10737db96d56Sopenharmony_ci            list1: The first list to compare.
10747db96d56Sopenharmony_ci            list2: The second list to compare.
10757db96d56Sopenharmony_ci            msg: Optional message to use on failure instead of a list of
10767db96d56Sopenharmony_ci                    differences.
10777db96d56Sopenharmony_ci
10787db96d56Sopenharmony_ci        """
10797db96d56Sopenharmony_ci        self.assertSequenceEqual(list1, list2, msg, seq_type=list)
10807db96d56Sopenharmony_ci
10817db96d56Sopenharmony_ci    def assertTupleEqual(self, tuple1, tuple2, msg=None):
10827db96d56Sopenharmony_ci        """A tuple-specific equality assertion.
10837db96d56Sopenharmony_ci
10847db96d56Sopenharmony_ci        Args:
10857db96d56Sopenharmony_ci            tuple1: The first tuple to compare.
10867db96d56Sopenharmony_ci            tuple2: The second tuple to compare.
10877db96d56Sopenharmony_ci            msg: Optional message to use on failure instead of a list of
10887db96d56Sopenharmony_ci                    differences.
10897db96d56Sopenharmony_ci        """
10907db96d56Sopenharmony_ci        self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
10917db96d56Sopenharmony_ci
10927db96d56Sopenharmony_ci    def assertSetEqual(self, set1, set2, msg=None):
10937db96d56Sopenharmony_ci        """A set-specific equality assertion.
10947db96d56Sopenharmony_ci
10957db96d56Sopenharmony_ci        Args:
10967db96d56Sopenharmony_ci            set1: The first set to compare.
10977db96d56Sopenharmony_ci            set2: The second set to compare.
10987db96d56Sopenharmony_ci            msg: Optional message to use on failure instead of a list of
10997db96d56Sopenharmony_ci                    differences.
11007db96d56Sopenharmony_ci
11017db96d56Sopenharmony_ci        assertSetEqual uses ducktyping to support different types of sets, and
11027db96d56Sopenharmony_ci        is optimized for sets specifically (parameters must support a
11037db96d56Sopenharmony_ci        difference method).
11047db96d56Sopenharmony_ci        """
11057db96d56Sopenharmony_ci        try:
11067db96d56Sopenharmony_ci            difference1 = set1.difference(set2)
11077db96d56Sopenharmony_ci        except TypeError as e:
11087db96d56Sopenharmony_ci            self.fail('invalid type when attempting set difference: %s' % e)
11097db96d56Sopenharmony_ci        except AttributeError as e:
11107db96d56Sopenharmony_ci            self.fail('first argument does not support set difference: %s' % e)
11117db96d56Sopenharmony_ci
11127db96d56Sopenharmony_ci        try:
11137db96d56Sopenharmony_ci            difference2 = set2.difference(set1)
11147db96d56Sopenharmony_ci        except TypeError as e:
11157db96d56Sopenharmony_ci            self.fail('invalid type when attempting set difference: %s' % e)
11167db96d56Sopenharmony_ci        except AttributeError as e:
11177db96d56Sopenharmony_ci            self.fail('second argument does not support set difference: %s' % e)
11187db96d56Sopenharmony_ci
11197db96d56Sopenharmony_ci        if not (difference1 or difference2):
11207db96d56Sopenharmony_ci            return
11217db96d56Sopenharmony_ci
11227db96d56Sopenharmony_ci        lines = []
11237db96d56Sopenharmony_ci        if difference1:
11247db96d56Sopenharmony_ci            lines.append('Items in the first set but not the second:')
11257db96d56Sopenharmony_ci            for item in difference1:
11267db96d56Sopenharmony_ci                lines.append(repr(item))
11277db96d56Sopenharmony_ci        if difference2:
11287db96d56Sopenharmony_ci            lines.append('Items in the second set but not the first:')
11297db96d56Sopenharmony_ci            for item in difference2:
11307db96d56Sopenharmony_ci                lines.append(repr(item))
11317db96d56Sopenharmony_ci
11327db96d56Sopenharmony_ci        standardMsg = '\n'.join(lines)
11337db96d56Sopenharmony_ci        self.fail(self._formatMessage(msg, standardMsg))
11347db96d56Sopenharmony_ci
11357db96d56Sopenharmony_ci    def assertIn(self, member, container, msg=None):
11367db96d56Sopenharmony_ci        """Just like self.assertTrue(a in b), but with a nicer default message."""
11377db96d56Sopenharmony_ci        if member not in container:
11387db96d56Sopenharmony_ci            standardMsg = '%s not found in %s' % (safe_repr(member),
11397db96d56Sopenharmony_ci                                                  safe_repr(container))
11407db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
11417db96d56Sopenharmony_ci
11427db96d56Sopenharmony_ci    def assertNotIn(self, member, container, msg=None):
11437db96d56Sopenharmony_ci        """Just like self.assertTrue(a not in b), but with a nicer default message."""
11447db96d56Sopenharmony_ci        if member in container:
11457db96d56Sopenharmony_ci            standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
11467db96d56Sopenharmony_ci                                                        safe_repr(container))
11477db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
11487db96d56Sopenharmony_ci
11497db96d56Sopenharmony_ci    def assertIs(self, expr1, expr2, msg=None):
11507db96d56Sopenharmony_ci        """Just like self.assertTrue(a is b), but with a nicer default message."""
11517db96d56Sopenharmony_ci        if expr1 is not expr2:
11527db96d56Sopenharmony_ci            standardMsg = '%s is not %s' % (safe_repr(expr1),
11537db96d56Sopenharmony_ci                                             safe_repr(expr2))
11547db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
11557db96d56Sopenharmony_ci
11567db96d56Sopenharmony_ci    def assertIsNot(self, expr1, expr2, msg=None):
11577db96d56Sopenharmony_ci        """Just like self.assertTrue(a is not b), but with a nicer default message."""
11587db96d56Sopenharmony_ci        if expr1 is expr2:
11597db96d56Sopenharmony_ci            standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
11607db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
11617db96d56Sopenharmony_ci
11627db96d56Sopenharmony_ci    def assertDictEqual(self, d1, d2, msg=None):
11637db96d56Sopenharmony_ci        self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
11647db96d56Sopenharmony_ci        self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
11657db96d56Sopenharmony_ci
11667db96d56Sopenharmony_ci        if d1 != d2:
11677db96d56Sopenharmony_ci            standardMsg = '%s != %s' % _common_shorten_repr(d1, d2)
11687db96d56Sopenharmony_ci            diff = ('\n' + '\n'.join(difflib.ndiff(
11697db96d56Sopenharmony_ci                           pprint.pformat(d1).splitlines(),
11707db96d56Sopenharmony_ci                           pprint.pformat(d2).splitlines())))
11717db96d56Sopenharmony_ci            standardMsg = self._truncateMessage(standardMsg, diff)
11727db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
11737db96d56Sopenharmony_ci
11747db96d56Sopenharmony_ci    def assertDictContainsSubset(self, subset, dictionary, msg=None):
11757db96d56Sopenharmony_ci        """Checks whether dictionary is a superset of subset."""
11767db96d56Sopenharmony_ci        warnings.warn('assertDictContainsSubset is deprecated',
11777db96d56Sopenharmony_ci                      DeprecationWarning)
11787db96d56Sopenharmony_ci        missing = []
11797db96d56Sopenharmony_ci        mismatched = []
11807db96d56Sopenharmony_ci        for key, value in subset.items():
11817db96d56Sopenharmony_ci            if key not in dictionary:
11827db96d56Sopenharmony_ci                missing.append(key)
11837db96d56Sopenharmony_ci            elif value != dictionary[key]:
11847db96d56Sopenharmony_ci                mismatched.append('%s, expected: %s, actual: %s' %
11857db96d56Sopenharmony_ci                                  (safe_repr(key), safe_repr(value),
11867db96d56Sopenharmony_ci                                   safe_repr(dictionary[key])))
11877db96d56Sopenharmony_ci
11887db96d56Sopenharmony_ci        if not (missing or mismatched):
11897db96d56Sopenharmony_ci            return
11907db96d56Sopenharmony_ci
11917db96d56Sopenharmony_ci        standardMsg = ''
11927db96d56Sopenharmony_ci        if missing:
11937db96d56Sopenharmony_ci            standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
11947db96d56Sopenharmony_ci                                                    missing)
11957db96d56Sopenharmony_ci        if mismatched:
11967db96d56Sopenharmony_ci            if standardMsg:
11977db96d56Sopenharmony_ci                standardMsg += '; '
11987db96d56Sopenharmony_ci            standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
11997db96d56Sopenharmony_ci
12007db96d56Sopenharmony_ci        self.fail(self._formatMessage(msg, standardMsg))
12017db96d56Sopenharmony_ci
12027db96d56Sopenharmony_ci
12037db96d56Sopenharmony_ci    def assertCountEqual(self, first, second, msg=None):
12047db96d56Sopenharmony_ci        """Asserts that two iterables have the same elements, the same number of
12057db96d56Sopenharmony_ci        times, without regard to order.
12067db96d56Sopenharmony_ci
12077db96d56Sopenharmony_ci            self.assertEqual(Counter(list(first)),
12087db96d56Sopenharmony_ci                             Counter(list(second)))
12097db96d56Sopenharmony_ci
12107db96d56Sopenharmony_ci         Example:
12117db96d56Sopenharmony_ci            - [0, 1, 1] and [1, 0, 1] compare equal.
12127db96d56Sopenharmony_ci            - [0, 0, 1] and [0, 1] compare unequal.
12137db96d56Sopenharmony_ci
12147db96d56Sopenharmony_ci        """
12157db96d56Sopenharmony_ci        first_seq, second_seq = list(first), list(second)
12167db96d56Sopenharmony_ci        try:
12177db96d56Sopenharmony_ci            first = collections.Counter(first_seq)
12187db96d56Sopenharmony_ci            second = collections.Counter(second_seq)
12197db96d56Sopenharmony_ci        except TypeError:
12207db96d56Sopenharmony_ci            # Handle case with unhashable elements
12217db96d56Sopenharmony_ci            differences = _count_diff_all_purpose(first_seq, second_seq)
12227db96d56Sopenharmony_ci        else:
12237db96d56Sopenharmony_ci            if first == second:
12247db96d56Sopenharmony_ci                return
12257db96d56Sopenharmony_ci            differences = _count_diff_hashable(first_seq, second_seq)
12267db96d56Sopenharmony_ci
12277db96d56Sopenharmony_ci        if differences:
12287db96d56Sopenharmony_ci            standardMsg = 'Element counts were not equal:\n'
12297db96d56Sopenharmony_ci            lines = ['First has %d, Second has %d:  %r' % diff for diff in differences]
12307db96d56Sopenharmony_ci            diffMsg = '\n'.join(lines)
12317db96d56Sopenharmony_ci            standardMsg = self._truncateMessage(standardMsg, diffMsg)
12327db96d56Sopenharmony_ci            msg = self._formatMessage(msg, standardMsg)
12337db96d56Sopenharmony_ci            self.fail(msg)
12347db96d56Sopenharmony_ci
12357db96d56Sopenharmony_ci    def assertMultiLineEqual(self, first, second, msg=None):
12367db96d56Sopenharmony_ci        """Assert that two multi-line strings are equal."""
12377db96d56Sopenharmony_ci        self.assertIsInstance(first, str, 'First argument is not a string')
12387db96d56Sopenharmony_ci        self.assertIsInstance(second, str, 'Second argument is not a string')
12397db96d56Sopenharmony_ci
12407db96d56Sopenharmony_ci        if first != second:
12417db96d56Sopenharmony_ci            # don't use difflib if the strings are too long
12427db96d56Sopenharmony_ci            if (len(first) > self._diffThreshold or
12437db96d56Sopenharmony_ci                len(second) > self._diffThreshold):
12447db96d56Sopenharmony_ci                self._baseAssertEqual(first, second, msg)
12457db96d56Sopenharmony_ci            firstlines = first.splitlines(keepends=True)
12467db96d56Sopenharmony_ci            secondlines = second.splitlines(keepends=True)
12477db96d56Sopenharmony_ci            if len(firstlines) == 1 and first.strip('\r\n') == first:
12487db96d56Sopenharmony_ci                firstlines = [first + '\n']
12497db96d56Sopenharmony_ci                secondlines = [second + '\n']
12507db96d56Sopenharmony_ci            standardMsg = '%s != %s' % _common_shorten_repr(first, second)
12517db96d56Sopenharmony_ci            diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
12527db96d56Sopenharmony_ci            standardMsg = self._truncateMessage(standardMsg, diff)
12537db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
12547db96d56Sopenharmony_ci
12557db96d56Sopenharmony_ci    def assertLess(self, a, b, msg=None):
12567db96d56Sopenharmony_ci        """Just like self.assertTrue(a < b), but with a nicer default message."""
12577db96d56Sopenharmony_ci        if not a < b:
12587db96d56Sopenharmony_ci            standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
12597db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
12607db96d56Sopenharmony_ci
12617db96d56Sopenharmony_ci    def assertLessEqual(self, a, b, msg=None):
12627db96d56Sopenharmony_ci        """Just like self.assertTrue(a <= b), but with a nicer default message."""
12637db96d56Sopenharmony_ci        if not a <= b:
12647db96d56Sopenharmony_ci            standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
12657db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
12667db96d56Sopenharmony_ci
12677db96d56Sopenharmony_ci    def assertGreater(self, a, b, msg=None):
12687db96d56Sopenharmony_ci        """Just like self.assertTrue(a > b), but with a nicer default message."""
12697db96d56Sopenharmony_ci        if not a > b:
12707db96d56Sopenharmony_ci            standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
12717db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
12727db96d56Sopenharmony_ci
12737db96d56Sopenharmony_ci    def assertGreaterEqual(self, a, b, msg=None):
12747db96d56Sopenharmony_ci        """Just like self.assertTrue(a >= b), but with a nicer default message."""
12757db96d56Sopenharmony_ci        if not a >= b:
12767db96d56Sopenharmony_ci            standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
12777db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
12787db96d56Sopenharmony_ci
12797db96d56Sopenharmony_ci    def assertIsNone(self, obj, msg=None):
12807db96d56Sopenharmony_ci        """Same as self.assertTrue(obj is None), with a nicer default message."""
12817db96d56Sopenharmony_ci        if obj is not None:
12827db96d56Sopenharmony_ci            standardMsg = '%s is not None' % (safe_repr(obj),)
12837db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
12847db96d56Sopenharmony_ci
12857db96d56Sopenharmony_ci    def assertIsNotNone(self, obj, msg=None):
12867db96d56Sopenharmony_ci        """Included for symmetry with assertIsNone."""
12877db96d56Sopenharmony_ci        if obj is None:
12887db96d56Sopenharmony_ci            standardMsg = 'unexpectedly None'
12897db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
12907db96d56Sopenharmony_ci
12917db96d56Sopenharmony_ci    def assertIsInstance(self, obj, cls, msg=None):
12927db96d56Sopenharmony_ci        """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
12937db96d56Sopenharmony_ci        default message."""
12947db96d56Sopenharmony_ci        if not isinstance(obj, cls):
12957db96d56Sopenharmony_ci            standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
12967db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
12977db96d56Sopenharmony_ci
12987db96d56Sopenharmony_ci    def assertNotIsInstance(self, obj, cls, msg=None):
12997db96d56Sopenharmony_ci        """Included for symmetry with assertIsInstance."""
13007db96d56Sopenharmony_ci        if isinstance(obj, cls):
13017db96d56Sopenharmony_ci            standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
13027db96d56Sopenharmony_ci            self.fail(self._formatMessage(msg, standardMsg))
13037db96d56Sopenharmony_ci
13047db96d56Sopenharmony_ci    def assertRaisesRegex(self, expected_exception, expected_regex,
13057db96d56Sopenharmony_ci                          *args, **kwargs):
13067db96d56Sopenharmony_ci        """Asserts that the message in a raised exception matches a regex.
13077db96d56Sopenharmony_ci
13087db96d56Sopenharmony_ci        Args:
13097db96d56Sopenharmony_ci            expected_exception: Exception class expected to be raised.
13107db96d56Sopenharmony_ci            expected_regex: Regex (re.Pattern object or string) expected
13117db96d56Sopenharmony_ci                    to be found in error message.
13127db96d56Sopenharmony_ci            args: Function to be called and extra positional args.
13137db96d56Sopenharmony_ci            kwargs: Extra kwargs.
13147db96d56Sopenharmony_ci            msg: Optional message used in case of failure. Can only be used
13157db96d56Sopenharmony_ci                    when assertRaisesRegex is used as a context manager.
13167db96d56Sopenharmony_ci        """
13177db96d56Sopenharmony_ci        context = _AssertRaisesContext(expected_exception, self, expected_regex)
13187db96d56Sopenharmony_ci        return context.handle('assertRaisesRegex', args, kwargs)
13197db96d56Sopenharmony_ci
13207db96d56Sopenharmony_ci    def assertWarnsRegex(self, expected_warning, expected_regex,
13217db96d56Sopenharmony_ci                         *args, **kwargs):
13227db96d56Sopenharmony_ci        """Asserts that the message in a triggered warning matches a regexp.
13237db96d56Sopenharmony_ci        Basic functioning is similar to assertWarns() with the addition
13247db96d56Sopenharmony_ci        that only warnings whose messages also match the regular expression
13257db96d56Sopenharmony_ci        are considered successful matches.
13267db96d56Sopenharmony_ci
13277db96d56Sopenharmony_ci        Args:
13287db96d56Sopenharmony_ci            expected_warning: Warning class expected to be triggered.
13297db96d56Sopenharmony_ci            expected_regex: Regex (re.Pattern object or string) expected
13307db96d56Sopenharmony_ci                    to be found in error message.
13317db96d56Sopenharmony_ci            args: Function to be called and extra positional args.
13327db96d56Sopenharmony_ci            kwargs: Extra kwargs.
13337db96d56Sopenharmony_ci            msg: Optional message used in case of failure. Can only be used
13347db96d56Sopenharmony_ci                    when assertWarnsRegex is used as a context manager.
13357db96d56Sopenharmony_ci        """
13367db96d56Sopenharmony_ci        context = _AssertWarnsContext(expected_warning, self, expected_regex)
13377db96d56Sopenharmony_ci        return context.handle('assertWarnsRegex', args, kwargs)
13387db96d56Sopenharmony_ci
13397db96d56Sopenharmony_ci    def assertRegex(self, text, expected_regex, msg=None):
13407db96d56Sopenharmony_ci        """Fail the test unless the text matches the regular expression."""
13417db96d56Sopenharmony_ci        if isinstance(expected_regex, (str, bytes)):
13427db96d56Sopenharmony_ci            assert expected_regex, "expected_regex must not be empty."
13437db96d56Sopenharmony_ci            expected_regex = re.compile(expected_regex)
13447db96d56Sopenharmony_ci        if not expected_regex.search(text):
13457db96d56Sopenharmony_ci            standardMsg = "Regex didn't match: %r not found in %r" % (
13467db96d56Sopenharmony_ci                expected_regex.pattern, text)
13477db96d56Sopenharmony_ci            # _formatMessage ensures the longMessage option is respected
13487db96d56Sopenharmony_ci            msg = self._formatMessage(msg, standardMsg)
13497db96d56Sopenharmony_ci            raise self.failureException(msg)
13507db96d56Sopenharmony_ci
13517db96d56Sopenharmony_ci    def assertNotRegex(self, text, unexpected_regex, msg=None):
13527db96d56Sopenharmony_ci        """Fail the test if the text matches the regular expression."""
13537db96d56Sopenharmony_ci        if isinstance(unexpected_regex, (str, bytes)):
13547db96d56Sopenharmony_ci            unexpected_regex = re.compile(unexpected_regex)
13557db96d56Sopenharmony_ci        match = unexpected_regex.search(text)
13567db96d56Sopenharmony_ci        if match:
13577db96d56Sopenharmony_ci            standardMsg = 'Regex matched: %r matches %r in %r' % (
13587db96d56Sopenharmony_ci                text[match.start() : match.end()],
13597db96d56Sopenharmony_ci                unexpected_regex.pattern,
13607db96d56Sopenharmony_ci                text)
13617db96d56Sopenharmony_ci            # _formatMessage ensures the longMessage option is respected
13627db96d56Sopenharmony_ci            msg = self._formatMessage(msg, standardMsg)
13637db96d56Sopenharmony_ci            raise self.failureException(msg)
13647db96d56Sopenharmony_ci
13657db96d56Sopenharmony_ci
13667db96d56Sopenharmony_ci    def _deprecate(original_func):
13677db96d56Sopenharmony_ci        def deprecated_func(*args, **kwargs):
13687db96d56Sopenharmony_ci            warnings.warn(
13697db96d56Sopenharmony_ci                'Please use {0} instead.'.format(original_func.__name__),
13707db96d56Sopenharmony_ci                DeprecationWarning, 2)
13717db96d56Sopenharmony_ci            return original_func(*args, **kwargs)
13727db96d56Sopenharmony_ci        return deprecated_func
13737db96d56Sopenharmony_ci
13747db96d56Sopenharmony_ci    # see #9424
13757db96d56Sopenharmony_ci    failUnlessEqual = assertEquals = _deprecate(assertEqual)
13767db96d56Sopenharmony_ci    failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
13777db96d56Sopenharmony_ci    failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
13787db96d56Sopenharmony_ci    failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
13797db96d56Sopenharmony_ci    failUnless = assert_ = _deprecate(assertTrue)
13807db96d56Sopenharmony_ci    failUnlessRaises = _deprecate(assertRaises)
13817db96d56Sopenharmony_ci    failIf = _deprecate(assertFalse)
13827db96d56Sopenharmony_ci    assertRaisesRegexp = _deprecate(assertRaisesRegex)
13837db96d56Sopenharmony_ci    assertRegexpMatches = _deprecate(assertRegex)
13847db96d56Sopenharmony_ci    assertNotRegexpMatches = _deprecate(assertNotRegex)
13857db96d56Sopenharmony_ci
13867db96d56Sopenharmony_ci
13877db96d56Sopenharmony_ci
13887db96d56Sopenharmony_ciclass FunctionTestCase(TestCase):
13897db96d56Sopenharmony_ci    """A test case that wraps a test function.
13907db96d56Sopenharmony_ci
13917db96d56Sopenharmony_ci    This is useful for slipping pre-existing test functions into the
13927db96d56Sopenharmony_ci    unittest framework. Optionally, set-up and tidy-up functions can be
13937db96d56Sopenharmony_ci    supplied. As with TestCase, the tidy-up ('tearDown') function will
13947db96d56Sopenharmony_ci    always be called if the set-up ('setUp') function ran successfully.
13957db96d56Sopenharmony_ci    """
13967db96d56Sopenharmony_ci
13977db96d56Sopenharmony_ci    def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
13987db96d56Sopenharmony_ci        super(FunctionTestCase, self).__init__()
13997db96d56Sopenharmony_ci        self._setUpFunc = setUp
14007db96d56Sopenharmony_ci        self._tearDownFunc = tearDown
14017db96d56Sopenharmony_ci        self._testFunc = testFunc
14027db96d56Sopenharmony_ci        self._description = description
14037db96d56Sopenharmony_ci
14047db96d56Sopenharmony_ci    def setUp(self):
14057db96d56Sopenharmony_ci        if self._setUpFunc is not None:
14067db96d56Sopenharmony_ci            self._setUpFunc()
14077db96d56Sopenharmony_ci
14087db96d56Sopenharmony_ci    def tearDown(self):
14097db96d56Sopenharmony_ci        if self._tearDownFunc is not None:
14107db96d56Sopenharmony_ci            self._tearDownFunc()
14117db96d56Sopenharmony_ci
14127db96d56Sopenharmony_ci    def runTest(self):
14137db96d56Sopenharmony_ci        self._testFunc()
14147db96d56Sopenharmony_ci
14157db96d56Sopenharmony_ci    def id(self):
14167db96d56Sopenharmony_ci        return self._testFunc.__name__
14177db96d56Sopenharmony_ci
14187db96d56Sopenharmony_ci    def __eq__(self, other):
14197db96d56Sopenharmony_ci        if not isinstance(other, self.__class__):
14207db96d56Sopenharmony_ci            return NotImplemented
14217db96d56Sopenharmony_ci
14227db96d56Sopenharmony_ci        return self._setUpFunc == other._setUpFunc and \
14237db96d56Sopenharmony_ci               self._tearDownFunc == other._tearDownFunc and \
14247db96d56Sopenharmony_ci               self._testFunc == other._testFunc and \
14257db96d56Sopenharmony_ci               self._description == other._description
14267db96d56Sopenharmony_ci
14277db96d56Sopenharmony_ci    def __hash__(self):
14287db96d56Sopenharmony_ci        return hash((type(self), self._setUpFunc, self._tearDownFunc,
14297db96d56Sopenharmony_ci                     self._testFunc, self._description))
14307db96d56Sopenharmony_ci
14317db96d56Sopenharmony_ci    def __str__(self):
14327db96d56Sopenharmony_ci        return "%s (%s)" % (strclass(self.__class__),
14337db96d56Sopenharmony_ci                            self._testFunc.__name__)
14347db96d56Sopenharmony_ci
14357db96d56Sopenharmony_ci    def __repr__(self):
14367db96d56Sopenharmony_ci        return "<%s tec=%s>" % (strclass(self.__class__),
14377db96d56Sopenharmony_ci                                     self._testFunc)
14387db96d56Sopenharmony_ci
14397db96d56Sopenharmony_ci    def shortDescription(self):
14407db96d56Sopenharmony_ci        if self._description is not None:
14417db96d56Sopenharmony_ci            return self._description
14427db96d56Sopenharmony_ci        doc = self._testFunc.__doc__
14437db96d56Sopenharmony_ci        return doc and doc.split("\n")[0].strip() or None
14447db96d56Sopenharmony_ci
14457db96d56Sopenharmony_ci
14467db96d56Sopenharmony_ciclass _SubTest(TestCase):
14477db96d56Sopenharmony_ci
14487db96d56Sopenharmony_ci    def __init__(self, test_case, message, params):
14497db96d56Sopenharmony_ci        super().__init__()
14507db96d56Sopenharmony_ci        self._message = message
14517db96d56Sopenharmony_ci        self.test_case = test_case
14527db96d56Sopenharmony_ci        self.params = params
14537db96d56Sopenharmony_ci        self.failureException = test_case.failureException
14547db96d56Sopenharmony_ci
14557db96d56Sopenharmony_ci    def runTest(self):
14567db96d56Sopenharmony_ci        raise NotImplementedError("subtests cannot be run directly")
14577db96d56Sopenharmony_ci
14587db96d56Sopenharmony_ci    def _subDescription(self):
14597db96d56Sopenharmony_ci        parts = []
14607db96d56Sopenharmony_ci        if self._message is not _subtest_msg_sentinel:
14617db96d56Sopenharmony_ci            parts.append("[{}]".format(self._message))
14627db96d56Sopenharmony_ci        if self.params:
14637db96d56Sopenharmony_ci            params_desc = ', '.join(
14647db96d56Sopenharmony_ci                "{}={!r}".format(k, v)
14657db96d56Sopenharmony_ci                for (k, v) in self.params.items())
14667db96d56Sopenharmony_ci            parts.append("({})".format(params_desc))
14677db96d56Sopenharmony_ci        return " ".join(parts) or '(<subtest>)'
14687db96d56Sopenharmony_ci
14697db96d56Sopenharmony_ci    def id(self):
14707db96d56Sopenharmony_ci        return "{} {}".format(self.test_case.id(), self._subDescription())
14717db96d56Sopenharmony_ci
14727db96d56Sopenharmony_ci    def shortDescription(self):
14737db96d56Sopenharmony_ci        """Returns a one-line description of the subtest, or None if no
14747db96d56Sopenharmony_ci        description has been provided.
14757db96d56Sopenharmony_ci        """
14767db96d56Sopenharmony_ci        return self.test_case.shortDescription()
14777db96d56Sopenharmony_ci
14787db96d56Sopenharmony_ci    def __str__(self):
14797db96d56Sopenharmony_ci        return "{} {}".format(self.test_case, self._subDescription())
1480