case.py 48.5 KB
Newer Older
1
"""Test case implementation"""
2

3
import sys
4
import functools
5
import difflib
6 7 8
import pprint
import re
import warnings
9
import collections
10

11 12
from . import result
from .util import (strclass, safe_repr, sorted_list_difference,
13 14
                   unorderable_list_difference, _count_diff_all_purpose,
                   _count_diff_hashable)
15

16
__unittest = True
17

18 19 20 21

DIFF_OMITTED = ('\nDiff is %s characters long. '
                 'Set self.maxDiff to None to see it.')

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
class SkipTest(Exception):
    """
    Raise this exception in a test to skip it.

    Usually you can use TestResult.skip() or one of the skipping decorators
    instead of raising this directly.
    """

class _ExpectedFailure(Exception):
    """
    Raise this when a test is expected to fail.

    This is an implementation detail.
    """

    def __init__(self, exc_info):
        super(_ExpectedFailure, self).__init__()
        self.exc_info = exc_info

class _UnexpectedSuccess(Exception):
    """
    The test was supposed to fail, but it didn't!
    """
45 46 47 48 49 50 51 52 53 54 55


class _Outcome(object):
    def __init__(self):
        self.success = True
        self.skipped = None
        self.unexpectedSuccess = None
        self.expectedFailure = None
        self.errors = []
        self.failures = []

56 57 58 59 60 61 62 63 64

def _id(obj):
    return obj

def skip(reason):
    """
    Unconditionally skip a test.
    """
    def decorator(test_item):
65 66 67 68 69 70 71 72 73
        if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
            @functools.wraps(test_item)
            def skip_wrapper(*args, **kwargs):
                raise SkipTest(reason)
            test_item = skip_wrapper

        test_item.__unittest_skip__ = True
        test_item.__unittest_skip_why__ = reason
        return test_item
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
    return decorator

def skipIf(condition, reason):
    """
    Skip a test if the condition is true.
    """
    if condition:
        return skip(reason)
    return _id

def skipUnless(condition, reason):
    """
    Skip a test unless the condition is true.
    """
    if not condition:
        return skip(reason)
    return _id


