diff --git a/tests/integration/test_reports.py b/tests/integration/test_reports.py new file mode 100644 index 0000000..fb57a49 --- /dev/null +++ b/tests/integration/test_reports.py @@ -0,0 +1,213 @@ +"""Integration tests for reports.""" + +import json +import tempfile +from pathlib import Path + +import pytest +from vibeguard.reports.generator import ReportGenerator + + +class TestReportGenerator: + """Tests for report generator.""" + + def test_generate_json_report(self, tmp_path): + """Test generating JSON report.""" + issues = [ + { + "pattern": "PY001", + "severity": "warning", + "file": "test.py", + "line": 1, + "message": "Magic string detected", + "suggestion": "Extract to constant", + } + ] + + output_path = tmp_path / "report.json" + generator = ReportGenerator() + + generator.generate_json(issues, str(output_path)) + + assert output_path.exists() + + with open(output_path) as f: + report = json.load(f) + + assert "version" in report + assert "timestamp" in report + assert "summary" in report + assert "issues" in report + assert len(report["issues"]) == 1 + + def test_load_json_report(self, tmp_path): + """Test loading issues from JSON file.""" + issues = [ + { + "pattern": "PY001", + "severity": "warning", + "file": "test.py", + "line": 1, + "message": "Magic string detected", + "suggestion": "Extract to constant", + } + ] + + input_file = tmp_path / "input.json" + input_file.write_text(json.dumps({"issues": issues})) + + generator = ReportGenerator() + loaded_issues = generator.load_json(str(input_file)) + + assert len(loaded_issues) == 1 + assert loaded_issues[0]["pattern"] == "PY001" + + def test_generate_sarif_report(self, tmp_path): + """Test generating SARIF report.""" + issues = [ + { + "pattern": "PY001", + "severity": "warning", + "file": "test.py", + "line": 1, + "message": "Magic string detected", + "suggestion": "Extract to constant", + } + ] + + output_path = tmp_path / "report.sarif" + generator = ReportGenerator() + + generator.generate_sarif(issues, str(output_path)) + + assert output_path.exists() + + with open(output_path) as f: + sarif = json.load(f) + + assert "$schema" in sarif + assert sarif["version"] == "2.1.0" + assert "runs" in sarif + assert len(sarif["runs"]) == 1 + + def test_sarif_rule_generation(self, tmp_path): + """Test SARIF rule generation.""" + issues = [ + { + "pattern": "PY001", + "severity": "warning", + "file": "test.py", + "line": 1, + "message": "Test message", + "suggestion": "Test suggestion", + }, + { + "pattern": "PY002", + "severity": "error", + "file": "test.py", + "line": 2, + "message": "Test message 2", + "suggestion": "Test suggestion 2", + }, + ] + + output_path = tmp_path / "report.sarif" + generator = ReportGenerator() + + generator.generate_sarif(issues, str(output_path)) + + with open(output_path) as f: + sarif = json.load(f) + + rules = sarif["runs"][0]["tool"]["driver"]["rules"] + assert len(rules) == 2 + + def test_sarif_severity_mapping(self, tmp_path): + """Test SARIF severity level mapping.""" + test_cases = [ + ("critical", "error"), + ("error", "error"), + ("warning", "warning"), + ("info", "note"), + ] + + for vibeguard_severity, expected_sarif in test_cases: + issues = [ + { + "pattern": "TEST", + "severity": vibeguard_severity, + "file": "test.py", + "line": 1, + "message": "Test", + "suggestion": "Test", + } + ] + + output_path = tmp_path / "report.sarif" + generator = ReportGenerator() + + generator.generate_sarif(issues, str(output_path)) + + with open(output_path) as f: + sarif = json.load(f) + + result = sarif["runs"][0]["results"][0] + assert result["level"] == expected_sarif + + def test_summary_generation(self, tmp_path): + """Test summary generation.""" + issues = [ + {"pattern": "P1", "severity": "critical"}, + {"pattern": "P2", "severity": "error"}, + {"pattern": "P3", "severity": "error"}, + {"pattern": "P4", "severity": "warning"}, + {"pattern": "P5", "severity": "warning"}, + {"pattern": "P6", "severity": "warning"}, + {"pattern": "P7", "severity": "info"}, + ] + + generator = ReportGenerator() + summary = generator._generate_summary(issues) + + assert summary["critical"] == 1 + assert summary["error"] == 2 + assert summary["warning"] == 3 + assert summary["info"] == 1 + assert summary["total"] == 7 + + def test_empty_issues(self, tmp_path): + """Test report generation with no issues.""" + generator = ReportGenerator() + + output_path = tmp_path / "report.json" + generator.generate_json([], str(output_path)) + + with open(output_path) as f: + report = json.load(f) + + assert report["summary"]["total"] == 0 + + def test_html_report_generation(self, tmp_path): + """Test HTML report generation.""" + issues = [ + { + "pattern": "PY001", + "severity": "warning", + "file": "test.py", + "line": 1, + "message": "Magic string detected", + "suggestion": "Extract to constant", + } + ] + + output_path = tmp_path / "report.html" + generator = ReportGenerator() + + generator.generate_html(issues, str(output_path)) + + assert output_path.exists() + + content = output_path.read_text() + assert "VibeGuard Analysis Report" in content + assert "Magic string detected" in content + assert "PY001" in content