Initial upload of ai-code-audit-cli project
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / test (3.9) (push) Has been cancelled
CI / build (push) Has been cancelled
CI / release (push) Has been cancelled

This commit is contained in:
2026-02-03 10:30:19 +00:00
parent 4f0b34b131
commit ef180cc64c

287
tests/test_confidence.py Normal file
View File

@@ -0,0 +1,287 @@
"""Tests for confidence scoring module."""
import pytest
from src.core.models import ScanResult, Issue, IssueCategory, SeverityLevel
from src.reporting.confidence import ConfidenceScorer
class TestConfidenceScorer:
"""Tests for ConfidenceScorer."""
def test_calculate_perfect_score(self, clean_python_code):
"""Test that clean code gets a high score."""
scorer = ConfidenceScorer()
result = ScanResult(files_scanned=1, target_path="/test")
score = scorer.calculate(result)
assert score == 100
def test_calculate_with_issues(self, mock_scan_result):
"""Test score calculation with issues."""
scorer = ConfidenceScorer()
score = scorer.calculate(mock_scan_result)
assert score < 100
assert score >= 0
def test_security_issues_reduce_score_more(self):
"""Test that security issues reduce score more than other issues."""
scorer = ConfidenceScorer()
result_security = ScanResult(files_scanned=1, target_path="/test")
result_security.add_issue(Issue(
severity=SeverityLevel.HIGH,
category=IssueCategory.SECURITY,
file_path="/test.py",
line_number=1,
message="Security issue",
scanner_name="test",
))
result_quality = ScanResult(files_scanned=1, target_path="/test")
result_quality.add_issue(Issue(
severity=SeverityLevel.HIGH,
category=IssueCategory.CODE_QUALITY,
file_path="/test.py",
line_number=1,
message="Quality issue",
scanner_name="test",
))
security_score = scorer.calculate(result_security)
quality_score = scorer.calculate(result_quality)
assert security_score < quality_score
def test_critical_issues_reduce_score_more(self):
"""Test that critical issues reduce score more."""
scorer = ConfidenceScorer()
result_critical = ScanResult(files_scanned=1, target_path="/test")
result_critical.add_issue(Issue(
severity=SeverityLevel.CRITICAL,
category=IssueCategory.SECURITY,
file_path="/test.py",
line_number=1,
message="Critical issue",
scanner_name="test",
))
result_high = ScanResult(files_scanned=1, target_path="/test")
result_high.add_issue(Issue(
severity=SeverityLevel.HIGH,
category=IssueCategory.SECURITY,
file_path="/test.py",
line_number=1,
message="High issue",
scanner_name="test",
))
critical_score = scorer.calculate(result_critical)
high_score = scorer.calculate(result_high)
assert critical_score < high_score
def test_get_score_breakdown(self, mock_scan_result):
"""Test score breakdown generation."""
scorer = ConfidenceScorer()
breakdown = scorer.get_score_breakdown(mock_scan_result)
assert "base_score" in breakdown
assert "total_deductions" in breakdown
assert "final_score" in breakdown
assert "issues_by_category" in breakdown
assert "issues_by_severity" in breakdown
def test_get_score_grade(self):
"""Test score grade calculation."""
scorer = ConfidenceScorer()
assert scorer.get_score_grade(95) == "A+"
assert scorer.get_score_grade(90) == "A"
assert scorer.get_score_grade(85) == "A-"
assert scorer.get_score_grade(80) == "B+"
assert scorer.get_score_grade(75) == "B"
assert scorer.get_score_grade(70) == "B-"
assert scorer.get_score_grade(65) == "C+"
assert scorer.get_score_grade(60) == "C"
assert scorer.get_score_grade(55) == "C-"
assert scorer.get_score_grade(50) == "D+"
assert scorer.get_score_grade(45) == "D"
assert scorer.get_score_grade(40) == "D-"
assert scorer.get_score_grade(30) == "F"
def test_get_score_description(self):
"""Test score description generation."""
scorer = ConfidenceScorer()
desc_90 = scorer.get_score_description(90)
assert "Excellent" in desc_90
desc_75 = scorer.get_score_description(75)
assert "Good" in desc_75
desc_50 = scorer.get_score_description(50)
assert "Poor" in desc_50
desc_25 = scorer.get_score_description(25)
assert "Critical" in desc_25
def test_empty_result_gets_100(self):
"""Test that empty scan result gets 100 score."""
scorer = ConfidenceScorer()
result = ScanResult(files_scanned=0, target_path="/test")
score = scorer.calculate(result)
assert score == 100
def test_score_never_negative(self):
"""Test that score never goes below 0."""
scorer = ConfidenceScorer()
result = ScanResult(files_scanned=1, target_path="/test")
for _ in range(100):
result.add_issue(Issue(
severity=SeverityLevel.CRITICAL,
category=IssueCategory.SECURITY,
file_path="/test.py",
line_number=1,
message="Critical issue",
scanner_name="test",
))
score = scorer.calculate(result)
assert score >= 0
def test_score_never_exceeds_100(self):
"""Test that score never goes above 100."""
scorer = ConfidenceScorer()
result = ScanResult(files_scanned=10, target_path="/test")
score = scorer.calculate(result)
assert score <= 100
class TestIssueModel:
"""Tests for Issue data model."""
def test_issue_to_dict(self):
"""Test issue serialization to dictionary."""
issue = Issue(
severity=SeverityLevel.HIGH,
category=IssueCategory.SECURITY,
file_path="/test.py",
line_number=10,
message="Test issue",
suggestion="Fix this",
scanner_name="test",
)
data = issue.to_dict()
assert data["severity"] == "high"
assert data["category"] == "security"
assert data["file_path"] == "/test.py"
assert data["line_number"] == 10
assert data["message"] == "Test issue"
assert data["suggestion"] == "Fix this"
assert data["scanner_name"] == "test"
class TestScanResultModel:
"""Tests for ScanResult data model."""
def test_add_issue(self):
"""Test adding issues to scan result."""
result = ScanResult(files_scanned=1, target_path="/test")
issue = Issue(
severity=SeverityLevel.LOW,
category=IssueCategory.STYLE,
file_path="/test.py",
line_number=1,
message="Style issue",
scanner_name="test",
)
result.add_issue(issue)
assert len(result.issues) == 1
assert result.issues[0] == issue
def test_add_warning(self):
"""Test adding warnings to scan result."""
result = ScanResult(files_scanned=1, target_path="/test")
result.add_warning("Test warning")
assert len(result.warnings) == 1
assert result.warnings[0] == "Test warning"
def test_filter_by_severity(self):
"""Test filtering issues by severity."""
result = ScanResult(files_scanned=1, target_path="/test")
result.add_issue(Issue(
severity=SeverityLevel.LOW,
category=IssueCategory.STYLE,
file_path="/test.py",
line_number=1,
message="Low issue",
scanner_name="test",
))
result.add_issue(Issue(
severity=SeverityLevel.CRITICAL,
category=IssueCategory.SECURITY,
file_path="/test.py",
line_number=2,
message="Critical issue",
scanner_name="test",
))
filtered = result.filter_by_severity(SeverityLevel.HIGH)
assert len(filtered.issues) == 1
assert filtered.issues[0].severity == SeverityLevel.CRITICAL
def test_get_summary(self):
"""Test getting scan summary."""
result = ScanResult(files_scanned=2, target_path="/test")
result.add_issue(Issue(
severity=SeverityLevel.HIGH,
category=IssueCategory.SECURITY,
file_path="/test.py",
line_number=1,
message="Issue 1",
scanner_name="test",
))
result.add_issue(Issue(
severity=SeverityLevel.LOW,
category=IssueCategory.STYLE,
file_path="/test.py",
line_number=2,
message="Issue 2",
scanner_name="test",
))
summary = result.get_summary()
assert summary["files_scanned"] == 2
assert summary["total_issues"] == 2
assert "high" in summary["issues_by_severity"]
assert "low" in summary["issues_by_severity"]
assert "security" in summary["issues_by_category"]
assert "style" in summary["issues_by_category"]
def test_to_dict(self):
"""Test scan result serialization to dictionary."""
result = ScanResult(files_scanned=1, target_path="/test")
result.add_issue(Issue(
severity=SeverityLevel.MEDIUM,
category=IssueCategory.CODE_QUALITY,
file_path="/test.py",
line_number=5,
message="Test issue",
scanner_name="test",
))
data = result.to_dict()
assert data["files_scanned"] == 1
assert data["target_path"] == "/test"
assert len(data["issues"]) == 1
assert data["issues"][0]["severity"] == "medium"