def expectedFailure(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        try:
            func(*args, **kwargs)
        except Exception:
            raise _ExpectedFailure(sys.exc_info())
        raise _UnexpectedSuccess
    return wrapper

103

104
class _AssertRaisesBaseContext(object):
105

106
    def __init__(self, expected, test_case, callable_obj=None,
107
                  expected_regex=None):
108 109 110 111 112 113 114 115 116
        self.expected = expected
        self.failureException = test_case.failureException
        if callable_obj is not None:
            try:
                self.obj_name = callable_obj.__name__
            except AttributeError:
                self.obj_name = str(callable_obj)
        else:
            self.obj_name = None
117 118 119
        if isinstance(expected_regex, (bytes, str)):
            expected_regex = re.compile(expected_regex)
        self.expected_regex = expected_regex
120

121 122 123 124

class _AssertRaisesContext(_AssertRaisesBaseContext):
    """A context manager used to implement TestCase.assertRaises* methods."""

125
    def __enter__(self):
126
        return self
127

Benjamin Peterson's avatar
Benjamin Peterson committed
128
    def __exit__(self, exc_type, exc_value, tb):
129 130 131 132 133 134 135 136 137 138 139
        if exc_type is None:
            try:
                exc_name = self.expected.__name__
            except AttributeError:
                exc_name = str(self.expected)
            if self.obj_name:
                raise self.failureException("{0} not raised by {1}"
                    .format(exc_name, self.obj_name))
            else:
                raise self.failureException("{0} not raised"
                    .format(exc_name))
140 141 142
        if not issubclass(exc_type, self.expected):
            # let unexpected exceptions pass through
            return False
143 144
        # store exception, without traceback, for later retrieval
        self.exception = exc_value.with_traceback(None)
145
        if self.expected_regex is None:
146
            return True
147

148 149
        expected_regex = self.expected_regex
        if not expected_regex.search(str(exc_value)):
150
            raise self.failureException('"%s" does not match "%s"' %
151
                     (expected_regex.pattern, str(exc_value)))
152 153 154
        return True


155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
class _AssertWarnsContext(_AssertRaisesBaseContext):
    """A context manager used to implement TestCase.assertWarns* methods."""

    def __enter__(self):
        # The __warningregistry__'s need to be in a pristine state for tests
        # to work properly.
        for v in sys.modules.values():
            if getattr(v, '__warningregistry__', None):
                v.__warningregistry__ = {}
        self.warnings_manager = warnings.catch_warnings(record=True)
        self.warnings = self.warnings_manager.__enter__()
        warnings.simplefilter("always", self.expected)
        return self

    def __exit__(self, exc_type, exc_value, tb):
        self.warnings_manager.__exit__(exc_type, exc_value, tb)
        if exc_type is not None:
            # let unexpected exceptions pass through
            return
        try:
            exc_name = self.expected.__name__
        except AttributeError:
            exc_name = str(self.expected)
        first_matching = None
        for m in self.warnings:
            w = m.message
            if not isinstance(w, self.expected):
                continue
            if first_matching is None:
                first_matching = w
185 186
            if (self.expected_regex is not None and
                not self.expected_regex.search(str(w))):
187 188 189 190 191 192 193 194 195
                continue
            # store warning for later retrieval
            self.warning = w
            self.filename = m.filename
            self.lineno = m.lineno
            return
        # Now we simply try to choose a helpful failure message
        if first_matching is not None:
            raise self.failureException('"%s" does not match "%s"' %
196
                     (self.expected_regex.pattern, str(first_matching)))
197 198 199 200 201 202 203 204
        if self.obj_name:
            raise self.failureException("{0} not triggered by {1}"
                .format(exc_name, self.obj_name))
        else:
            raise self.failureException("{0} not triggered"
                .format(exc_name))


205
class TestCase(object):
206 207 208 209
    """A class whose instances are single test cases.

    By default, the test code itself should be placed in a method named
    'runTest'.
210

Tim Peters's avatar
Tim Peters committed
211
    If the fixture may be used for many test cases, create as
212 213 214
    many test methods as are needed. When instantiating such a TestCase
    subclass, specify in the constructor arguments the name of the test method
    that the instance is to execute.
215

Tim Peters's avatar
Tim Peters committed
216
    Test authors should subclass TestCase for their own tests. Construction
217 218 219 220 221 222 223 224
    and deconstruction of the test's environment ('fixture') can be
    implemented by overriding the 'setUp' and 'tearDown' methods respectively.

    If it is necessary to override the __init__ method, the base class
    __init__ method must always be called. It is important that subclasses
    should not change the signature of their __init__ method, since instances
    of the classes are instantiated automatically by parts of the framework
    in order to be run.
225
    """
226 227 228 229 230 231 232

    # This attribute determines which exception will be raised when
    # the instance's assertion methods fail; test methods raising this
    # exception will be deemed to have 'failed' rather than 'errored'

    failureException = AssertionError

233 234 235 236
    # This attribute determines whether long messages (including repr of
    # objects used in assert methods) will be printed on failure in *addition*
    # to any explicit message passed.

237
    longMessage = True
238

239
    # This attribute sets the maximum length of a diff in failure messages
240 241
    # by assert methods using difflib. It is looked up as an instance attribute
    # so can be configured by individual tests if required.
242

243 244
    maxDiff = 80*8

Ezio Melotti's avatar
Ezio Melotti committed
245 246 247 248
    # If a string is longer than _diffThreshold, use normal comparison instead
    # of difflib.  See #11763.
    _diffThreshold = 2**16

249 250 251
    # Attribute used by TestSuite for classSetUp

    _classSetupFailed = False
252

253 254 255 256 257
    def __init__(self, methodName='runTest'):
        """Create an instance of the class that will use the named test
           method when executed. Raises a ValueError if the instance does
           not have a method with the specified name.
        """
258
        self._testMethodName = methodName
259
        self._outcomeForDoCleanups = None
260
        self._testMethodDoc = 'No test'
261
        try:
262
            testMethod = getattr(self, methodName)
263
        except AttributeError:
264 265 266 267 268 269 270
            if methodName != 'runTest':
                # we allow instantiation with no explicit method name
                # but not an *incorrect* or missing method name
                raise ValueError("no such test method in %s: %s" %
                      (self.__class__, methodName))
        else:
            self._testMethodDoc = testMethod.__doc__
Benjamin Peterson's avatar
Benjamin Peterson committed
271
        self._cleanups = []
272

273 274 275
        # Map types to custom assertEqual functions that will compare
        # instances of said type in more detail to generate a more useful
        # error message.
276
        self._type_equality_funcs = {}
277 278 279 280 281 282
        self.addTypeEqualityFunc(dict, 'assertDictEqual')
        self.addTypeEqualityFunc(list, 'assertListEqual')
        self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
        self.addTypeEqualityFunc(set, 'assertSetEqual')
        self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
        self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
283 284 285 286 287 288 289 290 291 292 293 294 295 296

    def addTypeEqualityFunc(self, typeobj, function):
        """Add a type specific assertEqual style function to compare a type.

        This method is for use by TestCase subclasses that need to register
        their own type equality functions to provide nicer error messages.

        Args:
            typeobj: The data type to call this function on when both values
                    are of the same type in assertEqual().
            function: The callable taking two arguments and an optional
                    msg= argument that raises self.failureException with a
                    useful error message when the two arguments are not equal.
        """
297
        self._type_equality_funcs[typeobj] = function
298

Benjamin Peterson's avatar
Benjamin Peterson committed
299 300 301 302 303 304 305 306
    def addCleanup(self, function, *args, **kwargs):
        """Add a function, with arguments, to be called when the test is
        completed. Functions added are called on a LIFO basis and are
        called after tearDown on test failure or success.

        Cleanup items are called even if setUp fails (unlike tearDown)."""
        self._cleanups.append((function, args, kwargs))

307 308 309 310 311 312 313 314
    def setUp(self):
        "Hook method for setting up the test fixture before exercising it."
        pass

    def tearDown(self):
        "Hook method for deconstructing the test fixture after testing it."
        pass

315 316 317 318 319 320 321 322
    @classmethod
    def setUpClass(cls):
        "Hook method for setting up class fixture before running tests in the class."

    @classmethod
    def tearDownClass(cls):
        "Hook method for deconstructing the class fixture after running all tests in the class."

323 324 325 326
    def countTestCases(self):
        return 1

    def defaultTestResult(self):
327
        return result.TestResult()
328 329

    def shortDescription(self):
330 331
        """Returns a one-line description of the test, or None if no
        description has been provided.
332

333 334
        The default implementation of this method returns the first line of
        the specified test method's docstring.
335
        """
336 337
        doc = self._testMethodDoc
        return doc and doc.split("\n")[0].strip() or None
338

339 340

    def id(self):
341
        return "%s.%s" % (strclass(self.__class__), self._testMethodName)
342

343 344
    def __eq__(self, other):
        if type(self) is not type(other):
345
            return NotImplemented
346 347 348 349 350 351

        return self._testMethodName == other._testMethodName

    def __hash__(self):
        return hash((type(self), self._testMethodName))

352
    def __str__(self):
353
        return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
354 355 356

    def __repr__(self):
        return "<%s testMethod=%s>" % \
357 358 359 360 361 362 363 364 365 366
               (strclass(self.__class__), self._testMethodName)

    def _addSkip(self, result, reason):
        addSkip = getattr(result, 'addSkip', None)
        if addSkip is not None:
            addSkip(self, reason)
        else:
            warnings.warn("TestResult has no addSkip method, skips not reported",
                          RuntimeWarning, 2)
            result.addSuccess(self)
367

368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
    def _executeTestPart(self, function, outcome, isTest=False):
        try:
            function()
        except KeyboardInterrupt:
            raise
        except SkipTest as e:
            outcome.success = False
            outcome.skipped = str(e)
        except _UnexpectedSuccess:
            exc_info = sys.exc_info()
            outcome.success = False
            if isTest:
                outcome.unexpectedSuccess = exc_info
            else:
                outcome.errors.append(exc_info)
        except _ExpectedFailure:
            outcome.success = False
            exc_info = sys.exc_info()
            if isTest:
                outcome.expectedFailure = exc_info
            else:
                outcome.errors.append(exc_info)
        except self.failureException:
            outcome.success = False
            outcome.failures.append(sys.exc_info())
            exc_info = sys.exc_info()
        except:
            outcome.success = False
            outcome.errors.append(sys.exc_info())

398
    def run(self, result=None):
Benjamin Peterson's avatar
Benjamin Peterson committed
399
        orig_result = result
400 401
        if result is None:
            result = self.defaultTestResult()
Benjamin Peterson's avatar
Benjamin Peterson committed
402 403 404 405
            startTestRun = getattr(result, 'startTestRun', None)
            if startTestRun is not None:
                startTestRun()

406
        result.startTest(self)
407 408 409 410 411

        testMethod = getattr(self, self._testMethodName)
        if (getattr(self.__class__, "__unittest_skip__", False) or
            getattr(testMethod, "__unittest_skip__", False)):
            # If the class or method was skipped.
412
            try:
413 414 415
                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
                            or getattr(testMethod, '__unittest_skip_why__', ''))
                self._addSkip(result, skip_why)
