Coverage for tests / unit / tools / ruff / check / test_path_filtering.py: 100%

44 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-03 18:53 +0000

1"""Tests for path filtering in execute_ruff_check.""" 

2 

3from __future__ import annotations 

4 

5from unittest.mock import MagicMock, patch 

6 

7from assertpy import assert_that 

8 

9from lintro.tools.implementations.ruff.check import execute_ruff_check 

10 

11 

12def test_execute_ruff_check_filters_python_files( 

13 mock_ruff_tool: MagicMock, 

14) -> None: 

15 """Filter files to only Python files. 

16 

17 Args: 

18 mock_ruff_tool: Mock RuffTool instance for testing. 

19 """ 

20 with ( 

21 patch( 

22 "lintro.tools.implementations.ruff.check.walk_files_with_excludes", 

23 return_value=["test.py", "module.pyi"], 

24 ) as mock_walk, 

25 patch( 

26 "lintro.tools.implementations.ruff.check.run_subprocess_with_timeout", 

27 return_value=(True, "[]"), 

28 ), 

29 patch( 

30 "lintro.tools.implementations.ruff.check.parse_ruff_output", 

31 return_value=[], 

32 ), 

33 ): 

34 execute_ruff_check(mock_ruff_tool, ["/test/project"]) 

35 

36 mock_walk.assert_called_once() 

37 call_kwargs = mock_walk.call_args.kwargs 

38 assert_that(call_kwargs["file_patterns"]).contains("*.py", "*.pyi") 

39 

40 

41def test_execute_ruff_check_uses_exclude_patterns( 

42 mock_ruff_tool: MagicMock, 

43) -> None: 

44 """Pass exclude patterns to file walker. 

45 

46 Args: 

47 mock_ruff_tool: Mock RuffTool instance for testing. 

48 """ 

49 mock_ruff_tool.exclude_patterns = ["*_test.py", "__pycache__"] 

50 

51 with ( 

52 patch( 

53 "lintro.tools.implementations.ruff.check.walk_files_with_excludes", 

54 return_value=["main.py"], 

55 ) as mock_walk, 

56 patch( 

57 "lintro.tools.implementations.ruff.check.run_subprocess_with_timeout", 

58 return_value=(True, "[]"), 

59 ), 

60 patch( 

61 "lintro.tools.implementations.ruff.check.parse_ruff_output", 

62 return_value=[], 

63 ), 

64 ): 

65 execute_ruff_check(mock_ruff_tool, ["/test/project"]) 

66 

67 call_kwargs = mock_walk.call_args.kwargs 

68 assert_that(call_kwargs["exclude_patterns"]).contains( 

69 "*_test.py", 

70 "__pycache__", 

71 ) 

72 

73 

74def test_execute_ruff_check_respects_include_venv( 

75 mock_ruff_tool: MagicMock, 

76) -> None: 

77 """Pass include_venv setting to file walker. 

78 

79 Args: 

80 mock_ruff_tool: Mock RuffTool instance for testing. 

81 """ 

82 mock_ruff_tool.include_venv = True 

83 

84 with ( 

85 patch( 

86 "lintro.tools.implementations.ruff.check.walk_files_with_excludes", 

87 return_value=["test.py"], 

88 ) as mock_walk, 

89 patch( 

90 "lintro.tools.implementations.ruff.check.run_subprocess_with_timeout", 

91 return_value=(True, "[]"), 

92 ), 

93 patch( 

94 "lintro.tools.implementations.ruff.check.parse_ruff_output", 

95 return_value=[], 

96 ), 

97 ): 

98 execute_ruff_check(mock_ruff_tool, ["/test/project"]) 

99 

100 call_kwargs = mock_walk.call_args.kwargs 

101 assert_that(call_kwargs["include_venv"]).is_true() 

102 

103 

104def test_execute_ruff_check_converts_paths_to_relative( 

105 mock_ruff_tool: MagicMock, 

106) -> None: 

