diff --git a/pre_commit_hooks/forbid_articles_in_test_filenames.py b/pre_commit_hooks/forbid_articles_in_test_filenames.py new file mode 100755 index 0000000..1a800bc --- /dev/null +++ b/pre_commit_hooks/forbid_articles_in_test_filenames.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 + +import subprocess +import sys +from pathlib import Path + +FORBIDDEN = {"a", "an", "the"} + + +def git_ls_python_files(): + result = subprocess.run( + ["git", "ls-files", "*.py"], + capture_output=True, + text=True, + check=True, + ) + return [Path(p) for p in result.stdout.splitlines()] + + +def is_test_file(path: Path) -> bool: + name = path.name + return ( + name.startswith("test_") + or name.startswith("tests_") + or name.endswith("_test.py") + ) + + +def has_forbidden_article(path: Path) -> bool: + parts = path.stem.split("_") + return any(part in FORBIDDEN for part in parts) + + +def main() -> int: + for path in git_ls_python_files(): + if not is_test_file(path): + continue + + if has_forbidden_article(path): + print("ERROR: Forbidden article in test filename:") + print(path) + return 1 + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/test_forbid_articles_in_test_filenames.py b/tests/test_forbid_articles_in_test_filenames.py new file mode 100644 index 0000000..95a0b9d --- /dev/null +++ b/tests/test_forbid_articles_in_test_filenames.py @@ -0,0 +1,56 @@ +import subprocess +import sys +from pathlib import Path + + +HOOK = Path(__file__).parents[1] / "pre_commit_hooks" / "forbid_articles_in_test_filenames.py" + + +def run_hook(repo_path: Path): + """Run the hook in a temporary git repo and return (exit_code, stdout).""" + result = subprocess.run( + [sys.executable, str(HOOK)], + cwd=repo_path, + capture_output=True, + text=True, + ) + return result.returncode, result.stdout.strip() + + +def init_git_repo(tmp_path: Path): + subprocess.run(["git", "init"], cwd=tmp_path, check=True) + subprocess.run(["git", "config", "user.email", "test@example.com"], cwd=tmp_path, check=True) + subprocess.run(["git", "config", "user.name", "Test User"], cwd=tmp_path, check=True) + + +def git_add_all(tmp_path: Path): + subprocess.run(["git", "add", "."], cwd=tmp_path, check=True) + + +def test_fails_on_forbidden_article_in_test_filename(tmp_path: Path): + init_git_repo(tmp_path) + + bad_test = tmp_path / "tests_create_an_address.py" + bad_test.write_text("def test_something(): pass\n") + + git_add_all(tmp_path) + + code, output = run_hook(tmp_path) + + assert code == 1 + assert "ERROR: Forbidden article in test filename:" in output + assert "tests_create_an_address.py" in output + + +def test_passes_on_valid_test_filename(tmp_path: Path): + init_git_repo(tmp_path) + + good_test = tmp_path / "tests_create_address.py" + good_test.write_text("def test_something(): pass\n") + + git_add_all(tmp_path) + + code, output = run_hook(tmp_path) + + assert code == 0 + assert output == "" \ No newline at end of file