Ctrl K
ComunidadGuías…

tests/github/test_coverage_total.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""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"