Coverage for tests / unit / tools / rustfmt / test_fix_method.py: 100%

62 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-05 16:51 +0000

1"""Tests for RustfmtPlugin.fix method initial_issues population.""" 

2 

3from __future__ import annotations 

4 

5from pathlib import Path 

6from unittest.mock import patch 

7 

8from assertpy import assert_that 

9 

10from lintro.tools.definitions.rustfmt import RustfmtPlugin 

11 

12 

13def test_fix_populates_initial_issues( 

14 rustfmt_plugin: RustfmtPlugin, 

15 tmp_path: Path, 

16) -> None: 

17 """Fix populates initial_issues when issues are found and fixed. 

18 

19 Args: 

20 rustfmt_plugin: The RustfmtPlugin instance to test. 

21 tmp_path: Temporary directory path for test files. 

22 """ 

23 cargo_toml = tmp_path / "Cargo.toml" 

24 cargo_toml.write_text('[package]\nname = "test"\nversion = "0.1.0"') 

25 

26 test_file = tmp_path / "src" / "main.rs" 

27 test_file.parent.mkdir(parents=True, exist_ok=True) 

28 test_file.write_text("fn main(){}") 

29 

30 call_count = 0 

31 

32 def mock_run( 

33 cmd: list[str], 

34 timeout: int, 

35 cwd: str | None = None, 

36 ) -> tuple[bool, str]: 

37 """Mock subprocess for check→fix→verify. 

38 

39 Args: 

40 cmd: Command list. 

41 timeout: Timeout in seconds. 

42 cwd: Working directory. 

43 

44 Returns: 

45 Tuple of (success, output). 

46 """ 

47 nonlocal call_count 

48 call_count += 1 

49 if call_count == 1: 

50 return (False, "Diff in src/main.rs:1:") 

51 elif call_count == 2: 

52 return (True, "") 

53 else: 

54 return (True, "") 

55 

56 with patch( 

57 "lintro.plugins.execution_preparation.verify_tool_version", 

58 return_value=None, 

59 ): 

60 with patch.object(rustfmt_plugin, "_run_subprocess", side_effect=mock_run): 

61 result = rustfmt_plugin.fix([str(test_file)], {}) 

62 

63 assert_that(result.success).is_true() 

64 assert_that(result.initial_issues).is_not_none() 

65 assert_that(result.initial_issues).is_length(1) 

66 assert_that(result.initial_issues_count).is_equal_to(1) 

67 assert_that(result.fixed_issues_count).is_equal_to(1) 

68 assert_that(result.remaining_issues_count).is_equal_to(0) 

69 

70 

71def test_fix_initial_issues_none_when_no_issues( 

72 rustfmt_plugin: RustfmtPlugin, 

73 tmp_path: Path, 

74) -> None: 

75 """Fix sets initial_issues to None when no issues detected. 

76 

77 Args: 

78 rustfmt_plugin: The RustfmtPlugin instance to test. 

79 tmp_path: Temporary directory path for test files. 

80 """ 

81 cargo_toml = tmp_path / "Cargo.toml" 

82 cargo_toml.write_text('[package]\nname = "test"\nversion = "0.1.0"') 

83 

84 test_file = tmp_path / "src" / "main.rs" 

85 test_file.parent.mkdir(parents=True, exist_ok=True) 

86 test_file.write_text("fn main() {}\n") 

87 

88 with patch( 

89 "lintro.plugins.execution_preparation.verify_tool_version", 

90 return_value=None, 

91 ): 

92 with patch.object( 

93 rustfmt_plugin, 

94 "_run_subprocess", 

95 return_value=(True, ""), 

96 ): 

97 result = rustfmt_plugin.fix([str(test_file)], {}) 

98 

99 assert_that(result.success).is_true() 

100 assert_that(result.initial_issues).is_none() 

101 

102 

103def test_fix_partial_fix_preserves_initial_issues( 

104 rustfmt_plugin: RustfmtPlugin, 

105 tmp_path: Path, 

106) -> None: 

107 """Fix preserves initial_issues when some issues remain after fix. 

108 

109 Args: 

110 rustfmt_plugin: The RustfmtPlugin instance to test. 

111 tmp_path: Temporary directory path for test files. 

112 """ 

113 cargo_toml = tmp_path / "Cargo.toml" 

114 cargo_toml.write_text('[package]\nname = "test"\nversion = "0.1.0"') 

115 

116 test_file = tmp_path / "src" / "main.rs" 

117 test_file.parent.mkdir(parents=True, exist_ok=True) 

118 test_file.write_text("fn main(){}") 

119 

120 call_count = 0 

121 

122 def mock_run( 

123 cmd: list[str], 

124 timeout: int, 

125 cwd: str | None = None, 

126 ) -> tuple[bool, str]: 

127 """Mock subprocess where fix doesn't resolve all issues. 

128 

129 Args: 

130 cmd: Command list. 

131 timeout: Timeout in seconds. 

132 cwd: Working directory. 

133 

134 Returns: 

135 Tuple of (success, output). 

136 """ 

137 nonlocal call_count 

138 call_count += 1 

139 if call_count == 1: 

140 # Initial check: 2 issues (different files for dedup) 

141 return (False, "Diff in src/main.rs:1:\nDiff in src/lib.rs:1:") 

142 elif call_count == 2: 

143 return (True, "") 

144 else: 

145 # Verify: 1 issue remains 

146 return (False, "Diff in src/lib.rs:1:") 

147 

148 with patch( 

149 "lintro.plugins.execution_preparation.verify_tool_version", 

150 return_value=None, 

151 ): 

152 with patch.object(rustfmt_plugin, "_run_subprocess", side_effect=mock_run): 

153 result = rustfmt_plugin.fix([str(test_file)], {}) 

154 

155 assert_that(result.success).is_false() 

156 assert_that(result.initial_issues).is_not_none() 

157 assert_that(result.initial_issues).is_length(2) 

158 assert_that(result.initial_issues_count).is_equal_to(2) 

159 assert_that(result.fixed_issues_count).is_equal_to(1) 

160 assert_that(result.remaining_issues_count).is_equal_to(1)