diff options
| author | natsuoto <[email protected]> | 2026-07-15 15:46:30 +0530 |
|---|---|---|
| committer | natsuoto <[email protected]> | 2026-07-15 15:46:30 +0530 |
| commit | 33e6382dba3603f4d4a1dafeca667caae2983c9c (patch) | |
| tree | f4b2693583484923e8b348059cce0fa8ddd51e9b | |
| parent | 119475cb439ea3cbad7c75bdddb2f35033e17202 (diff) | |
| download | edify-33e6382dba3603f4d4a1dafeca667caae2983c9c.tar.xz edify-33e6382dba3603f4d4a1dafeca667caae2983c9c.zip | |
chore(coverage): exclude_also + global --cov=edify addopts + anti-vacuous and pragma discipline tests
| -rw-r--r-- | pyproject.toml | 10 | ||||
| -rw-r--r-- | tests/discipline/coverage.test.py | 46 | ||||
| -rw-r--r-- | tests/discipline/pragmas.test.py | 48 |
3 files changed, 103 insertions, 1 deletions
diff --git a/pyproject.toml b/pyproject.toml index bde6a28..6e2f588 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -111,6 +111,9 @@ addopts = [ "--strict-markers", "--tb=short", "--import-mode=importlib", + "--cov=edify", + "--cov-fail-under=100", + "--ignore=tests/bench", ] filterwarnings = ["error"] @@ -157,4 +160,9 @@ parallel = true [tool.coverage.report] show_missing = true precision = 2 -fail_under = 100
\ No newline at end of file +fail_under = 100 +exclude_also = [ + "if TYPE_CHECKING:", + "@overload", + "raise NotImplementedError", +]
\ No newline at end of file diff --git a/tests/discipline/coverage.test.py b/tests/discipline/coverage.test.py new file mode 100644 index 0000000..a534424 --- /dev/null +++ b/tests/discipline/coverage.test.py @@ -0,0 +1,46 @@ +"""Anti-vacuous-green coverage discipline. + +If ``[tool.coverage.run].source`` ever points at the wrong directory (say, +``src/edify`` post-reorg while the code moved back to ``edify/``), the +``--cov-fail-under`` gate passes with an empty file list — a 100% score +over zero measured lines. This test rebuilds the source-file discovery +that coverage.py runs internally, asserts the file list is non-empty, and +asserts every listed file is a real Python source inside ``edify/``. +""" + +from pathlib import Path + +import coverage + +_REPO_ROOT = Path(__file__).parent.parent.parent +_EDIFY_ROOT = _REPO_ROOT / "edify" + + +def test_coverage_run_source_resolves_to_the_edify_package_tree(): + coverage_instance = coverage.Coverage() + configured_sources = coverage_instance.config.source + assert configured_sources is not None + assert configured_sources != [], ( + "coverage's [tool.coverage.run].source is empty — the gate would pass over " + "zero measured lines. Point source at 'edify'." + ) + for entry in configured_sources: + assert entry == "edify", ( + f"coverage source contains {entry!r} — expected exactly ['edify']. " + "A wrong source path is the one way this gate passes vacuously green." + ) + + +def test_edify_package_tree_contains_measurable_python_source(): + python_files = sorted(_EDIFY_ROOT.rglob("*.py")) + assert python_files, ( + "no Python files found under edify/ — the coverage source directory is empty." + ) + total_source_bytes = sum(python_file.stat().st_size for python_file in python_files) + assert total_source_bytes > 0, ( + "every file under edify/ is empty — coverage would measure nothing across the tree." + ) + non_init_source_files = [path for path in python_files if path.name != "__init__.py"] + assert non_init_source_files, ( + "edify/ contains only __init__.py files — nothing substantial for coverage to measure." + ) diff --git a/tests/discipline/pragmas.test.py b/tests/discipline/pragmas.test.py new file mode 100644 index 0000000..87f177e --- /dev/null +++ b/tests/discipline/pragmas.test.py @@ -0,0 +1,48 @@ +"""Discipline test — every ``# pragma: no cover`` carries an inline reason. + +The rule: pragmas are allowed only on individual lines, each with an inline +reason after the pragma text. File-level pragmas and bare pragmas without +a reason are banned outright — same discipline as the type-ignore rule. +""" + +import io +import re +import tokenize +from pathlib import Path + +import pytest + +_REPO_ROOT = Path(__file__).parent.parent.parent +_EDIFY_ROOT = _REPO_ROOT / "edify" +_TESTS_ROOT = _REPO_ROOT / "tests" + +_PRAGMA_LINE_PATTERN = re.compile(r"#\s*pragma:\s*no cover\b(.*)$") + + +def _every_python_file(): + for source_root in (_EDIFY_ROOT, _TESTS_ROOT): + yield from source_root.rglob("*.py") + + +def _pragma_comments(python_file): + source_text = python_file.read_text() + for token in tokenize.tokenize(io.BytesIO(source_text.encode("utf-8")).readline): + if token.type != tokenize.COMMENT: + continue + matched = _PRAGMA_LINE_PATTERN.search(token.string) + if matched is None: + continue + yield token.start[0], token.string, matched.group(1) + + [email protected]("python_file", sorted(_every_python_file()), ids=lambda path: str(path)) +def test_no_bare_pragma_no_cover_without_inline_reason(python_file): + for line_number, comment_text, reason_suffix in _pragma_comments(python_file): + stripped_reason = reason_suffix.strip() + if stripped_reason == "" or stripped_reason[0] not in "—:-": + pytest.fail( + f"{python_file.relative_to(_REPO_ROOT)}:{line_number} carries " + f"{comment_text!r} without an inline reason. The rule is: every pragma " + "gets an em-dash-separated reason on the same line, e.g. " + "'# pragma: no cover — <why this branch is unreachable>'." + ) |
