"""TDD — describe_commit BFS must use walk_dag, not inline deque. DC1 Structural — describe_commit uses walk_dag; no inline deque BFS DC2 Behavioural — finds nearest tag with correct distance """ from __future__ import annotations import datetime import inspect import json import pathlib import pytest from muse._version import __version__ from muse.core.object_store import write_object from muse.core.ids import hash_commit as compute_commit_id, hash_snapshot as compute_snapshot_id from muse.core.commits import ( CommitRecord, write_commit, ) from muse.core.snapshots import ( SnapshotRecord, write_snapshot, ) from muse.core.types import blob_id from muse.core.paths import muse_dir def _repo(tmp_path: pathlib.Path, monkeypatch: pytest.MonkeyPatch) -> pathlib.Path: dot_muse = muse_dir(tmp_path) for d in ("commits", "snapshots", "objects", "refs/heads", "remotes"): (dot_muse / d).mkdir(parents=True, exist_ok=True) (dot_muse / "HEAD").write_text("ref: refs/heads/main\n") (dot_muse / "repo.json").write_text( json.dumps({"repo_id": "test-repo", "schema_version": __version__, "domain": "code"}) ) monkeypatch.setenv("MUSE_REPO_ROOT", str(tmp_path)) monkeypatch.chdir(tmp_path) return tmp_path def _make_commit( root: pathlib.Path, parent_id: str | None = None, *, message: str = "test", ) -> CommitRecord: oid = blob_id(b"data-" + message.encode()) write_object(root, oid, b"data-" + message.encode()) manifest = {"f.py": oid} snap_id = compute_snapshot_id(manifest) write_snapshot(root, SnapshotRecord(snapshot_id=snap_id, manifest=manifest)) ts = datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc) cid = compute_commit_id( parent_ids=[parent_id] if parent_id else [], snapshot_id=snap_id, message=message, committed_at_iso=ts.isoformat(), ) rec = CommitRecord( commit_id=cid, branch="main", snapshot_id=snap_id, message=message, committed_at=ts, parent_commit_id=parent_id, ) write_commit(root, rec) return rec # --------------------------------------------------------------------------- # DC1 Structural # --------------------------------------------------------------------------- def test_dc1_describe_commit_uses_walk_dag() -> None: """describe_commit must not contain an inline deque BFS.""" from muse.core import describe as describe_mod src = inspect.getsource(describe_mod.describe_commit) assert "walk_dag" in src, ( "describe_commit must delegate its BFS to walk_dag. " "Replace the inline deque queue." ) assert "deque" not in src, ( "describe_commit still uses an inline deque. Replace with walk_dag." ) # --------------------------------------------------------------------------- # DC2 Behavioural — nearest tag with correct distance # --------------------------------------------------------------------------- def test_dc2_describe_commit_distance( tmp_path: pathlib.Path, monkeypatch: pytest.MonkeyPatch, ) -> None: """describe_commit returns distance=2 when HEAD is 2 hops after the tag. Chain: C1(tag=v1.0) → C2 → C3(HEAD) Expected: tag=v1.0, distance=2. """ import muse.core.describe as describe_mod from muse.core.describe import describe_commit from muse.core.tags import TagRecord root = _repo(tmp_path, monkeypatch) c1 = _make_commit(root, message="c1") c2 = _make_commit(root, c1.commit_id, message="c2") c3 = _make_commit(root, c2.commit_id, message="c3") fake_tag = TagRecord( tag_id="tag-v1", repo_id="test-repo", tag="v1.0", commit_id=c1.commit_id, ) monkeypatch.setattr(describe_mod, "get_all_tags", lambda root, repo_id: [fake_tag]) result = describe_commit(root, "test-repo", c3.commit_id) assert result["tag"] == "v1.0", f"Expected tag=v1.0, got {result['tag']}" assert result["distance"] == 2, f"Expected distance=2, got {result['distance']}"