Ctrl K
ComunidadGuías…

scripts/test_check_changelog.py

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

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env python3
"""Unit tests for scripts/check_changelog.py (stdlib unittest)."""

from __future__ import annotations

import tempfile
import unittest
import importlib.util
from pathlib import Path
from textwrap import dedent


def _load_checker():
    path = Path(__file__).with_name("check-changelog.py")
    spec = importlib.util.spec_from_file_location("check_changelog", path)
    if spec is None or spec.loader is None:
        raise ImportError(f"cannot load {path}")
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module


check_changelog = _load_checker()

VALID = dedent(
    """\
    # Changelog

    ## [0.1.0] - 2026-08-16

    ### Added

    - First public release.

    ### Changed

    - None.

    ### Deprecated

    - None.

    ### Fixed

    - None.

    ### Improved

    - None.
    """
)


MULTI = dedent(
    """\
    # Changelog

    ## [0.1.2] - 2026-08-21

    ### Added

    - Third release.

    ## [0.1.1] - 2026-08-17

    ### Added

    - Second release.

    ## [0.1.0] - 2026-08-16

    ### Added

    - First release.
    """
)


class PreviousVersionTests(unittest.TestCase):
    def test_returns_the_tag_of_the_preceding_release(self) -> None:
        self.assertEqual(check_changelog.previous_version(MULTI, "v0.1.2"), "v0.1.1")
        self.assertEqual(check_changelog.previous_version(MULTI, "v0.1.1"), "v0.1.0")

    def test_accepts_a_bare_version(self) -> None:
        self.assertEqual(check_changelog.previous_version(MULTI, "0.1.2"), "v0.1.1")

    def test_oldest_release_has_no_predecessor(self) -> None:
        self.assertIsNone(check_changelog.previous_version(MULTI, "v0.1.0"))

    def test_unknown_tag_raises(self) -> None:
        with self.assertRaises(check_changelog.ChangelogError):
            check_changelog.previous_version(MULTI, "v9.9.9")

    def test_repo_latest_release_points_at_the_one_below_it(self) -> None:
        # The contributor range for a release must start at the release before
        # it, so an earlier release's contributors are not re-listed.
        repo = Path(__file__).resolve().parent.parent
        text = (repo / "CHANGELOG.md").read_text(encoding="utf-8")
        releases = check_changelog._split_releases(text)
        self.assertGreaterEqual(len(releases), 2)
        latest, second = releases[0][0], releases[1][0]
        self.assertEqual(check_changelog.previous_version(text, f"v{latest}"), f"v{second}")


class ValidateChangelogTests(unittest.TestCase):
    def test_valid_document_has_no_problems(self) -> None:
        self.assertEqual(check_changelog.validate_text(VALID, "0.1.0"), [])

    def test_missing_required_section_is_reported(self) -> None:
        text = VALID.replace("### Improved\n\n- None.\n", "")
        problems = check_changelog.validate_text(text, "0.1.0")
        self.assertTrue(any("Improved" in problem for problem in problems), problems)

    def test_version_heading_must_match_workspace(self) -> None:
        problems = check_changelog.validate_text(VALID, "0.2.0")
        self.assertTrue(any("0.2.0" in problem for problem in problems), problems)

    def test_extract_returns_the_named_release_body(self) -> None:
        body = check_changelog.extract_notes(VALID, "v0.1.0")
        self.assertIn("### Added", body)
        self.assertIn("First public release.", body)
        self.assertTrue(body.startswith("## [0.1.0] - 2026-08-16"))

    def test_extract_unknown_tag_raises(self) -> None:
        with self.assertRaises(check_changelog.ChangelogError):
            check_changelog.extract_notes(VALID, "v9.9.9")

    def test_repo_changelog_matches_workspace_version(self) -> None:
        repo = Path(__file__).resolve().parent.parent
        version = check_changelog.workspace_version(repo / "Cargo.toml")
        problems = check_changelog.validate_path(repo / "CHANGELOG.md", version)
        self.assertEqual(problems, [], problems)


class FileHelperTests(unittest.TestCase):
    def test_validate_path_missing_file(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            path = Path(tmp) / "CHANGELOG.md"
            problems = check_changelog.validate_path(path, "0.1.0")
        self.assertTrue(any("missing" in problem.lower() for problem in problems), problems)


if __name__ == "__main__":
    unittest.main()