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

96 lines
3.3 KiB
Python

from __future__ import annotations
import json
from band_aider.context.class_meta import ClassMeta
from band_aider.context.cot_task_generator import CotTaskGenerator
from band_aider.judgement.prompt_formatter import MarkdownPromptFormatterBuilder
from band_aider.judgement.python_ast_dependency_graph_maintainer import (
PythonAstDependencyGraphMaintainer,
_StaticFacts,
)
from tests.support.completion_clients import ScriptedCompletionClient
from tests.support.memory_repo_exec import MemoryRepoExec
def _static_graph_does_not_link_shared_unqualified_names() -> None:
"""A local name shared with another file's public symbol is not a dependency."""
maintainer = PythonAstDependencyGraphMaintainer(
repo_exec=MemoryRepoExec(),
)
candidate = _StaticFacts(
module_name="band_aider.context.memento",
referenced_names=frozenset({"shared_name"}),
)
unrelated_dependency = _StaticFacts(
module_name="band_aider.judgement.unrelated",
defined_public_symbols=frozenset({"shared_name"}),
)
has_dependency = maintainer._static_pair_exists(
candidate,
unrelated_dependency,
)
assert not has_dependency, (
"A bare-name collision incorrectly created a cross-file dependency: "
f"candidate={candidate}; dependency={unrelated_dependency}"
)
def _generate_cot_tasks_preserves_generator_order_without_a_graph_reranker() -> None:
"""A stationary broad response keeps its explicit file-owned record order."""
memento = ClassMeta(
"band_aider/context/memento.py",
"Memento source",
["relevant"],
{},
)
class_meta = ClassMeta(
"band_aider/context/class_meta.py",
"ClassMeta source",
["relevant"],
{},
)
generator = CotTaskGenerator(
client=ScriptedCompletionClient((
json.dumps({
"cot_tasks": [
{
"task": "Preserve Memento lifecycle ownership.",
"location": memento.location,
},
{
"task": "Preserve ClassMeta caller ownership.",
"location": class_meta.location,
},
],
}),
)),
prompt_formatter_builder=MarkdownPromptFormatterBuilder(),
)
records = generator.generate(
"Keep each selected source record in response order.",
[memento, class_meta],
)
expected_locations = [memento.location, class_meta.location]
actual_locations = [record.location for record in records]
assert actual_locations == expected_locations, (
"The generated COT records did not preserve stationary response order. "
f"generated={expected_locations}; actual={actual_locations}"
)
class TestDependencyOrderRegressions:
"""Independently verifiable regressions for graph facts and COT ordering."""
def test_static_graph_does_not_link_shared_unqualified_names(self) -> None:
_static_graph_does_not_link_shared_unqualified_names()
def test_generate_cot_tasks_preserves_generator_order_without_a_graph_reranker(
self,
) -> None:
_generate_cot_tasks_preserves_generator_order_without_a_graph_reranker()