"""Tests for message_generator.py.""" from unittest.mock import MagicMock, patch import pytest from git_commit_generator.message_generator import MessageGenerator class TestMessageGenerator: """Test cases for MessageGenerator.""" @pytest.fixture def message_generator(self): """Create a MessageGenerator instance with mocked dependencies.""" with patch("git_commit_generator.message_generator.get_config") as mock_config: with patch("git_commit_generator.message_generator.get_ollama_client") as mock_ollama: config = MagicMock() config.ollama_host = "http://localhost:11434" config.ollama_model = "llama3" config.read_prompt.return_value = "Generate a commit message." mock_config.return_value = config ollama_client = MagicMock() ollama_client.generate_commit_message.return_value = "feat(core): test feature" mock_ollama.return_value = ollama_client with patch("git_commit_generator.message_generator.get_git_utils") as mock_git: git_utils = MagicMock() git_utils.get_all_changes.return_value = "diff content" mock_git.return_value = git_utils generator = MessageGenerator( config=config, ollama_client=ollama_client, ) generator.git_utils = git_utils yield generator def test_detect_change_type_feature(self, message_generator): """Test change type detection for features.""" diff = "+def new_function():\n return 'hello'" result = message_generator.detect_change_type(diff) assert result == "feat" def test_detect_change_type_fix(self, message_generator): """Test change type detection for fixes.""" diff = "-def old_function():\n bug fix" result = message_generator.detect_change_type(diff) assert result == "fix" def test_detect_change_type_test(self, message_generator): """Test change type detection for tests.""" diff = "+def test_function():\n assert True" result = message_generator.detect_change_type(diff) assert result == "test" def test_detect_change_type_docs(self, message_generator): """Test change type detection for documentation.""" diff = "update readme documentation" result = message_generator.detect_change_type(diff) assert result == "docs" def test_detect_scope_files(self, message_generator): """Test scope detection from file paths.""" files = ["api/main.py", "api/routes.py"] result = message_generator.detect_scope(files) assert result == "api" def test_detect_scope_root_files(self, message_generator): """Test scope detection for root files.""" files = ["main.py", "config.py"] result = message_generator.detect_scope(files) assert result == "core" def test_parse_conventional_message_full(self, message_generator): """Test parsing a full conventional commit message.""" message = "feat(auth): add login functionality" result = message_generator.parse_conventional_message(message) assert result["type"] == "feat" assert result["scope"] == "auth" assert result["description"] == "add login functionality" assert result["full_message"] == message def test_parse_conventional_message_no_scope(self, message_generator): """Test parsing a conventional message without scope.""" message = "fix: resolve memory leak" result = message_generator.parse_conventional_message(message) assert result["type"] == "fix" assert result["scope"] == "" assert result["description"] == "resolve memory leak" def test_format_conventional_message_with_scope(self, message_generator): """Test formatting a message with scope.""" message = message_generator.format_conventional_message( message_type="feat", scope="api", description="add new endpoint" ) assert message == "feat(api): add new endpoint" def test_format_conventional_message_no_scope(self, message_generator): """Test formatting a message without scope.""" message = message_generator.format_conventional_message( message_type="fix", scope="", description="fix bug" ) assert message == "fix: fix bug" def test_clean_message_removes_quotes(self, message_generator): """Test that clean_message removes surrounding quotes.""" message = '"feat(core): test message"' result = message_generator._clean_message(message) assert result == "feat(core): test message" def test_clean_message_strips_whitespace(self, message_generator): """Test that clean_message strips whitespace.""" message = " feat(core): test message \n" result = message_generator._clean_message(message) assert result == "feat(core): test message" def test_generate_success(self, message_generator): """Test successful message generation.""" with patch.object(message_generator, 'ollama_client') as mock_client: mock_client.generate_commit_message.return_value = "feat(core): test" result = message_generator.generate() assert result == "feat(core): test" def test_generate_no_changes_raises_error(self, message_generator): """Test that generate raises error when no changes.""" message_generator.git_utils.get_all_changes.return_value = "" with pytest.raises(ValueError, match="No changes detected"): message_generator.generate()