tests/github/test_coverage_total.py
Rama main · réplica de lectura del repositorio original.
"""CI's reused total matches coverage.py's report and failure behavior."""
from __future__ import annotations
import os
import subprocess
import sys
from pathlib import Path
import coverage
import pytest
SCRIPT = Path(__file__).resolve().parents[2] / ".github/scripts/ci/coverage-total.py"
def _run(directory: Path, *args: str) -> subprocess.CompletedProcess[str]:
env = {k: v for k, v in os.environ.items() if not k.startswith("COVERAGE_")}
return subprocess.run(
[sys.executable, *args], cwd=directory, env=env, capture_output=True, text=True
)
def _reports(directory: Path) -> tuple[Path, str]:
markdown = _run(directory, "-m", "coverage", "report", "--format=markdown", "--ignore-errors")
total = _run(directory, "-m", "coverage", "report", "--format=total", "--ignore-errors")
assert markdown.returncode == total.returncode == 0, (markdown.stderr, total.stderr)
path = directory / "report.md"
path.write_text(markdown.stdout)
return path, total.stdout
@pytest.mark.parametrize(
("covered", "precision"), [(0, 0), (1, 0), (1334, 0), (2000, 0), (2001, 0), (1334, 2)]
)
def test_total_matches_cli_rounding(tmp_path: Path, covered: int, precision: int) -> None:
source = tmp_path / "sample.py"
source.write_text("value = 1\n" * 2001)
(tmp_path / ".coveragerc").write_text(f"[report]\nprecision = {precision}\n")
data = coverage.CoverageData(basename=str(tmp_path / ".coverage"))
data.add_lines({str(source): set(range(1, covered + 1))})
data.write()
markdown, expected = _reports(tmp_path)
result = _run(tmp_path, str(SCRIPT), str(markdown))
assert result.returncode == 0, result.stderr
assert result.stdout == expected
assert result.stderr == "" # The fast path must not fall back to a second analysis.
def test_branch_coverage_and_omitted_missing_source(tmp_path: Path) -> None:
source = tmp_path / "sample.py"
source.write_text('if __name__ == "__main__":\n value = 1\nelse:\n value = 2\n')
ignored = tmp_path / "ignored.py"
ignored.write_text("value = 3\n")
(tmp_path / ".coveragerc").write_text("[run]\nbranch = true\n[report]\nomit = ignored.py\n")
data = coverage.CoverageData(basename=str(tmp_path / ".coverage"))
data.add_arcs(
{
str(source): {(-1, 1), (1, 2), (2, -1)},
str(ignored): {(-1, 1), (1, -1)},
str(tmp_path / "generated.py"): {(-1, 1), (1, -1)},
}
)
data.write()
markdown, expected = _reports(tmp_path)
assert "Branch" in markdown.read_text()
assert "ignored.py" not in markdown.read_text()
result = _run(tmp_path, str(SCRIPT), str(markdown))
assert result.returncode == 0, result.stderr
assert result.stdout == expected
assert result.stderr == ""
@pytest.mark.parametrize(
"markdown_text",
[
"",
"| **TOTAL** | **2** | **0** | **101%** |",
"| **TOTAL** | **2** | **1** | **50%** |\n" * 2,
],
)
def test_changed_format_falls_back_to_cli(tmp_path: Path, markdown_text: str) -> None:
source = tmp_path / "sample.py"
source.write_text("value = 1\nother = 2\n")
data = coverage.CoverageData(basename=str(tmp_path / ".coverage"))
data.add_lines({str(source): {1}})
data.write()
(tmp_path / "report.md").write_text(markdown_text)
result = _run(tmp_path, str(SCRIPT), "report.md")
assert result.returncode == 0, result.stderr
assert result.stdout == "50\n"
assert "regenerating" in result.stderr
def test_fallback_failure_is_not_published_as_zero(tmp_path: Path) -> None:
(tmp_path / "report.md").write_text("")
result = _run(tmp_path, str(SCRIPT), "report.md")
assert result.returncode != 0
assert result.stdout != "0\n"