416 417 418
            finally:
                result.stopTest(self)
            return
419
        try:
420 421 422 423 424 425 426 427 428 429 430
            outcome = _Outcome()
            self._outcomeForDoCleanups = outcome

            self._executeTestPart(self.setUp, outcome)
            if outcome.success:
                self._executeTestPart(testMethod, outcome, isTest=True)
                self._executeTestPart(self.tearDown, outcome)

            self.doCleanups()
            if outcome.success:
                result.addSuccess(self)
431
            else:
432 433 434 435 436 437 438
                if outcome.skipped is not None:
                    self._addSkip(result, outcome.skipped)
                for exc_info in outcome.errors:
                    result.addError(self, exc_info)
                for exc_info in outcome.failures:
                    result.addFailure(self, exc_info)
                if outcome.unexpectedSuccess is not None:
439 440 441 442 443 444
                    addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
                    if addUnexpectedSuccess is not None:
                        addUnexpectedSuccess(self)
                    else:
                        warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
                                      RuntimeWarning)
445 446 447 448 449 450 451 452 453 454 455
                        result.addFailure(self, outcome.unexpectedSuccess)

                if outcome.expectedFailure is not None:
                    addExpectedFailure = getattr(result, 'addExpectedFailure', None)
                    if addExpectedFailure is not None:
                        addExpectedFailure(self, outcome.expectedFailure)
                    else:
                        warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
                                      RuntimeWarning)
                        result.addSuccess(self)

456 457
        finally:
            result.stopTest(self)
Benjamin Peterson's avatar
Benjamin Peterson committed
458 459 460 461 462 463 464 465
            if orig_result is None:
                stopTestRun = getattr(result, 'stopTestRun', None)
                if stopTestRun is not None:
                    stopTestRun()

    def doCleanups(self):
        """Execute all cleanup functions. Normally called for you after
        tearDown."""
466
        outcome = self._outcomeForDoCleanups or _Outcome()
Benjamin Peterson's avatar
Benjamin Peterson committed
467
        while self._cleanups:
468 469 470 471 472 473 474
            function, args, kwargs = self._cleanups.pop()
            part = lambda: function(*args, **kwargs)
            self._executeTestPart(part, outcome)

        # return this for backwards compatibility
        # even though we no longer us it internally
        return outcome.success
475

476 477
    def __call__(self, *args, **kwds):
        return self.run(*args, **kwds)
478

479
    def debug(self):
480
        """Run the test without collecting errors in a TestResult"""
481
        self.setUp()
482
        getattr(self, self._testMethodName)()
483
        self.tearDown()
484 485 486
        while self._cleanups:
            function, args, kwargs = self._cleanups.pop(-1)
            function(*args, **kwargs)
487

Benjamin Peterson's avatar
Benjamin Peterson committed
488
    def skipTest(self, reason):
489 490 491
        """Skip this test."""
        raise SkipTest(reason)

492 493
    def fail(self, msg=None):
        """Fail immediately, with the given message."""
494
        raise self.failureException(msg)
495

496
    def assertFalse(self, expr, msg=None):
497
        """Check that the expression is false."""
498
        if expr:
499
            msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
500
            raise self.failureException(msg)
501

502
    def assertTrue(self, expr, msg=None):
503
        """Check that the expression is true."""
504
        if not expr:
505
            msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
506
            raise self.failureException(msg)
507

508 509 510 511 512 513 514 515 516 517 518 519 520 521
    def _formatMessage(self, msg, standardMsg):
        """Honour the longMessage attribute when generating failure messages.
        If longMessage is False this means:
        * Use only an explicit message if it is provided
        * Otherwise use the standard message for the assert

        If longMessage is True:
        * Use the standard message
        * If an explicit message is provided, plus ' : ' and the explicit message
        """
        if not self.longMessage:
            return msg or standardMsg
        if msg is None:
            return standardMsg
