import pytest from tests.unit_tests.rag.asserts_intent_router import ( assert_domain_layer_prefixes, assert_domains, assert_file_only_scope, assert_has_file_path, assert_intent, assert_no_symbol_keyword, assert_no_symbol_leakage_from_paths, assert_spans_valid, assert_sub_intent, assert_test_policy, ) from tests.unit_tests.rag.intent_router_testkit import run_sequence pytestmark = pytest.mark.intent_router def test_invariant_code_file_path_with_canonical_key_term() -> None: result = run_sequence(["Уточни по файлу app/core/config.py"])[0] assert_intent(result, "CODE_QA") assert_has_file_path(result, "app/core/config.py") assert_file_only_scope(result, "app/core/config.py") key_terms = [anchor.value for anchor in result.query_plan.anchors if anchor.type == "KEY_TERM"] assert "файл" in key_terms assert "файлу" not in key_terms assert_spans_valid(result) assert_domain_layer_prefixes(result) def test_invariant_open_file_for_specified_file_phrase_uses_narrow_layers() -> None: result = run_sequence(["Уточни по файлу app/core/config.py"])[0] assert_intent(result, "CODE_QA") assert_sub_intent(result, "OPEN_FILE") assert_file_only_scope(result, "app/core/config.py") layer_ids = [item.layer_id for item in result.retrieval_spec.layer_queries] assert layer_ids == ["C0_SOURCE_CHUNKS"] assert result.evidence_policy.require_flow is False def test_invariant_inline_code_span_routes_to_code_and_extracts_symbol() -> None: result = run_sequence(["Уточни по коду `def build(x): return x`"])[0] assert_intent(result, "CODE_QA") assert_spans_valid(result) assert_no_symbol_keyword(result) symbols = [anchor.value for anchor in result.query_plan.anchors if anchor.type == "SYMBOL"] key_terms = [anchor.value for anchor in result.query_plan.anchors if anchor.type == "KEY_TERM"] assert "build" in symbols assert "def" in key_terms def test_invariant_docs_cyrillic_path_with_quotes() -> None: result = run_sequence(["Что сказано в «docs/архитектура.md»?"])[0] assert_intent(result, "DOCS_QA") assert_sub_intent(result, "EXPLAIN") assert_domains(result, ["DOCS"]) assert "docs/архитектура.md" in result.query_plan.normalized assert_has_file_path(result, "docs/архитектура.md") assert any(anchor.type == "DOC_REF" for anchor in result.query_plan.anchors) assert result.retrieval_spec.filters.doc_kinds == [] assert_spans_valid(result) assert_domain_layer_prefixes(result) def test_invariant_file_check_phrase_not_project_misc() -> None: result = run_sequence(["Проверь app/modules/rag/explain/intent_builder.py и объясни"])[0] assert_intent(result, "CODE_QA") assert_domains(result, ["CODE"]) assert_no_symbol_leakage_from_paths(result) assert_domain_layer_prefixes(result) def test_invariant_tests_include_routing() -> None: result = run_sequence(["Где тесты на ConfigManager?"])[0] assert_intent(result, "CODE_QA") assert_test_policy(result, "INCLUDE") symbols = [anchor.value for anchor in result.query_plan.anchors if anchor.type == "SYMBOL"] key_terms = [anchor.value for anchor in result.query_plan.anchors if anchor.type == "KEY_TERM"] assert "ConfigManager" in symbols assert "тест" in key_terms def test_invariant_keyword_hints_and_expansions_for_function_identifier() -> None: result = run_sequence(["Теперь объясни функцию load_config"])[0] assert_intent(result, "CODE_QA") assert "load_config" in result.query_plan.keyword_hints assert "функция" not in result.query_plan.keyword_hints assert "def" not in result.query_plan.expansions def test_invariant_open_file_sub_intent_uses_narrow_retrieval_profile() -> None: result = run_sequence(["Открой файл app/core/config.py"])[0] assert_intent(result, "CODE_QA") assert_sub_intent(result, "OPEN_FILE") assert_file_only_scope(result, "app/core/config.py") layer_ids = [item.layer_id for item in result.retrieval_spec.layer_queries] assert "C0_SOURCE_CHUNKS" in layer_ids assert "C1_SYMBOL_CATALOG" not in layer_ids assert "C2_DEPENDENCY_GRAPH" not in layer_ids assert "C3_ENTRYPOINTS" not in layer_ids assert result.evidence_policy.require_flow is False def test_invariant_docs_question_routes_to_docs() -> None: result = run_sequence(["Что сказано в документации?"])[0] assert_intent(result, "DOCS_QA") assert_domains(result, ["DOCS"]) assert_domain_layer_prefixes(result) assert result.query_plan.keyword_hints assert any(item in result.query_plan.expansions for item in result.query_plan.keyword_hints)