Skip to content

Commit

Permalink
test: update tests for AiCommit and add commit change tests
Browse files Browse the repository at this point in the history
This commit updates the tests to reflect the refactor from GitCommitAssistant to AiCommit, ensuring that the new functionality is covered. It also introduces tests for the new get_commit_changes method.
  • Loading branch information
versun committed Dec 23, 2024
1 parent 22b38c6 commit ec82d56
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 31 deletions.
37 changes: 6 additions & 31 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,22 @@
import pytest
from unittest.mock import patch
from aicmt.cli import GitCommitAssistant, cli
from aicmt.cli import AiCommit, cli
from aicmt.git_operations import Change


@pytest.fixture
def assistant(monkeypatch):
monkeypatch.setattr("aicmt.config._load_cli_config", lambda: {})
return GitCommitAssistant()
return AiCommit()


def test_git_commit_assistant_init(assistant):
assert hasattr(assistant, "git_ops")
assert hasattr(assistant, "ai_analyzer")
assert hasattr(assistant, "cli")


@patch("aicmt.cli.GitCommitAssistant")
@patch("aicmt.cli.parse_args")
def test_cli_value_error(mock_parse_args, mock_assistant, capsys):
mock_assistant.return_value.run.side_effect = ValueError("Test error")

with pytest.raises(SystemExit):
cli()

captured = capsys.readouterr()
assert "Configuration Error" in captured.out


@patch("aicmt.cli.GitCommitAssistant")
@patch("aicmt.cli.parse_args")
def test_cli_keyboard_interrupt(mock_parse_args, mock_assistant, capsys):
mock_parse_args.side_effect = KeyboardInterrupt()

with pytest.raises(SystemExit):
cli()

captured = capsys.readouterr()
assert "Program interrupted by user" in captured.out


def test_run_keyboard_interrupt(assistant, capsys):
"""Test that KeyboardInterrupt is handled properly in GitCommitAssistant.run"""
"""Test that KeyboardInterrupt is handled properly in AiCommit.run"""
changes = [Change(file="test.py", status="modified", diff="test diff", insertions=1, deletions=0)]

with patch.multiple(assistant.git_ops, get_unstaged_changes=lambda: changes, get_current_branch=lambda: "main"):
Expand Down Expand Up @@ -123,9 +98,9 @@ def test_run_push_error(mock_confirm, assistant):


@patch("aicmt.cli.parse_args")
@patch("aicmt.cli.GitCommitAssistant")
@patch("aicmt.cli.AiCommit")
def test_cli_runtime_error(mock_assistant, mock_parse_args, capsys):
# Mock GitCommitAssistant to raise a runtime error
# Mock AiCommit to raise a runtime error
mock_instance = mock_assistant.return_value
mock_instance.run.side_effect = Exception("Simulated runtime error")

Expand All @@ -138,7 +113,7 @@ def test_cli_runtime_error(mock_assistant, mock_parse_args, capsys):

# Check error message
captured = capsys.readouterr()
assert "Runtime Error: Simulated runtime error" in captured.out
assert "Error: Simulated runtime error" in captured.out


@patch("rich.prompt.Confirm.ask")
Expand Down
86 changes: 86 additions & 0 deletions tests/test_git_operations.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import pytest
from git import Repo, InvalidGitRepositoryError, GitCommandError, NoSuchPathError
from gitdb.exc import BadName
from aicmt.git_operations import GitOperations
from pathlib import Path

Expand Down Expand Up @@ -385,3 +386,88 @@ def test_stage_deleted_file(temp_git_repo):
finally:
# Restore the original directory
os.chdir(current_dir)


def test_get_commit_changes(temp_git_repo):
"""Test getting changes from a specific commit"""
git_ops = GitOperations(temp_git_repo)

# Switch to the repository directory
current_dir = os.getcwd()
os.chdir(temp_git_repo)

try:
# Create and commit initial files
with open("test1.txt", "w") as f:
f.write("initial content")
with open("test2.txt", "w") as f:
f.write("file to be deleted")
with open("test3.bin", "wb") as f:
f.write(b'\x00\x01\x02\x03') # Binary content
with open("test4.txt", "w") as f:
pass # Empty file

git_ops.repo.index.add(["test1.txt", "test2.txt", "test3.bin", "test4.txt"])
initial_commit = git_ops.repo.index.commit("Initial commit")

# Make various changes
# 1. Modify test1.txt
with open("test1.txt", "w") as f:
f.write("modified content")

# 2. Delete test2.txt
os.remove("test2.txt")

# 3. Modify binary file
with open("test3.bin", "wb") as f:
f.write(b'\x03\x02\x01\x00')

# 4. Create new empty file
with open("test5.txt", "w") as f:
pass

git_ops.repo.index.add(["test1.txt", "test3.bin", "test5.txt"])
git_ops.repo.index.remove(["test2.txt"])
second_commit = git_ops.repo.index.commit("Various changes")

# Get changes from the second commit
changes = git_ops.get_commit_changes(second_commit.hexsha)

# Verify number of changes
assert len(changes) == 4

# Find changes by filename
test1_change = next(change for change in changes if change.file == "test1.txt")
test2_change = next(change for change in changes if change.file == "test2.txt")
test3_change = next(change for change in changes if change.file == "test3.bin")
test5_change = next(change for change in changes if change.file == "test5.txt")

# Test modified text file
assert test1_change.status == "modified"
assert "modified content" in test1_change.diff
assert test1_change.insertions > 0
assert test1_change.deletions > 0

# Test deleted file
assert test2_change.status == "deleted"
assert "[File deleted]" in test2_change.diff
assert test2_change.insertions == 0
assert test2_change.deletions > 0

# Test binary file
assert test3_change.status == "modified"
assert test3_change.insertions >= 0
assert test3_change.deletions >= 0

# Test new empty file
assert test5_change.status == "new file"
assert test5_change.insertions == 0
assert test5_change.deletions == 0

# Test invalid commit hash
with pytest.raises(BadName):
git_ops.get_commit_changes("invalid_hash")

finally:
# Restore the original directory
os.chdir(current_dir)

0 comments on commit ec82d56

Please sign in to comment.