gabriel / muse public
test_cmd_worktree.py python
136 lines 4.9 KB
95b86799 feat: add --format json to all porcelain commands for agent-first output Gabriel Cardona <gabriel@tellurstori.com> 2d ago
1 """Comprehensive tests for ``muse worktree``.
2
3 Covers:
4 - E2E: add, list, remove worktrees
5 - Integration: worktree directory created and removed
6 - Security: sanitized path output
7 """
8
9 from __future__ import annotations
10
11 import datetime
12 import json
13 import pathlib
14 import uuid
15
16 import pytest
17 from typer.testing import CliRunner
18
19 from muse.cli.app import cli
20
21 runner = CliRunner()
22
23
24 # ---------------------------------------------------------------------------
25 # Shared helpers
26 # ---------------------------------------------------------------------------
27
28 def _env(root: pathlib.Path) -> dict[str, str]:
29 return {"MUSE_REPO_ROOT": str(root)}
30
31
32 def _init_repo(tmp_path: pathlib.Path) -> tuple[pathlib.Path, str]:
33 muse_dir = tmp_path / ".muse"
34 muse_dir.mkdir()
35 repo_id = str(uuid.uuid4())
36 (muse_dir / "repo.json").write_text(json.dumps({
37 "repo_id": repo_id,
38 "domain": "midi",
39 "default_branch": "main",
40 "created_at": "2025-01-01T00:00:00+00:00",
41 }), encoding="utf-8")
42 (muse_dir / "HEAD").write_text("ref: refs/heads/main", encoding="utf-8")
43 (muse_dir / "refs" / "heads").mkdir(parents=True)
44 (muse_dir / "snapshots").mkdir()
45 (muse_dir / "commits").mkdir()
46 (muse_dir / "objects").mkdir()
47 return tmp_path, repo_id
48
49
50 def _make_commit(root: pathlib.Path, repo_id: str, message: str = "test") -> str:
51 from muse.core.store import CommitRecord, SnapshotRecord, write_commit, write_snapshot
52 from muse.core.snapshot import compute_snapshot_id, compute_commit_id
53
54 ref_file = root / ".muse" / "refs" / "heads" / "main"
55 parent_id = ref_file.read_text().strip() if ref_file.exists() else None
56 manifest: dict[str, str] = {}
57 snap_id = compute_snapshot_id(manifest)
58 committed_at = datetime.datetime.now(datetime.timezone.utc)
59 commit_id = compute_commit_id(
60 parent_ids=[parent_id] if parent_id else [],
61 snapshot_id=snap_id, message=message,
62 committed_at_iso=committed_at.isoformat(),
63 )
64 write_snapshot(root, SnapshotRecord(snapshot_id=snap_id, manifest=manifest))
65 write_commit(root, CommitRecord(
66 commit_id=commit_id, repo_id=repo_id, branch="main",
67 snapshot_id=snap_id, message=message, committed_at=committed_at,
68 parent_commit_id=parent_id,
69 ))
70 ref_file.parent.mkdir(parents=True, exist_ok=True)
71 ref_file.write_text(commit_id, encoding="utf-8")
72 return commit_id
73
74
75 # ---------------------------------------------------------------------------
76 # Tests
77 # ---------------------------------------------------------------------------
78
79 class TestWorktreeCLI:
80 def test_worktree_list_empty(self, tmp_path: pathlib.Path) -> None:
81 root, _ = _init_repo(tmp_path)
82 result = runner.invoke(cli, ["worktree", "list"], env=_env(root), catch_exceptions=False)
83 assert result.exit_code == 0
84
85 def test_worktree_add_creates_directory(self, tmp_path: pathlib.Path) -> None:
86 root, repo_id = _init_repo(tmp_path)
87 _make_commit(root, repo_id)
88 result = runner.invoke(
89 cli, ["worktree", "add", "my-wt", "main"],
90 env=_env(root), catch_exceptions=False
91 )
92 assert result.exit_code == 0
93
94 def test_worktree_list_after_add(self, tmp_path: pathlib.Path) -> None:
95 root, repo_id = _init_repo(tmp_path)
96 _make_commit(root, repo_id)
97 runner.invoke(
98 cli, ["worktree", "add", "my-wt2", "main"],
99 env=_env(root), catch_exceptions=False
100 )
101 result = runner.invoke(cli, ["worktree", "list"], env=_env(root), catch_exceptions=False)
102 assert result.exit_code == 0
103
104 def test_worktree_remove(self, tmp_path: pathlib.Path) -> None:
105 root, repo_id = _init_repo(tmp_path)
106 _make_commit(root, repo_id)
107 runner.invoke(
108 cli, ["worktree", "add", "rm-wt", "main"],
109 env=_env(root), catch_exceptions=False
110 )
111 result = runner.invoke(
112 cli, ["worktree", "remove", "rm-wt"],
113 env=_env(root), catch_exceptions=False
114 )
115 assert result.exit_code == 0
116
117 def test_worktree_list_format_json(self, tmp_path: pathlib.Path) -> None:
118 root, _ = _init_repo(tmp_path)
119 result = runner.invoke(
120 cli, ["worktree", "list", "--format", "json"],
121 env=_env(root), catch_exceptions=False
122 )
123 assert result.exit_code == 0
124 data = json.loads(result.output)
125 assert isinstance(data, list)
126
127 def test_worktree_output_sanitized(self, tmp_path: pathlib.Path) -> None:
128 root, repo_id = _init_repo(tmp_path)
129 _make_commit(root, repo_id)
130 result = runner.invoke(cli, ["worktree", "list"], env=_env(root), catch_exceptions=False)
131 assert "\x1b" not in result.output
132
133 def test_worktree_remove_nonexistent_fails(self, tmp_path: pathlib.Path) -> None:
134 root, _ = _init_repo(tmp_path)
135 result = runner.invoke(cli, ["worktree", "remove", "nonexistent"], env=_env(root))
136 assert result.exit_code != 0