test_checkout_symbol_symlog_ref.py
python
sha256:b1e8171f3a34834bb8eb9b5a111e9365ae9735403e6ed67b7177ecfea9a1f548
feat: muse#53 item 7 — checkout-symbol accepts embedded sym…
Sonnet 5
patch
15 hours ago
| 1 | """muse#53 item 7 -- `muse code checkout-symbol "file.py::Symbol@{N}"`. |
| 2 | |
| 3 | ADDRESS may embed a symlog ref directly instead of requiring a separate |
| 4 | --commit flag -- the natural extension of `muse code cat`/`muse symlog |
| 5 | resolve`'s addr@{N} syntax: cat reads, checkout-symbol restores. |
| 6 | """ |
| 7 | |
| 8 | from __future__ import annotations |
| 9 | |
| 10 | import json |
| 11 | import pathlib |
| 12 | import textwrap |
| 13 | |
| 14 | import pytest |
| 15 | |
| 16 | from tests.cli_test_helper import CliRunner |
| 17 | |
| 18 | cli = None |
| 19 | runner = CliRunner() |
| 20 | |
| 21 | |
| 22 | @pytest.fixture |
| 23 | def repo(tmp_path: pathlib.Path, monkeypatch: pytest.MonkeyPatch) -> pathlib.Path: |
| 24 | monkeypatch.chdir(tmp_path) |
| 25 | monkeypatch.setenv("MUSE_REPO_ROOT", str(tmp_path)) |
| 26 | result = runner.invoke(cli, ["init", "--domain", "code"]) |
| 27 | assert result.exit_code == 0, result.output |
| 28 | return tmp_path |
| 29 | |
| 30 | |
| 31 | @pytest.fixture |
| 32 | def two_commit_repo(repo: pathlib.Path) -> pathlib.Path: |
| 33 | (repo / "billing.py").write_text(textwrap.dedent("""\ |
| 34 | def compute(items): |
| 35 | return sum(items) |
| 36 | """)) |
| 37 | runner.invoke(cli, ["code", "add", "."]) |
| 38 | r1 = runner.invoke(cli, ["commit", "-m", "v1"]) |
| 39 | assert r1.exit_code == 0, r1.output |
| 40 | |
| 41 | (repo / "billing.py").write_text(textwrap.dedent("""\ |
| 42 | def compute(items): |
| 43 | return sum(items) * 2 |
| 44 | """)) |
| 45 | runner.invoke(cli, ["code", "add", "."]) |
| 46 | r2 = runner.invoke(cli, ["commit", "-m", "v2"]) |
| 47 | assert r2.exit_code == 0, r2.output |
| 48 | return repo |
| 49 | |
| 50 | |
| 51 | class TestCheckoutSymbolWithSymlogRef: |
| 52 | def test_restores_older_version_via_symlog_ref(self, two_commit_repo: pathlib.Path) -> None: |
| 53 | result = runner.invoke( |
| 54 | cli, ["code", "checkout-symbol", "billing.py::compute@{1}", "--json"], |
| 55 | ) |
| 56 | assert result.exit_code == 0, result.output |
| 57 | data = json.loads(result.output) |
| 58 | assert data["changed"] is True |
| 59 | assert data["address"] == "billing.py::compute" |
| 60 | |
| 61 | content = (two_commit_repo / "billing.py").read_text() |
| 62 | assert "* 2" not in content |
| 63 | assert "return sum(items)" in content |
| 64 | |
| 65 | def test_at_index_0_is_a_noop(self, two_commit_repo: pathlib.Path) -> None: |
| 66 | result = runner.invoke( |
| 67 | cli, ["code", "checkout-symbol", "billing.py::compute@{0}", "--json"], |
| 68 | ) |
| 69 | assert result.exit_code == 0, result.output |
| 70 | data = json.loads(result.output) |
| 71 | assert data["changed"] is False |
| 72 | |
| 73 | content = (two_commit_repo / "billing.py").read_text() |
| 74 | assert "* 2" in content |
| 75 | |
| 76 | def test_symlog_ref_and_commit_flag_together_errors(self, two_commit_repo: pathlib.Path) -> None: |
| 77 | result = runner.invoke( |
| 78 | cli, [ |
| 79 | "code", "checkout-symbol", "billing.py::compute@{1}", |
| 80 | "--commit", "HEAD", "--json", |
| 81 | ], |
| 82 | ) |
| 83 | assert result.exit_code != 0 |
| 84 | |
| 85 | def test_out_of_range_index_errors(self, two_commit_repo: pathlib.Path) -> None: |
| 86 | result = runner.invoke( |
| 87 | cli, ["code", "checkout-symbol", "billing.py::compute@{99}", "--json"], |
| 88 | ) |
| 89 | assert result.exit_code != 0 |
| 90 | |
| 91 | def test_plain_address_without_commit_still_errors(self, two_commit_repo: pathlib.Path) -> None: |
| 92 | """Non-regression: a plain address (no @{N}) still requires --commit.""" |
| 93 | result = runner.invoke( |
| 94 | cli, ["code", "checkout-symbol", "billing.py::compute", "--json"], |
| 95 | ) |
| 96 | assert result.exit_code != 0 |
| 97 | |
| 98 | def test_plain_address_with_commit_still_works(self, two_commit_repo: pathlib.Path) -> None: |
| 99 | """Non-regression: the original --commit REF form still works.""" |
| 100 | result = runner.invoke( |
| 101 | cli, ["code", "checkout-symbol", "billing.py::compute", "--commit", "HEAD~1", "--json"], |
| 102 | ) |
| 103 | assert result.exit_code == 0, result.output |
| 104 | data = json.loads(result.output) |
| 105 | assert data["changed"] is True |
File History
1 commit
sha256:b1e8171f3a34834bb8eb9b5a111e9365ae9735403e6ed67b7177ecfea9a1f548
feat: muse#53 item 7 — checkout-symbol accepts embedded sym…
Sonnet 5
patch
15 hours ago