Files
teng-lin--notebooklm-py/tests/unit/test_check_coverage_thresholds.py
wehub-resource-sync 09e9f3545f
CodeQL / Analyze (push) Waiting to run
dependency-audit / pip-audit (push) Waiting to run
Test / Code Quality (push) Has been cancelled
Test / Test (macos-latest, Python 3.10) (push) Has been cancelled
Test / Test (macos-latest, Python 3.11) (push) Has been cancelled
Test / Test (macos-latest, Python 3.12) (push) Has been cancelled
Test / Test (macos-latest, Python 3.13) (push) Has been cancelled
Test / Test (macos-latest, Python 3.14) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.10) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.11) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.12) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.13) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.14) (push) Has been cancelled
Test / Test (windows-latest, Python 3.10) (push) Has been cancelled
Test / Test (windows-latest, Python 3.11) (push) Has been cancelled
Test / Test (windows-latest, Python 3.12) (push) Has been cancelled
Test / Test (windows-latest, Python 3.13) (push) Has been cancelled
Test / Test (windows-latest, Python 3.14) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:30:13 +08:00

259 lines
9.4 KiB
Python

"""Tests for ``scripts/check_coverage_thresholds.py``.
Covers both the original drift check and the per-file floor extension.
The script is imported via spec-loading rather than ``from
scripts.check_coverage_thresholds import main`` because ``scripts/`` is not
a package in this repo.
"""
from __future__ import annotations
import importlib.util
import json
import sys
from pathlib import Path
import pytest
pytestmark = pytest.mark.repo_lint
REPO_ROOT = Path(__file__).resolve().parents[2]
SCRIPT_PATH = REPO_ROOT / "scripts" / "check_coverage_thresholds.py"
def _load_module():
spec = importlib.util.spec_from_file_location("check_coverage_thresholds", SCRIPT_PATH)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
@pytest.fixture(scope="module")
def script():
return _load_module()
# ---------------------------------------------------------------------------
# Original Phase-1 drift check (regression guard for the existing behavior)
# ---------------------------------------------------------------------------
def _write_pyproject(tmp_path: Path, fail_under: int = 90, per_file: dict | None = None) -> Path:
body = f"""\
[tool.coverage.report]
fail_under = {fail_under}
"""
if per_file:
body += "\n[tool.notebooklm.per_file_coverage_floors]\n"
for k, v in per_file.items():
body += f'"{k}" = {v}\n'
p = tmp_path / "pyproject.toml"
p.write_text(body, encoding="utf-8")
return p
def _write_workflow(tmp_path: Path, threshold: int = 90) -> Path:
p = tmp_path / "test.yml"
p.write_text(
f"jobs:\n test:\n steps:\n - run: pytest --cov-fail-under={threshold}\n",
encoding="utf-8",
)
return p
def test_original_drift_match(tmp_path, capsys, script):
pp = _write_pyproject(tmp_path, fail_under=90)
yml = _write_workflow(tmp_path, threshold=90)
rc = script.main(["--pyproject", str(pp), "--workflow", str(yml)])
assert rc == 0
out = capsys.readouterr().out
assert "OK" in out and "90%" in out
def test_original_drift_mismatch_fails(tmp_path, capsys, script):
pp = _write_pyproject(tmp_path, fail_under=90)
yml = _write_workflow(tmp_path, threshold=70)
rc = script.main(["--pyproject", str(pp), "--workflow", str(yml)])
assert rc == 1
err = capsys.readouterr().err
assert "DRIFT" in err
# ---------------------------------------------------------------------------
# per-file floor enforcement
# ---------------------------------------------------------------------------
def _write_coverage_json(tmp_path: Path, files: dict[str, float]) -> Path:
"""Build a minimal coverage.json with the requested per-file percentages."""
payload = {
"files": {path: {"summary": {"percent_covered": pct}} for path, pct in files.items()}
}
p = tmp_path / "coverage.json"
p.write_text(json.dumps(payload), encoding="utf-8")
return p
def test_per_file_floors_all_met(tmp_path, capsys, script):
pp = _write_pyproject(
tmp_path,
fail_under=90,
per_file={"src/notebooklm/cli/doctor.py": 60, "src/notebooklm/cli/profile.py": 70},
)
yml = _write_workflow(tmp_path, threshold=90)
cov = _write_coverage_json(
tmp_path,
{
"src/notebooklm/cli/doctor.py": 65.0,
"src/notebooklm/cli/profile.py": 75.0,
},
)
rc = script.main(["--pyproject", str(pp), "--workflow", str(yml), "--coverage-json", str(cov)])
assert rc == 0
out = capsys.readouterr().out
assert "2 per-file floor(s) all met" in out
def test_per_file_floor_breach_fails_with_filename(tmp_path, capsys, script):
pp = _write_pyproject(
tmp_path,
fail_under=90,
per_file={"src/notebooklm/cli/doctor.py": 80},
)
yml = _write_workflow(tmp_path, threshold=90)
cov = _write_coverage_json(tmp_path, {"src/notebooklm/cli/doctor.py": 65.0})
rc = script.main(["--pyproject", str(pp), "--workflow", str(yml), "--coverage-json", str(cov)])
assert rc == 1
err = capsys.readouterr().err
assert "PER-FILE COVERAGE FLOOR BREACH" in err
assert "src/notebooklm/cli/doctor.py" in err
assert "65.00" in err
assert "80%" in err
def test_per_file_missing_from_coverage_json_fails(tmp_path, capsys, script):
"""A guarded file with no measurement is itself a CI failure."""
pp = _write_pyproject(
tmp_path,
fail_under=90,
per_file={"src/notebooklm/cli/doctor.py": 60, "src/notebooklm/renamed.py": 60},
)
yml = _write_workflow(tmp_path, threshold=90)
cov = _write_coverage_json(tmp_path, {"src/notebooklm/cli/doctor.py": 65.0})
rc = script.main(["--pyproject", str(pp), "--workflow", str(yml), "--coverage-json", str(cov)])
assert rc == 1
err = capsys.readouterr().err
assert "MISSING" in err
assert "src/notebooklm/renamed.py" in err
def test_per_file_no_floors_table_passes(tmp_path, capsys, script):
pp = _write_pyproject(tmp_path, fail_under=90) # no per_file table
yml = _write_workflow(tmp_path, threshold=90)
cov = _write_coverage_json(tmp_path, {"src/notebooklm/cli/doctor.py": 0.0})
rc = script.main(["--pyproject", str(pp), "--workflow", str(yml), "--coverage-json", str(cov)])
assert rc == 0
out = capsys.readouterr().out
assert "no [tool.notebooklm.per_file_coverage_floors]" in out
def test_coverage_json_missing_returns_2(tmp_path, capsys, script):
pp = _write_pyproject(tmp_path, fail_under=90, per_file={"foo.py": 0})
yml = _write_workflow(tmp_path, threshold=90)
rc = script.main(
[
"--pyproject",
str(pp),
"--workflow",
str(yml),
"--coverage-json",
str(tmp_path / "no-such.json"),
]
)
assert rc == 2
def test_per_file_floors_non_table_returns_2(tmp_path, capsys, script):
"""A non-table ``per_file_coverage_floors`` (string, list, etc.) is a
misconfiguration that must not silently bypass enforcement."""
pp = tmp_path / "pyproject.toml"
pp.write_text(
"[tool.coverage.report]\nfail_under = 90\n\n"
'[tool.notebooklm]\nper_file_coverage_floors = "oops"\n',
encoding="utf-8",
)
yml = _write_workflow(tmp_path, threshold=90)
cov = _write_coverage_json(tmp_path, {"src/notebooklm/cli/doctor.py": 50.0})
rc = script.main(["--pyproject", str(pp), "--workflow", str(yml), "--coverage-json", str(cov)])
assert rc == 2
err = capsys.readouterr().err
assert "must be a TOML table" in err
def test_per_file_floor_non_numeric_returns_2(tmp_path, capsys, script):
"""A non-numeric floor value (string, etc.) yields exit 2 with context, not a crash."""
pp = _write_pyproject(
tmp_path,
fail_under=90,
per_file={"src/notebooklm/cli/doctor.py": '"sixty"'}, # raw TOML — string value
)
yml = _write_workflow(tmp_path, threshold=90)
cov = _write_coverage_json(tmp_path, {"src/notebooklm/cli/doctor.py": 70.0})
rc = script.main(["--pyproject", str(pp), "--workflow", str(yml), "--coverage-json", str(cov)])
assert rc == 2
err = capsys.readouterr().err
assert "could not be compared" in err
assert "src/notebooklm/cli/doctor.py" in err
def test_coverage_json_files_wrong_shape_returns_2(tmp_path, capsys, script):
"""``coverage.json`` with ``files`` as something other than an object → exit 2."""
pp = _write_pyproject(tmp_path, fail_under=90, per_file={"foo.py": 0})
yml = _write_workflow(tmp_path, threshold=90)
bad = tmp_path / "coverage.json"
bad.write_text(json.dumps({"files": []}), encoding="utf-8") # list, not dict
rc = script.main(["--pyproject", str(pp), "--workflow", str(yml), "--coverage-json", str(bad)])
assert rc == 2
assert "'files' must be an object map" in capsys.readouterr().err
def test_coverage_json_malformed_returns_2(tmp_path, capsys, script):
pp = _write_pyproject(tmp_path, fail_under=90, per_file={"foo.py": 0})
yml = _write_workflow(tmp_path, threshold=90)
bad = tmp_path / "coverage.json"
bad.write_text("{not-json", encoding="utf-8")
rc = script.main(["--pyproject", str(pp), "--workflow", str(yml), "--coverage-json", str(bad)])
assert rc == 2
assert "malformed" in capsys.readouterr().err
def test_per_file_real_baselines_pass_against_repo_pyproject(tmp_path, capsys, script):
"""Round-trip: the floors checked into pyproject.toml pass against a fresh
coverage.json that records the floor exact value (sanity check that the
parser+comparator agree on the data shape that ``coverage json`` emits).
"""
real_pp = REPO_ROOT / "pyproject.toml"
yml = _write_workflow(tmp_path, threshold=90)
cov = _write_coverage_json(
tmp_path,
{
# Match the floors checked in — every path at exactly its floor
# should pass (>= comparison).
"src/notebooklm/__main__.py": 0.0,
"src/notebooklm/cli/_firefox_containers.py": 95.0,
"src/notebooklm/cli/doctor_cmd.py": 63.0,
"src/notebooklm/cli/profile_cmd.py": 74.0,
"src/notebooklm/cli/session_cmd.py": 83.0,
},
)
rc = script.main(
["--pyproject", str(real_pp), "--workflow", str(yml), "--coverage-json", str(cov)]
)
assert rc == 0
def teardown_module():
"""Drop the spec-loaded module so other tests aren't affected."""
sys.modules.pop("check_coverage_thresholds", None)