mirror of
https://fuchsia.googlesource.com/third_party/github.com/pylint-dev/pylint
synced 2024-09-21 16:19:21 +00:00
71bbbdb294
* Allow checking of `end_col_offset` and `end_lineno` in unittests * Allow checking of `col_offset` in unittests * Allow checking of `lineno` in unittests * Update tests for ``TestVariablesChecker`` * Fix ``TestMultiNamingStyle`` * Update tests for ``TestImportsChecker`` * Add location attributes to messages of ``TestTypeChecker`` * Add location params to ``TestMessage``'s of ``TestDeprecatedChecker`` * Add location params to ``TestMessage``'s of ``TestTypeCheckerOnDecorators`` * Add changelog and ``DeprecationWarning``
84 lines
3.5 KiB
Python
84 lines
3.5 KiB
Python
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
|
|
|
|
import contextlib
|
|
import warnings
|
|
from typing import Dict, Generator, Optional, Type
|
|
|
|
from pylint.constants import PY38_PLUS
|
|
from pylint.testutils.global_test_linter import linter
|
|
from pylint.testutils.output_line import MessageTest
|
|
from pylint.testutils.unittest_linter import UnittestLinter
|
|
from pylint.utils import ASTWalker
|
|
|
|
|
|
class CheckerTestCase:
|
|
"""A base testcase class for unit testing individual checker classes."""
|
|
|
|
CHECKER_CLASS: Optional[Type] = None
|
|
CONFIG: Dict = {}
|
|
|
|
def setup_method(self):
|
|
self.linter = UnittestLinter()
|
|
self.checker = self.CHECKER_CLASS(self.linter) # pylint: disable=not-callable
|
|
for key, value in self.CONFIG.items():
|
|
setattr(self.checker.config, key, value)
|
|
self.checker.open()
|
|
|
|
@contextlib.contextmanager
|
|
def assertNoMessages(self):
|
|
"""Assert that no messages are added by the given method."""
|
|
with self.assertAddsMessages():
|
|
yield
|
|
|
|
@contextlib.contextmanager
|
|
def assertAddsMessages(self, *messages: MessageTest) -> Generator[None, None, None]:
|
|
"""Assert that exactly the given method adds the given messages.
|
|
|
|
The list of messages must exactly match *all* the messages added by the
|
|
method. Additionally, we check to see whether the args in each message can
|
|
actually be substituted into the message string.
|
|
"""
|
|
yield
|
|
got = self.linter.release_messages()
|
|
no_msg = "No message."
|
|
expected = "\n".join(repr(m) for m in messages) or no_msg
|
|
got_str = "\n".join(repr(m) for m in got) or no_msg
|
|
msg = (
|
|
"Expected messages did not match actual.\n"
|
|
f"\nExpected:\n{expected}\n\nGot:\n{got_str}\n"
|
|
)
|
|
|
|
assert len(messages) == len(got), msg
|
|
|
|
for expected_msg, gotten_msg in zip(messages, got):
|
|
assert expected_msg.msg_id == gotten_msg.msg_id, msg
|
|
assert expected_msg.line == gotten_msg.line, msg
|
|
assert expected_msg.node == gotten_msg.node, msg
|
|
assert expected_msg.args == gotten_msg.args, msg
|
|
assert expected_msg.confidence == gotten_msg.confidence, msg
|
|
assert expected_msg.col_offset == gotten_msg.col_offset, msg
|
|
if PY38_PLUS:
|
|
# pylint: disable=fixme
|
|
# TODO: Require end_line and end_col_offset and remove the warning
|
|
if not expected_msg.end_line == gotten_msg.end_line:
|
|
warnings.warn(
|
|
f"The end_line attribute of {gotten_msg} does not match "
|
|
f"the expected value in {expected_msg}. In pylint 3.0 correct end_line "
|
|
"attributes will be required for MessageTest.",
|
|
DeprecationWarning,
|
|
)
|
|
if not expected_msg.end_col_offset == gotten_msg.end_col_offset:
|
|
warnings.warn(
|
|
f"The end_col_offset attribute of {gotten_msg} does not match "
|
|
f"the expected value in {expected_msg}. In pylint 3.0 correct end_col_offset "
|
|
"attributes will be required for MessageTest.",
|
|
DeprecationWarning,
|
|
)
|
|
|
|
def walk(self, node):
|
|
"""recursive walk on the given node"""
|
|
walker = ASTWalker(linter)
|
|
walker.add_checker(self.checker)
|
|
walker.walk(node)
|