band-aider-pub/tests/conftest.py
2026-10-17 11:57:37 -07:00

115 lines
3.9 KiB
Python

# SPDX-FileCopyrightText: 2026 Art Sea LLC
#
# SPDX-License-Identifier: AGPL-3.0-only
from __future__ import annotations
import pytest
from collections.abc import Iterator
from pathlib import Path
from typing import Callable, cast
from band_aider.context.resume_state import (
configure_resume_settings,
reset_resume_state_for_tests,
)
from band_aider.strategies import LanguageStrategySet, language_strategy_set_factory
from band_aider.strategies.registration import register_strategies
from band_aider.judgement import model2vec_code_parser
from band_aider.judgement.prompt_localization import PromptLocalization
from tests.support.memory_path import MemoryPath
from tests.support.memory_repo_exec import MemoryRepoExec
# Bind concrete handlers at the test suite's composition boundary.
register_strategies()
@pytest.fixture
def without_embedding_model(monkeypatch: pytest.MonkeyPatch) -> None:
"""Keep opted-in orchestration tests independent of the host's embedding cache."""
monkeypatch.setattr(model2vec_code_parser, "model2vec_package_available", lambda: False)
@pytest.fixture
def memory_root() -> MemoryPath:
"""Return the fixed lexical root used by isolated in-memory repositories."""
return MemoryPath.from_repo(MemoryRepoExec())
@pytest.fixture
def tmp_path() -> MemoryPath:
"""Replace pytest's disk fixture with a fresh nominal in-memory project root."""
return MemoryPath.from_repo(MemoryRepoExec())
def pytest_addoption(parser: pytest.Parser) -> None:
"""Expose the opt-in tier that is allowed to exercise concrete adapters."""
parser.addoption(
"--run-integration",
action="store_true",
default=False,
help="run tests marked integration alongside the isolated skinny suite",
)
def pytest_configure(config: pytest.Config) -> None:
"""Document the explicit integration tier in every pytest invocation."""
config.addinivalue_line(
"markers",
"integration: exercises a concrete adapter through an explicit local integration harness.",
)
config.addinivalue_line("markers", "prompt_localization: exercises the real pre-completion localization and its validation.")
def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None:
"""Keep concrete adapter tests out of the default no-host-IO tier."""
if config.getoption("--run-integration"):
return
integration_items = [item for item in items if item.get_closest_marker("integration")]
if not integration_items:
return
selected_items = [item for item in items if item not in integration_items]
config.hook.pytest_deselected(items=integration_items)
items[:] = selected_items
@pytest.fixture(autouse=True)
def isolate_resume_checkpoints() -> Iterator[None]:
"""Bind implicit checkpoint traffic to a nominal in-memory project adapter."""
reset_resume_state_for_tests()
configure_resume_settings(
hydrate=False,
checkpoint_dir=MemoryRepoExec().root / "checkpoints",
keep=5,
repo_exec=MemoryRepoExec(),
)
yield
reset_resume_state_for_tests()
@pytest.fixture(autouse=True)
def isolate_language_strategy_set() -> Iterator[None]:
"""Clear the process-wide language strategy singleton between tests."""
LanguageStrategySet.instance = cast(
Callable,
language_strategy_set_factory.build_language_set("python"),
)
yield
LanguageStrategySet.instance = cast(
Callable,
language_strategy_set_factory.build_language_set("python"),
)
@pytest.fixture(autouse=True)
def isolate_prompt_localization(request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch) -> None:
"""Exercise the production bypass by default; localization cases explicitly opt in."""
monkeypatch.setattr(PromptLocalization, "enabled",
request.node.get_closest_marker("prompt_localization") is not None)