"""Tests for data models.""" from repohealth.models.author import AuthorStats from repohealth.models.file_stats import FileAnalysis from repohealth.models.result import RepositoryResult 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