522 523 524 525 526 527
        try:
            # don't switch to '{}' formatting in Python 2.X
            # it changes the way unicode input is handled
            return '%s : %s' % (standardMsg, msg)
        except UnicodeDecodeError:
            return  '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
528 529 530


    def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
531
        """Fail unless an exception of class excClass is thrown
532 533 534 535 536
           by callableObj when invoked with arguments args and keyword
           arguments kwargs. If a different type of exception is
           thrown, it will not be caught, and the test case will be
           deemed to have suffered an error, exactly as for an
           unexpected exception.
537 538 539 540

           If called with callableObj omitted or None, will return a
           context object used like this::

541
                with self.assertRaises(SomeException):
542
                    do_something()
543 544

           The context manager keeps a reference to the exception as
545
           the 'exception' attribute. This allows you to inspect the
546 547 548 549
           exception after the assertion::

               with self.assertRaises(SomeException) as cm:
                   do_something()
550
               the_exception = cm.exception
551
               self.assertEqual(the_exception.error_code, 3)
552
        """
553
        context = _AssertRaisesContext(excClass, self, callableObj)
554 555 556
        if callableObj is None:
            return context
        with context:
557
            callableObj(*args, **kwargs)
558

559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
    def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
        """Fail unless a warning of class warnClass is triggered
           by callableObj when invoked with arguments args and keyword
           arguments kwargs.  If a different type of warning is
           triggered, it will not be handled: depending on the other
           warning filtering rules in effect, it might be silenced, printed
           out, or raised as an exception.

           If called with callableObj omitted or None, will return a
           context object used like this::

                with self.assertWarns(SomeWarning):
                    do_something()

           The context manager keeps a reference to the first matching
           warning as the 'warning' attribute; similarly, the 'filename'
           and 'lineno' attributes give you information about the line
           of Python code from which the warning was triggered.
           This allows you to inspect the warning after the assertion::

               with self.assertWarns(SomeWarning) as cm:
                   do_something()
               the_warning = cm.warning
               self.assertEqual(the_warning.some_attribute, 147)
        """
        context = _AssertWarnsContext(expected_warning, self, callable_obj)
        if callable_obj is None:
            return context
        with context:
            callable_obj(*args, **kwargs)

590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
    def _getAssertEqualityFunc(self, first, second):
        """Get a detailed comparison function for the types of the two args.

        Returns: A callable accepting (first, second, msg=None) that will
        raise a failure exception if first != second with a useful human
        readable error message for those types.
        """
        #
        # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
        # and vice versa.  I opted for the conservative approach in case
        # subclasses are not intended to be compared in detail to their super
        # class instances using a type equality func.  This means testing
        # subtypes won't automagically use the detailed comparison.  Callers
        # should use their type specific assertSpamEqual method to compare
        # subclasses if the detailed comparison is desired and appropriate.
        # See the discussion in http://bugs.python.org/issue2578.
        #
        if type(first) is type(second):
            asserter = self._type_equality_funcs.get(type(first))
            if asserter is not None:
610 611
                if isinstance(asserter, str):
                    asserter = getattr(self, asserter)
612
                return asserter
613 614 615 616 617 618

        return self._baseAssertEqual

    def _baseAssertEqual(self, first, second, msg=None):
        """The default assertEqual implementation, not type specific."""
        if not first == second:
619
            standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
620 621 622 623
            msg = self._formatMessage(msg, standardMsg)
            raise self.failureException(msg)

    def assertEqual(self, first, second, msg=None):
624
        """Fail if the two objects are unequal as determined by the '=='
625 626
           operator.
        """
627 628
        assertion_func = self._getAssertEqualityFunc(first, second)
        assertion_func(first, second, msg=msg)
629

630
    def assertNotEqual(self, first, second, msg=None):
631
        """Fail if the two objects are equal as determined by the '=='
632 633
           operator.
        """
634
        if not first != second:
635 636
            msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
                                                          safe_repr(second)))
637
            raise self.failureException(msg)
638

639
    def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Peterson's avatar
Benjamin Peterson committed
640
                          delta=None):
641 642
        """Fail if the two objects are unequal as determined by their
           difference rounded to the given number of decimal places
Benjamin Peterson's avatar
Benjamin Peterson committed
643 644
           (default 7) and comparing to zero, or by comparing that the
           between the two objects is more than the given delta.
645

646
           Note that decimal places (from zero) are usually not the same
647
           as significant digits (measured from the most signficant digit).
Benjamin Peterson's avatar
Benjamin Peterson committed
648 649 650

           If the two objects compare equal then they will automatically
           compare almost equal.
651
        """
Benjamin Peterson's avatar
Benjamin Peterson committed
652
        if first == second:
Benjamin Peterson's avatar
Benjamin Peterson committed
653
            # shortcut
Benjamin Peterson's avatar
Benjamin Peterson committed
654
            return
Benjamin Peterson's avatar
Benjamin Peterson committed
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
        if delta is not None and places is not None:
            raise TypeError("specify delta or places not both")

        if delta is not None:
            if abs(first - second) <= delta:
                return

            standardMsg = '%s != %s within %s delta' % (safe_repr(first),
                                                        safe_repr(second),
                                                        safe_repr(delta))
        else:
            if places is None:
                places = 7

            if round(abs(second-first), places) == 0:
                return

672 673 674
            standardMsg = '%s != %s within %r places' % (safe_repr(first),
                                                          safe_repr(second),
                                                          places)
