177 lines
6.5 KiB
Python
177 lines
6.5 KiB
Python
import pytest
|
|
from datetime import datetime
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
|
|
class TestCommitPatternAnalyzer:
|
|
"""Test CommitPatternAnalyzer."""
|
|
|
|
@pytest.fixture
|
|
def mock_commit(self):
|
|
return MagicMock(
|
|
sha="abc123",
|
|
message="Test commit",
|
|
author_name="John Doe",
|
|
author_email="john@test.com",
|
|
committed_datetime=datetime(2024, 1, 15, 10, 30, 0),
|
|
author_datetime=datetime(2024, 1, 15, 10, 30, 0),
|
|
additions=50,
|
|
deletions=10,
|
|
files_changed=["src/main.py"],
|
|
parents=[],
|
|
is_merge=False,
|
|
)
|
|
|
|
def test_analyze_empty_repo(self):
|
|
"""Test analyzing empty repository."""
|
|
with patch('src.analyzers.git_repository.GitRepository.get_commits', return_value=[]):
|
|
from src.analyzers import CommitPatternAnalyzer
|
|
analyzer = CommitPatternAnalyzer(MagicMock(), days=30)
|
|
result = analyzer.analyze()
|
|
assert result.total_commits == 0
|
|
assert result.unique_authors == 0
|
|
|
|
def test_analyze_with_commits(self, mock_commit):
|
|
"""Test analyzing repository with commits."""
|
|
with patch('src.analyzers.git_repository.GitRepository.get_commits', return_value=[mock_commit]):
|
|
from src.analyzers import CommitPatternAnalyzer
|
|
analyzer = CommitPatternAnalyzer(MagicMock(), days=30)
|
|
result = analyzer.analyze()
|
|
assert result.total_commits == 1
|
|
assert result.unique_authors == 1
|
|
|
|
|
|
class TestCodeChurnAnalyzer:
|
|
"""Test CodeChurnAnalyzer."""
|
|
|
|
@pytest.fixture
|
|
def mock_commit(self):
|
|
return MagicMock(
|
|
sha="abc123",
|
|
message="Large commit",
|
|
author_name="Jane",
|
|
author_email="jane@test.com",
|
|
committed_datetime=datetime.now(),
|
|
author_datetime=datetime.now(),
|
|
additions=1000,
|
|
deletions=100,
|
|
files_changed=["src/main.py"],
|
|
lines_changed_count=1100,
|
|
parents=[],
|
|
is_merge=False,
|
|
)
|
|
|
|
def test_analyze_empty_repo(self):
|
|
"""Test analyzing empty repository."""
|
|
with patch('src.analyzers.git_repository.GitRepository.get_commits', return_value=[]):
|
|
from src.analyzers import CodeChurnAnalyzer
|
|
analyzer = CodeChurnAnalyzer(MagicMock(), days=30)
|
|
result = analyzer.analyze()
|
|
assert result.total_lines_added == 0
|
|
assert result.total_lines_deleted == 0
|
|
|
|
def test_churn_threshold(self, mock_commit):
|
|
"""Test churn threshold detection."""
|
|
with patch('src.analyzers.git_repository.GitRepository.get_commits', return_value=[mock_commit]):
|
|
from src.analyzers import CodeChurnAnalyzer
|
|
analyzer = CodeChurnAnalyzer(MagicMock(), days=30, churn_threshold=500)
|
|
result = analyzer.analyze()
|
|
assert len(result.high_churn_files) >= 0
|
|
|
|
|
|
class TestVelocityAnalyzer:
|
|
"""Test VelocityAnalyzer."""
|
|
|
|
@pytest.fixture
|
|
def mock_commits(self):
|
|
commits = []
|
|
for i in range(7):
|
|
commit = MagicMock(
|
|
sha=f"sha{i}",
|
|
message=f"Commit {i}",
|
|
author_name="John",
|
|
author_email="john@test.com",
|
|
committed_datetime=datetime(2024, 1, i + 1, 10, 0, 0),
|
|
author_datetime=datetime(2024, 1, i + 1, 10, 0, 0),
|
|
additions=10,
|
|
deletions=5,
|
|
files_changed=["src/file.py"],
|
|
lines_changed_count=15,
|
|
parents=[],
|
|
is_merge=False,
|
|
)
|
|
commits.append(commit)
|
|
return commits
|
|
|
|
def test_analyze_empty_repo(self):
|
|
"""Test analyzing empty repository."""
|
|
with patch('src.analyzers.git_repository.GitRepository.get_commits', return_value=[]):
|
|
from src.analyzers import VelocityAnalyzer
|
|
analyzer = VelocityAnalyzer(MagicMock(), days=30)
|
|
result = analyzer.analyze()
|
|
assert result.total_commits == 0
|
|
assert result.commits_per_day == 0.0
|
|
|
|
def test_velocity_calculation(self, mock_commits):
|
|
"""Test velocity calculation."""
|
|
with patch('src.analyzers.git_repository.GitRepository.get_commits', return_value=mock_commits):
|
|
from src.analyzers import VelocityAnalyzer
|
|
analyzer = VelocityAnalyzer(MagicMock(), days=7)
|
|
result = analyzer.analyze()
|
|
assert result.total_commits == 7
|
|
assert result.commits_per_day == 1.0
|
|
|
|
|
|
class TestRiskyCommitDetector:
|
|
"""Test RiskyCommitDetector."""
|
|
|
|
@pytest.fixture
|
|
def mock_large_commit(self):
|
|
return MagicMock(
|
|
sha="abc123",
|
|
message="Huge commit",
|
|
author_name="John",
|
|
author_email="john@test.com",
|
|
committed_datetime=datetime.now(),
|
|
author_datetime=datetime.now(),
|
|
additions=1000,
|
|
deletions=500,
|
|
files_changed=["src/main.py"],
|
|
lines_changed_count=1500,
|
|
parents=[],
|
|
is_merge=False,
|
|
)
|
|
|
|
@pytest.fixture
|
|
def mock_merge_commit(self):
|
|
return MagicMock(
|
|
sha="def456",
|
|
message="Merge branch",
|
|
author_name="Jane",
|
|
author_email="jane@test.com",
|
|
committed_datetime=datetime.now(),
|
|
author_datetime=datetime.now(),
|
|
additions=10,
|
|
deletions=5,
|
|
files_changed=["src/main.py"],
|
|
lines_changed_count=15,
|
|
parents=["parent1", "parent2"],
|
|
is_merge=True,
|
|
)
|
|
|
|
def test_detect_large_commits(self, mock_large_commit):
|
|
"""Test detecting large commits."""
|
|
with patch('src.analyzers.git_repository.GitRepository.get_commits', return_value=[mock_large_commit]):
|
|
from src.analyzers import RiskyCommitDetector
|
|
detector = RiskyCommitDetector(MagicMock(), days=30, large_commit_threshold=500)
|
|
result = detector.analyze()
|
|
assert len(result.large_commits) == 1
|
|
|
|
def test_detect_merge_commits(self, mock_merge_commit):
|
|
"""Test detecting merge commits."""
|
|
with patch('src.analyzers.git_repository.GitRepository.get_commits', return_value=[mock_merge_commit]):
|
|
from src.analyzers import RiskyCommitDetector
|
|
detector = RiskyCommitDetector(MagicMock(), days=30)
|
|
result = detector.analyze()
|
|
assert len(result.merge_commits) == 1
|