-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ test: add unit tests for git operations
✨ test: add unit tests for git operations ✨ Features: - Added unit tests for git commit operations in test_commits.py - Implemented tests for file operations in test_files.py - Created tests for basic git operations in test_operations.py ✅ Tests: - Tested success and failure scenarios for commit creation - Verified handling of warnings during git operations - Ensured correct retrieval of staged files and handling of errors Implemented comprehensive unit tests for git operations
- Loading branch information
Test User
committed
Dec 9, 2024
1 parent
91f4a7b
commit e803cef
Showing
3 changed files
with
286 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
"""Tests for git commit operations.""" | ||
|
||
import subprocess | ||
from unittest.mock import MagicMock, patch | ||
|
||
import pytest | ||
|
||
from commitloom.core.git import GitError, GitOperations | ||
|
||
|
||
@pytest.fixture | ||
def git_operations(): | ||
"""Fixture for GitOperations instance.""" | ||
return GitOperations() | ||
|
||
|
||
@patch("subprocess.run") | ||
def test_create_commit_success(mock_run, git_operations): | ||
"""Test successful commit creation.""" | ||
mock_run.side_effect = [ | ||
# git diff --cached --quiet | ||
MagicMock(returncode=1), # Non-zero means there are staged changes | ||
# git commit | ||
MagicMock(returncode=0, stdout="", stderr=""), | ||
] | ||
|
||
result = git_operations.create_commit( | ||
title="test: add new feature", message="Detailed commit message" | ||
) | ||
|
||
assert result is True | ||
mock_run.assert_any_call( | ||
[ | ||
"git", | ||
"commit", | ||
"-m", | ||
"test: add new feature", | ||
"-m", | ||
"Detailed commit message", | ||
], | ||
capture_output=True, | ||
text=True, | ||
check=True, | ||
) | ||
|
||
|
||
@patch("subprocess.run") | ||
def test_create_commit_failure(mock_run, git_operations): | ||
"""Test handling of commit creation failure.""" | ||
mock_run.side_effect = [ | ||
# git diff --cached --quiet | ||
MagicMock(returncode=1), # Non-zero means there are staged changes | ||
# git commit | ||
subprocess.CalledProcessError(1, "git", stderr=b"error"), | ||
] | ||
|
||
with pytest.raises(GitError) as exc_info: | ||
git_operations.create_commit(title="test: add new feature", message="Detailed commit message") | ||
|
||
assert "Failed to create commit" in str(exc_info.value) | ||
|
||
|
||
@patch("subprocess.run") | ||
@patch("commitloom.core.git.logger") | ||
def test_create_commit_with_warning(mock_logger, mock_run, git_operations): | ||
"""Test handling of git warnings during commit.""" | ||
mock_run.side_effect = [ | ||
# git diff --cached --quiet | ||
MagicMock(returncode=1), # Non-zero means there are staged changes | ||
# git commit | ||
MagicMock(returncode=0, stderr="warning: CRLF will be replaced by LF", stdout=""), | ||
] | ||
|
||
result = git_operations.create_commit(title="test", message="message") | ||
|
||
assert result is True | ||
# Verify warning was logged | ||
mock_logger.warning.assert_called_once_with( | ||
"Git warning during commit: %s", "warning: CRLF will be replaced by LF" | ||
) | ||
|
||
|
||
@patch("subprocess.run") | ||
@patch("commitloom.core.git.logger") | ||
def test_create_commit_nothing_to_commit(mock_logger, mock_run, git_operations): | ||
"""Test handling of 'nothing to commit' message.""" | ||
mock_run.return_value = MagicMock( | ||
returncode=0, # Zero means no staged changes | ||
stderr="", | ||
stdout="nothing to commit, working tree clean", | ||
) | ||
|
||
result = git_operations.create_commit(title="test", message="message") | ||
|
||
assert result is False | ||
mock_logger.info.assert_called_once_with("Nothing to commit") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
"""Tests for git file operations.""" | ||
|
||
import subprocess | ||
from unittest.mock import MagicMock, patch | ||
|
||
import pytest | ||
|
||
from commitloom.core.git import GitError, GitOperations | ||
|
||
|
||
@pytest.fixture | ||
def git_operations(): | ||
"""Fixture for GitOperations instance.""" | ||
return GitOperations() | ||
|
||
|
||
@patch("subprocess.run") | ||
def test_get_diff_text_files(mock_run, git_operations, mock_git_file): | ||
"""Test getting diff for text files.""" | ||
mock_diff = "diff --git a/file1.py b/file1.py\n+new line" | ||
mock_run.return_value = MagicMock( | ||
stdout=mock_diff, | ||
stderr="", | ||
returncode=0, | ||
) | ||
|
||
diff = git_operations.get_diff([mock_git_file("file1.py")]) | ||
|
||
assert diff == mock_diff | ||
|
||
|
||
@patch("subprocess.run") | ||
def test_get_diff_binary_files(mock_run, git_operations, mock_git_file): | ||
"""Test getting diff for binary files.""" | ||
mock_run.return_value = MagicMock( | ||
stdout="Binary files a/image.png and b/image.png differ", | ||
stderr="", | ||
returncode=0, | ||
) | ||
|
||
diff = git_operations.get_diff( | ||
[mock_git_file("image.png", size=1024, hash_="abc123")] | ||
) | ||
|
||
assert "Binary files" in diff | ||
|
||
|
||
@patch("subprocess.run") | ||
def test_reset_staged_changes_success(mock_run, git_operations): | ||
"""Test successful reset of staged changes.""" | ||
mock_run.return_value = MagicMock(returncode=0) | ||
|
||
git_operations.reset_staged_changes() | ||
|
||
mock_run.assert_called_with(["git", "reset"], capture_output=True, text=True, check=True) | ||
|
||
|
||
@patch("subprocess.run") | ||
def test_reset_staged_changes_failure(mock_run, git_operations): | ||
"""Test handling of reset failure.""" | ||
mock_run.side_effect = subprocess.CalledProcessError(1, "git", stderr=b"error") | ||
|
||
with pytest.raises(GitError) as exc_info: | ||
git_operations.reset_staged_changes() | ||
|
||
assert "Failed to reset staged changes" in str(exc_info.value) | ||
|
||
|
||
@patch("subprocess.run") | ||
@patch("commitloom.core.git.logger") | ||
def test_stage_files_with_warning(mock_logger, mock_run, git_operations): | ||
"""Test handling of git warnings during staging.""" | ||
mock_run.return_value = MagicMock( | ||
returncode=0, | ||
stderr="warning: LF will be replaced by CRLF in file1.py", | ||
stdout="", | ||
) | ||
|
||
git_operations.stage_files(["file1.py"]) | ||
|
||
# Verify warning was logged | ||
mock_logger.warning.assert_called_once_with( | ||
"Git warning while staging %s: %s", | ||
"file1.py", | ||
"warning: LF will be replaced by CRLF in file1.py", | ||
) | ||
|
||
|
||
@patch("subprocess.run") | ||
@patch("commitloom.core.git.logger") | ||
def test_stage_files_with_info(mock_logger, mock_run, git_operations): | ||
"""Test handling of git info messages during staging.""" | ||
mock_run.return_value = MagicMock( | ||
returncode=0, | ||
stderr="Updating index", | ||
stdout="", | ||
) | ||
|
||
git_operations.stage_files(["file1.py"]) | ||
|
||
# Verify info was logged | ||
mock_logger.info.assert_called_once_with( | ||
"Git message while staging %s: %s", "file1.py", "Updating index" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
"""Tests for basic git operations.""" | ||
|
||
import subprocess | ||
from unittest.mock import MagicMock, patch | ||
|
||
import pytest | ||
|
||
from commitloom.core.git import GitError, GitOperations | ||
|
||
|
||
@pytest.fixture | ||
def git_operations(): | ||
"""Fixture for GitOperations instance.""" | ||
return GitOperations() | ||
|
||
|
||
@patch("subprocess.run") | ||
def test_get_staged_files_success(mock_run, git_operations, mock_git_file): | ||
"""Test successful retrieval of staged files.""" | ||
mock_run.return_value = MagicMock( | ||
stdout=" M file1.py\nM file2.py\n", | ||
stderr="", | ||
returncode=0, | ||
) | ||
|
||
files = git_operations.get_staged_files() | ||
|
||
assert len(files) == 2 | ||
assert files[0].path == "file1.py" | ||
assert files[0].status == "M" | ||
assert files[1].path == "file2.py" | ||
assert files[1].status == "M" | ||
|
||
|
||
@patch("subprocess.run") | ||
def test_get_staged_files_empty(mock_run, git_operations): | ||
"""Test when no files are staged.""" | ||
mock_run.return_value = MagicMock(stdout="", stderr="", returncode=0) | ||
|
||
files = git_operations.get_staged_files() | ||
|
||
assert len(files) == 0 | ||
|
||
|
||
@patch("subprocess.run") | ||
def test_get_staged_files_error(mock_run, git_operations): | ||
"""Test error handling in get_staged_files.""" | ||
mock_run.side_effect = subprocess.CalledProcessError(1, "git", stderr=b"error") | ||
|
||
with pytest.raises(GitError) as exc_info: | ||
git_operations.get_staged_files() | ||
|
||
assert "Failed to get staged files" in str(exc_info.value) | ||
|
||
|
||
@patch("subprocess.run") | ||
def test_get_staged_files_with_renames(mock_run, git_operations): | ||
"""Test handling of renamed files.""" | ||
mock_run.return_value = MagicMock( | ||
stdout='R "old file.py" -> "new file.py"\n', | ||
stderr="", | ||
returncode=0, | ||
) | ||
|
||
files = git_operations.get_staged_files() | ||
|
||
assert len(files) == 1 | ||
assert files[0].path == "new file.py" | ||
assert files[0].status == "R" | ||
assert files[0].old_path == "old file.py" | ||
|
||
|
||
@patch("subprocess.run") | ||
def test_get_staged_files_ignores_untracked(mock_run, git_operations): | ||
"""Test that untracked files are ignored.""" | ||
mock_run.return_value = MagicMock( | ||
stdout="?? new.py\n M tracked.py\n", | ||
stderr="", | ||
returncode=0, | ||
) | ||
|
||
files = git_operations.get_staged_files() | ||
|
||
assert len(files) == 1 | ||
assert files[0].path == "tracked.py" | ||
assert files[0].status == "M" |