myclaude -r: 固定块 ANSI 重绘修复对齐与滚动冲突 + cli 测试 mock 修复
- picker 弃用 Live 整屏接管,改固定 12 行块增量重绘(\x1b[{n}A 回到块顶逐行覆盖),scrollback 不受影响
- 每行单行渲染,title 列定宽 43 + CJK 感知截断,布局按 80 列设计
- tests: 新增 TestPickerBlock;test_cli which mock 改 side_effect 只命中后端二进制,避免 _npm_global_bin 多跑 subprocess.run;裸 --resume 测试更新为新 picker 语义
This commit is contained in:
+41
-23
@@ -11,6 +11,20 @@ import myagents.launcher
|
||||
from myagents.cli import cli
|
||||
|
||||
|
||||
def _backend_which(*names: str):
|
||||
"""Patch ``shutil.which`` to find backend binaries and nothing else.
|
||||
|
||||
The launcher also probes ``which("npm")`` while resolving npm-global
|
||||
installs; returning None there keeps that probe from spawning a real
|
||||
``subprocess.run`` in tests (which would break ``assert_called_once``).
|
||||
"""
|
||||
|
||||
def _which(name: str) -> str | None:
|
||||
return f"/usr/bin/{name}" if name in names else None
|
||||
|
||||
return _which
|
||||
|
||||
|
||||
class TestMyagentsHelp:
|
||||
"""Tests for top-level myagents command."""
|
||||
|
||||
@@ -74,7 +88,7 @@ class TestClaudeSubcommand:
|
||||
def test_runs_claude(self) -> None:
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch("myagents.launcher.shutil.which", return_value="/usr/bin/claude"),
|
||||
patch("myagents.launcher.shutil.which", side_effect=_backend_which("claude")),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
@@ -99,7 +113,7 @@ class TestClaudeSubcommand:
|
||||
test_dir.mkdir()
|
||||
|
||||
with (
|
||||
patch("myagents.launcher.shutil.which", return_value="/usr/bin/claude"),
|
||||
patch("myagents.launcher.shutil.which", side_effect=_backend_which("claude")),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
@@ -121,7 +135,7 @@ class TestClaudePassthrough:
|
||||
def _invoke(self, args: list[str], tmp_path: Path) -> list[str]:
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch("myagents.launcher.shutil.which", return_value="/usr/bin/claude"),
|
||||
patch("myagents.launcher.shutil.which", side_effect=_backend_which("claude")),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
@@ -132,13 +146,17 @@ class TestClaudePassthrough:
|
||||
mock_run.assert_called_once()
|
||||
return mock_run.call_args[0][0]
|
||||
|
||||
def test_resume_flag_passes_through(self, tmp_path: Path) -> None:
|
||||
cmd = self._invoke(["--resume"], tmp_path)
|
||||
assert cmd == [
|
||||
"/usr/bin/claude",
|
||||
"--dangerously-skip-permissions",
|
||||
"--resume",
|
||||
]
|
||||
def test_bare_resume_opens_picker_not_launch(self, tmp_path: Path) -> None:
|
||||
"""Bare --resume opens the unified picker; non-tty lists and exits."""
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch("myagents.launcher.shutil.which", side_effect=_backend_which("claude")),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
result = runner.invoke(cli, ["claude", "--cwd", str(tmp_path), "--resume"])
|
||||
assert result.exit_code == 0, result.output
|
||||
mock_run.assert_not_called()
|
||||
|
||||
def test_resume_with_session_id(self, tmp_path: Path) -> None:
|
||||
cmd = self._invoke(["-r", "abc123"], tmp_path)
|
||||
@@ -175,7 +193,7 @@ class TestKimiSubcommand:
|
||||
def test_runs_kimi(self) -> None:
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch("myagents.launcher.shutil.which", return_value="/usr/bin/kimi"),
|
||||
patch("myagents.launcher.shutil.which", side_effect=_backend_which("kimi")),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
@@ -197,7 +215,7 @@ class TestKimiSubcommand:
|
||||
test_dir.mkdir()
|
||||
|
||||
with (
|
||||
patch("myagents.launcher.shutil.which", return_value="/usr/bin/kimi"),
|
||||
patch("myagents.launcher.shutil.which", side_effect=_backend_which("kimi")),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
@@ -212,7 +230,7 @@ class TestKimiPassthrough:
|
||||
def _invoke(self, args: list[str], tmp_path: Path) -> list[str]:
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch("myagents.launcher.shutil.which", return_value="/usr/bin/kimi"),
|
||||
patch("myagents.launcher.shutil.which", side_effect=_backend_which("kimi")),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
@@ -265,7 +283,7 @@ class TestCodexSubcommand:
|
||||
def test_runs_codex(self) -> None:
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch("myagents.launcher.shutil.which", return_value="/usr/bin/codex"),
|
||||
patch("myagents.launcher.shutil.which", side_effect=_backend_which("codex")),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
@@ -287,7 +305,7 @@ class TestCodexSubcommand:
|
||||
test_dir.mkdir()
|
||||
|
||||
with (
|
||||
patch("myagents.launcher.shutil.which", return_value="/usr/bin/codex"),
|
||||
patch("myagents.launcher.shutil.which", side_effect=_backend_which("codex")),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
@@ -302,7 +320,7 @@ class TestCodexPassthrough:
|
||||
def _invoke(self, args: list[str], tmp_path: Path) -> list[str]:
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch("myagents.launcher.shutil.which", return_value="/usr/bin/codex"),
|
||||
patch("myagents.launcher.shutil.which", side_effect=_backend_which("codex")),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
@@ -328,7 +346,7 @@ class TestCodexResumeOptions:
|
||||
def _invoke(self, args: list[str], tmp_path: Path) -> list[str]:
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch("myagents.launcher.shutil.which", return_value="/usr/bin/codex"),
|
||||
patch("myagents.launcher.shutil.which", side_effect=_backend_which("codex")),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
@@ -437,7 +455,7 @@ class TestHermesSubcommand:
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch(
|
||||
"myagents.launcher.shutil.which", return_value="/usr/bin/hermes"
|
||||
"myagents.launcher.shutil.which", side_effect=_backend_which("hermes")
|
||||
),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
@@ -461,7 +479,7 @@ class TestHermesSubcommand:
|
||||
|
||||
with (
|
||||
patch(
|
||||
"myagents.launcher.shutil.which", return_value="/usr/bin/hermes"
|
||||
"myagents.launcher.shutil.which", side_effect=_backend_which("hermes")
|
||||
),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
@@ -478,7 +496,7 @@ class TestHermesPassthrough:
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch(
|
||||
"myagents.launcher.shutil.which", return_value="/usr/bin/hermes"
|
||||
"myagents.launcher.shutil.which", side_effect=_backend_which("hermes")
|
||||
),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
@@ -616,7 +634,7 @@ class TestCursorSubcommand:
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch(
|
||||
"myagents.launcher.shutil.which", return_value="/usr/bin/agent"
|
||||
"myagents.launcher.shutil.which", side_effect=_backend_which("agent")
|
||||
),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
@@ -664,7 +682,7 @@ class TestCursorSubcommand:
|
||||
|
||||
with (
|
||||
patch(
|
||||
"myagents.launcher.shutil.which", return_value="/usr/bin/agent"
|
||||
"myagents.launcher.shutil.which", side_effect=_backend_which("agent")
|
||||
),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
@@ -681,7 +699,7 @@ class TestCursorPassthrough:
|
||||
runner = CliRunner()
|
||||
with (
|
||||
patch(
|
||||
"myagents.launcher.shutil.which", return_value="/usr/bin/agent"
|
||||
"myagents.launcher.shutil.which", side_effect=_backend_which("agent")
|
||||
),
|
||||
patch("myagents.launcher.subprocess.run") as mock_run,
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user