gabriel / muse public
test_describe_walk.py python
134 lines 4.3 KB
Raw
sha256:c0eba5ad689cec79f4a3fcdc4f5da78556cb4b8cb7b330f944634356c10379ed chore: pivot to nightly channel — bump version to 0.2.0.dev… Sonnet 5 patch 12 days ago
1 """TDD — describe_commit BFS must use walk_dag, not inline deque.
2
3 DC1 Structural — describe_commit uses walk_dag; no inline deque BFS
4 DC2 Behavioural — finds nearest version tag with correct distance
5 """
6 from __future__ import annotations
7
8 import datetime
9 import inspect
10 import json
11 import pathlib
12
13 import pytest
14
15 from muse._version import __version__
16 from muse.core.object_store import write_object
17 from muse.core.ids import hash_commit as compute_commit_id, hash_snapshot as compute_snapshot_id
18 from muse.core.commits import (
19 CommitRecord,
20 write_commit,
21 )
22 from muse.core.snapshots import (
23 SnapshotRecord,
24 write_snapshot,
25 )
26 from muse.core.version_tags import VersionTagRecord, write_version_tag
27 from muse.core.semver import parse_semver
28 from muse.core.types import blob_id, content_hash
29 from muse.core.paths import muse_dir
30
31 _REPO_ID = content_hash({"name": "walk-test"})
32
33
34 def _repo(tmp_path: pathlib.Path, monkeypatch: pytest.MonkeyPatch) -> pathlib.Path:
35 dot_muse = muse_dir(tmp_path)
36 for d in ("commits", "snapshots", "objects", "refs/heads", "remotes", "version-tags"):
37 (dot_muse / d).mkdir(parents=True, exist_ok=True)
38 (dot_muse / "HEAD").write_text("ref: refs/heads/main\n")
39 (dot_muse / "repo.json").write_text(
40 json.dumps({"repo_id": _REPO_ID, "schema_version": __version__, "domain": "code"})
41 )
42 monkeypatch.setenv("MUSE_REPO_ROOT", str(tmp_path))
43 monkeypatch.chdir(tmp_path)
44 return tmp_path
45
46
47 def _make_commit(
48 root: pathlib.Path,
49 parent_id: str | None = None,
50 *,
51 message: str = "test",
52 ) -> CommitRecord:
53 oid = blob_id(b"data-" + message.encode())
54 write_object(root, oid, b"data-" + message.encode())
55 manifest = {"f.py": oid}
56 snap_id = compute_snapshot_id(manifest)
57 write_snapshot(root, SnapshotRecord(snapshot_id=snap_id, manifest=manifest))
58 ts = datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc)
59 cid = compute_commit_id(
60 parent_ids=[parent_id] if parent_id else [],
61 snapshot_id=snap_id,
62 message=message,
63 committed_at_iso=ts.isoformat(),
64 )
65 rec = CommitRecord(
66 commit_id=cid,
67 branch="main",
68 snapshot_id=snap_id,
69 message=message,
70 committed_at=ts,
71 parent_commit_id=parent_id,
72 )
73 write_commit(root, rec)
74 return rec
75
76
77 def _make_vtag(root: pathlib.Path, tag: str, commit_id: str) -> None:
78 write_version_tag(root, VersionTagRecord(
79 tag_id=content_hash({"tag": tag, "commit_id": commit_id}),
80 repo_id=_REPO_ID,
81 tag=tag,
82 semver=parse_semver(tag),
83 commit_id=commit_id,
84 created_at=datetime.datetime.now(datetime.timezone.utc),
85 author="",
86 message="",
87 ))
88
89
90 # ---------------------------------------------------------------------------
91 # DC1 Structural
92 # ---------------------------------------------------------------------------
93
94 def test_dc1_describe_commit_uses_walk_dag() -> None:
95 """describe_commit must not contain an inline deque BFS."""
96 from muse.core import describe as describe_mod
97
98 src = inspect.getsource(describe_mod.describe_commit)
99
100 assert "walk_dag" in src, (
101 "describe_commit must delegate its BFS to walk_dag. "
102 "Replace the inline deque queue."
103 )
104 assert "deque" not in src, (
105 "describe_commit still uses an inline deque. Replace with walk_dag."
106 )
107
108
109 # ---------------------------------------------------------------------------
110 # DC2 Behavioural — nearest version tag with correct distance
111 # ---------------------------------------------------------------------------
112
113 def test_dc2_describe_commit_distance(
114 tmp_path: pathlib.Path,
115 monkeypatch: pytest.MonkeyPatch,
116 ) -> None:
117 """describe_commit returns distance=2 when HEAD is 2 hops after the tag.
118
119 Chain: C1(tag=v1.0.0) → C2 → C3(HEAD)
120 Expected: tag=v1.0.0, distance=2.
121 """
122 from muse.core.describe import describe_commit
123
124 root = _repo(tmp_path, monkeypatch)
125 c1 = _make_commit(root, message="c1")
126 c2 = _make_commit(root, c1.commit_id, message="c2")
127 c3 = _make_commit(root, c2.commit_id, message="c3")
128
129 _make_vtag(root, "v1.0.0", c1.commit_id)
130
131 result = describe_commit(root, _REPO_ID, c3.commit_id)
132
133 assert result["tag"] == "v1.0.0", f"Expected tag=v1.0.0, got {result['tag']}"
134 assert result["distance"] == 2, f"Expected distance=2, got {result['distance']}"
File History 10 commits
sha256:c287f599c5429903a139eadf3c5db5d930520e57cb0c3c575d9570e953c3b2d6 chore: bump version to 0.2.0.dev2 — nightly.2 Sonnet 4.6 patch 11 days ago
sha256:8de4334a98c945aace420969d389ad678aa926d4ab4e886b2ac4c4241cb3bf2b revert: keep pyproject.toml in canonical PEP 440 form Sonnet 4.6 patch 14 days ago
sha256:50bb615c573aa4b928fca75b60f82ba2a659910066507cec6a95c412ae22ccb9 docs: add issue docs for push have-negotiation bug (#55) an… Sonnet 4.6 18 days ago
sha256:d90d175cded68aae1d4ffcf4858917854195d0cd8ce1fe73cee4dbc02541cb74 chore: trigger push to surface null-OID paths Sonnet 4.6 23 days ago
sha256:e452ad9a6ace6ccc6d875a35e06caf9da5576a970c1c36133b69a891ce5fefa8 chore: prebuild timing test Sonnet 4.6 33 days ago
sha256:0008ab6695e3e064b3e236b24fd19e538fef6a588eb0d211622f4466d919c0b1 merge: pull staging/dev — advance to 0.2.0rc12 Sonnet 4.6 patch 35 days ago
sha256:9c33d61749fff814c5226d5386aa2af7064c2c02788594a25fdd709358132eea fix: _PROPOSAL_PREFIX_RESOLVE_LIMIT 200 → 100 to match hub … Sonnet 4.6 47 days ago
sha256:36c3cb3e76619d4c30a6d9bf81b5ec4ff148e30dcfed913e3114ca7b43b81c7e fix: rename objects→blobs in push client and all stale test… Sonnet 4.6 patch 49 days ago
sha256:c06a9b9b9fee26c68ea725b44d54b2c0a171301ce9de746d5b656617b4463a9a fix: repair four test failures from post-migration audit Sonnet 4.6 patch 56 days ago
sha256:1900655993c83c4107067375548a7be823e471d2515830842f1a12cba4bd3cdf fix: unified object store migration — idempotent writes, JS… Sonnet 4.6 minor 56 days ago