"""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 option only.""" runner = CliRunner() result = runner.invoke(cli, ["--help"]) assert result.exit_code == 0 assert "--cwd" in result.output assert "--dangerously-skip-permissions" not 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 with skip-permissions.""" 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", "--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): 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_cwd_invalid_directory(self, tmp_path: Path) -> None: """--cwd pointing to non-existent directory should error.""" runner = CliRunner() bad_dir = tmp_path / "does_not_exist" result = runner.invoke(cli, ["--cwd", str(bad_dir)]) assert result.exit_code == 1 assert "not a directory" in result.output.lower()