Benjamin Peterson's avatar
Benjamin Peterson committed
675 676
        msg = self._formatMessage(msg, standardMsg)
        raise self.failureException(msg)
677

678
    def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Peterson's avatar
Benjamin Peterson committed
679
                             delta=None):
680 681
        """Fail if the two objects are equal as determined by their
           difference rounded to the given number of decimal places
Benjamin Peterson's avatar
Benjamin Peterson committed
682 683
           (default 7) and comparing to zero, or by comparing that the
           between the two objects is less than the given delta.
684

685
           Note that decimal places (from zero) are usually not the same
686
           as significant digits (measured from the most signficant digit).
Benjamin Peterson's avatar
Benjamin Peterson committed
687 688

           Objects that are equal automatically fail.
689
        """
Benjamin Peterson's avatar
Benjamin Peterson committed
690 691 692 693 694 695 696 697 698 699 700 701 702
        if delta is not None and places is not None:
            raise TypeError("specify delta or places not both")
        if delta is not None:
            if not (first == second) and abs(first - second) > delta:
                return
            standardMsg = '%s == %s within %s delta' % (safe_repr(first),
                                                        safe_repr(second),
                                                        safe_repr(delta))
        else:
            if places is None:
                places = 7
            if not (first == second) and round(abs(second-first), places) != 0:
                return
703
            standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Peterson's avatar
Benjamin Peterson committed
704 705 706 707 708
                                                         safe_repr(second),
                                                         places)

        msg = self._formatMessage(msg, standardMsg)
        raise self.failureException(msg)
709

710

711
    def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
712 713
        """An equality assertion for ordered sequences (like lists and tuples).

714
        For the purposes of this function, a valid ordered sequence type is one
715 716 717 718 719 720 721 722 723 724 725 726 727
        which can be indexed, has a length, and has an equality operator.

        Args:
            seq1: The first sequence to compare.
            seq2: The second sequence to compare.
            seq_type: The expected datatype of the sequences, or None if no
                    datatype should be enforced.
            msg: Optional message to use on failure instead of a list of
                    differences.
        """
        if seq_type != None:
            seq_type_name = seq_type.__name__
            if not isinstance(seq1, seq_type):
728 729
                raise self.failureException('First sequence is not a %s: %s'
                                        % (seq_type_name, safe_repr(seq1)))
730
            if not isinstance(seq2, seq_type):
731 732
                raise self.failureException('Second sequence is not a %s: %s'
                                        % (seq_type_name, safe_repr(seq2)))
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
        else:
            seq_type_name = "sequence"

        differing = None
        try:
            len1 = len(seq1)
        except (TypeError, NotImplementedError):
            differing = 'First %s has no length.    Non-sequence?' % (
                    seq_type_name)

        if differing is None:
            try:
                len2 = len(seq2)
            except (TypeError, NotImplementedError):
                differing = 'Second %s has no length.    Non-sequence?' % (
                        seq_type_name)

        if differing is None:
            if seq1 == seq2:
                return

754 755
            seq1_repr = safe_repr(seq1)
            seq2_repr = safe_repr(seq2)
Benjamin Peterson's avatar
Benjamin Peterson committed
756 757 758 759 760 761 762
            if len(seq1_repr) > 30:
                seq1_repr = seq1_repr[:30] + '...'
            if len(seq2_repr) > 30:
                seq2_repr = seq2_repr[:30] + '...'
            elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
            differing = '%ss differ: %s != %s\n' % elements

763 764 765 766
            for i in range(min(len1, len2)):
                try:
                    item1 = seq1[i]
                except (TypeError, IndexError, NotImplementedError):
Benjamin Peterson's avatar
Benjamin Peterson committed
767
                    differing += ('\nUnable to index element %d of first %s\n' %
768 769 770 771 772 773
                                 (i, seq_type_name))
                    break

                try:
                    item2 = seq2[i]
                except (TypeError, IndexError, NotImplementedError):
Benjamin Peterson's avatar
Benjamin Peterson committed
774
                    differing += ('\nUnable to index element %d of second %s\n' %
775 776 777 778
                                 (i, seq_type_name))
                    break

                if item1 != item2:
Benjamin Peterson's avatar
Benjamin Peterson committed
779
                    differing += ('\nFirst differing element %d:\n%s\n%s\n' %
780 781 782 783 784 785 786
                                 (i, item1, item2))
                    break
            else:
                if (len1 == len2 and seq_type is None and
                    type(seq1) != type(seq2)):
                    # The sequences are the same, but have differing types.
                    return
Benjamin Peterson's avatar
Benjamin Peterson committed
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805

            if len1 > len2:
                differing += ('\nFirst %s contains %d additional '
                             'elements.\n' % (seq_type_name, len1 - len2))
                try:
                    differing += ('First extra element %d:\n%s\n' %
                                  (len2, seq1[len2]))
                except (TypeError, IndexError, NotImplementedError):
                    differing += ('Unable to index element %d '
                                  'of first %s\n' % (len2, seq_type_name))
            elif len1 < len2:
                differing += ('\nSecond %s contains %d additional '
                             'elements.\n' % (seq_type_name, len2 - len1))
                try:
                    differing += ('First extra element %d:\n%s\n' %
                                  (len1, seq2[len1]))
                except (TypeError, IndexError, NotImplementedError):
                    differing += ('Unable to index element %d '
                                  'of second %s\n' % (len1, seq_type_name))
806 807
        standardMsg = differing
        diffMsg = '\n' + '\n'.join(
808 809
            difflib.ndiff(pprint.pformat(seq1).splitlines(),
                          pprint.pformat(seq2).splitlines()))
810 811

        standardMsg = self._truncateMessage(standardMsg, diffMsg)
812 813 814
        msg = self._formatMessage(msg, standardMsg)
        self.fail(msg)

