diff --git a/git_commit_ai/tests/test_git_handler.py b/git_commit_ai/tests/test_git_handler.py new file mode 100644 index 0000000..ee860ff --- /dev/null +++ b/git_commit_ai/tests/test_git_handler.py @@ -0,0 +1,137 @@ +"""Tests for the Git handler module.""" + +import os +from pathlib import Path +from unittest.mock import MagicMock + +import pytest +from git.exc import GitCommandError + +from git_commit_ai.core.git_handler import GitHandler, GitError, get_git_handler + + +class TestGitHandlerBasic: + """Basic Git handler tests.""" + + def test_is_repository_true(self, temp_git_repo): + """Test is_repository returns True for git repo.""" + handler = GitHandler(str(temp_git_repo)) + assert handler.is_repository() is True + + def test_is_repository_false(self, tmp_path): + """Test is_repository returns False for non-git directory.""" + handler = GitHandler(str(tmp_path)) + assert handler.is_repository() is False + + +class TestGitHandlerStagedChanges: + """Tests for staged changes functionality.""" + + def test_is_staged_true(self, temp_git_repo): + """Test is_staged returns True when changes are staged.""" + handler = GitHandler(str(temp_git_repo)) + + test_file = temp_git_repo / "test.py" + test_file.write_text("print('test')") + os.system(f"git add {test_file}") + + assert handler.is_staged() is True + + def test_get_staged_changes(self, temp_git_repo): + """Test getting staged changes.""" + handler = GitHandler(str(temp_git_repo)) + + test_file = temp_git_repo / "test.py" + test_file.write_text("print('test')") + os.system(f"git add {test_file}") + + diff = handler.get_staged_changes() + assert diff != "" + assert "test.py" in diff + + +class TestGitHandlerCommitHistory: + """Tests for commit history functionality.""" + + def test_get_commit_history(self, temp_git_repo): + """Test getting commit history.""" + handler = GitHandler(str(temp_git_repo)) + commits = handler.get_commit_history(max_commits=5) + + assert len(commits) >= 1 + assert any(c["message"] == "Initial commit" for c in commits) + + def test_get_commit_history_conventional_only(self, temp_git_repo): + """Test getting only conventional commits.""" + handler = GitHandler(str(temp_git_repo)) + commits = handler.get_commit_history(max_commits=10, conventional_only=True) + + for commit in commits: + assert commit["type"] != "unknown" + + +class TestGitHandlerLanguageDetection: + """Tests for language detection functionality.""" + + def test_get_changed_languages_python(self, temp_git_repo): + """Test detecting Python files.""" + handler = GitHandler(str(temp_git_repo)) + + test_file = temp_git_repo / "test.py" + test_file.write_text("print('hello')") + os.system(f"git add {test_file}") + + languages = handler.get_changed_languages() + assert "Python" in languages + + def test_get_changed_languages_multiple(self, temp_git_repo): + """Test detecting multiple languages.""" + handler = GitHandler(str(temp_git_repo)) + + py_file = temp_git_repo / "test.py" + py_file.write_text("print('hello')") + js_file = temp_git_repo / "test.js" + js_file.write_text("console.log('hello')") + + os.system(f"git add {py_file} {js_file}") + + languages = handler.get_changed_languages() + assert "Python" in languages + assert "JavaScript" in languages + + +class TestGitHandlerHelpers: + """Tests for helper methods.""" + + def test_get_staged_files(self, temp_git_repo): + """Test getting staged files list.""" + handler = GitHandler(str(temp_git_repo)) + + test_file = temp_git_repo / "test.py" + test_file.write_text("print('test')") + os.system(f"git add {test_file}") + + files = handler.get_staged_files() + assert "test.py" in [f for f in files if "test.py" in f] + + def test_get_diff_summary(self, temp_git_repo): + """Test getting diff summary.""" + handler = GitHandler(str(temp_git_repo)) + + test_file = temp_git_repo / "test.py" + test_file.write_text("print('test')") + os.system(f"git add {test_file}") + + summary = handler.get_diff_summary() + assert "Files changed" in summary + assert "Python" in summary + + +class TestGitError: + """Tests for GitError exception.""" + + def test_git_error_raised(self): + """Test GitError is raised on git errors.""" + with pytest.raises(GitError): + handler = GitHandler("/nonexistent/path") + handler.repo