gabriel / muse public
test_cmd_diff.py python
132 lines 5.0 KB
86000da9 fix: replace typer CliRunner with argparse-compatible test helper Gabriel Cardona <gabriel@tellurstori.com> 1d ago
1 """Comprehensive tests for ``muse diff``.
2
3 Covers:
4 - E2E: CLI flags (--commit / -c, --format json/text, --plugin)
5 - Integration: diff HEAD vs working tree
6 - Stress: diff with many files
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 tests.cli_test_helper import CliRunner
18
19 cli = None # argparse migration — CliRunner ignores this arg
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",
51 manifest: dict[str, str] | None = None) -> str:
52 from muse.core.store import CommitRecord, SnapshotRecord, write_commit, write_snapshot
53 from muse.core.snapshot import compute_snapshot_id, compute_commit_id
54
55 ref_file = root / ".muse" / "refs" / "heads" / "main"
56 parent_id = ref_file.read_text().strip() if ref_file.exists() else None
57 m = manifest or {}
58 snap_id = compute_snapshot_id(m)
59 committed_at = datetime.datetime.now(datetime.timezone.utc)
60 commit_id = compute_commit_id(
61 parent_ids=[parent_id] if parent_id else [],
62 snapshot_id=snap_id, message=message,
63 committed_at_iso=committed_at.isoformat(),
64 )
65 write_snapshot(root, SnapshotRecord(snapshot_id=snap_id, manifest=m))
66 write_commit(root, CommitRecord(
67 commit_id=commit_id, repo_id=repo_id, branch="main",
68 snapshot_id=snap_id, message=message, committed_at=committed_at,
69 parent_commit_id=parent_id,
70 ))
71 ref_file.parent.mkdir(parents=True, exist_ok=True)
72 ref_file.write_text(commit_id, encoding="utf-8")
73 return commit_id
74
75
76 # ---------------------------------------------------------------------------
77 # Tests
78 # ---------------------------------------------------------------------------
79
80 class TestDiffCLI:
81 def test_diff_empty_repo(self, tmp_path: pathlib.Path) -> None:
82 root, _ = _init_repo(tmp_path)
83 result = runner.invoke(cli, ["diff"], env=_env(root), catch_exceptions=False)
84 assert result.exit_code == 0
85
86 def test_diff_after_commit_no_changes(self, tmp_path: pathlib.Path) -> None:
87 root, repo_id = _init_repo(tmp_path)
88 _make_commit(root, repo_id)
89 result = runner.invoke(cli, ["diff"], env=_env(root), catch_exceptions=False)
90 assert result.exit_code == 0
91
92 def test_diff_shows_added_files(self, tmp_path: pathlib.Path) -> None:
93 root, repo_id = _init_repo(tmp_path)
94 _make_commit(root, repo_id)
95 (root / "new_song.mid").write_bytes(b"MIDI data here")
96 result = runner.invoke(cli, ["diff"], env=_env(root), catch_exceptions=False)
97 assert result.exit_code == 0
98 assert "new_song.mid" in result.output
99
100 def test_diff_format_json(self, tmp_path: pathlib.Path) -> None:
101 root, repo_id = _init_repo(tmp_path)
102 _make_commit(root, repo_id)
103 result = runner.invoke(cli, ["diff", "--format", "json"], env=_env(root), catch_exceptions=False)
104 assert result.exit_code == 0
105 data = json.loads(result.output)
106 assert isinstance(data, (dict, list))
107
108 def test_diff_between_two_commits(self, tmp_path: pathlib.Path) -> None:
109 root, repo_id = _init_repo(tmp_path)
110 commit1 = _make_commit(root, repo_id, message="first")
111 commit2 = _make_commit(root, repo_id, message="second")
112 result = runner.invoke(
113 cli, ["diff", commit1, commit2],
114 env=_env(root), catch_exceptions=False
115 )
116 assert result.exit_code == 0
117
118 def test_diff_output_clean_no_exception(self, tmp_path: pathlib.Path) -> None:
119 root, repo_id = _init_repo(tmp_path)
120 _make_commit(root, repo_id)
121 result = runner.invoke(cli, ["diff"], env=_env(root))
122 assert result.exception is None
123
124
125 class TestDiffStress:
126 def test_diff_with_many_changed_files(self, tmp_path: pathlib.Path) -> None:
127 root, repo_id = _init_repo(tmp_path)
128 _make_commit(root, repo_id)
129 for i in range(50):
130 (root / f"track_{i:03d}.mid").write_bytes(f"data {i}".encode())
131 result = runner.invoke(cli, ["diff"], env=_env(root), catch_exceptions=False)
132 assert result.exit_code == 0