Initial upload: Local Commit Message Generator v0.1.0

This commit is contained in:
2026-02-04 16:49:42 +00:00
parent 17ddf5073c
commit 110f0d560b

View File

@@ -0,0 +1,238 @@
"""Tests for git hooks module."""
import os
import tempfile
from pathlib import Path
from unittest.mock import patch
import pytest
from src.hooks import (
HookManager,
HookResult,
is_hook_mode,
)
class TestHookManager:
"""Tests for HookManager class."""
def test_init_with_repo_path(self):
"""Test initialization with repository path."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
assert manager.repo_path == Path(tmpdir)
assert manager.hooks_dir == Path(tmpdir) / ".git" / "hooks"
def test_get_hook_path(self):
"""Test getting hook file path."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
expected = Path(tmpdir) / ".git" / "hooks" / "prepare-commit-msg"
assert manager.get_hook_path() == expected
def test_hook_exists_false_when_no_file(self):
"""Test hook_exists returns False when no hook file."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
assert manager.hook_exists() is False
def test_hook_exists_true_when_file_exists(self):
"""Test hook_exists returns True when hook file exists."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
hooks_dir = Path(tmpdir) / ".git" / "hooks"
hooks_dir.mkdir(parents=True)
hook_file = hooks_dir / "prepare-commit-msg"
hook_file.write_text("# existing hook")
assert manager.hook_exists() is True
def test_has_our_hook_false_when_no_file(self):
"""Test has_our_hook returns False when no hook."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
assert manager.has_our_hook() is False
def test_has_our_hook_true_when_our_hook(self):
"""Test has_our_hook returns True when our hook is installed."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
hooks_dir = Path(tmpdir) / ".git" / "hooks"
hooks_dir.mkdir(parents=True)
hook_file = hooks_dir / "prepare-commit-msg"
hook_file.write_text("# commit-gen hook")
assert manager.has_our_hook() is True
def test_has_our_hook_false_when_other_hook(self):
"""Test has_our_hook returns False for other hooks."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
hooks_dir = Path(tmpdir) / ".git" / "hooks"
hooks_dir.mkdir(parents=True)
hook_file = hooks_dir / "prepare-commit-msg"
hook_file.write_text("# other hook")
assert manager.has_our_hook() is False
def test_backup_existing_hook(self):
"""Test backing up existing hook."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
hooks_dir = Path(tmpdir) / ".git" / "hooks"
hooks_dir.mkdir(parents=True)
hook_file = hooks_dir / "prepare-commit-msg"
hook_file.write_text("# existing hook")
backup = manager.backup_existing_hook()
assert backup is not None
assert backup.exists()
assert backup.read_text() == "# existing hook"
def test_backup_existing_hook_no_file(self):
"""Test backup returns None when no file."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
backup = manager.backup_existing_hook()
assert backup is None
def test_install_hook_success(self):
"""Test successful hook installation."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
hooks_dir = Path(tmpdir) / ".git" / "hooks"
hooks_dir.mkdir(parents=True)
result = manager.install_hook()
assert result.success is True
assert manager.has_our_hook() is True
def test_install_hook_creates_executable(self):
"""Test installed hook is executable."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
hooks_dir = Path(tmpdir) / ".git" / "hooks"
hooks_dir.mkdir(parents=True)
manager.install_hook()
hook_file = manager.get_hook_path()
mode = os.stat(hook_file).st_mode
assert mode & 0o111
def test_install_hook_backs_up_existing(self):
"""Test hook installation backs up existing hook."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
hooks_dir = Path(tmpdir) / ".git" / "hooks"
hooks_dir.mkdir(parents=True)
hook_file = hooks_dir / "prepare-commit-msg"
hook_file.write_text("# existing hook")
result = manager.install_hook()
assert result.success is True
assert result.backup_path is not None
def test_install_hook_no_backup_when_our_hook(self):
"""Test no backup when reinstalling our hook."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
hooks_dir = Path(tmpdir) / ".git" / "hooks"
hooks_dir.mkdir(parents=True)
hook_file = hooks_dir / "prepare-commit-msg"
hook_file.write_text("# commit-gen hook")
result = manager.install_hook()
assert result.success is True
assert result.backup_path is None
def test_install_hook_no_hooks_dir(self):
"""Test install fails when .git/hooks doesn't exist."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
result = manager.install_hook()
assert result.success is False
assert "not found" in result.message
def test_uninstall_hook_success(self):
"""Test successful hook uninstallation."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
hooks_dir = Path(tmpdir) / ".git" / "hooks"
hooks_dir.mkdir(parents=True)
hook_file = hooks_dir / "prepare-commit-msg"
hook_file.write_text("# commit-gen hook")
result = manager.uninstall_hook()
assert result.success is True
assert not manager.has_our_hook()
def test_uninstall_hook_no_our_hook(self):
"""Test uninstall fails when our hook isn't installed."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
hooks_dir = Path(tmpdir) / ".git" / "hooks"
hooks_dir.mkdir(parents=True)
hook_file = hooks_dir / "prepare-commit-msg"
hook_file.write_text("# other hook")
result = manager.uninstall_hook()
assert result.success is False
def test_uninstall_hook_no_file(self):
"""Test uninstall fails when no hook file."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
result = manager.uninstall_hook()
assert result.success is False
def test_restore_hook_success(self):
"""Test restoring backed up hook."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
hooks_dir = Path(tmpdir) / ".git" / "hooks"
hooks_dir.mkdir(parents=True)
hook_file = hooks_dir / "prepare-commit-msg"
backup_file = hooks_dir / "prepare-commit-msg.backup"
backup_file.write_text("# original hook")
result = manager.restore_hook()
assert result.success is True
assert hook_file.exists()
assert hook_file.read_text() == "# original hook"
def test_restore_hook_no_backup(self):
"""Test restore fails when no backup exists."""
with tempfile.TemporaryDirectory() as tmpdir:
manager = HookManager(tmpdir)
result = manager.restore_hook()
assert result.success is False
class TestIsHookMode:
"""Tests for is_hook_mode function."""
def test_hook_mode_true(self):
"""Test detecting hook mode."""
assert is_hook_mode(["hook"]) is True
assert is_hook_mode(["hook", "msgfile", "source"]) is True
def test_hook_mode_false(self):
"""Test not hook mode."""
assert is_hook_mode([]) is False
assert is_hook_mode(["generate"]) is False
assert is_hook_mode(["--help"]) is False