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

1"""Tests for AI metadata helpers.""" 

2 

3from __future__ import annotations 

4 

5from assertpy import assert_that 

6 

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 

18 

19 

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 ) 

30 

31 attach_summary_metadata(result, summary) 

32 attach_fix_suggestions_metadata(result, [suggestion]) 

33 

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 

39 

40 

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 } 

48 

49 normalized = normalize_ai_metadata(raw) 

50 

51 assert_that(normalized).contains_key("summary") 

52 assert_that(normalized).contains_key("fix_suggestions") 

53 assert_that(normalized["fix_suggestions"]).is_length(1) 

54 

55 

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 ) 

65 

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 

75 

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) 

81 

82 

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") 

87 

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") 

91 

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")