Coverage for tests / unit / utils / test_config_reporting.py: 100%
84 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"""Unit tests for config_reporting module."""
3from __future__ import annotations
5from typing import Any
6from unittest.mock import MagicMock, patch
8import pytest
9from assertpy import assert_that
11from lintro.utils.config_reporting import get_config_report, print_config_report
14@pytest.fixture
15def mock_tool_config_summary() -> dict[str, Any]:
16 """Create mock tool config summary.
18 Returns:
19 Dictionary containing mock tool config summary.
20 """
21 mock_info = MagicMock()
22 mock_info.is_injectable = True
23 mock_info.effective_config = {"line_length": 88}
24 mock_info.lintro_tool_config = {"line_length": 88}
25 mock_info.native_config = None
26 return {"ruff": mock_info}
29@pytest.fixture
30def standard_patches(mock_tool_config_summary: dict[str, Any]) -> tuple[Any, ...]:
31 """Provide standard patches for get_config_report tests.
33 Args:
34 mock_tool_config_summary: Mock tool config summary fixture.
36 Returns:
37 Tuple of patch objects for testing.
38 """
39 return (
40 patch(
41 "lintro.utils.unified_config.get_tool_config_summary",
42 return_value=mock_tool_config_summary,
43 ),
44 patch(
45 "lintro.utils.config_reporting.get_effective_line_length",
46 return_value=88,
47 ),
48 patch(
49 "lintro.utils.config_reporting.get_tool_order_config",
50 return_value={"strategy": "priority"},
51 ),
52 patch(
53 "lintro.utils.config_reporting.get_ordered_tools",
54 return_value=["ruff"],
55 ),
56 patch(
57 "lintro.utils.config_reporting.get_tool_priority",
58 return_value=100,
59 ),
60 patch(
61 "lintro.utils.config_reporting.validate_config_consistency",
62 return_value=[],
63 ),
64 )
67# --- get_config_report tests ---
70def test_report_contains_header(standard_patches: tuple[Any, ...]) -> None:
71 """Test report contains header section.
73 Args:
74 standard_patches: Standard patches for testing.
75 """
76 with (
77 standard_patches[0],
78 standard_patches[1],
79 standard_patches[2],
80 standard_patches[3],
81 standard_patches[4],
82 standard_patches[5],
83 ):
84 report = get_config_report()
86 assert_that(report).contains("LINTRO CONFIGURATION REPORT")
87 assert_that(report).contains("=" * 60)
90def test_report_contains_global_settings(standard_patches: tuple[Any, ...]) -> None:
91 """Test report contains global settings section.
93 Args:
94 standard_patches: Standard patches for testing.
95 """
96 with (
97 standard_patches[0],
98 standard_patches[1],
99 standard_patches[2],
100 standard_patches[3],
101 standard_patches[4],
102 standard_patches[5],
103 ):
104 report = get_config_report()
106 assert_that(report).contains("── Global Settings ──")
107 assert_that(report).contains("Central line_length: 88")
108 assert_that(report).contains("Tool order strategy: priority")
111def test_report_contains_tool_execution_order(
112 standard_patches: tuple[Any, ...],
113) -> None:
114 """Test report contains tool execution order section.
116 Args:
117 standard_patches: Standard patches for testing.
118 """
119 with (
120 standard_patches[0],
121 standard_patches[1],
122 standard_patches[2],
123 standard_patches[3],
124 standard_patches[4],
125 standard_patches[5],
126 ):
127 report = get_config_report()
129 assert_that(report).contains("── Tool Execution Order ──")
130 assert_that(report).contains("1. ruff (priority: 100)")
133def test_report_contains_per_tool_config(standard_patches: tuple[Any, ...]) -> None:
134 """Test report contains per-tool configuration section.
136 Args:
137 standard_patches: Standard patches for testing.
138 """
139 with (
140 standard_patches[0],
141 standard_patches[1],
142 standard_patches[2],
143 standard_patches[3],
144 standard_patches[4],
145 standard_patches[5],
146 ):
147 report = get_config_report()
149 assert_that(report).contains("── Per-Tool Configuration ──")
150 assert_that(report).contains("ruff:")
151 assert_that(report).contains("Status: ✅ Syncable")
152 assert_that(report).contains("Effective line_length: 88")
155def test_report_shows_native_only_for_non_injectable() -> None:
156 """Test non-injectable tools show native only status."""
157 mock_info = MagicMock()
158 mock_info.is_injectable = False
159 mock_info.effective_config = {"line_length": 80}
160 mock_info.lintro_tool_config = None
161 mock_info.native_config = {"some": "config"}
163 with (
164 patch(
165 "lintro.utils.unified_config.get_tool_config_summary",
166 return_value={"prettier": mock_info},
167 ),
168 patch(
169 "lintro.utils.config_reporting.get_effective_line_length",
170 return_value=88,
171 ),
172 patch(
173 "lintro.utils.config_reporting.get_tool_order_config",
174 return_value={"strategy": "priority"},
175 ),
176 patch(
177 "lintro.utils.config_reporting.get_ordered_tools",
178 return_value=["prettier"],
179 ),
180 patch(
181 "lintro.utils.config_reporting.get_tool_priority",
182 return_value=50,
183 ),
184 patch(
185 "lintro.utils.config_reporting.validate_config_consistency",
186 return_value=[],
187 ),
188 ):
189 report = get_config_report()
190 assert_that(report).contains("Status: ⚠️ Native only")
193def test_report_shows_warnings(standard_patches: tuple[Any, ...]) -> None:
194 """Test report shows warnings when present.
196 Args:
197 standard_patches: Standard patches for testing.
198 """
199 warnings = ["Warning 1: Config mismatch", "Warning 2: Missing config"]
201 with (
202 standard_patches[0],
203 standard_patches[1],
204 standard_patches[2],
205 standard_patches[3],
206 standard_patches[4],
207 patch(
208 "lintro.utils.config_reporting.validate_config_consistency",
209 return_value=warnings,
210 ),
211 ):
212 report = get_config_report()
214 assert_that(report).contains("── Configuration Warnings ──")
215 assert_that(report).contains("Warning 1: Config mismatch")
216 assert_that(report).contains("Warning 2: Missing config")
219def test_report_shows_no_warnings_message(standard_patches: tuple[Any, ...]) -> None:
220 """Test report shows no warnings message when consistent.
222 Args:
223 standard_patches: Standard patches for testing.
224 """
225 with (
226 standard_patches[0],
227 standard_patches[1],
228 standard_patches[2],
229 standard_patches[3],
230 standard_patches[4],
231 standard_patches[5],
232 ):
233 report = get_config_report()
234 assert_that(report).contains("None - all configs consistent!")
237def test_report_with_custom_order(mock_tool_config_summary: dict[str, Any]) -> None:
238 """Test report shows custom order when configured.
240 Args:
241 mock_tool_config_summary: Mock tool config summary.
242 """
243 with (
244 patch(
245 "lintro.utils.unified_config.get_tool_config_summary",
246 return_value=mock_tool_config_summary,
247 ),
248 patch(
249 "lintro.utils.config_reporting.get_effective_line_length",
250 return_value=88,
251 ),
252 patch(
253 "lintro.utils.config_reporting.get_tool_order_config",
254 return_value={"strategy": "custom", "custom_order": ["ruff", "mypy"]},
255 ),
256 patch(
257 "lintro.utils.config_reporting.get_ordered_tools",
258 return_value=["ruff"],
259 ),
260 patch(
261 "lintro.utils.config_reporting.get_tool_priority",
262 return_value=100,
263 ),
264 patch(
265 "lintro.utils.config_reporting.validate_config_consistency",
266 return_value=[],
267 ),
268 ):
269 report = get_config_report()
270 assert_that(report).contains("Custom order: ruff, mypy")
273def test_report_line_length_not_configured(
274 mock_tool_config_summary: dict[str, Any],
275) -> None:
276 """Test report shows Not configured when line_length is None.
278 Args:
279 mock_tool_config_summary: Mock tool config summary.
280 """
281 with (
282 patch(
283 "lintro.utils.unified_config.get_tool_config_summary",
284 return_value=mock_tool_config_summary,
285 ),
286 patch(
287 "lintro.utils.config_reporting.get_effective_line_length",
288 return_value=None,
289 ),
290 patch(
291 "lintro.utils.config_reporting.get_tool_order_config",
292 return_value={"strategy": "priority"},
293 ),
294 patch(
295 "lintro.utils.config_reporting.get_ordered_tools",
296 return_value=["ruff"],
297 ),
298 patch(
299 "lintro.utils.config_reporting.get_tool_priority",
300 return_value=100,
301 ),
302 patch(
303 "lintro.utils.config_reporting.validate_config_consistency",
304 return_value=[],
305 ),
306 ):
307 report = get_config_report()
308 assert_that(report).contains("Central line_length: Not configured")
311# --- print_config_report tests ---
314def test_print_logs_report_lines() -> None:
315 """Test that report lines are logged."""
316 mock_report = "── Global Settings ──\n line_length: 88\n── End ──"
318 with (
319 patch(
320 "lintro.utils.config_reporting.get_config_report",
321 return_value=mock_report,
322 ),
323 patch("lintro.utils.config_reporting.logger") as mock_logger,
324 ):
325 print_config_report()
326 assert_that(mock_logger.info.called).is_true()
329def test_print_warnings_logged_at_warning_level() -> None:
330 """Test that warnings section lines are logged at warning level."""
331 mock_report = (
332 "── Configuration Warnings ──\n" " Warning: Config mismatch\n" "── End ──"
333 )
335 with (
336 patch(
337 "lintro.utils.config_reporting.get_config_report",
338 return_value=mock_report,
339 ),
340 patch("lintro.utils.config_reporting.logger") as mock_logger,
341 ):
342 print_config_report()
343 warning_calls = list(mock_logger.warning.call_args_list)
344 assert_that(len(warning_calls)).is_greater_than(0)
347def test_print_non_warning_lines_logged_at_info() -> None:
348 """Test that non-warning lines are logged at info level."""
349 mock_report = "── Global Settings ──\n line_length: 88"
351 with (
352 patch(
353 "lintro.utils.config_reporting.get_config_report",
354 return_value=mock_report,
355 ),
356 patch("lintro.utils.config_reporting.logger") as mock_logger,
357 ):
358 print_config_report()
359 assert_that(mock_logger.info.called).is_true()