diff --git a/tests/test_git_status.py b/tests/test_git_status.py new file mode 100644 index 0000000..69baeaa --- /dev/null +++ b/tests/test_git_status.py @@ -0,0 +1,107 @@ +import pytest +from unittest.mock import patch, MagicMock +from src.git.status import ( + GitStatus, + get_git_status, + is_git_repo, + GitStatusError, + _run_git_command, + _get_current_branch, + _get_commit_hash, + _is_detached, + _get_staged_count, + _get_unstaged_count, + _get_untracked_count, +) + + +class TestGitStatus: + def test_git_status_creation(self): + status = GitStatus( + branch="main", + commit="abc123", + staged=1, + unstaged=2, + untracked=3, + is_clean=False, + ) + assert status.branch == "main" + assert status.is_clean is False + + +class TestIsGitRepo: + def test_is_git_repo_true(self, tmp_path): + with patch("src.git.status._run_git_command") as mock: + mock.return_value = ".git" + result = is_git_repo(str(tmp_path)) + assert result is True + + def test_is_git_repo_false(self, tmp_path): + with patch("src.git.status._run_git_command") as mock: + mock.side_effect = GitStatusError("Not a git repo") + result = is_git_repo(str(tmp_path)) + assert result is False + + +class TestGetGitStatus: + def test_get_git_status_success(self, tmp_path): + with patch("src.git.status._get_current_branch") as mock_branch, \ + patch("src.git.status._get_commit_hash") as mock_commit, \ + patch("src.git.status._get_staged_count") as mock_staged, \ + patch("src.git.status._get_unstaged_count") as mock_unstaged, \ + patch("src.git.status._get_untracked_count") as mock_untracked: + mock_branch.return_value = "main" + mock_commit.return_value = "abc123def" + mock_staged.return_value = 1 + mock_unstaged.return_value = 2 + mock_untracked.return_value = 3 + + status = get_git_status(str(tmp_path)) + + assert status.branch == "main" + assert status.commit == "abc123def" + assert status.staged == 1 + assert status.unstaged == 2 + assert status.untracked == 3 + assert status.is_clean is False + + def test_get_git_status_detached_head(self, tmp_path): + with patch("src.git.status._is_detached") as mock_detached: + mock_detached.return_value = True + + with patch("src.git.status._get_commit_hash") as mock_commit, \ + patch("src.git.status._get_staged_count") as mock_staged, \ + patch("src.git.status._get_unstaged_count") as mock_unstaged, \ + patch("src.git.status._get_untracked_count") as mock_untracked: + mock_commit.return_value = "abc123def" + mock_staged.return_value = 0 + mock_unstaged.return_value = 0 + mock_untracked.return_value = 0 + + status = get_git_status(str(tmp_path)) + + assert status.is_detached is True + assert status.branch == "(detached)" + + def test_get_git_status_clean_repo(self, tmp_path): + with patch("src.git.status._get_current_branch") as mock_branch, \ + patch("src.git.status._get_commit_hash") as mock_commit, \ + patch("src.git.status._get_staged_count") as mock_staged, \ + patch("src.git.status._get_unstaged_count") as mock_unstaged, \ + patch("src.git.status._get_untracked_count") as mock_untracked: + mock_branch.return_value = "feature-branch" + mock_commit.return_value = "xyz789abc" + mock_staged.return_value = 0 + mock_unstaged.return_value = 0 + mock_untracked.return_value = 0 + + status = get_git_status(str(tmp_path)) + + assert status.is_clean is True + + def test_get_git_status_error(self, tmp_path): + with patch("src.git.status._is_detached") as mock_detached: + mock_detached.side_effect = GitStatusError("Git command failed") + + with pytest.raises(GitStatusError): + get_git_status(str(tmp_path))