"""Additional edge case tests for formatters to ensure robustness."""
from arcade_cli.formatters import (
HtmlFormatter,
JsonFormatter,
MarkdownFormatter,
TextFormatter,
)
class MockEvaluation:
"""Mock EvaluationResult for testing."""
def __init__(
self,
passed: bool = True,
warning: bool = False,
score: float = 1.0,
failure_reason: str | None = None,
results: list[dict] | None = None,
):
self.passed = passed
self.warning = warning
self.score = score
self.failure_reason = failure_reason
self.results = results or []
def make_empty_results() -> list[list[dict]]:
"""Create empty evaluation results."""
return [[{"model": "gpt-4o", "suite_name": "empty_suite", "rubric": "Test", "cases": []}]]
class TestFormatterEdgeCases:
"""Test edge cases that might not be covered elsewhere."""
def test_empty_results_all_formatters(self) -> None:
"""All formatters should handle empty results gracefully."""
results = make_empty_results()
for formatter_class in [TextFormatter, MarkdownFormatter, HtmlFormatter, JsonFormatter]:
formatter = formatter_class()
output = formatter.format(results)
assert output # Should produce some output
assert "0" in output or "Total: 0" in output.lower() or '"total_cases": 0' in output
def test_failed_only_with_zero_original_total(self) -> None:
"""Should handle original_counts with zero total without crashing."""
results = make_empty_results()
# Edge case: original_counts with 0 total (shouldn't happen in practice but should be safe)
original_counts = (0, 0, 0, 0)
for formatter_class in [TextFormatter, MarkdownFormatter, HtmlFormatter, JsonFormatter]:
formatter = formatter_class()
# Should not raise ZeroDivisionError
output = formatter.format(results, failed_only=True, original_counts=original_counts)
assert output # Should produce some output
def test_failed_only_with_empty_results_but_nonzero_original(self) -> None:
"""Should handle case where filtered results are empty but original had cases."""
results = make_empty_results()
# All cases were filtered out, but there were originally 5 cases (all passed)
original_counts = (5, 5, 0, 0)
for formatter_class in [TextFormatter, MarkdownFormatter, HtmlFormatter, JsonFormatter]:
formatter = formatter_class()
output = formatter.format(results, failed_only=True, original_counts=original_counts)
assert output
# Should show original counts
assert "5" in output
def test_all_formatters_handle_none_original_counts(self) -> None:
"""All formatters should handle None original_counts gracefully."""
results = [[{
"model": "gpt-4o",
"suite_name": "test",
"rubric": "Test",
"cases": [{
"name": "test_case",
"input": "test",
"evaluation": MockEvaluation(passed=False, score=0.0),
}],
}]]
for formatter_class in [TextFormatter, MarkdownFormatter, HtmlFormatter, JsonFormatter]:
formatter = formatter_class()
# Should not crash with None original_counts
output = formatter.format(results, failed_only=True, original_counts=None)
assert output
def test_comparative_with_missing_track_data(self) -> None:
"""Comparative formatters should handle missing track gracefully."""
# Create comparative result where one track is missing data
results = [[
{
"model": "gpt-4o",
"suite_name": "Test Suite [track_a]",
"track_name": "track_a",
"rubric": None,
"cases": [{
"name": "test_case",
"input": "test",
"evaluation": MockEvaluation(passed=True, score=1.0),
}],
},
{
"model": "gpt-4o",
"suite_name": "Test Suite [track_b]",
"track_name": "track_b",
"rubric": None,
"cases": [], # Empty cases for this track
},
]]
for formatter_class in [TextFormatter, MarkdownFormatter, HtmlFormatter, JsonFormatter]:
formatter = formatter_class()
output = formatter.format(results)
assert output
# Should mention both tracks
assert "track_a" in output
assert "track_b" in output
def test_html_formatter_escapes_all_special_chars(self) -> None:
"""HTML formatter must escape all special characters to prevent XSS."""
results = [[{
"model": "gpt-4o",
"suite_name": "Suite & Test",
"rubric": "Test",
"cases": [{
"name": "
",
"input": "test' OR '1'='1",
"evaluation": MockEvaluation(
passed=False,
score=0.0,
failure_reason="Error: ",
),
}],
}]]
formatter = HtmlFormatter()
output = formatter.format(results)
# The template includes a legitimate