- Merge nested with statements in test_project_root.py - Reformat multi-line calls in test_cli.py and update.py
102 lines
3.6 KiB
Python
102 lines
3.6 KiB
Python
"""Tests for myclaude.cli."""
|
|
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from click.testing import CliRunner
|
|
|
|
from bin.cli import cli
|
|
|
|
|
|
class TestCliHelp:
|
|
"""Tests for CLI help and basic invocation."""
|
|
|
|
def test_help_shows_options(self) -> None:
|
|
"""--help should show cwd and skip permissions options."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["--help"])
|
|
assert result.exit_code == 0
|
|
assert "--cwd" in result.output
|
|
assert "--dangerously-skip-permissions" in result.output
|
|
|
|
def test_version_shows_version(self) -> None:
|
|
"""--version should show package version."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["--version"])
|
|
assert result.exit_code == 0
|
|
assert "version" in result.output.lower()
|
|
|
|
def test_update_subcommand_exists(self) -> None:
|
|
"""update subcommand should be registered."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["update", "--help"])
|
|
assert result.exit_code == 0
|
|
assert (
|
|
"update" in result.output.lower()
|
|
or "reinstall" in result.output.lower()
|
|
)
|
|
|
|
def test_upgrade_alias_exists(self) -> None:
|
|
"""upgrade should be an alias for update."""
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli, ["upgrade", "--help"])
|
|
assert result.exit_code == 0
|
|
|
|
|
|
class TestCliDefaultBehavior:
|
|
"""Tests for default chat behavior."""
|
|
|
|
def test_no_subcommand_runs_claude(self) -> None:
|
|
"""Running without subcommand should invoke claude binary."""
|
|
runner = CliRunner()
|
|
|
|
with (
|
|
patch("bin.cli.shutil.which", return_value="/usr/bin/claude"),
|
|
patch("bin.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"]
|
|
|
|
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):
|
|
result = runner.invoke(cli, [])
|
|
assert result.exit_code == 127
|
|
assert "not found" in result.output.lower()
|
|
|
|
def test_cwd_option_passed(self, tmp_path: Path) -> None:
|
|
"""--cwd should be passed as working directory."""
|
|
runner = CliRunner()
|
|
test_dir = tmp_path / "test_cwd"
|
|
test_dir.mkdir()
|
|
|
|
with (
|
|
patch("bin.cli.shutil.which", return_value="/usr/bin/claude"),
|
|
patch("bin.cli.subprocess.run") as mock_run,
|
|
):
|
|
mock_run.return_value = MagicMock(returncode=0)
|
|
result = runner.invoke(cli, ["--cwd", str(test_dir)])
|
|
assert result.exit_code == 0
|
|
call_kwargs = mock_run.call_args.kwargs
|
|
assert call_kwargs.get("cwd") == str(test_dir.resolve())
|
|
|
|
def test_dangerously_skip_permissions_flag(self) -> None:
|
|
"""--dangerously-skip-permissions should be forwarded."""
|
|
runner = CliRunner()
|
|
|
|
with (
|
|
patch("bin.cli.shutil.which", return_value="/usr/bin/claude"),
|
|
patch("bin.cli.subprocess.run") as mock_run,
|
|
):
|
|
mock_run.return_value = MagicMock(returncode=0)
|
|
result = runner.invoke(cli, ["--dangerously-skip-permissions"])
|
|
assert result.exit_code == 0
|
|
call_args = mock_run.call_args[0][0]
|
|
assert "--dangerously-skip-permissions" in call_args
|