"""muse#53 item 7 -- `muse code checkout-symbol "file.py::Symbol@{N}"`. ADDRESS may embed a symlog ref directly instead of requiring a separate --commit flag -- the natural extension of `muse code cat`/`muse symlog resolve`'s addr@{N} syntax: cat reads, checkout-symbol restores. """ from __future__ import annotations import json import pathlib import textwrap import pytest from tests.cli_test_helper import CliRunner cli = None runner = CliRunner() @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)) result = runner.invoke(cli, ["init", "--domain", "code"]) assert result.exit_code == 0, result.output return tmp_path @pytest.fixture def two_commit_repo(repo: pathlib.Path) -> pathlib.Path: (repo / "billing.py").write_text(textwrap.dedent("""\ def compute(items): return sum(items) """)) runner.invoke(cli, ["code", "add", "."]) r1 = runner.invoke(cli, ["commit", "-m", "v1"]) assert r1.exit_code == 0, r1.output (repo / "billing.py").write_text(textwrap.dedent("""\ def compute(items): return sum(items) * 2 """)) runner.invoke(cli, ["code", "add", "."]) r2 = runner.invoke(cli, ["commit", "-m", "v2"]) assert r2.exit_code == 0, r2.output return repo class TestCheckoutSymbolWithSymlogRef: def test_restores_older_version_via_symlog_ref(self, two_commit_repo: pathlib.Path) -> None: result = runner.invoke( cli, ["code", "checkout-symbol", "billing.py::compute@{1}", "--json"], ) assert result.exit_code == 0, result.output data = json.loads(result.output) assert data["changed"] is True assert data["address"] == "billing.py::compute" content = (two_commit_repo / "billing.py").read_text() assert "* 2" not in content assert "return sum(items)" in content def test_at_index_0_is_a_noop(self, two_commit_repo: pathlib.Path) -> None: result = runner.invoke( cli, ["code", "checkout-symbol", "billing.py::compute@{0}", "--json"], ) assert result.exit_code == 0, result.output data = json.loads(result.output) assert data["changed"] is False content = (two_commit_repo / "billing.py").read_text() assert "* 2" in content def test_symlog_ref_and_commit_flag_together_errors(self, two_commit_repo: pathlib.Path) -> None: result = runner.invoke( cli, [ "code", "checkout-symbol", "billing.py::compute@{1}", "--commit", "HEAD", "--json", ], ) assert result.exit_code != 0 def test_out_of_range_index_errors(self, two_commit_repo: pathlib.Path) -> None: result = runner.invoke( cli, ["code", "checkout-symbol", "billing.py::compute@{99}", "--json"], ) assert result.exit_code != 0 def test_plain_address_without_commit_still_errors(self, two_commit_repo: pathlib.Path) -> None: """Non-regression: a plain address (no @{N}) still requires --commit.""" result = runner.invoke( cli, ["code", "checkout-symbol", "billing.py::compute", "--json"], ) assert result.exit_code != 0 def test_plain_address_with_commit_still_works(self, two_commit_repo: pathlib.Path) -> None: """Non-regression: the original --commit REF form still works.""" result = runner.invoke( cli, ["code", "checkout-symbol", "billing.py::compute", "--commit", "HEAD~1", "--json"], ) assert result.exit_code == 0, result.output data = json.loads(result.output) assert data["changed"] is True