From 62c8c68005cd8fa537901eb4e104c9c4f83e2a67 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Wed, 4 Feb 2026 16:49:42 +0000 Subject: [PATCH] Initial upload: Local Commit Message Generator v0.1.0 --- .../tests/test_cli.py | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 app/local_commit_message_generator/tests/test_cli.py diff --git a/app/local_commit_message_generator/tests/test_cli.py b/app/local_commit_message_generator/tests/test_cli.py new file mode 100644 index 0000000..4227bb8 --- /dev/null +++ b/app/local_commit_message_generator/tests/test_cli.py @@ -0,0 +1,139 @@ +"""Tests for CLI interface.""" + +import tempfile +from pathlib import Path +from unittest.mock import patch, MagicMock + +import pytest +from click.testing import CliRunner + +from src.cli import main + + +class TestMainGroup: + """Tests for main CLI group.""" + + def test_main_help(self): + """Test main command shows help.""" + runner = CliRunner() + result = runner.invoke(main, ["--help"]) + assert result.exit_code == 0 + assert "Generate conventional commit messages" in result.output + + def test_main_version(self): + """Test version flag works.""" + runner = CliRunner() + result = runner.invoke(main, ["--version"]) + assert result.exit_code == 0 + assert "local-commit-message-generator" in result.output + + +class TestGenerateCommand: + """Tests for generate command.""" + + def test_generate_handles_error(self): + """Test generate handles errors gracefully.""" + runner = CliRunner() + with patch('src.generator.generate_commit_message') as mock: + mock.side_effect = Exception("No staged changes") + result = runner.invoke(main, ["generate"]) + assert result.exit_code == 1 + + +class TestInstallHookCommand: + """Tests for install-hook command.""" + + def test_install_hook_no_git_dir(self): + """Test install hook fails without .git directory.""" + with tempfile.TemporaryDirectory() as tmpdir: + runner = CliRunner() + result = runner.invoke(main, ["install-hook"], obj={"repo": tmpdir}) + + assert result.exit_code != 0 + assert "not found" in result.output.lower() + + +class TestUninstallHookCommand: + """Tests for uninstall-hook command.""" + + def test_uninstall_hook_not_installed(self): + """Test uninstall when hook not installed.""" + with tempfile.TemporaryDirectory() as tmpdir: + git_dir = Path(tmpdir) / ".git" + hooks_dir = git_dir / "hooks" + hooks_dir.mkdir(parents=True) + + runner = CliRunner() + result = runner.invoke(main, ["uninstall-hook"], obj={"repo": tmpdir}) + + assert result.exit_code != 0 + + +class TestConfigCommand: + """Tests for config subcommand.""" + + def test_config_show(self): + """Test config show displays configuration.""" + runner = CliRunner() + result = runner.invoke(main, ["config", "show"]) + + assert result.exit_code == 0 + assert "Current Configuration" in result.output + assert "template" in result.output + + +class TestPreviewCommand: + """Tests for preview command.""" + + def test_preview_displays_message(self): + """Test preview displays message.""" + runner = CliRunner() + with patch('src.generator.get_commit_message_preview') as mock: + mock.return_value = ("feat: new feature", True) + result = runner.invoke(main, ["preview"]) + + assert result.exit_code == 0 + assert "Preview" in result.output + assert "feat: new feature" in result.output + + def test_preview_no_changes(self): + """Test preview with no changes.""" + runner = CliRunner() + with patch('src.generator.get_commit_message_preview') as mock: + mock.return_value = ("", False) + result = runner.invoke(main, ["preview"]) + + assert result.exit_code == 0 + assert "No staged changes" in result.output + + +class TestStatusCommand: + """Tests for status command.""" + + def test_status_with_changes(self): + """Test status shows changes.""" + runner = CliRunner() + with patch('src.analyzer.ChangeAnalyzer') as mock_analyzer: + from src.analyzer import ChangeSet, StagedChange, ChangeType + + mock_analyzer.return_value.get_staged_changes.return_value = ChangeSet([ + StagedChange("src/main.py", ChangeType.ADDED), + ]) + + result = runner.invoke(main, ["status"]) + + assert result.exit_code == 0 + assert "Staged changes" in result.output or "+" in result.output + + def test_status_no_changes(self): + """Test status with no changes.""" + runner = CliRunner() + with patch('src.analyzer.ChangeAnalyzer') as mock_analyzer: + from src.analyzer import ChangeSet + + mock_analyzer.return_value.get_staged_changes.return_value = ChangeSet([]) + + result = runner.invoke(main, ["status"]) + + assert result.exit_code == 0 + assert "No staged changes" in result.output