Ctrl K
ComunidadGuías…

tests/github/test_pr_autoformat.py

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

Archivo original ↗Preguntar a KiBot
from __future__ import annotations

import importlib.util
import json
import os
import shutil
import subprocess
import sys
from pathlib import Path

import pytest
import yaml

_SCRIPT = Path(__file__).parents[2] / ".github" / "scripts" / "pr-template" / "format_body.py"
_WORKFLOW = Path(__file__).parents[2] / ".github" / "workflows" / "autoformat-pr.yml"
sys.path.insert(0, str(_SCRIPT.parent))
_SPEC = importlib.util.spec_from_file_location("pr_autoformat", _SCRIPT)
assert _SPEC is not None and _SPEC.loader is not None
pr_autoformat = importlib.util.module_from_spec(_SPEC)
_SPEC.loader.exec_module(pr_autoformat)


def test_wraps_existing_description_in_summary_without_deleting_it() -> None:
    formatted = pr_autoformat.format_body("Fix the important thing.")

    assert formatted.startswith("## Summary\n\nFix the important thing.")
    assert "## Type of change" in formatted
    assert "- [ ] Bug fix" in formatted
    assert "## Test coverage" in formatted
    assert "- [ ] Unit tests added / updated" in formatted


def test_preserves_existing_sections_without_adding_explanation_scaffolds() -> None:
    original = "## Summary\n\nExisting summary.\n\n## Type of change\n\n- [x] Feature\n"
    formatted = pr_autoformat.format_body(original)

    assert "Existing summary." in formatted
    assert "- [x] Feature" in formatted
    assert formatted.count("## Summary") == 1
    assert formatted.count("## Type of change") == 1
    assert "## ELI5" not in formatted
    assert "## Diagram" not in formatted
    assert "## Test Plan" in formatted
    assert "## Coverage notes" in formatted
    assert "## Changelog" in formatted


def test_preserves_an_authored_diagram() -> None:
    original = "## Summary\n\nClear summary.\n\n## Diagram\n\nA -> B\n"

    formatted = pr_autoformat.format_body(original)

    assert formatted.count("## Diagram") == 1
    assert "A -> B" in formatted


def test_cli_adds_template_without_unrequested_explanation(tmp_path: Path) -> None:
    source = tmp_path / "body.md"
    destination = tmp_path / "formatted.md"
    source.write_text("A short, plain-language fix.\n", encoding="utf-8")

    result = subprocess.run(
        [sys.executable, str(_SCRIPT), str(source), str(destination)],
        capture_output=True,
        text=True,
        check=False,
    )

    assert result.returncode == 0
    body = destination.read_text(encoding="utf-8")
    assert "## Summary\n\nA short, plain-language fix." in body
    assert "## Test Plan" in body
    assert "## ELI5" not in body
    assert "## Diagram" not in body


def test_scaffolds_changelog_section_with_delete_placeholder() -> None:
    formatted = pr_autoformat.format_body("Fix the important thing.")
    assert "## Changelog" in formatted
    # The scaffolded section defaults to the delete-if-not-noteworthy placeholder.
    assert formatted.rstrip().endswith("else delete this section>")


@pytest.mark.posix_only
@pytest.mark.skipif(shutil.which("jq") is None, reason="the workflow requires jq")
def test_workflow_keeps_an_already_formatted_body_unchanged(tmp_path: Path) -> None:
    workflow = yaml.safe_load(_WORKFLOW.read_text())
    step = next(
        step
        for step in workflow["jobs"]["autoformat"]["steps"]
        if step.get("name") == "Autoformat PR body and assign author"
    )
    extraction = [
        line.strip()
        for line in step["run"].splitlines()
        if line.strip().startswith("jq ") and '> "$body_file"' in line
    ]
    assert len(extraction) == 1

    body = pr_autoformat.format_body(
        "## Summary\n\nExisting text.\n\n## ELI5\n\nAuthored explanation.\n\n"
        "## Diagram\n\nA -> B\n"
    )
    source = tmp_path / "body.md"
    destination = tmp_path / "formatted.md"
    subprocess.run(
        ["bash", "-euo", "pipefail", "-c", extraction[0]],
        env={**os.environ, "pr_json": json.dumps({"body": body}), "body_file": str(source)},
        check=True,
    )
    subprocess.run(
        [sys.executable, str(_SCRIPT), str(source), str(destination)],
        check=True,
    )

    assert source.read_text() == body
    assert destination.read_text() == body