Coverage for tests / unit / ai / test_metadata.py: 100%
50 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 metadata helpers."""
3from __future__ import annotations
5from assertpy import assert_that
7from lintro.ai.metadata import (
8 AIFixSuggestionPayload,
9 AISummaryPayload,
10 attach_fix_suggestions_metadata,
11 attach_fixed_count_metadata,
12 attach_summary_metadata,
13 attach_validation_counts_metadata,
14 normalize_ai_metadata,
15)
16from lintro.ai.models import AIFixSuggestion, AISummary
17from lintro.models.core.tool_result import ToolResult
20def test_metadata_summary_and_fixes_coexist():
21 """Summary and fix_suggestions metadata coexist on a ToolResult."""
22 result = ToolResult(name="ruff", success=True)
23 summary = AISummary(overview="Overview")
24 suggestion = AIFixSuggestion(
25 file="src/main.py",
26 line=1,
27 code="B101",
28 explanation="Replace assert",
29 )
31 attach_summary_metadata(result, summary)
32 attach_fix_suggestions_metadata(result, [suggestion])
34 assert_that(result.ai_metadata).is_not_none()
35 assert_that(result.ai_metadata).contains_key("summary")
36 assert_that(result.ai_metadata).contains_key("fix_suggestions")
37 assert_that(result.ai_metadata["summary"]["overview"]).is_equal_to("Overview") # type: ignore[index] # assertpy is_not_none narrows this
38 assert_that(result.ai_metadata["fix_suggestions"]).is_length(1) # type: ignore[index] # assertpy is_not_none narrows this
41def test_metadata_normalize_supports_legacy_suggestions_key():
42 """Verify that the legacy 'suggestions' key is normalized to 'fix_suggestions'."""
43 raw = {
44 "summary": {"overview": "Legacy summary"},
45 "type": "fix_suggestions",
46 "suggestions": [{"file": "a.py", "line": 1, "code": "E501"}],
47 }
49 normalized = normalize_ai_metadata(raw)
51 assert_that(normalized).contains_key("summary")
52 assert_that(normalized).contains_key("fix_suggestions")
53 assert_that(normalized["fix_suggestions"]).is_length(1)
56def test_metadata_fixed_count_is_attached_and_normalized():
57 """Fixed and validation counts are attached and normalized."""
58 result = ToolResult(name="ruff", success=True)
59 attach_fixed_count_metadata(result, 3)
60 attach_validation_counts_metadata(
61 result,
62 verified_count=2,
63 unverified_count=1,
64 )
66 assert_that(result.ai_metadata).is_not_none()
67 assert_that(result.ai_metadata).contains_key("fixed_count")
68 assert_that(result.ai_metadata).contains_key("applied_count")
69 assert_that(result.ai_metadata).contains_key("verified_count")
70 assert_that(result.ai_metadata).contains_key("unverified_count")
71 assert_that(result.ai_metadata["fixed_count"]).is_equal_to(3) # type: ignore[index] # assertpy is_not_none narrows this
72 assert_that(result.ai_metadata["applied_count"]).is_equal_to(3) # type: ignore[index] # assertpy is_not_none narrows this
73 assert_that(result.ai_metadata["verified_count"]).is_equal_to(2) # type: ignore[index] # assertpy is_not_none narrows this
74 assert_that(result.ai_metadata["unverified_count"]).is_equal_to(1) # type: ignore[index] # assertpy is_not_none narrows this
76 normalized = normalize_ai_metadata(result.ai_metadata or {})
77 assert_that(normalized["fixed_count"]).is_equal_to(3)
78 assert_that(normalized["applied_count"]).is_equal_to(3)
79 assert_that(normalized["verified_count"]).is_equal_to(2)
80 assert_that(normalized["unverified_count"]).is_equal_to(1)
83def test_payload_to_dict_serialization():
84 """Verify that payload to_dict methods serialize fields correctly."""
85 summary = AISummaryPayload(overview="Test overview", estimated_effort="1h")
86 suggestion = AIFixSuggestionPayload(file="a.py", line=10, code="E501")
88 sd = summary.to_dict()
89 assert_that(sd["overview"]).is_equal_to("Test overview")
90 assert_that(sd["estimated_effort"]).is_equal_to("1h")
92 fd = suggestion.to_dict()
93 assert_that(fd["file"]).is_equal_to("a.py")
94 assert_that(fd["line"]).is_equal_to(10)
95 assert_that(fd["code"]).is_equal_to("E501")