Coverage for tests / integration / conftest.py: 68%
38 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 integration tests."""
3import os
4import tempfile
5from collections.abc import Callable, Generator
6from pathlib import Path
8import pytest
11@pytest.fixture
12def temp_project_dir() -> Generator[Path, None, None]:
13 """Create a temporary directory structure for integration testing.
15 Yields:
16 Path: Path to the temporary project directory.
17 """
18 with tempfile.TemporaryDirectory() as tmpdir:
19 project_dir = Path(tmpdir)
20 # Create a basic project structure
21 (project_dir / "pyproject.toml").write_text(
22 """[tool.lintro]
23line_length = 88
25[tool.ruff]
26line-length = 88
27""",
28 )
29 (project_dir / "src").mkdir()
30 (project_dir / "tests").mkdir()
32 # Change to the temp directory for the test
33 original_cwd = os.getcwd()
34 os.chdir(project_dir)
35 try:
36 yield project_dir
37 finally:
38 os.chdir(original_cwd)
41@pytest.fixture
42def lintro_test_mode(monkeypatch: pytest.MonkeyPatch) -> str:
43 """Set LINTRO_TEST_MODE=1 environment variable for tests.
45 This disables config injection and other test-incompatible features.
47 Args:
48 monkeypatch: Pytest monkeypatch fixture for environment manipulation.
50 Returns:
51 str: The test mode value that was set.
52 """
53 monkeypatch.setenv("LINTRO_TEST_MODE", "1")
54 return "1"
57@pytest.fixture
58def skip_if_tool_unavailable() -> Callable[[str], None]:
59 """Skip test if required tool is not available in PATH.
61 Returns:
62 callable: Function that takes a tool_name (str) parameter and can be used
63 to skip tests for unavailable tools.
64 """
66 def _skip_if_unavailable(tool_name: str) -> None:
67 """Skip the current test if tool is not available.
69 Args:
70 tool_name: Name of the tool to check for availability.
71 """
72 import shutil
74 if not shutil.which(tool_name):
75 pytest.skip(f"Tool '{tool_name}' not available in PATH")
77 return _skip_if_unavailable
80@pytest.fixture
81def get_plugin(lintro_test_mode: str) -> Callable[[str], object]:
82 """Factory fixture to get a fresh plugin instance by name.
84 This fixture ensures LINTRO_TEST_MODE is set before getting the plugin,
85 which disables config injection and other test-incompatible features.
87 Creates a fresh instance to avoid test pollution from shared state.
89 Args:
90 lintro_test_mode: The test mode fixture (dependency).
92 Returns:
93 callable: Function that takes a tool name and returns a fresh plugin instance.
94 """
95 from lintro.plugins.registry import ToolRegistry
97 def _get_plugin(name: str) -> object:
98 """Get a fresh plugin instance by name.
100 Args:
101 name: Name of the tool to get.
103 Returns:
104 A fresh plugin instance (not the cached singleton).
105 """
106 name_lower = name.lower()
107 # Get the class from the registry and create a new instance
108 # to avoid test pollution from modified options on the cached instance
109 if name_lower not in ToolRegistry._tools:
110 ToolRegistry._ensure_discovered()
111 plugin_class = ToolRegistry._tools[name_lower]
112 return plugin_class()
114 return _get_plugin