815 816 817 818
    def _truncateMessage(self, message, diff):
        max_diff = self.maxDiff
        if max_diff is None or len(diff) <= max_diff:
            return message + diff
819
        return message + (DIFF_OMITTED % len(diff))
820

821 822 823 824 825 826 827 828 829 830 831 832 833 834
    def assertListEqual(self, list1, list2, msg=None):
        """A list-specific equality assertion.

        Args:
            list1: The first list to compare.
            list2: The second list to compare.
            msg: Optional message to use on failure instead of a list of
                    differences.

        """
        self.assertSequenceEqual(list1, list2, msg, seq_type=list)

    def assertTupleEqual(self, tuple1, tuple2, msg=None):
        """A tuple-specific equality assertion.
835

836 837 838 839 840 841 842
        Args:
            tuple1: The first tuple to compare.
            tuple2: The second tuple to compare.
            msg: Optional message to use on failure instead of a list of
                    differences.
        """
        self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
843

844 845
    def assertSetEqual(self, set1, set2, msg=None):
        """A set-specific equality assertion.
846

847 848 849 850 851
        Args:
            set1: The first set to compare.
            set2: The second set to compare.
            msg: Optional message to use on failure instead of a list of
                    differences.
852

853 854 855
        assertSetEqual uses ducktyping to support different types of sets, and
        is optimized for sets specifically (parameters must support a
        difference method).
856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
        """
        try:
            difference1 = set1.difference(set2)
        except TypeError as e:
            self.fail('invalid type when attempting set difference: %s' % e)
        except AttributeError as e:
            self.fail('first argument does not support set difference: %s' % e)

        try:
            difference2 = set2.difference(set1)
        except TypeError as e:
            self.fail('invalid type when attempting set difference: %s' % e)
        except AttributeError as e:
            self.fail('second argument does not support set difference: %s' % e)

        if not (difference1 or difference2):
            return

        lines = []
        if difference1:
            lines.append('Items in the first set but not the second:')
            for item in difference1:
                lines.append(repr(item))
        if difference2:
            lines.append('Items in the second set but not the first:')
            for item in difference2:
                lines.append(repr(item))

        standardMsg = '\n'.join(lines)
        self.fail(self._formatMessage(msg, standardMsg))

    def assertIn(self, member, container, msg=None):
        """Just like self.assertTrue(a in b), but with a nicer default message."""
        if member not in container:
890 891
            standardMsg = '%s not found in %s' % (safe_repr(member),
                                                  safe_repr(container))
892 893 894 895 896
            self.fail(self._formatMessage(msg, standardMsg))

    def assertNotIn(self, member, container, msg=None):
        """Just like self.assertTrue(a not in b), but with a nicer default message."""
        if member in container:
897 898
            standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
                                                        safe_repr(container))
899 900
            self.fail(self._formatMessage(msg, standardMsg))

Benjamin Peterson's avatar
Benjamin Peterson committed
901 902 903
    def assertIs(self, expr1, expr2, msg=None):
        """Just like self.assertTrue(a is b), but with a nicer default message."""
        if expr1 is not expr2:
904 905
            standardMsg = '%s is not %s' % (safe_repr(expr1),
                                             safe_repr(expr2))
Benjamin Peterson's avatar
Benjamin Peterson committed
906 907 908 909 910
            self.fail(self._formatMessage(msg, standardMsg))

    def assertIsNot(self, expr1, expr2, msg=None):
        """Just like self.assertTrue(a is not b), but with a nicer default message."""
        if expr1 is expr2:
911
            standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Peterson's avatar
Benjamin Peterson committed
912 913
            self.fail(self._formatMessage(msg, standardMsg))

914
    def assertDictEqual(self, d1, d2, msg=None):
915 916
        self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
        self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
917 918

        if d1 != d2:
919
            standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
920
            diff = ('\n' + '\n'.join(difflib.ndiff(
921 922
                           pprint.pformat(d1).splitlines(),
                           pprint.pformat(d2).splitlines())))
923
            standardMsg = self._truncateMessage(standardMsg, diff)
924 925
            self.fail(self._formatMessage(msg, standardMsg))

926 927
    def assertDictContainsSubset(self, subset, dictionary, msg=None):
        """Checks whether dictionary is a superset of subset."""
928 929
        warnings.warn('assertDictContainsSubset is deprecated',
                      DeprecationWarning)
930 931
        missing = []
        mismatched = []
932 933
        for key, value in subset.items():
            if key not in dictionary:
934
                missing.append(key)
935
            elif value != dictionary[key]:
936
                mismatched.append('%s, expected: %s, actual: %s' %
937
                                  (safe_repr(key), safe_repr(value),
938
                                   safe_repr(dictionary[key])))
939 940 941 942 943 944

        if not (missing or mismatched):
            return

        standardMsg = ''
        if missing:
945 946
            standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
                                                    missing)
947 948 949 950 951 952 953 954 955 956 957 958
        if mismatched:
            if standardMsg:
                standardMsg += '; '
            standardMsg += 'Mismatched values: %s' % ','.join(mismatched)

        self.fail(self._formatMessage(msg, standardMsg))

    def assertSameElements(self, expected_seq, actual_seq, msg=None):
        """An unordered sequence specific comparison.

        Raises with an error message listing which elements of expected_seq
        are missing from actual_seq and vice versa if any.
959 960 961 962 963

        Duplicate elements are ignored when comparing *expected_seq* and
        *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
        set(actual))`` but it works with sequences of unhashable objects as
        well.
964
        """
965 966
        warnings.warn('assertSameElements is deprecated',
                      DeprecationWarning)
967 968 969
        try:
            expected = set(expected_seq)
            actual = set(actual_seq)
