95a7454bee
- Fall back to symbolic-ref when checkout --orphan fails on bare repos\n- Fall back to symbolic-ref when checkout fails on bare repos\n- Make get_current_branch handle bare repos with unborn branches\n- Add integration tests for bare repo branch operations\n\nQuality gates: pytest integration tests (12 passed)
165 lines
5.1 KiB
Python
165 lines
5.1 KiB
Python
"""Tests for git control utilities."""
|
|
|
|
import os
|
|
import tempfile
|
|
|
|
import pytest
|
|
|
|
from src.utils.git_control import (
|
|
GitStatus,
|
|
checkout_branch,
|
|
commit_changes,
|
|
create_branch,
|
|
delete_branch,
|
|
get_current_branch,
|
|
get_status,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def temp_repo():
|
|
"""Create a temporary git repository."""
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
# Initialize git repo
|
|
os.system(f"cd {tmpdir} && git init && git config user.email 'test@test.com' && git config user.name 'Test User'")
|
|
|
|
# Create initial commit
|
|
with open(os.path.join(tmpdir, "README.md"), "w") as f:
|
|
f.write("# Test Repo\n")
|
|
os.system(f"cd {tmpdir} && git add README.md && git commit -m 'Initial commit'")
|
|
|
|
yield tmpdir
|
|
|
|
|
|
class TestGitStatus:
|
|
"""Tests for get_status function."""
|
|
|
|
def test_clean_repo(self, temp_repo):
|
|
"""Test status of a clean repository."""
|
|
status = get_status(temp_repo)
|
|
assert isinstance(status, GitStatus)
|
|
assert status.branch in ["main", "master"]
|
|
assert len(status.modified) == 0
|
|
assert len(status.added) == 0
|
|
assert len(status.deleted) == 0
|
|
assert len(status.untracked) == 0
|
|
|
|
def test_modified_file(self, temp_repo):
|
|
"""Test detecting modified files."""
|
|
# Modify a file
|
|
with open(os.path.join(temp_repo, "README.md"), "w") as f:
|
|
f.write("# Modified\n")
|
|
|
|
status = get_status(temp_repo)
|
|
assert "README.md" in status.modified
|
|
|
|
def test_untracked_file(self, temp_repo):
|
|
"""Test detecting untracked files."""
|
|
# Create new file
|
|
with open(os.path.join(temp_repo, "new.py"), "w") as f:
|
|
f.write("print('hello')\n")
|
|
|
|
status = get_status(temp_repo)
|
|
assert "new.py" in status.untracked
|
|
|
|
|
|
def test_get_current_branch_handles_unborn_main() -> None:
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
os.system(f"git init -b main {tmpdir} >/dev/null 2>&1")
|
|
|
|
assert get_current_branch(tmpdir) == "main"
|
|
|
|
|
|
def test_create_branch_on_bare_repo_with_no_commits() -> None:
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
os.system(f"git init --bare {tmpdir}/bare.git >/dev/null 2>&1")
|
|
create_branch(f"{tmpdir}/bare.git", "main")
|
|
assert get_current_branch(f"{tmpdir}/bare.git") == "main"
|
|
|
|
|
|
def test_checkout_branch_on_bare_repo_with_no_commits() -> None:
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
os.system(f"git init --bare {tmpdir}/bare.git >/dev/null 2>&1")
|
|
checkout_branch(f"{tmpdir}/bare.git", "main")
|
|
assert get_current_branch(f"{tmpdir}/bare.git") == "main"
|
|
|
|
|
|
class TestBranchOperations:
|
|
"""Tests for branch management functions."""
|
|
|
|
def test_create_branch(self, temp_repo):
|
|
"""Test creating a new branch."""
|
|
# Get the actual default branch name
|
|
default_branch = get_current_branch(temp_repo)
|
|
create_branch(temp_repo, "feature/test", default_branch)
|
|
|
|
# Check branch exists
|
|
branches = get_status(temp_repo)
|
|
# Branch should still be on default
|
|
assert branches.branch == default_branch
|
|
|
|
def test_checkout_branch(self, temp_repo):
|
|
"""Test checking out a branch."""
|
|
default_branch = get_current_branch(temp_repo)
|
|
create_branch(temp_repo, "feature/test", default_branch)
|
|
checkout_branch(temp_repo, "feature/test")
|
|
|
|
current = get_current_branch(temp_repo)
|
|
assert current == "feature/test"
|
|
|
|
def test_delete_branch(self, temp_repo):
|
|
"""Test deleting a branch."""
|
|
default_branch = get_current_branch(temp_repo)
|
|
create_branch(temp_repo, "feature/delete", default_branch)
|
|
delete_branch(temp_repo, "feature/delete")
|
|
|
|
# Should be back on default
|
|
current = get_current_branch(temp_repo)
|
|
assert current == default_branch
|
|
|
|
def test_get_current_branch(self, temp_repo):
|
|
"""Test getting current branch."""
|
|
branch = get_current_branch(temp_repo)
|
|
assert branch in ["main", "master"]
|
|
|
|
|
|
class TestCommit:
|
|
"""Tests for commit function."""
|
|
|
|
def test_commit_changes(self, temp_repo):
|
|
"""Test committing changes."""
|
|
# Modify file
|
|
with open(os.path.join(temp_repo, "README.md"), "w") as f:
|
|
f.write("# Updated\n")
|
|
|
|
# Commit
|
|
commit_changes(
|
|
temp_repo,
|
|
"Update README",
|
|
"Test User",
|
|
"test@test.com",
|
|
["README.md"]
|
|
)
|
|
|
|
# Check status is clean
|
|
status = get_status(temp_repo)
|
|
assert "README.md" not in status.modified
|
|
|
|
def test_commit_all_changes(self, temp_repo):
|
|
"""Test committing all changes."""
|
|
# Modify file
|
|
with open(os.path.join(temp_repo, "README.md"), "w") as f:
|
|
f.write("# All updated\n")
|
|
|
|
# Commit all
|
|
commit_changes(
|
|
temp_repo,
|
|
"Update all",
|
|
"Test User",
|
|
"test@test.com"
|
|
)
|
|
|
|
# Check status is clean
|
|
status = get_status(temp_repo)
|
|
assert len(status.modified) == 0
|