diff --git a/tests/test_cli.py b/tests/test_cli.py index 4713a50..4786a6c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -5,7 +5,7 @@ from unittest.mock import MagicMock, patch from click.testing import CliRunner -from bin.cli import cli +from myclaude.cli import cli class TestCliHelp: @@ -51,21 +51,24 @@ class TestCliDefaultBehavior: runner = CliRunner() with ( - patch("bin.cli.shutil.which", return_value="/usr/bin/claude"), - patch("bin.cli.subprocess.run") as mock_run, + patch("myclaude.cli.shutil.which", return_value="/usr/bin/claude"), + patch("myclaude.cli.subprocess.run") as mock_run, ): mock_run.return_value = MagicMock(returncode=0) result = runner.invoke(cli, []) assert result.exit_code == 0 mock_run.assert_called_once() call_args = mock_run.call_args - assert call_args[0][0] == ["/usr/bin/claude", "--dangerously-skip-permissions"] + assert call_args[0][0] == [ + "/usr/bin/claude", + "--dangerously-skip-permissions", + ] def test_missing_claude_binary_error(self) -> None: """Should exit with error when claude binary not found.""" runner = CliRunner() - with patch("bin.cli.shutil.which", return_value=None): + with patch("myclaude.cli.shutil.which", return_value=None): result = runner.invoke(cli, []) assert result.exit_code == 127 assert "not found" in result.output.lower() @@ -77,8 +80,8 @@ class TestCliDefaultBehavior: test_dir.mkdir() with ( - patch("bin.cli.shutil.which", return_value="/usr/bin/claude"), - patch("bin.cli.subprocess.run") as mock_run, + patch("myclaude.cli.shutil.which", return_value="/usr/bin/claude"), + patch("myclaude.cli.subprocess.run") as mock_run, ): mock_run.return_value = MagicMock(returncode=0) result = runner.invoke(cli, ["--cwd", str(test_dir)]) @@ -94,3 +97,51 @@ class TestCliDefaultBehavior: result = runner.invoke(cli, ["--cwd", str(bad_dir)]) assert result.exit_code == 1 assert "not a directory" in result.output.lower() + + +class TestCliPassthrough: + """Unknown leading flags forward to claude instead of erroring.""" + + def _invoke(self, args: list[str], tmp_path: Path) -> list[str]: + """Run cli with mocked claude and return the command claude was called with.""" + runner = CliRunner() + with ( + patch("myclaude.cli.shutil.which", return_value="/usr/bin/claude"), + patch("myclaude.cli.subprocess.run") as mock_run, + ): + mock_run.return_value = MagicMock(returncode=0) + result = runner.invoke(cli, ["--cwd", str(tmp_path), *args]) + assert result.exit_code == 0, result.output + mock_run.assert_called_once() + return mock_run.call_args[0][0] + + def test_resume_flag_passes_through(self, tmp_path: Path) -> None: + """`--resume` must reach claude, not be parsed as a subcommand.""" + cmd = self._invoke(["--resume"], tmp_path) + assert cmd == [ + "/usr/bin/claude", + "--dangerously-skip-permissions", + "--resume", + ] + + def test_resume_with_session_id(self, tmp_path: Path) -> None: + """`-r ` forwards both the flag and its value.""" + cmd = self._invoke(["-r", "abc123"], tmp_path) + assert cmd[-2:] == ["-r", "abc123"] + + def test_continue_flag_passes_through(self, tmp_path: Path) -> None: + cmd = self._invoke(["--continue"], tmp_path) + assert cmd[-1] == "--continue" + + +class TestCliListSessions: + """`--list` reports resumable sessions without launching claude.""" + + def test_list_empty_directory(self, tmp_path: Path) -> None: + """A directory with no recorded sessions reports none and exits 0.""" + runner = CliRunner() + with patch("myclaude.cli.subprocess.run") as mock_run: + result = runner.invoke(cli, ["--cwd", str(tmp_path), "--list"]) + assert result.exit_code == 0 + assert "no sessions" in result.output.lower() + mock_run.assert_not_called() diff --git a/tests/test_project_root.py b/tests/test_project_root.py index 2cbc721..6887f57 100644 --- a/tests/test_project_root.py +++ b/tests/test_project_root.py @@ -4,7 +4,7 @@ import os from pathlib import Path from unittest.mock import patch -from bin.project_root import get_myclaude_project_root, get_workspace_root +from myclaude.project_root import get_myclaude_project_root, get_workspace_root class TestGetMyclaudeProjectRoot: @@ -44,7 +44,7 @@ class TestGetMyclaudeProjectRoot: patch.dict(os.environ, {}, clear=True), patch("pathlib.Path.cwd", side_effect=OSError), patch( - "bin.project_root._pyproject_names_myclaude", + "myclaude.project_root._pyproject_names_myclaude", return_value=False, ), ): @@ -95,7 +95,7 @@ class TestGetWorkspaceRoot: with ( patch.dict(os.environ, {}, clear=True), patch( - "bin.project_root.get_myclaude_project_root", + "myclaude.project_root.get_myclaude_project_root", return_value=tmp_path / ".myclaude", ), patch("pathlib.Path.home", return_value=home),