139 lines
4.9 KiB
Python
139 lines
4.9 KiB
Python
"""Tests for git_utils.py."""
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from git_commit_generator.git_utils import GitUtils
|
|
|
|
|
|
class TestGitUtils:
|
|
"""Test cases for GitUtils."""
|
|
|
|
@pytest.fixture
|
|
def git_utils(self):
|
|
"""Create a GitUtils instance with mocked repository."""
|
|
with patch("git_commit_generator.git_utils.Repo") as mock_repo:
|
|
repo = MagicMock()
|
|
mock_repo.return_value = repo
|
|
utils = GitUtils("/fake/path")
|
|
utils.repo = repo
|
|
yield utils
|
|
|
|
def test_is_repo_true(self, git_utils):
|
|
"""Test is_repo returns True for valid repository."""
|
|
git_utils.repo.bare = False
|
|
result = git_utils.is_repo()
|
|
assert result is True
|
|
|
|
def test_is_repo_false(self, git_utils):
|
|
"""Test is_repo returns False for invalid repository."""
|
|
git_utils.repo.bare = True
|
|
result = git_utils.is_repo()
|
|
assert result is False
|
|
|
|
def test_get_staged_diff(self, git_utils):
|
|
"""Test getting staged diff."""
|
|
diff_mock = MagicMock()
|
|
diff_mock.diff = b"diff --git a/file.py b/file.py"
|
|
git_utils.repo.index.diff.return_value = [diff_mock]
|
|
|
|
result = git_utils.get_staged_diff()
|
|
|
|
assert "diff --git a/file.py b/file.py" in result
|
|
|
|
def test_get_unstaged_diff(self, git_utils):
|
|
"""Test getting unstaged diff."""
|
|
diff_mock = MagicMock()
|
|
diff_mock.diff = "diff --git a/file.py b/file.py"
|
|
git_utils.repo.index.diff.return_value = [diff_mock]
|
|
|
|
result = git_utils.get_unstaged_diff()
|
|
|
|
assert "diff --git a/file.py b/file.py" in result
|
|
|
|
def test_get_staged_files(self, git_utils):
|
|
"""Test getting list of staged files."""
|
|
diff_mock = MagicMock()
|
|
diff_mock.a_path = "src/main.py"
|
|
git_utils.repo.index.diff.return_value = [diff_mock]
|
|
|
|
result = git_utils.get_staged_files()
|
|
|
|
assert result == ["src/main.py"]
|
|
|
|
def test_get_commit_history(self, git_utils):
|
|
"""Test getting commit history."""
|
|
commit_mock = MagicMock()
|
|
commit_mock.hexsha = "abc1234567890"
|
|
commit_mock.message = "feat: add new feature"
|
|
commit_mock.author.name = "Test User"
|
|
commit_mock.author.email = "test@example.com"
|
|
commit_mock.committed_datetime.isoformat.return_value = "2024-01-15T10:30:00"
|
|
|
|
git_utils.repo.iter_commits.return_value = [commit_mock]
|
|
|
|
result = git_utils.get_commit_history(limit=10)
|
|
|
|
assert len(result) == 1
|
|
assert result[0]["hash"] == "abc1234"
|
|
assert result[0]["full_hash"] == "abc1234567890"
|
|
assert result[0]["message"] == "feat: add new feature"
|
|
|
|
def test_get_conventional_commits(self, git_utils):
|
|
"""Test filtering conventional commits."""
|
|
commit_mock = MagicMock()
|
|
commit_mock.hexsha = "abc1234567890"
|
|
commit_mock.message = "feat(api): new feature"
|
|
commit_mock.author.name = "Test User"
|
|
commit_mock.author.email = "test@example.com"
|
|
commit_mock.committed_datetime.isoformat.return_value = "2024-01-15T10:30:00"
|
|
|
|
git_utils.repo.iter_commits.return_value = [commit_mock]
|
|
|
|
result = git_utils.get_conventional_commits()
|
|
|
|
assert len(result) == 1
|
|
assert result[0]["type"] == "feat"
|
|
assert result[0]["scope"] == "api"
|
|
|
|
def test_get_file_scopes(self, git_utils):
|
|
"""Test extracting scopes from file paths."""
|
|
git_utils.get_changed_files = MagicMock(return_value=[
|
|
"api/routes.py",
|
|
"auth/login.py",
|
|
"tests/test_main.py",
|
|
])
|
|
|
|
result = git_utils.get_file_scopes()
|
|
|
|
assert "api" in result
|
|
assert "auth" in result
|
|
|
|
def test_is_conventional_message_valid(self, git_utils):
|
|
"""Test conventional message validation."""
|
|
message = "feat(auth): add login functionality"
|
|
result = git_utils._is_conventional_message(message)
|
|
assert result is True
|
|
|
|
def test_is_conventional_message_invalid(self, git_utils):
|
|
"""Test non-conventional message validation."""
|
|
message = "Added new feature"
|
|
result = git_utils._is_conventional_message(message)
|
|
assert result is False
|
|
|
|
def test_parse_conventional_commit_full(self, git_utils):
|
|
"""Test parsing full conventional commit."""
|
|
message = "fix(database): resolve connection timeout issue"
|
|
result = git_utils._parse_conventional_commit(message)
|
|
assert result["type"] == "fix"
|
|
assert result["scope"] == "database"
|
|
assert result["description"] == "resolve connection timeout issue"
|
|
|
|
def test_parse_conventional_commit_no_scope(self, git_utils):
|
|
"""Test parsing conventional commit without scope."""
|
|
message = "chore: update dependencies"
|
|
result = git_utils._parse_conventional_commit(message)
|
|
assert result["type"] == "chore"
|
|
assert result["scope"] == ""
|
|
assert result["description"] == "update dependencies"
|