206 lines
6.0 KiB
Python
206 lines
6.0 KiB
Python
"""Tests for data models."""
|
|
|
|
import pytest
|
|
from datetime import datetime
|
|
|
|
from repohealth.models.file_stats import FileAnalysis
|
|
from repohealth.models.author import AuthorStats
|
|
from repohealth.models.result import RepositoryResult, RiskLevel
|
|
|
|
|
|
class TestFileAnalysis:
|
|
"""Tests for FileAnalysis model."""
|
|
|
|
def test_file_analysis_creation(self):
|
|
"""Test creating a FileAnalysis instance."""
|
|
analysis = FileAnalysis(
|
|
path="src/main.py",
|
|
total_commits=10,
|
|
author_commits={"author1@example.com": 6, "author2@example.com": 4}
|
|
)
|
|
|
|
assert analysis.path == "src/main.py"
|
|
assert analysis.total_commits == 10
|
|
assert analysis.num_authors == 2
|
|
assert analysis.bus_factor == 1.0
|
|
|
|
def test_num_authors(self):
|
|
"""Test num_authors property."""
|
|
analysis = FileAnalysis(
|
|
path="test.py",
|
|
total_commits=5,
|
|
author_commits={"a@x.com": 3, "b@x.com": 2}
|
|
)
|
|
|
|
assert analysis.num_authors == 2
|
|
|
|
def test_num_authors_empty(self):
|
|
"""Test num_authors with empty commits."""
|
|
analysis = FileAnalysis(
|
|
path="test.py",
|
|
total_commits=0,
|
|
author_commits={}
|
|
)
|
|
|
|
assert analysis.num_authors == 0
|
|
|
|
def test_top_author(self):
|
|
"""Test top_author property."""
|
|
analysis = FileAnalysis(
|
|
path="test.py",
|
|
total_commits=10,
|
|
author_commits={"a@x.com": 7, "b@x.com": 3}
|
|
)
|
|
|
|
top_author, count = analysis.top_author
|
|
assert top_author == "a@x.com"
|
|
assert count == 7
|
|
|
|
def test_top_author_empty(self):
|
|
"""Test top_author with empty commits."""
|
|
analysis = FileAnalysis(
|
|
path="test.py",
|
|
total_commits=0,
|
|
author_commits={}
|
|
)
|
|
|
|
assert analysis.top_author is None
|
|
|
|
def test_top_author_share(self):
|
|
"""Test top_author_share property."""
|
|
analysis = FileAnalysis(
|
|
path="test.py",
|
|
total_commits=10,
|
|
author_commits={"a@x.com": 8, "b@x.com": 2}
|
|
)
|
|
|
|
assert analysis.top_author_share == 0.8
|
|
|
|
def test_top_author_share_empty(self):
|
|
"""Test top_author_share with no commits."""
|
|
analysis = FileAnalysis(
|
|
path="test.py",
|
|
total_commits=0,
|
|
author_commits={}
|
|
)
|
|
|
|
assert analysis.top_author_share == 0.0
|
|
|
|
def test_get_author_share(self):
|
|
"""Test get_author_share method."""
|
|
analysis = FileAnalysis(
|
|
path="test.py",
|
|
total_commits=10,
|
|
author_commits={"a@x.com": 5, "b@x.com": 5}
|
|
)
|
|
|
|
assert analysis.get_author_share("a@x.com") == 0.5
|
|
assert analysis.get_author_share("b@x.com") == 0.50
|
|
assert analysis.get_author_share("c@x.com") == 0.0
|
|
|
|
def test_module_and_extension(self):
|
|
"""Test module and extension extraction."""
|
|
analysis = FileAnalysis(
|
|
path="src/core/main.py",
|
|
total_commits=5,
|
|
author_commits={},
|
|
module="src/core",
|
|
extension="py"
|
|
)
|
|
|
|
assert analysis.module == "src/core"
|
|
assert analysis.extension == "py"
|
|
|
|
|
|
class TestAuthorStats:
|
|
"""Tests for AuthorStats model."""
|
|
|
|
def test_author_stats_creation(self):
|
|
"""Test creating an AuthorStats instance."""
|
|
stats = AuthorStats(
|
|
name="Test Author",
|
|
email="test@example.com",
|
|
total_commits=100
|
|
)
|
|
|
|
assert stats.name == "Test Author"
|
|
assert stats.email == "test@example.com"
|
|
assert stats.total_commits == 100
|
|
assert len(stats.files_touched) == 0
|
|
|
|
def test_add_file(self):
|
|
"""Test adding a file contribution."""
|
|
stats = AuthorStats(name="Test", email="test@test.com")
|
|
stats.add_file("src/main.py", "src")
|
|
|
|
assert "src/main.py" in stats.files_touched
|
|
assert "src" in stats.modules_contributed
|
|
assert stats.total_contributions == 1
|
|
|
|
def test_merge(self):
|
|
"""Test merging two AuthorStats."""
|
|
stats1 = AuthorStats(name="Test", email="test@test.com")
|
|
stats1.total_commits = 10
|
|
stats1.files_touched = {"file1.py"}
|
|
|
|
stats2 = AuthorStats(name="Test", email="test@test.com")
|
|
stats2.total_commits = 5
|
|
stats2.files_touched = {"file2.py"}
|
|
|
|
stats1.merge(stats2)
|
|
|
|
assert stats1.total_commits == 15
|
|
assert "file1.py" in stats1.files_touched
|
|
assert "file2.py" in stats1.files_touched
|
|
|
|
|
|
class TestRepositoryResult:
|
|
"""Tests for RepositoryResult model."""
|
|
|
|
def test_repository_result_creation(self):
|
|
"""Test creating a RepositoryResult instance."""
|
|
result = RepositoryResult(
|
|
repository_path="/test/repo",
|
|
files_analyzed=100,
|
|
total_commits=500,
|
|
unique_authors=5
|
|
)
|
|
|
|
assert result.repository_path == "/test/repo"
|
|
assert result.files_analyzed == 100
|
|
assert result.total_commits == 500
|
|
assert result.unique_authors == 5
|
|
|
|
def test_risk_count_properties(self):
|
|
"""Test risk count properties."""
|
|
result = RepositoryResult(
|
|
repository_path="/test/repo",
|
|
files=[
|
|
{"risk_level": "critical"},
|
|
{"risk_level": "critical"},
|
|
{"risk_level": "high"},
|
|
{"risk_level": "high"},
|
|
{"risk_level": "medium"},
|
|
{"risk_level": "low"}
|
|
]
|
|
)
|
|
|
|
assert result.high_risk_count == 2
|
|
assert result.medium_risk_count == 1
|
|
assert result.low_risk_count == 1
|
|
|
|
def test_to_dict(self):
|
|
"""Test to_dict serialization."""
|
|
result = RepositoryResult(
|
|
repository_path="/test/repo",
|
|
files_analyzed=10,
|
|
total_commits=50,
|
|
unique_authors=3
|
|
)
|
|
|
|
result_dict = result.to_dict()
|
|
|
|
assert result_dict["repository"] == "/test/repo"
|
|
assert result_dict["files_analyzed"] == 10
|
|
assert "analyzed_at" in result_dict
|