970 971
            missing = sorted(expected.difference(actual))
            unexpected = sorted(actual.difference(expected))
972 973 974 975 976
        except TypeError:
            # Fall back to slower list-compare if any of the objects are
            # not hashable.
            expected = list(expected_seq)
            actual = list(actual_seq)
977 978 979 980
            try:
                expected.sort()
                actual.sort()
            except TypeError:
981
                missing, unexpected = unorderable_list_difference(expected,
982
                                                                  actual)
983 984
            else:
                missing, unexpected = sorted_list_difference(expected, actual)
985 986
        errors = []
        if missing:
987 988
            errors.append('Expected, but missing:\n    %s' %
                          safe_repr(missing))
989
        if unexpected:
990 991
            errors.append('Unexpected, but present:\n    %s' %
                          safe_repr(unexpected))
992 993 994
        if errors:
            standardMsg = '\n'.join(errors)
            self.fail(self._formatMessage(msg, standardMsg))
995 996


997 998 999 1000
    def assertCountEqual(self, first, second, msg=None):
        """An unordered sequence comparison asserting that the same elements,
        regardless of order.  If the same element occurs more than once,
        it verifies that the elements occur the same number of times.
1001

1002 1003
            self.assertEqual(Counter(list(first)),
                             Counter(list(second)))
1004

1005
         Example:
1006 1007
            - [0, 1, 1] and [1, 0, 1] compare equal.
            - [0, 0, 1] and [0, 1] compare unequal.
1008

1009
        """
1010
        first_seq, second_seq = list(first), list(second)
1011
        try:
1012 1013
            first = collections.Counter(first_seq)
            second = collections.Counter(second_seq)
1014
        except TypeError:
1015
            # Handle case with unhashable elements
1016
            differences = _count_diff_all_purpose(first_seq, second_seq)
1017
        else:
1018
            if first == second:
1019
                return
1020
            differences = _count_diff_hashable(first_seq, second_seq)
1021 1022 1023

        if differences:
            standardMsg = 'Element counts were not equal:\n'
1024
            lines = ['First has %d, Second has %d:  %r' % diff for diff in differences]
1025 1026 1027 1028
            diffMsg = '\n'.join(lines)
            standardMsg = self._truncateMessage(standardMsg, diffMsg)
            msg = self._formatMessage(msg, standardMsg)
            self.fail(msg)
1029 1030 1031

    def assertMultiLineEqual(self, first, second, msg=None):
        """Assert that two multi-line strings are equal."""
1032 1033
        self.assertIsInstance(first, str, 'First argument is not a string')
        self.assertIsInstance(second, str, 'Second argument is not a string')
1034 1035

        if first != second:
Ezio Melotti's avatar
Ezio Melotti committed
1036 1037 1038 1039
            # don't use difflib if the strings are too long
            if (len(first) > self._diffThreshold or
                len(second) > self._diffThreshold):
                self._baseAssertEqual(first, second, msg)
1040 1041 1042 1043 1044 1045 1046 1047
            firstlines = first.splitlines(True)
            secondlines = second.splitlines(True)
            if len(firstlines) == 1 and first.strip('\r\n') == first:
                firstlines = [first + '\n']
                secondlines = [second + '\n']
            standardMsg = '%s != %s' % (safe_repr(first, True),
                                        safe_repr(second, True))
            diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
1048
            standardMsg = self._truncateMessage(standardMsg, diff)
1049 1050 1051 1052 1053
            self.fail(self._formatMessage(msg, standardMsg))

    def assertLess(self, a, b, msg=None):
        """Just like self.assertTrue(a < b), but with a nicer default message."""
        if not a < b:
1054
            standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
1055 1056 1057 1058 1059
            self.fail(self._formatMessage(msg, standardMsg))

    def assertLessEqual(self, a, b, msg=None):
        """Just like self.assertTrue(a <= b), but with a nicer default message."""
        if not a <= b:
1060
            standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
1061 1062 1063 1064 1065
            self.fail(self._formatMessage(msg, standardMsg))

    def assertGreater(self, a, b, msg=None):
        """Just like self.assertTrue(a > b), but with a nicer default message."""
        if not a > b:
1066
            standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
1067 1068 1069 1070 1071
            self.fail(self._formatMessage(msg, standardMsg))

    def assertGreaterEqual(self, a, b, msg=None):
        """Just like self.assertTrue(a >= b), but with a nicer default message."""
        if not a >= b:
1072
            standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
1073 1074 1075 1076 1077
            self.fail(self._formatMessage(msg, standardMsg))

    def assertIsNone(self, obj, msg=None):
        """Same as self.assertTrue(obj is None), with a nicer default message."""
        if obj is not None:
1078
            standardMsg = '%s is not None' % (safe_repr(obj),)
1079 1080 1081 1082 1083 1084 1085 1086
            self.fail(self._formatMessage(msg, standardMsg))

    def assertIsNotNone(self, obj, msg=None):
        """Included for symmetry with assertIsNone."""
        if obj is None:
            standardMsg = 'unexpectedly None'
            self.fail(self._formatMessage(msg, standardMsg))

1087 1088 1089 1090
    def assertIsInstance(self, obj, cls, msg=None):
        """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
        default message."""
        if not isinstance(obj, cls):
1091
            standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
1092 1093 1094 1095 1096
            self.fail(self._formatMessage(msg, standardMsg))

    def assertNotIsInstance(self, obj, cls, msg=None):
        """Included for symmetry with assertIsInstance."""
        if isinstance(obj, cls):
1097
            standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
1098 1099
            self.fail(self._formatMessage(msg, standardMsg))

