Coverage for tests / unit / tools / ruff / conftest.py: 98%

54 statements  

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

1"""Shared fixtures for ruff tool tests.""" 

2 

3from __future__ import annotations 

4 

5import os 

6from collections.abc import Generator 

7from typing import TYPE_CHECKING, Any 

8from unittest.mock import MagicMock, patch 

9 

10import pytest 

11 

12from lintro.enums.tool_name import ToolName 

13 

14if TYPE_CHECKING: 

15 from lintro.tools.definitions.ruff import RuffPlugin 

16 

17 

18@pytest.fixture 

19def mock_ruff_tool() -> MagicMock: 

20 """Provide a mock RuffPlugin instance for testing. 

21 

22 Returns: 

23 MagicMock: Mock RuffPlugin instance with common attributes configured. 

24 """ 

25 tool = MagicMock() 

26 tool.definition.name = ToolName.RUFF 

27 tool.definition.file_patterns = ["*.py", "*.pyi"] 

28 tool.definition.can_fix = True 

29 tool.options = { 

30 "timeout": 30, 

31 "format_check": False, 

32 "select": None, 

33 "ignore": None, 

34 } 

35 tool.exclude_patterns = [] 

36 tool.include_venv = False 

37 tool._default_timeout = 30 

38 

39 # Mock common methods 

40 tool._get_executable_command.return_value = ["ruff"] 

41 tool._verify_tool_version.return_value = None 

42 tool._validate_paths.return_value = None 

43 tool._get_cwd.return_value = "/test/project" 

44 tool._build_config_args.return_value = [] 

45 tool._get_enforced_settings.return_value = {} 

46 

47 return tool 

48 

49 

50@pytest.fixture 

51def ruff_plugin() -> Generator[RuffPlugin, None, None]: 

52 """Provide a RuffPlugin instance for testing. 

53 

54 Sets LINTRO_TEST_MODE environment variable to skip config loading. 

55 

56 Yields: 

57 RuffPlugin: Configured RuffPlugin instance. 

58 """ 

59 from lintro.tools.definitions.ruff import RuffPlugin 

60 

61 with patch.dict(os.environ, {"LINTRO_TEST_MODE": "1"}): 

62 yield RuffPlugin() 

63 

64 

65@pytest.fixture 

66def sample_ruff_json_output() -> str: 

67 """Provide sample JSON output from ruff check. 

68 

69 Returns: 

70 str: Sample JSON output with lint issues. 

71 """ 

72 return """[ 

73 { 

74 "code": "F401", 

75 "message": "os imported but unused", 

76 "filename": "test.py", 

77 "location": {"row": 1, "column": 1}, 

78 "end_location": {"row": 1, "column": 10}, 

79 "fix": {"applicability": "safe"} 

80 }, 

81 { 

82 "code": "E501", 

83 "message": "Line too long (120 > 88)", 

84 "filename": "test.py", 

85 "location": {"row": 5, "column": 89}, 

86 "end_location": {"row": 5, "column": 120}, 

87 "fix": null 

88 } 

89]""" 

90 

91 

92@pytest.fixture 

93def sample_ruff_json_empty_output() -> str: 

94 """Provide empty JSON output from ruff check. 

95 

96 Returns: 

97 str: Empty JSON array indicating no issues. 

98 """ 

99 return "[]" 

100 

101 

102@pytest.fixture 

103def sample_ruff_format_check_output() -> str: 

104 """Provide sample output from ruff format --check. 

105 

106 Returns: 

107 str: Sample format check output listing files to reformat. 

108 """ 

109 return """Would reformat: test.py 

110Would reformat: src/module.py 

1112 files would be reformatted""" 

112 

113 

114@pytest.fixture 

115def sample_ruff_format_check_empty_output() -> str: 

116 """Provide empty output from ruff format --check. 

117 

118 Returns: 

119 str: Empty output indicating all files properly formatted. 

120 """ 

121 return "" 

122 

123 

124@pytest.fixture 

125def temp_python_file(tmp_path: Any) -> str: 

126 """Create a temporary Python file for testing. 

127 

128 Args: 

129 tmp_path: Pytest's tmp_path fixture. 

130 

131 Returns: 

132 str: Path to the created temporary Python file. 

133 """ 

134 test_file = tmp_path / "test_file.py" 

135 test_file.write_text("import os\nx = 1\n") 

136 return str(test_file) 

137 

138 

139@pytest.fixture 

140def temp_python_files(tmp_path: Any) -> list[str]: 

141 """Create multiple temporary Python files for testing. 

142 

143 Args: 

144 tmp_path: Pytest's tmp_path fixture. 

145 

146 Returns: 

147 list[str]: Paths to the created temporary Python files. 

148 """ 

149 files = [] 

150 for i in range(3): 

151 test_file = tmp_path / f"test_file_{i}.py" 

152 test_file.write_text(f"x = {i}\n") 

153 files.append(str(test_file)) 

154 return files