115 lines
3.9 KiB
Python
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)
|