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
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Shared fixtures for ruff tool tests."""
3from __future__ import annotations
5import os
6from collections.abc import Generator
7from typing import TYPE_CHECKING, Any
8from unittest.mock import MagicMock, patch
10import pytest
12from lintro.enums.tool_name import ToolName
14if TYPE_CHECKING:
15 from lintro.tools.definitions.ruff import RuffPlugin
18@pytest.fixture
19def mock_ruff_tool() -> MagicMock:
20 """Provide a mock RuffPlugin instance for testing.
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
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 = {}
47 return tool
50@pytest.fixture
51def ruff_plugin() -> Generator[RuffPlugin, None, None]:
52 """Provide a RuffPlugin instance for testing.
54 Sets LINTRO_TEST_MODE environment variable to skip config loading.
56 Yields:
57 RuffPlugin: Configured RuffPlugin instance.
58 """
59 from lintro.tools.definitions.ruff import RuffPlugin
61 with patch.dict(os.environ, {"LINTRO_TEST_MODE": "1"}):
62 yield RuffPlugin()
65@pytest.fixture
66def sample_ruff_json_output() -> str:
67 """Provide sample JSON output from ruff check.
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]"""
92@pytest.fixture
93def sample_ruff_json_empty_output() -> str:
94 """Provide empty JSON output from ruff check.
96 Returns:
97 str: Empty JSON array indicating no issues.
98 """
99 return "[]"
102@pytest.fixture
103def sample_ruff_format_check_output() -> str:
104 """Provide sample output from ruff format --check.
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"""
114@pytest.fixture
115def sample_ruff_format_check_empty_output() -> str:
116 """Provide empty output from ruff format --check.
118 Returns:
119 str: Empty output indicating all files properly formatted.
120 """
121 return ""
124@pytest.fixture
125def temp_python_file(tmp_path: Any) -> str:
126 """Create a temporary Python file for testing.
128 Args:
129 tmp_path: Pytest's tmp_path fixture.
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)
139@pytest.fixture
140def temp_python_files(tmp_path: Any) -> list[str]:
141 """Create multiple temporary Python files for testing.
143 Args:
144 tmp_path: Pytest's tmp_path fixture.
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