1100 1101 1102
    def assertRaisesRegex(self, expected_exception, expected_regex,
                          callable_obj=None, *args, **kwargs):
        """Asserts that the message in a raised exception matches a regex.
1103 1104 1105

        Args:
            expected_exception: Exception class expected to be raised.
1106
            expected_regex: Regex (re pattern object or string) expected
1107 1108 1109 1110 1111 1112
                    to be found in error message.
            callable_obj: Function to be called.
            args: Extra args.
            kwargs: Extra kwargs.
        """
        context = _AssertRaisesContext(expected_exception, self, callable_obj,
1113
                                       expected_regex)
1114 1115 1116 1117 1118
        if callable_obj is None:
            return context
        with context:
            callable_obj(*args, **kwargs)

1119 1120
    def assertWarnsRegex(self, expected_warning, expected_regex,
                         callable_obj=None, *args, **kwargs):
1121 1122 1123 1124 1125 1126 1127
        """Asserts that the message in a triggered warning matches a regexp.
        Basic functioning is similar to assertWarns() with the addition
        that only warnings whose messages also match the regular expression
        are considered successful matches.

        Args:
            expected_warning: Warning class expected to be triggered.
1128
            expected_regex: Regex (re pattern object or string) expected
1129 1130 1131 1132 1133 1134
                    to be found in error message.
            callable_obj: Function to be called.
            args: Extra args.
            kwargs: Extra kwargs.
        """
        context = _AssertWarnsContext(expected_warning, self, callable_obj,
1135
                                      expected_regex)
1136 1137 1138 1139 1140
        if callable_obj is None:
            return context
        with context:
            callable_obj(*args, **kwargs)

1141
    def assertRegex(self, text, expected_regex, msg=None):
1142
        """Fail the test unless the text matches the regular expression."""
1143
        if isinstance(expected_regex, (str, bytes)):
1144
            assert expected_regex, "expected_regex must not be empty."
1145 1146 1147 1148
            expected_regex = re.compile(expected_regex)
        if not expected_regex.search(text):
            msg = msg or "Regex didn't match"
            msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
1149
            raise self.failureException(msg)
1150

1151
    def assertNotRegex(self, text, unexpected_regex, msg=None):
1152
        """Fail the test if the text matches the regular expression."""
1153 1154 1155
        if isinstance(unexpected_regex, (str, bytes)):
            unexpected_regex = re.compile(unexpected_regex)
        match = unexpected_regex.search(text)
Benjamin Peterson's avatar
Benjamin Peterson committed
1156
        if match:
1157
            msg = msg or "Regex matched"
Benjamin Peterson's avatar
Benjamin Peterson committed
1158 1159
            msg = '%s: %r matches %r in %r' % (msg,
                                               text[match.start():match.end()],
1160
                                               unexpected_regex.pattern,
Benjamin Peterson's avatar
Benjamin Peterson committed
1161 1162 1163
                                               text)
            raise self.failureException(msg)

1164

1165 1166 1167 1168 1169 1170 1171 1172
    def _deprecate(original_func):
        def deprecated_func(*args, **kwargs):
            warnings.warn(
                'Please use {0} instead.'.format(original_func.__name__),
                DeprecationWarning, 2)
            return original_func(*args, **kwargs)
        return deprecated_func

1173
    # see #9424
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185
    failUnlessEqual = assertEquals = _deprecate(assertEqual)
    failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
    failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
    failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
    failUnless = assert_ = _deprecate(assertTrue)
    failUnlessRaises = _deprecate(assertRaises)
    failIf = _deprecate(assertFalse)
    assertRaisesRegexp = _deprecate(assertRaisesRegex)
    assertRegexpMatches = _deprecate(assertRegex)



1186 1187 1188 1189
class FunctionTestCase(TestCase):
    """A test case that wraps a test function.

    This is useful for slipping pre-existing test functions into the
1190
    unittest framework. Optionally, set-up and tidy-up functions can be
1191 1192 1193 1194
    supplied. As with TestCase, the tidy-up ('tearDown') function will
    always be called if the set-up ('setUp') function ran successfully.
    """

1195 1196
    def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
        super(FunctionTestCase, self).__init__()
1197 1198 1199 1200
        self._setUpFunc = setUp
        self._tearDownFunc = tearDown
        self._testFunc = testFunc
        self._description = description
1201 1202

    def setUp(self):
1203 1204
        if self._setUpFunc is not None:
            self._setUpFunc()
1205 1206

    def tearDown(self):
1207 1208
        if self._tearDownFunc is not None:
            self._tearDownFunc()
1209 1210

    def runTest(self):
1211
        self._testFunc()
1212 1213

    def id(self):
1214
        return self._testFunc.__name__
1215

1216
    def __eq__(self, other):
1217 1218
        if not isinstance(other, self.__class__):
            return NotImplemented
1219

1220 1221 1222 1223
        return self._setUpFunc == other._setUpFunc and \
               self._tearDownFunc == other._tearDownFunc and \
               self._testFunc == other._testFunc and \
               self._description == other._description
1224 1225 1226 1227 1228

    def __ne__(self, other):
        return not self == other

    def __hash__(self):
1229 1230
        return hash((type(self), self._setUpFunc, self._tearDownFunc,
                     self._testFunc, self._description))
1231

1232
    def __str__(self):
1233
        return "%s (%s)" % (strclass(self.__class__),
1234
                            self._testFunc.__name__)
1235 1236

    def __repr__(self):
1237
        return "<%s tec=%s>" % (strclass(self.__class__),
1238
                                     self._testFunc)
1239 1240

    def shortDescription(self):
1241 1242 1243
        if self._description is not None:
            return self._description
        doc = self._testFunc.__doc__
1244
        return doc and doc.split("\n")[0].strip() or None