107 """Convert absolute file paths to relative paths for ruff command. 

108 

109 Args: 

110 mock_ruff_tool: Mock RuffTool instance for testing. 

111 """ 

112 mock_ruff_tool._get_cwd.return_value = "/test/project" 

113 

114 with ( 

115 patch( 

116 "lintro.tools.implementations.ruff.check.walk_files_with_excludes", 

117 return_value=[ 

118 "/test/project/src/main.py", 

119 "/test/project/tests/test_main.py", 

120 ], 

121 ), 

122 patch( 

123 "lintro.tools.implementations.ruff.check.run_subprocess_with_timeout", 

124 return_value=(True, "[]"), 

125 ), 

126 patch( 

127 "lintro.tools.implementations.ruff.check.parse_ruff_output", 

128 return_value=[], 

129 ), 

130 patch( 

131 "lintro.tools.implementations.ruff.commands.build_ruff_check_command", 

132 ) as mock_build_cmd, 

133 ): 

134 mock_build_cmd.return_value = [ 

135 "ruff", 

136 "check", 

137 "src/main.py", 

138 "tests/test_main.py", 

139 ] 

140 

141 execute_ruff_check(mock_ruff_tool, ["/test/project"]) 

142 

143 call_args = mock_build_cmd.call_args 

144 files_arg = call_args.kwargs.get("files") or call_args.args[1] 

145 # Files should be relative paths 

146 assert_that(files_arg).contains("src/main.py") 

147 assert_that(files_arg).contains("tests/test_main.py") 

148 

149 

150def test_execute_ruff_check_handles_multiple_directories( 

151 mock_ruff_tool: MagicMock, 

152) -> None: 

153 """Handle files from multiple directories. 

154 

155 Args: 

156 mock_ruff_tool: Mock RuffTool instance for testing. 

157 """ 

158 mock_ruff_tool._get_cwd.return_value = "/test" 

159 

160 with ( 

161 patch( 

162 "lintro.tools.implementations.ruff.check.walk_files_with_excludes", 

163 return_value=["/test/project1/main.py", "/test/project2/main.py"], 

164 ), 

165 patch( 

166 "lintro.tools.implementations.ruff.check.run_subprocess_with_timeout", 

167 return_value=(True, "[]"), 

168 ), 

169 patch( 

170 "lintro.tools.implementations.ruff.check.parse_ruff_output", 

171 return_value=[], 

172 ), 

173 ): 

174 result = execute_ruff_check(mock_ruff_tool, ["/test"]) 

175 

176 assert_that(result.success).is_true() 

177 

178 

179def test_execute_ruff_check_uses_absolute_paths_when_no_cwd( 

180 mock_ruff_tool: MagicMock, 

181) -> None: 

182 """Use absolute paths when cwd cannot be determined. 

183 

184 Args: 

185 mock_ruff_tool: Mock RuffTool instance for testing. 

186 """ 

187 mock_ruff_tool._get_cwd.return_value = None 

188 

189 with ( 

190 patch( 

191 "lintro.tools.implementations.ruff.check.walk_files_with_excludes", 

192 return_value=["/test/project/test.py"], 

193 ), 

194 patch( 

195 "lintro.tools.implementations.ruff.check.run_subprocess_with_timeout", 

196 return_value=(True, "[]"), 

197 ), 

198 patch( 

199 "lintro.tools.implementations.ruff.check.parse_ruff_output", 

200 return_value=[], 

201 ), 

202 patch( 

203 "lintro.tools.implementations.ruff.commands.build_ruff_check_command", 

204 ) as mock_build_cmd, 

205 ): 

206 mock_build_cmd.return_value = ["ruff", "check", "/test/project/test.py"] 

207 

208 execute_ruff_check(mock_ruff_tool, ["/test/project"]) 

209 

210 call_args = mock_build_cmd.call_args 

211 files_arg = call_args.kwargs.get("files") or call_args.args[1] 

212 # Should use absolute path 

213 assert_that(files_arg[0]).starts_with("/")