import re import unittest from tools.linter.adapters.header_only_linter import ( check_file, CPP_TEST_GLOBS, find_matched_symbols, LINTER_CODE, LintMessage, LintSeverity, REPO_ROOT, ) class TestHeaderOnlyLinter(unittest.TestCase): """ Test the header only linter functionality """ def test_find_matched_symbols(self) -> None: sample_regex = re.compile("symDef|symD|symC|bbb|a") test_globs = ["tools/test/header_only_linter_testdata/*.cpp"] expected_matches = {"symDef", "symC", "a"} self.assertEqual( find_matched_symbols(sample_regex, test_globs), expected_matches ) def test_find_matched_symbols_empty_regex(self) -> None: sample_regex = re.compile("") test_globs = ["tools/test/header_only_linter_testdata/*.cpp"] expected_matches: set[str] = set() self.assertEqual( find_matched_symbols(sample_regex, test_globs), expected_matches ) def test_check_file_no_issues(self) -> None: sample_txt = str(REPO_ROOT / "tools/test/header_only_linter_testdata/good.txt") test_globs = ["tools/test/header_only_linter_testdata/*.cpp"] self.assertEqual(len(check_file(sample_txt, test_globs)), 0) def test_check_empty_file(self) -> None: sample_txt = str(REPO_ROOT / "tools/test/header_only_linter_testdata/empty.txt") test_globs = ["tools/test/header_only_linter_testdata/*.cpp"] self.assertEqual(len(check_file(sample_txt, test_globs)), 0) def test_check_file_with_untested_symbols(self) -> None: sample_txt = str(REPO_ROOT / "tools/test/header_only_linter_testdata/bad.txt") test_globs = ["tools/test/header_only_linter_testdata/*.cpp"] expected_msgs = [ LintMessage( path=sample_txt, line=7, char=None, code=LINTER_CODE, severity=LintSeverity.ERROR, name="[untested-symbol]", original=None, replacement=None, description=( f"bbb has been included as a header-only API " "but is not tested in any of CPP_TEST_GLOBS, which " f"contains {CPP_TEST_GLOBS}.\n" "Please add a .cpp test using the symbol without " "linking anything to verify that the symbol is in " "fact header-only. If you already have a test but it's" " not found, please add the .cpp file to CPP_TEST_GLOBS" " in tools/linters/adapters/header_only_linter.py." ), ), LintMessage( path=sample_txt, line=8, char=None, code=LINTER_CODE, severity=LintSeverity.ERROR, name="[untested-symbol]", original=None, replacement=None, description=( f"symD has been included as a header-only API " "but is not tested in any of CPP_TEST_GLOBS, which " f"contains {CPP_TEST_GLOBS}.\n" "Please add a .cpp test using the symbol without " "linking anything to verify that the symbol is in " "fact header-only. If you already have a test but it's" " not found, please add the .cpp file to CPP_TEST_GLOBS" " in tools/linters/adapters/header_only_linter.py." ), ), ] self.assertEqual(set(check_file(sample_txt, test_globs)), set(expected_msgs)) if __name__ == "__main__": unittest.main()