zulip/tools/tests/test_zulint_custom_rules.py

75 lines
3.1 KiB
Python

import os
from io import StringIO
from unittest import TestCase
from unittest.mock import patch
from zulint.custom_rules import RuleList
from linter_lib.custom_check import non_py_rules, python_rules
ROOT_DIR = os.path.abspath(os.path.join(__file__, "..", "..", ".."))
CHECK_MESSAGE = "Fix the corresponding rule in `tools/linter_lib/custom_check.py`."
class TestRuleList(TestCase):
def setUp(self) -> None:
self.all_rules = python_rules.rules
for rule in non_py_rules:
self.all_rules.extend(rule.rules)
def test_paths_in_rules(self) -> None:
"""Verifies that the paths mentioned in linter rules actually exist"""
for rule in self.all_rules:
for path in rule.get("exclude", {}):
abs_path = os.path.abspath(os.path.join(ROOT_DIR, path))
self.assertTrue(
os.path.exists(abs_path),
f"'{path}' is neither an existing file, nor a directory. {CHECK_MESSAGE}",
)
for line_tuple in rule.get("exclude_line", {}):
path = line_tuple[0]
abs_path = os.path.abspath(os.path.join(ROOT_DIR, path))
self.assertTrue(
os.path.isfile(abs_path), f"The file '{path}' doesn't exist. {CHECK_MESSAGE}"
)
for path in rule.get("include_only", {}):
if not os.path.splitext(path)[1]:
self.assertTrue(
path.endswith("/"),
f"The path '{path}' should end with '/'. {CHECK_MESSAGE}",
)
def test_rule_patterns(self) -> None:
"""Verifies that the search regex specified in a custom rule actually matches
the expectation and doesn't throw false positives."""
for rule in self.all_rules:
pattern = rule["pattern"]
for line in rule.get("good_lines", []):
# create=True is superfluous when mocking built-ins in Python >= 3.5
with patch(
"builtins.open",
return_value=StringIO(line + "\n\n"),
create=True,
autospec=True,
):
self.assertFalse(
RuleList([], [rule]).custom_check_file("foo.bar", "baz", ""),
f"The pattern '{pattern}' matched the line '{line}' while it shouldn't.",
)
for line in rule.get("bad_lines", []):
# create=True is superfluous when mocking built-ins in Python >= 3.5
with patch(
"builtins.open",
return_value=StringIO(line + "\n\n"),
create=True,
autospec=True,
), patch("builtins.print"):
filename = list(rule.get("include_only", {"foo.bar"}))[0]
self.assertTrue(
RuleList([], [rule]).custom_check_file(filename, "baz", ""),
f"The pattern '{pattern}' didn't match the line '{line}' while it should.",
)