gabriel / muse public
test_bundle_reachable_from.py python
115 lines 3.6 KB
Raw
sha256:81ae324db5ad375fbfe4834c6fcb378312cafad3cc92dec5d3e5c427306621a2 fix: remove commit_exists filter from have anchors — server… Sonnet 4.6 patch 20 days ago
1 """TDD — bundle._reachable_from must use ancestor_ids, not inline deque BFS.
2
3 B1 Structural — _reachable_from contains no inline deque/seen BFS
4 B2 Behavioural — returns all commit IDs reachable from tip_ids
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, hash_snapshot
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.types import blob_id
27 from muse.core.paths import muse_dir
28
29
30 def _repo(tmp_path: pathlib.Path, monkeypatch: pytest.MonkeyPatch) -> pathlib.Path:
31 dot_muse = muse_dir(tmp_path)
32 for d in ("commits", "snapshots", "objects", "refs/heads", "remotes"):
33 (dot_muse / d).mkdir(parents=True, exist_ok=True)
34 (dot_muse / "HEAD").write_text("ref: refs/heads/main\n")
35 (dot_muse / "repo.json").write_text(
36 json.dumps({"repo_id": "test-repo", "schema_version": __version__, "domain": "code"})
37 )
38 monkeypatch.setenv("MUSE_REPO_ROOT", str(tmp_path))
39 monkeypatch.chdir(tmp_path)
40 return tmp_path
41
42
43 def _make_commit(
44 root: pathlib.Path,
45 parent_id: str | None = None,
46 *,
47 message: str = "test",
48 ) -> CommitRecord:
49 oid = blob_id(b"data-" + message.encode())
50 write_object(root, oid, b"data-" + message.encode())
51 manifest = {"f.py": oid}
52 snap_id = hash_snapshot(manifest)
53 write_snapshot(root, SnapshotRecord(snapshot_id=snap_id, manifest=manifest))
54 ts = datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc)
55 cid = hash_commit(
56 parent_ids=[parent_id] if parent_id else [],
57 snapshot_id=snap_id,
58 message=message,
59 committed_at_iso=ts.isoformat(),
60 )
61 rec = CommitRecord(
62 commit_id=cid,
63 branch="main",
64 snapshot_id=snap_id,
65 message=message,
66 committed_at=ts,
67 parent_commit_id=parent_id,
68 )
69 write_commit(root, rec)
70 return rec
71
72
73 # ---------------------------------------------------------------------------
74 # B1 Structural
75 # ---------------------------------------------------------------------------
76
77 def test_b1_reachable_from_uses_ancestor_ids() -> None:
78 """_reachable_from must not contain an inline deque BFS."""
79 from muse.cli.commands import bundle as bundle_mod
80
81 src = inspect.getsource(bundle_mod._reachable_from) # type: ignore[attr-defined]
82
83 assert "ancestor_ids" in src, (
84 "_reachable_from must delegate to ancestor_ids. "
85 "Replace the inline deque BFS."
86 )
87 assert "deque" not in src, (
88 "_reachable_from still uses an inline deque. Replace with ancestor_ids."
89 )
90
91
92 # ---------------------------------------------------------------------------
93 # B2 Behavioural
94 # ---------------------------------------------------------------------------
95
96 def test_b2_reachable_from_returns_all_reachable(
97 tmp_path: pathlib.Path,
98 monkeypatch: pytest.MonkeyPatch,
99 ) -> None:
100 """_reachable_from returns every commit ID reachable from the tips.
101
102 Chain: C1 → C2 → C3. Starting from C3, all three must be returned.
103 """
104 from muse.cli.commands.bundle import _reachable_from # type: ignore[attr-defined]
105
106 root = _repo(tmp_path, monkeypatch)
107 c1 = _make_commit(root, message="c1")
108 c2 = _make_commit(root, c1.commit_id, message="c2")
109 c3 = _make_commit(root, c2.commit_id, message="c3")
110
111 result = _reachable_from(root, [c3.commit_id])
112
113 assert c1.commit_id in result
114 assert c2.commit_id in result
115 assert c3.commit_id in result
File History 4 commits
sha256:81ae324db5ad375fbfe4834c6fcb378312cafad3cc92dec5d3e5c427306621a2 fix: remove commit_exists filter from have anchors — server… Sonnet 4.6 patch 20 days ago
sha256:36c3cb3e76619d4c30a6d9bf81b5ec4ff148e30dcfed913e3114ca7b43b81c7e fix: rename objects→blobs in push client and all stale test… Sonnet 4.6 patch 22 days ago
sha256:c06a9b9b9fee26c68ea725b44d54b2c0a171301ce9de746d5b656617b4463a9a fix: repair four test failures from post-migration audit Sonnet 4.6 patch 28 days ago
sha256:1900655993c83c4107067375548a7be823e471d2515830842f1a12cba4bd3cdf fix: unified object store migration — idempotent writes, JS… Sonnet 4.6 minor 29 days ago