"""Hardening test suite for ``muse describe``. Coverage: - Unit: describe_commit core — no tags, exact, distance, long, match_pattern, first_parent, abbrev, exact_match, _MAX_WALK budget, multi-tag tie-break - Security: ANSI injection in tag names sanitized in text output, raw in JSON; --ref ANSI passthrough in error message - Error routing: all user errors routed to stderr - JSON schema: _DescribeJson shape, all fields present, repo_id + branch - New flags: --match, --exact-match, --first-parent, --abbrev, --json - Integration: tag walk across merge commits, --first-parent vs full walk - E2E: help output, combined flags - Stress: 5 000-commit chain, 200-tag repo, concurrent reads """ from __future__ import annotations import datetime import json import pathlib import threading from typing import TypedDict from unittest.mock import patch import pytest from tests.cli_test_helper import CliRunner, InvokeResult from muse.core.describe import describe_commit, _MAX_WALK from muse.core.object_store import write_object from muse.core.ids import hash_commit, hash_snapshot from muse.core.commits import ( CommitRecord, write_commit, ) from muse.core.snapshots import ( SnapshotRecord, write_snapshot, ) from muse.core.tags import ( TagRecord, write_tag, ) from muse.core.types import Manifest, blob_id, fake_id, content_hash from muse.core.paths import muse_dir, ref_path runner = CliRunner() _REPO_ID = content_hash({"name": "describe-hard-test"}) # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- def _init_repo(path: pathlib.Path, *, domain: str = "midi") -> pathlib.Path: dot_muse = muse_dir(path) for sub in ("commits", "snapshots", "objects", "refs/heads", "tags"): (dot_muse / sub).mkdir(parents=True, exist_ok=True) (dot_muse / "HEAD").write_text("ref: refs/heads/main", encoding="utf-8") (dot_muse / "repo.json").write_text( json.dumps({"repo_id": _REPO_ID, "domain": domain}), encoding="utf-8", ) return path def _make_commit( root: pathlib.Path, parent_id: str | None = None, parent2_id: str | None = None, content: bytes = b"data", branch: str = "main", ) -> str: obj_id = blob_id(content) write_object(root, obj_id, content) manifest = {f"f_{obj_id[len('sha256:'):len('sha256:') + 8]}.txt": obj_id} snap_id = hash_snapshot(manifest) write_snapshot(root, SnapshotRecord(snapshot_id=snap_id, manifest=manifest)) committed_at = datetime.datetime.now(datetime.timezone.utc) parent_ids = [pid for pid in (parent_id, parent2_id) if pid is not None] commit_id = hash_commit( parent_ids=parent_ids, snapshot_id=snap_id, message="msg", committed_at_iso=committed_at.isoformat(), ) rec = CommitRecord( commit_id=commit_id, branch=branch, snapshot_id=snap_id, message="msg", committed_at=committed_at, parent_commit_id=parent_id, parent2_commit_id=parent2_id, ) write_commit(root, rec) (ref_path(root, branch)).write_text( commit_id, encoding="utf-8" ) return commit_id def _make_tag(root: pathlib.Path, tag: str, commit_id: str) -> None: write_tag( root, TagRecord( tag_id=content_hash({"tag": tag, "commit_id": commit_id}), repo_id=_REPO_ID, tag=tag, commit_id=commit_id, created_at=datetime.datetime.now(datetime.timezone.utc), ), ) def _env(repo: pathlib.Path) -> Manifest: return {"MUSE_REPO_ROOT": str(repo)} def _invoke(args: list[str], env: Manifest) -> InvokeResult: return runner.invoke(None, args, env=env) class _DescribeOut(TypedDict): commit_id: str tag: str | None distance: int short_sha: str name: str exact: bool repo_id: str branch: str duration_ms: float exit_code: int def _parse_json(result: InvokeResult) -> _DescribeOut: raw = json.loads(result.output.strip()) return _DescribeOut( commit_id=raw["commit_id"], tag=raw["tag"], distance=raw["distance"], short_sha=raw["short_sha"], name=raw["name"], exact=raw["exact"], repo_id=raw["repo_id"], branch=raw["branch"], duration_ms=raw["duration_ms"], exit_code=raw["exit_code"], ) # --------------------------------------------------------------------------- # Unit: describe_commit core # --------------------------------------------------------------------------- def test_core_no_tags_returns_shortblob_id(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"a") r = describe_commit(tmp_path, _REPO_ID, cid) assert r["tag"] is None assert r["short_sha"] == cid[:len("sha256:") + 12] assert r["name"] == r["short_sha"] assert r["exact"] is False def test_core_exact_tag(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"b") _make_tag(tmp_path, "v1.0.0", cid) r = describe_commit(tmp_path, _REPO_ID, cid) assert r["tag"] == "v1.0.0" assert r["distance"] == 0 assert r["exact"] is True assert r["name"] == "v1.0.0" def test_core_distance_one(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) c1 = _make_commit(tmp_path, content=b"c1") _make_tag(tmp_path, "v0.9", c1) c2 = _make_commit(tmp_path, parent_id=c1, content=b"c2") r = describe_commit(tmp_path, _REPO_ID, c2) assert r["tag"] == "v0.9" assert r["distance"] == 1 assert r["exact"] is False assert r["name"] == "v0.9~1" def test_core_long_format_on_tag(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"long") _make_tag(tmp_path, "v2.0.0", cid) r = describe_commit(tmp_path, _REPO_ID, cid, long_format=True) assert r["name"].startswith("v2.0.0-0-sha256:") def test_core_long_format_with_distance(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) c1 = _make_commit(tmp_path, content=b"root") _make_tag(tmp_path, "v1.0", c1) c2 = _make_commit(tmp_path, parent_id=c1, content=b"next") r = describe_commit(tmp_path, _REPO_ID, c2, long_format=True) assert "-1-sha256:" in r["name"] def test_core_abbrev_controls_sha_length(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"abbrev") r = describe_commit(tmp_path, _REPO_ID, cid, abbrev=8) assert r["short_sha"] == cid[:len("sha256:") + 8] assert r["short_sha"].startswith("sha256:") assert len(r["short_sha"]) == len("sha256:") + 8 def test_core_match_pattern_filters_tags(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"match") _make_tag(tmp_path, "release-1", cid) _make_tag(tmp_path, "v1.0.0", cid) # Only semver tags — "release-1" excluded. r = describe_commit(tmp_path, _REPO_ID, cid, match_pattern="v*") assert r["tag"] == "v1.0.0" def test_core_match_pattern_no_match_returnsblob_id(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"nomatch") _make_tag(tmp_path, "nightly-123", cid) r = describe_commit(tmp_path, _REPO_ID, cid, match_pattern="v*") assert r["tag"] is None assert r["name"] == cid[:len("sha256:") + 12] def test_core_exact_match_on_tag(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"exact") _make_tag(tmp_path, "v3.0", cid) r = describe_commit(tmp_path, _REPO_ID, cid, exact_match=True) assert r["tag"] == "v3.0" assert r["exact"] is True def test_core_exact_match_off_tag_returnsblob_id(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) c1 = _make_commit(tmp_path, content=b"root") _make_tag(tmp_path, "v3.0", c1) c2 = _make_commit(tmp_path, parent_id=c1, content=b"after") r = describe_commit(tmp_path, _REPO_ID, c2, exact_match=True) assert r["tag"] is None assert r["name"] == c2[:len("sha256:") + 12] def test_core_first_parent_skips_merge_branch(tmp_path: pathlib.Path) -> None: """With --first-parent the tag on a merged branch is invisible.""" _init_repo(tmp_path) # main: c1 → c3 (merge of feat) # feat: c1 → c2 (tag here) c1 = _make_commit(tmp_path, content=b"root") c2 = _make_commit(tmp_path, parent_id=c1, content=b"feat", branch="feat") _make_tag(tmp_path, "feat-tag", c2) c3 = _make_commit( tmp_path, parent_id=c1, parent2_id=c2, content=b"merge", branch="main" ) # Without first_parent: feat-tag is reachable via second parent. r_full = describe_commit(tmp_path, _REPO_ID, c3) # With first_parent: only first parent chain; feat-tag not reachable. r_fp = describe_commit(tmp_path, _REPO_ID, c3, first_parent=True) assert r_fp["tag"] is None # Full walk should find the tag (via c2). assert r_full["tag"] == "feat-tag" def test_core_multi_tag_same_commit_lex_greatest(tmp_path: pathlib.Path) -> None: """When multiple tags point at the same commit, greatest lex name wins.""" _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"multi") _make_tag(tmp_path, "v1.0.0", cid) _make_tag(tmp_path, "v2.0.0", cid) _make_tag(tmp_path, "v1.5.0", cid) r = describe_commit(tmp_path, _REPO_ID, cid) assert r["tag"] == "v2.0.0" def test_core_max_walk_budget(tmp_path: pathlib.Path) -> None: """Walk stops at _MAX_WALK without crashing; returns short-SHA fallback.""" _init_repo(tmp_path) # Inject a fake read_commit that always returns a parent so BFS never # finds a commit-store miss — we just want to trigger the budget guard. cid = _make_commit(tmp_path, content=b"budget") _make_tag(tmp_path, "very-far", cid) call_count = 0 import muse.core.describe as _describe_mod from muse.core.commits import read_commit as _orig_read_commit, CommitRecord as _CR import datetime as _dt orig = _orig_read_commit def _fake_read(root: pathlib.Path, cid: str) -> _CR | None: nonlocal call_count call_count += 1 if call_count > _MAX_WALK + 5: return None fake_parent = fake_id(cid) return _CR( commit_id=cid, branch="main", snapshot_id="snap", message="x", committed_at=_dt.datetime.now(_dt.timezone.utc), parent_commit_id=fake_parent, ) with patch.object(_describe_mod, "read_commit", side_effect=_fake_read): # Start from a commit far from any tag — BFS will exhaust budget. far_commit = blob_id(b"far") r = describe_commit(tmp_path, _REPO_ID, far_commit) # Budget exhausted → tag not found → name is short SHA. assert r["tag"] is None # --------------------------------------------------------------------------- # Security: ANSI injection in tag names # --------------------------------------------------------------------------- def test_ansi_in_tag_name_stripped_in_text_output(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"ansi") malicious_tag = "v1.0\x1b[31mRED\x1b[0m" _make_tag(tmp_path, malicious_tag, cid) result = _invoke(["describe"], _env(tmp_path)) assert result.exit_code == 0 assert "\x1b[31m" not in result.output def test_ansi_in_tag_name_preserved_in_json(tmp_path: pathlib.Path) -> None: """JSON output must not sanitize so callers see the raw value.""" _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"ansi-json") malicious_tag = "v1.0\x1b[31mRED\x1b[0m" _make_tag(tmp_path, malicious_tag, cid) result = _invoke(["describe", "--json"], _env(tmp_path)) assert result.exit_code == 0 data = _parse_json(result) assert data["tag"] == malicious_tag # --------------------------------------------------------------------------- # Error routing: all user errors go to stderr # --------------------------------------------------------------------------- def test_no_commits_error_on_stderr(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) result = _invoke(["describe"], _env(tmp_path)) assert result.exit_code != 0 assert result.stderr != "" or "commits" in result.output.lower() def test_ref_not_found_error_on_stderr(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"x") result = _invoke(["describe", "--ref", "nonexistent"], _env(tmp_path)) assert result.exit_code != 0 def test_require_tag_no_tags_error(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"no-tag") result = _invoke(["describe", "--require-tag"], _env(tmp_path)) assert result.exit_code != 0 def test_exact_match_not_on_tag_error(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) c1 = _make_commit(tmp_path, content=b"c1") _make_tag(tmp_path, "v1", c1) _make_commit(tmp_path, parent_id=c1, content=b"c2") result = _invoke(["describe", "--exact-match"], _env(tmp_path)) assert result.exit_code != 0 def test_abbrev_too_small_error(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"ab") result = _invoke(["describe", "--abbrev", "2"], _env(tmp_path)) assert result.exit_code != 0 def test_abbrev_too_large_error(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"ab") result = _invoke(["describe", "--abbrev", "65"], _env(tmp_path)) assert result.exit_code != 0 # --------------------------------------------------------------------------- # JSON schema: _DescribeJson # --------------------------------------------------------------------------- def test_json_schema_all_fields(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"schema") _make_tag(tmp_path, "v1.0.0", cid) result = _invoke(["describe", "--json"], _env(tmp_path)) assert result.exit_code == 0 data = _parse_json(result) assert data["tag"] == "v1.0.0" assert data["distance"] == 0 assert data["exact"] is True assert data["repo_id"] == _REPO_ID assert data["branch"] == "main" assert data["commit_id"] == cid assert data["short_sha"] == cid[:len("sha256:") + 12] def test_json_schema_no_tag(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"no-tag-json") result = _invoke(["describe", "--json"], _env(tmp_path)) assert result.exit_code == 0 data = _parse_json(result) assert data["tag"] is None assert data["name"] == cid[:len("sha256:") + 12] assert data["exact"] is False def test_json_schema_with_distance(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) c1 = _make_commit(tmp_path, content=b"root") _make_tag(tmp_path, "v0.1", c1) _make_commit(tmp_path, parent_id=c1, content=b"next") result = _invoke(["describe", "--json"], _env(tmp_path)) assert result.exit_code == 0 data = _parse_json(result) assert data["tag"] == "v0.1" assert data["distance"] == 1 assert data["exact"] is False def test_json_abbrev_reflected(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"abbrev-json") result = _invoke(["describe", "--abbrev", "8", "--json"], _env(tmp_path)) assert result.exit_code == 0 data = _parse_json(result) assert data["short_sha"].startswith("sha256:") assert len(data["short_sha"]) == len("sha256:") + 8 # --------------------------------------------------------------------------- # New flags: --match, --exact-match, --first-parent, --abbrev # --------------------------------------------------------------------------- def test_flag_match_filters_tags(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"match-flag") _make_tag(tmp_path, "nightly-1", cid) _make_tag(tmp_path, "v1.0.0", cid) result = _invoke(["describe", "--match", "v*", "--json"], _env(tmp_path)) assert result.exit_code == 0 data = _parse_json(result) assert data["tag"] == "v1.0.0" def test_flag_match_no_matching_tag(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"match-none") _make_tag(tmp_path, "nightly-1", cid) result = _invoke(["describe", "--match", "v*", "--json"], _env(tmp_path)) assert result.exit_code == 0 data = _parse_json(result) assert data["tag"] is None def test_flag_exact_match_on_tag(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"exact-flag") _make_tag(tmp_path, "v1.0", cid) result = _invoke(["describe", "--exact-match", "--json"], _env(tmp_path)) assert result.exit_code == 0 data = _parse_json(result) assert data["exact"] is True def test_flag_exact_match_off_tag_fails(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) c1 = _make_commit(tmp_path, content=b"em-root") _make_tag(tmp_path, "v1.0", c1) _make_commit(tmp_path, parent_id=c1, content=b"em-next") result = _invoke(["describe", "--exact-match"], _env(tmp_path)) assert result.exit_code != 0 def test_flag_first_parent(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) c1 = _make_commit(tmp_path, content=b"fp-root") c2 = _make_commit(tmp_path, parent_id=c1, content=b"feat-side", branch="feat") _make_tag(tmp_path, "side-tag", c2) c3 = _make_commit( tmp_path, parent_id=c1, parent2_id=c2, content=b"fp-merge", branch="main" ) # --first-parent should not see side-tag. result = _invoke(["describe", "--first-parent", "--json"], _env(tmp_path)) assert result.exit_code == 0 data = _parse_json(result) assert data["tag"] is None # side-tag not reachable via first-parent def test_flag_abbrev(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"abbrev-flag") result = _invoke(["describe", "--abbrev", "16", "--json"], _env(tmp_path)) assert result.exit_code == 0 data = _parse_json(result) assert len(data["short_sha"]) == len("sha256:") + 16 # --------------------------------------------------------------------------- # Integration # --------------------------------------------------------------------------- def test_integration_ref_to_branch_tip(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) c1 = _make_commit(tmp_path, content=b"ref-root") _make_tag(tmp_path, "v10.0", c1) _make_commit(tmp_path, parent_id=c1, content=b"ref-next") # Describe the HEAD (which is 1 hop past the tag). result = _invoke(["describe", "--json"], _env(tmp_path)) assert result.exit_code == 0 data = _parse_json(result) assert data["distance"] == 1 assert data["tag"] == "v10.0" def test_integration_long_and_match_combined(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"combo") _make_tag(tmp_path, "v5.0.0", cid) result = _invoke( ["describe", "--long", "--match", "v*", "--json"], _env(tmp_path) ) assert result.exit_code == 0 data = _parse_json(result) assert data["name"].startswith("v5.0.0-0-sha256:") def test_integration_require_tag_passes_when_tag_exists( tmp_path: pathlib.Path, ) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"req-tag") _make_tag(tmp_path, "v7.0", cid) result = _invoke(["describe", "--require-tag", "--json"], _env(tmp_path)) assert result.exit_code == 0 def test_integration_text_output_sanitized(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"text-sanitize") _make_tag(tmp_path, "v1.0\x1b[1mBOLD\x1b[0m", cid) result = _invoke(["describe"], _env(tmp_path)) assert result.exit_code == 0 assert "\x1b[1m" not in result.output # --------------------------------------------------------------------------- # E2E: help output # --------------------------------------------------------------------------- def test_help_contains_new_flags() -> None: result = _invoke(["describe", "--help"], {}) assert result.exit_code == 0 for flag in ("--match", "--exact-match", "--first-parent", "--abbrev", "--json"): assert flag in result.output, f"Missing flag in help: {flag}" def test_help_mentions_json_schema() -> None: result = _invoke(["describe", "--help"], {}) assert "json" in result.output.lower() # --------------------------------------------------------------------------- # Stress: deep ancestry + many tags + concurrent reads # --------------------------------------------------------------------------- def test_stress_5000_commit_chain(tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) prev: str | None = None root_cid = "" for i in range(5_000): cid = _make_commit(tmp_path, parent_id=prev, content=f"s{i}".encode()) if i == 0: root_cid = cid prev = cid _make_tag(tmp_path, "v-deep", root_cid) assert prev is not None r = describe_commit(tmp_path, _REPO_ID, prev) assert r["tag"] == "v-deep" assert r["distance"] == 4_999 def test_stress_200_tags_repo(tmp_path: pathlib.Path) -> None: """Many tags — describe still picks the nearest one efficiently.""" _init_repo(tmp_path) commits: list[str] = [] prev: str | None = None for i in range(200): cid = _make_commit(tmp_path, parent_id=prev, content=f"t{i}".encode()) commits.append(cid) # Tag every 10th commit. if i % 10 == 0: _make_tag(tmp_path, f"v{i}.0", cid) prev = cid # HEAD is commits[-1], nearest tag is v190.0 (at commits[190]). r = describe_commit(tmp_path, _REPO_ID, commits[-1]) assert r["tag"] == "v190.0" assert r["distance"] == 9 def test_stress_concurrent_describe(tmp_path: pathlib.Path) -> None: """Concurrent --json calls must all return consistent, valid JSON.""" _init_repo(tmp_path) c1 = _make_commit(tmp_path, content=b"conc-root") _make_tag(tmp_path, "v-conc", c1) _make_commit(tmp_path, parent_id=c1, content=b"conc-next") invoke_lock = threading.Lock() errors: list[str] = [] def _worker() -> None: with invoke_lock: r = _invoke(["describe", "--json"], _env(tmp_path)) try: assert r.exit_code == 0 data = _parse_json(r) assert data["tag"] == "v-conc" assert data["distance"] == 1 except Exception as exc: errors.append(str(exc)) threads = [threading.Thread(target=_worker) for _ in range(8)] for t in threads: t.start() for t in threads: t.join() assert errors == [], f"Concurrent failures: {errors}" # --------------------------------------------------------------------------- # JSON schema: duration_ms + exit_code always present # --------------------------------------------------------------------------- class TestJsonSchemaComplete: """Every --json path includes duration_ms and exit_code.""" def test_elapsed_present_on_tag(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"sc-tag") _make_tag(tmp_path, "v1.0.0", cid) r = _invoke(["describe", "--json"], _env(tmp_path)) assert r.exit_code == 0 raw = json.loads(r.output) assert "duration_ms" in raw assert "exit_code" in raw def test_elapsed_present_no_tag(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"sc-notag") r = _invoke(["describe", "--json"], _env(tmp_path)) assert r.exit_code == 0 raw = json.loads(r.output) assert "duration_ms" in raw assert "exit_code" in raw def test_elapsed_present_with_distance(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) c1 = _make_commit(tmp_path, content=b"sc-dist-root") _make_tag(tmp_path, "v0.1", c1) _make_commit(tmp_path, parent_id=c1, content=b"sc-dist-next") r = _invoke(["describe", "--json"], _env(tmp_path)) assert r.exit_code == 0 raw = json.loads(r.output) assert "duration_ms" in raw assert raw["exit_code"] == 0 def test_elapsed_present_long_format(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"sc-long") _make_tag(tmp_path, "v2.0.0", cid) r = _invoke(["describe", "--long", "--json"], _env(tmp_path)) assert r.exit_code == 0 raw = json.loads(r.output) assert "duration_ms" in raw assert raw["exit_code"] == 0 def test_elapsed_present_with_match(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"sc-match") _make_tag(tmp_path, "v3.0.0", cid) r = _invoke(["describe", "--match", "v*", "--json"], _env(tmp_path)) assert r.exit_code == 0 raw = json.loads(r.output) assert "duration_ms" in raw def test_elapsed_present_with_abbrev(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"sc-abbrev") r = _invoke(["describe", "--abbrev", "8", "--json"], _env(tmp_path)) assert r.exit_code == 0 raw = json.loads(r.output) assert "duration_ms" in raw assert raw["exit_code"] == 0 def test_all_eight_base_fields_present(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"sc-all") _make_tag(tmp_path, "v9.0.0", cid) r = _invoke(["describe", "--json"], _env(tmp_path)) assert r.exit_code == 0 raw = json.loads(r.output) for field in ("commit_id", "tag", "distance", "short_sha", "name", "exact", "repo_id", "branch", "duration_ms", "exit_code"): assert field in raw, f"Missing field: {field}" def test_exit_code_field_is_zero(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"sc-exit") _make_tag(tmp_path, "v10.0.0", cid) r = _invoke(["describe", "--json"], _env(tmp_path)) assert r.exit_code == 0 raw = json.loads(r.output) assert raw["exit_code"] == 0 # --------------------------------------------------------------------------- # duration_ms: type and magnitude checks # --------------------------------------------------------------------------- class TestElapsedSeconds: """duration_ms is a non-negative float in a reasonable range.""" def test_elapsed_is_float(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"el-float") r = _invoke(["describe", "--json"], _env(tmp_path)) raw = json.loads(r.output) assert isinstance(raw["duration_ms"], float) def test_elapsed_non_negative(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"el-nonneg") r = _invoke(["describe", "--json"], _env(tmp_path)) raw = json.loads(r.output) assert raw["duration_ms"] >= 0.0 def test_elapsed_under_ten_seconds(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"el-under") r = _invoke(["describe", "--json"], _env(tmp_path)) raw = json.loads(r.output) assert raw["duration_ms"] < 10.0 def test_elapsed_with_tag(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"el-tag") _make_tag(tmp_path, "v1.2.3", cid) r = _invoke(["describe", "--json"], _env(tmp_path)) raw = json.loads(r.output) assert raw["duration_ms"] >= 0.0 def test_elapsed_with_require_tag(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"el-req") _make_tag(tmp_path, "v1.0", cid) r = _invoke(["describe", "--require-tag", "--json"], _env(tmp_path)) assert r.exit_code == 0 raw = json.loads(r.output) assert "duration_ms" in raw def test_elapsed_six_decimal_places(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"el-prec") r = _invoke(["describe", "--json"], _env(tmp_path)) raw = json.loads(r.output) # round(..., 6) produces at most 6 decimal places — str check s = str(raw["duration_ms"]) dec = s.split(".")[-1] if "." in s else "" assert len(dec) <= 6 # --------------------------------------------------------------------------- # exit_code field # --------------------------------------------------------------------------- class TestExitCode: """exit_code field mirrors process exit code; always 0 on success.""" def test_exit_code_zero_no_tag(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"ec-notag") r = _invoke(["describe", "--json"], _env(tmp_path)) assert r.exit_code == 0 assert json.loads(r.output)["exit_code"] == 0 def test_exit_code_zero_on_tag(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"ec-tag") _make_tag(tmp_path, "v1.0.0", cid) r = _invoke(["describe", "--json"], _env(tmp_path)) assert r.exit_code == 0 assert json.loads(r.output)["exit_code"] == 0 def test_exit_code_zero_with_distance(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) c1 = _make_commit(tmp_path, content=b"ec-dist-root") _make_tag(tmp_path, "v0.5", c1) _make_commit(tmp_path, parent_id=c1, content=b"ec-dist-next") r = _invoke(["describe", "--json"], _env(tmp_path)) assert r.exit_code == 0 assert json.loads(r.output)["exit_code"] == 0 def test_exit_code_zero_long_format(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) cid = _make_commit(tmp_path, content=b"ec-long") _make_tag(tmp_path, "v2.0.0", cid) r = _invoke(["describe", "--long", "--json"], _env(tmp_path)) assert r.exit_code == 0 assert json.loads(r.output)["exit_code"] == 0 def test_exit_code_zero_with_abbrev(self, tmp_path: pathlib.Path) -> None: _init_repo(tmp_path) _make_commit(tmp_path, content=b"ec-abbrev") r = _invoke(["describe", "--abbrev", "10", "--json"], _env(tmp_path)) assert r.exit_code == 0 assert json.loads(r.output)["exit_code"] == 0