Coverage for tests / unit / ai / test_summary_formatting.py: 100%
74 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Tests for AI summary formatting and rendering.
3Covers render_summary_terminal, render_summary_github,
4and render_summary_markdown.
5"""
7from __future__ import annotations
9from assertpy import assert_that
11from lintro.ai.display import (
12 render_summary_github,
13 render_summary_markdown,
14 render_summary_terminal,
15)
16from lintro.ai.models import AISummary
18# -- render_summary_terminal --------------------------------------------------
21def test_render_summary_terminal_renders_overview():
22 """Verify terminal rendering includes overview, patterns, actions, and effort."""
23 summary = AISummary(
24 overview="Code quality is good overall.",
25 key_patterns=["Missing docstrings"],
26 priority_actions=["Add docstrings to public functions"],
27 estimated_effort="15 minutes",
28 )
29 output = render_summary_terminal(summary)
30 assert_that(output).contains("Code quality is good overall")
31 assert_that(output).contains("Missing docstrings")
32 assert_that(output).contains("Add docstrings")
33 assert_that(output).contains("15 minutes")
36def test_render_summary_terminal_empty_summary():
37 """Verify an empty AISummary produces empty terminal output."""
38 summary = AISummary()
39 output = render_summary_terminal(summary)
40 assert_that(output).is_empty()
43def test_render_summary_terminal_cost_display():
44 """Verify token cost is shown or hidden based on the show_cost flag."""
45 summary = AISummary(
46 overview="Test",
47 input_tokens=100,
48 output_tokens=50,
49 cost_estimate=0.005,
50 )
51 with_cost = render_summary_terminal(summary, show_cost=True)
52 assert_that(with_cost).contains("~150")
54 without_cost = render_summary_terminal(summary, show_cost=False)
55 assert_that(without_cost).does_not_contain("~150")
58def test_render_summary_terminal_strips_leading_numbers_from_priority_actions():
59 """Leading number prefixes are stripped from priority actions."""
60 summary = AISummary(
61 overview="Test",
62 priority_actions=[
63 "1. Fix OpenAI imports",
64 "2) Replace asserts",
65 "No number prefix here",
66 ],
67 )
68 output = render_summary_terminal(summary)
69 # Should not have double numbering like "1. 1. Fix"
70 assert_that(output).does_not_contain("1. 1.")
71 assert_that(output).does_not_contain("2. 2)")
72 # Content should still appear
73 assert_that(output).contains("Fix OpenAI imports")
74 assert_that(output).contains("Replace asserts")
75 assert_that(output).contains("No number prefix here")
78def test_render_summary_terminal_renders_triage_suggestions():
79 """Terminal rendering includes triage with stripped prefixes."""
80 summary = AISummary(
81 overview="Issues found",
82 triage_suggestions=[
83 "B101 in test files — assert is idiomatic, add # noqa: B101",
84 "1. E501 in generated code — long lines expected",
85 ],
86 )
87 output = render_summary_terminal(summary)
88 assert_that(output).contains("Triage")
89 assert_that(output).contains("B101 in test files")
90 # Leading number should be stripped
91 assert_that(output).contains("E501 in generated code")
94def test_render_summary_terminal_omits_triage_when_empty():
95 """Triage section is omitted when suggestions are empty."""
96 summary = AISummary(overview="Clean code", triage_suggestions=[])
97 output = render_summary_terminal(summary)
98 assert_that(output).does_not_contain("Triage")
101# -- render_summary_github ----------------------------------------------------
104def test_render_summary_github_renders_with_groups():
105 """Verify GitHub rendering wraps content in ::group::/::endgroup:: markers."""
106 summary = AISummary(
107 overview="Issues found",
108 key_patterns=["Pattern A"],
109 priority_actions=["Fix A"],
110 )
111 output = render_summary_github(summary)
112 assert_that(output).contains("::group::")
113 assert_that(output).contains("::endgroup::")
114 assert_that(output).contains("Issues found")
115 assert_that(output).contains("Pattern A")
118def test_render_summary_github_strips_leading_numbers_from_priority_actions():
119 """Verify GitHub rendering strips leading number prefixes from priority actions."""
120 summary = AISummary(
121 overview="Test",
122 priority_actions=["1. Fix imports", "2. Add tests"],
123 )
124 output = render_summary_github(summary)
125 assert_that(output).does_not_contain("1. 1.")
126 assert_that(output).contains("Fix imports")
129def test_render_summary_github_renders_triage_suggestions():
130 """Verify GitHub rendering includes triage suggestions section."""
131 summary = AISummary(
132 overview="Issues found",
133 triage_suggestions=[
134 "B101 in test files — assert is idiomatic, add # noqa: B101",
135 "E501 in generated code — long lines are expected",
136 ],
137 )
138 output = render_summary_github(summary)
139 assert_that(output).contains("Triage")
140 assert_that(output).contains("B101 in test files")
141 assert_that(output).contains("E501 in generated code")
144def test_render_summary_github_omits_triage_when_empty():
145 """Triage section omitted from GitHub output when empty."""
146 summary = AISummary(overview="Clean code", triage_suggestions=[])
147 output = render_summary_github(summary)
148 assert_that(output).does_not_contain("Triage")
151# -- render_summary_markdown ---------------------------------------------------
154def test_render_summary_markdown_renders_with_details():
155 """Verify markdown rendering wraps content in HTML details/summary tags."""
156 summary = AISummary(
157 overview="Some issues",
158 key_patterns=["Pattern X"],
159 priority_actions=["Action Y"],
160 estimated_effort="1 hour",
161 )
162 output = render_summary_markdown(summary)
163 assert_that(output).contains("<details>")
164 assert_that(output).contains("</details>")
165 assert_that(output).contains("Some issues")
166 assert_that(output).contains("Pattern X")
167 assert_that(output).contains("1 hour")
170def test_render_summary_markdown_renders_triage_suggestions():
171 """Verify markdown rendering includes triage suggestions section."""
172 summary = AISummary(
173 overview="Issues found",
174 triage_suggestions=[
175 "B101 in test files — assert is idiomatic, add # noqa: B101",
176 ],
177 )
178 output = render_summary_markdown(summary)
179 assert_that(output).contains("Triage")
180 assert_that(output).contains("B101 in test files")