Пример #1
0
    def __init__(self, *args, **kwargs):
        """Constructor."""
        super(DeprecationTestCase, self).__init__(*args, **kwargs)
        self.warning_log = []

        self.expect_warning_filename = inspect.getfile(self.__class__)
        if self.expect_warning_filename.endswith((".pyc", ".pyo")):
            self.expect_warning_filename = self.expect_warning_filename[:-1]

        self._do_test_warning_filename = True
        self._ignore_unknown_warning_packages = False

        self.context_manager = WarningSourceSkipContextManager(self.skip_list)
Пример #2
0
class DeprecationTestCase(DebugOnlyTestCase, TestCase):

    """Test cases for deprecation function in the tools module."""

    _generic_match = re.compile(r'.* is deprecated(; use .* instead)?\.')

    skip_list = [
        unittest.case._AssertRaisesContext,
        TestCase.assertRaises,
        TestCase.assertRaisesRegex,
        TestCase.assertRaisesRegexp,
    ]

    # Require no instead string
    NO_INSTEAD = object()
    # Require an instead string
    INSTEAD = object()

    # Python 3 component in the call stack of _AssertRaisesContext
    if hasattr(unittest.case, '_AssertRaisesBaseContext'):
        skip_list.append(unittest.case._AssertRaisesBaseContext)

    def __init__(self, *args, **kwargs):
        """Constructor."""
        super(DeprecationTestCase, self).__init__(*args, **kwargs)
        self.warning_log = []

        self.expect_warning_filename = inspect.getfile(self.__class__)
        if self.expect_warning_filename.endswith((".pyc", ".pyo")):
            self.expect_warning_filename = self.expect_warning_filename[:-1]

        self._do_test_warning_filename = True
        self._ignore_unknown_warning_packages = False

        self.context_manager = WarningSourceSkipContextManager(self.skip_list)

    def _reset_messages(self):
        """Reset captured deprecation warnings."""
        self._do_test_warning_filename = True
        del self.warning_log[:]

    @property
    def deprecation_messages(self):
        """Return captured deprecation warnings."""
        messages = [str(item.message) for item in self.warning_log]
        return messages

    @classmethod
    def _build_message(cls, deprecated, instead):
        if deprecated is None:
            if instead is None:
                msg = None
            elif instead is True:
                msg = cls.INSTEAD
            else:
                assert instead is False
                msg = cls.NO_INSTEAD
        else:
            msg = '{0} is deprecated'.format(deprecated)
            if instead:
                msg += '; use {0} instead'.format(instead)
            msg += '.'
        return msg

    def assertDeprecationParts(self, deprecated=None, instead=None):
        """
        Assert that a deprecation warning happened.

        To simplify deprecation tests it just requires the to separated parts
        and forwards the result to L{assertDeprecation}.

        @param deprecated: The deprecated string. If None it uses a generic
            match depending on instead.
        @type deprecated: str or None
        @param instead: The instead string unless deprecated is None. If it's
            None it allows any generic deprecation string, on True only those
            where instead string is present and on False only those where it's
            missing. If the deprecation string is not None, no instead string
            is expected when instead evaluates to False.
        @type instead: str or None or True or False
        """
        self.assertDeprecation(self._build_message(deprecated, instead))

    def assertDeprecation(self, msg=None):
        """
        Assert that a deprecation warning happened.

        @param msg: Either the specific message or None to allow any generic
            message. When set to C{INSTEAD} it only counts those supplying an
            alternative and when C{NO_INSTEAD} only those not supplying one.
        @type msg: string or None or INSTEAD or NO_INSTEAD
        """
        if msg is None or msg is self.INSTEAD or msg is self.NO_INSTEAD:
            deprecation_messages = self.deprecation_messages
            for deprecation_message in deprecation_messages:
                match = self._generic_match.match(deprecation_message)
                if (match and bool(match.group(1)) == (msg is self.INSTEAD) or
                        msg is None):
                    break
            else:
                self.fail('No generic deprecation message match found in '
                          '{0}'.format(deprecation_messages))
        else:
            self.assertIn(msg, self.deprecation_messages)
        if self._do_test_warning_filename:
            self.assertDeprecationFile(self.expect_warning_filename)

    def assertOneDeprecationParts(self, deprecated=None, instead=None, count=1):
        """
        Assert that exactly one deprecation message happened and reset.

        It uses the same arguments as L{assertDeprecationParts}.
        """
        self.assertOneDeprecation(self._build_message(deprecated, instead),
                                  count)

    def assertOneDeprecation(self, msg=None, count=1):
        """Assert that exactly one deprecation message happened and reset."""
        self.assertDeprecation(msg)
        # This is doing such a weird structure, so that it shows any other
        # deprecation message from the set.
        self.assertCountEqual(set(self.deprecation_messages),
                              [self.deprecation_messages[0]])
        self.assertEqual(len(self.deprecation_messages), count)
        self._reset_messages()

    def assertNoDeprecation(self, msg=None):
        """Assert that no deprecation warning happened."""
        if msg:
            self.assertNotIn(msg, self.deprecation_messages)
        else:
            self.assertEqual([], self.deprecation_messages)

    def assertDeprecationClass(self, cls):
        """Assert that all deprecation warning are of one class."""
        self.assertTrue(all(isinstance(item.message, cls)
                            for item in self.warning_log))

    def assertDeprecationFile(self, filename):
        """Assert that all deprecation warning are of one filename."""
        for item in self.warning_log:
            if (self._ignore_unknown_warning_packages and
                    'pywikibot' not in item.filename):
                continue

            if item.filename != filename:
                self.fail(
                    'expected warning filename %s; warning item: %s'
                    % (filename, item))

    def setUp(self):
        """Set up unit test."""
        super(DeprecationTestCase, self).setUp()

        self.warning_log = self.context_manager.__enter__()
        warnings.simplefilter("always")

        self._reset_messages()

    def tearDown(self):
        """Tear down unit test."""
        self.context_manager.__exit__()

        super(DeprecationTestCase, self).tearDown()