Coverage for tests / unit / formatters / test_format_fix_results.py: 100%

46 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-06 17:46 +0000

1"""Tests for format_fix_results function. 

2 

3Verifies the two-table display for fix mode: "Detected issues" and 

4"Remaining issues" tables, plus the "All issues were auto-fixed" message. 

5""" 

6 

7from __future__ import annotations 

8 

9from assertpy import assert_that 

10 

11from lintro.formatters.formatter import format_fix_results 

12from lintro.parsers.ruff.ruff_issue import RuffIssue 

13 

14 

15def _make_issue( 

16 file: str = "src/main.py", 

17 line: int = 1, 

18 code: str = "F401", 

19 message: str = "unused import", 

20) -> RuffIssue: 

21 """Create a RuffIssue for testing. 

22 

23 Args: 

24 file: File path. 

25 line: Line number. 

26 code: Rule code. 

27 message: Issue message. 

28 

29 Returns: 

30 A RuffIssue instance. 

31 """ 

32 return RuffIssue(file=file, line=line, column=1, code=code, message=message) 

33 

34 

35def test_all_fixed_shows_auto_fixed_message() -> None: 

36 """When remaining is empty, show 'All issues were auto-fixed.'.""" 

37 detected = [_make_issue()] 

38 result = format_fix_results(detected, remaining_issues=None) 

39 

40 assert_that(result).contains("Detected issues (1)") 

41 assert_that(result).contains("All issues were auto-fixed.") 

42 

43 

44def test_all_fixed_with_empty_list() -> None: 

45 """When remaining is an empty list, show 'All issues were auto-fixed.'.""" 

46 detected = [_make_issue(), _make_issue(line=2, code="E501")] 

47 result = format_fix_results(detected, remaining_issues=[]) 

48 

49 assert_that(result).contains("Detected issues (2)") 

50 assert_that(result).contains("All issues were auto-fixed.") 

51 

52 

53def test_partial_fix_shows_both_tables() -> None: 

54 """When some issues remain, show both Detected and Remaining tables.""" 

55 detected = [ 

56 _make_issue(code="F401"), 

57 _make_issue(line=5, code="E501", message="line too long"), 

58 ] 

59 remaining = [_make_issue(line=5, code="E501", message="line too long")] 

60 result = format_fix_results(detected, remaining_issues=remaining) 

61 

62 assert_that(result).contains("Detected issues (2)") 

63 assert_that(result).contains("Remaining issues (1)") 

64 assert_that(result).does_not_contain("All issues were auto-fixed.") 

65 

66 

67def test_no_detected_issues() -> None: 

68 """When no issues were detected, return 'No issues found.'.""" 

69 result = format_fix_results([], remaining_issues=None) 

70 

71 assert_that(result).is_equal_to("No issues found.") 

72 

73 

74def test_json_format_merges_tables() -> None: 

75 """JSON format combines detected and remaining into one output.""" 

76 detected = [_make_issue(code="F401")] 

77 remaining = [_make_issue(line=5, code="E501", message="line too long")] 

78 result = format_fix_results( 

79 detected, 

80 remaining_issues=remaining, 

81 output_format="json", 

82 ) 

83 

84 assert_that(result).does_not_contain("Detected issues") 

85 assert_that(result).does_not_contain("Remaining issues") 

86 # JSON output should contain both issues 

87 assert_that(result).contains("F401") 

88 assert_that(result).contains("E501") 

89 

90 

91def test_json_format_deduplicates() -> None: 

92 """JSON dedupes by attributes, not object identity. 

93 

94 Construct two distinct RuffIssue instances with identical attributes 

95 to verify the key used for deduplication is attribute-based. 

96 """ 

97 detected_issue = _make_issue(code="E501", message="line too long") 

98 remaining_issue = _make_issue(code="E501", message="line too long") 

99 # Sanity check: these are different instances 

100 assert_that(detected_issue).is_not_same_as(remaining_issue) 

101 

102 result = format_fix_results( 

103 [detected_issue], 

104 remaining_issues=[remaining_issue], 

105 output_format="json", 

106 ) 

107 

108 # Should only appear once after deduplication 

109 assert_that(result.count('"E501"')).is_equal_to(1) 

110 

111 

112def test_detected_table_contains_issue_details() -> None: 

113 """Detected table includes file, line, and code from issues.""" 

114 detected = [_make_issue(file="app.py", line=42, code="W291")] 

115 result = format_fix_results(detected, remaining_issues=None) 

116 

117 assert_that(result).contains("app.py") 

118 assert_that(result).contains("42") 

119 assert_that(result).contains("W291")