"""muse#53 item 11 -- symlog entries for `muse revert`. `muse revert` records a reflog entry for the branch ref move, but previously wrote no symlog entries for the symbols it touched. A revert of a commit that modified a symbol should produce a symbol-modified entry in that symbol's journal, just like a normal `muse commit` would. """ from __future__ import annotations import json import pathlib from collections.abc import Mapping import pytest from tests.cli_test_helper import CliRunner cli = None runner = CliRunner() def _env(root: pathlib.Path) -> Mapping[str, str]: return {"MUSE_REPO_ROOT": str(root)} @pytest.fixture() def repo(tmp_path: pathlib.Path, monkeypatch: pytest.MonkeyPatch) -> pathlib.Path: monkeypatch.chdir(tmp_path) monkeypatch.setenv("MUSE_REPO_ROOT", str(tmp_path)) r = runner.invoke(cli, ["init"], env=_env(tmp_path), catch_exceptions=False) assert r.exit_code == 0, r.output return tmp_path def _write(repo: pathlib.Path, rel: str, content: str) -> None: p = repo / rel p.parent.mkdir(parents=True, exist_ok=True) p.write_text(content) def _commit(repo: pathlib.Path, msg: str) -> str: runner.invoke(cli, ["code", "add", "."], env=_env(repo), catch_exceptions=False) result = runner.invoke(cli, ["commit", "-m", msg, "--json"], env=_env(repo), catch_exceptions=False) assert result.exit_code == 0, result.output return json.loads(result.output)["commit_id"] def _symlog(repo: pathlib.Path, *args: str): return runner.invoke(cli, ["symlog", *args], env=_env(repo), catch_exceptions=False) class TestRevertWritesSymlog: def test_revert_of_symbol_modifying_commit_writes_symlog_entry(self, repo: pathlib.Path) -> None: _write(repo, "src/billing.py", "def compute_total(items):\n return sum(items)\n") _commit(repo, "add compute_total") _write(repo, "src/billing.py", "def compute_total(items):\n return sum(items) * 2\n") doubled_commit = _commit(repo, "double the total") # Before revert: 2 symlog entries (created + modified). before = json.loads(_symlog(repo, "src/billing.py::compute_total", "--json").output) assert before["total"] == 2 # Revert the "double the total" commit, restoring the prior body. result = runner.invoke( cli, ["revert", doubled_commit, "--json"], env=_env(repo), catch_exceptions=False, ) assert result.exit_code == 0, result.output after = json.loads(_symlog(repo, "src/billing.py::compute_total", "--json").output) assert after["total"] == 3 assert after["entries"][0]["operation"].startswith("symbol-modified") def test_revert_no_commit_does_not_write_symlog(self, repo: pathlib.Path) -> None: """--no-commit only stages changes -- no commit record exists yet, so there's nothing for a symlog entry to attach to.""" _write(repo, "src/billing.py", "def compute_total(items):\n return sum(items)\n") _commit(repo, "add compute_total") _write(repo, "src/billing.py", "def compute_total(items):\n return sum(items) * 2\n") doubled_commit = _commit(repo, "double the total") before = json.loads(_symlog(repo, "src/billing.py::compute_total", "--json").output) result = runner.invoke( cli, ["revert", doubled_commit, "--no-commit", "--json"], env=_env(repo), catch_exceptions=False, ) assert result.exit_code == 0, result.output after = json.loads(_symlog(repo, "src/billing.py::compute_total", "--json").output) assert after["total"] == before["total"]