Initial upload: Local Commit Message Generator v0.1.0

This commit is contained in:
2026-02-04 16:49:40 +00:00
parent 9e602211c7
commit 1684221e2b

View File

@@ -0,0 +1,208 @@
"""Tests for change analyzer module."""
import tempfile
from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
from git import Repo
from src.analyzer import (
ChangeType,
StagedChange,
ChangeSet,
ChangeAnalyzer,
)
class TestStagedChange:
"""Tests for StagedChange class."""
def test_filename_property(self):
"""Test extracting filename from path."""
change = StagedChange(
path="src/cli.py",
change_type=ChangeType.MODIFIED
)
assert change.filename == "cli.py"
def test_is_new_true_for_added(self):
"""Test is_new returns True for added files."""
change = StagedChange(
path="new_file.py",
change_type=ChangeType.ADDED
)
assert change.is_new is True
def test_is_new_false_for_modified(self):
"""Test is_new returns False for modified files."""
change = StagedChange(
path="existing.py",
change_type=ChangeType.MODIFIED
)
assert change.is_new is False
def test_is_deleted_true_for_deleted(self):
"""Test is_deleted returns True for deleted files."""
change = StagedChange(
path="deleted.py",
change_type=ChangeType.DELETED
)
assert change.is_deleted is True
def test_is_deleted_false_for_modified(self):
"""Test is_deleted returns False for modified files."""
change = StagedChange(
path="existing.py",
change_type=ChangeType.MODIFIED
)
assert change.is_deleted is False
def test_deleted_file_path(self):
"""Test path handling for deleted files."""
change = StagedChange(
path="deleted.py",
change_type=ChangeType.DELETED
)
assert change.path == "deleted.py"
class TestChangeSet:
"""Tests for ChangeSet class."""
def test_added_property(self):
"""Test getting added files."""
change_set = ChangeSet([
StagedChange("a.py", ChangeType.ADDED),
StagedChange("b.py", ChangeType.MODIFIED),
StagedChange("c.py", ChangeType.ADDED),
])
assert len(change_set.added) == 2
assert all(c.is_new for c in change_set.added)
def test_deleted_property(self):
"""Test getting deleted files."""
change_set = ChangeSet([
StagedChange("a.py", ChangeType.DELETED),
StagedChange("b.py", ChangeType.MODIFIED),
])
assert len(change_set.deleted) == 1
assert change_set.deleted[0].path == "a.py"
def test_modified_property(self):
"""Test getting modified files."""
change_set = ChangeSet([
StagedChange("a.py", ChangeType.MODIFIED),
StagedChange("b.py", ChangeType.MODIFIED),
])
assert len(change_set.modified) == 2
def test_renamed_property(self):
"""Test getting renamed files."""
change_set = ChangeSet([
StagedChange("old.py", ChangeType.RENAMED, old_path="old.py", new_path="new.py"),
StagedChange("a.py", ChangeType.ADDED),
])
assert len(change_set.renamed) == 1
def test_total_count(self):
"""Test counting total changes."""
change_set = ChangeSet([
StagedChange("a.py", ChangeType.ADDED),
StagedChange("b.py", ChangeType.MODIFIED),
StagedChange("c.py", ChangeType.DELETED),
])
assert change_set.total_count == 3
def test_file_paths(self):
"""Test getting all file paths."""
change_set = ChangeSet([
StagedChange("a.py", ChangeType.ADDED),
StagedChange("b.py", ChangeType.MODIFIED),
])
assert change_set.file_paths == ["a.py", "b.py"]
def test_has_changes_true(self):
"""Test has_changes returns True when there are changes."""
change_set = ChangeSet([
StagedChange("a.py", ChangeType.ADDED),
])
assert change_set.has_changes is True
def test_has_changes_false(self):
"""Test has_changes returns False for empty change set."""
change_set = ChangeSet([])
assert change_set.has_changes is False
class TestChangeAnalyzer:
"""Tests for ChangeAnalyzer class."""
def test_init_with_repo_path(self):
"""Test initialization with repository path."""
with tempfile.TemporaryDirectory() as tmpdir:
analyzer = ChangeAnalyzer(tmpdir)
assert analyzer.repo_path == tmpdir
def test_get_staged_changes_no_repo(self):
"""Test error when not in git repository."""
with tempfile.TemporaryDirectory() as tmpdir:
analyzer = ChangeAnalyzer(tmpdir)
with pytest.raises(ValueError, match="Not a git repository"):
analyzer.get_staged_changes()
def test_get_staged_changes_with_repo(self):
"""Test getting staged changes from real repository."""
with tempfile.TemporaryDirectory() as tmpdir:
Repo.init(tmpdir)
analyzer = ChangeAnalyzer(tmpdir)
result = analyzer.get_staged_changes()
assert isinstance(result, ChangeSet)
def test_get_changed_extensions(self):
"""Test getting unique file extensions."""
change_set = ChangeSet([
StagedChange("file.py", ChangeType.ADDED),
StagedChange("test.py", ChangeType.MODIFIED),
StagedChange("noext", ChangeType.ADDED),
])
with patch.object(ChangeAnalyzer, 'get_staged_changes', return_value=change_set):
analyzer = ChangeAnalyzer()
extensions = analyzer.get_changed_extensions()
assert ".py" in extensions
def test_get_changed_directories(self):
"""Test getting unique directories."""
change_set = ChangeSet([
StagedChange("src/main.py", ChangeType.ADDED),
StagedChange("src/cli.py", ChangeType.MODIFIED),
StagedChange("tests/test.py", ChangeType.ADDED),
])
with patch.object(ChangeAnalyzer, 'get_staged_changes', return_value=change_set):
analyzer = ChangeAnalyzer()
directories = analyzer.get_changed_directories()
assert "src" in directories
assert "tests" in directories
class TestChangeType:
"""Tests for ChangeType enum."""
def test_enum_values(self):
"""Test enum values."""
assert ChangeType.ADDED.value == "added"
assert ChangeType.DELETED.value == "deleted"
assert ChangeType.MODIFIED.value == "modified"
assert ChangeType.RENAMED.value == "renamed"
def test_enum_members(self):
"""Test enum has expected members."""
members = list(ChangeType)
assert ChangeType.ADDED in members
assert ChangeType.DELETED in members
assert ChangeType.MODIFIED in members
assert ChangeType.RENAMED in members
assert ChangeType.TYPE_CHANGE in members
assert ChangeType.UNMERGED in members
assert ChangeType.UNKNOWN in members