Files
sfera/packages/semantic-kernel/tests/test_index_project.py
T
2026-05-16 19:03:49 +03:00

153 lines
5.3 KiB
Python

from pathlib import Path
from semantic_kernel import index_project
from sir import EdgeKind, NodeKind, validate_snapshot
def test_index_project_builds_valid_snapshot(tmp_path: Path):
module = tmp_path / "demo_module.bsl"
module.write_text(
"""
Процедура Проведение()
ПроверитьОстатки();
Движения.ОстаткиТоваров.Записать();
КонецПроцедуры
Процедура ПроверитьОстатки()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
Остатки.Номенклатура
ИЗ
РегистрНакопления.ОстаткиТоваров КАК Остатки";
КонецПроцедуры
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="demo")
validate_snapshot(snapshot)
assert any(node.kind == NodeKind.MODULE for node in snapshot.nodes)
assert any(node.kind == NodeKind.PROCEDURE and node.name == "Проведение" for node in snapshot.nodes)
assert any(node.kind == NodeKind.QUERY for node in snapshot.nodes)
assert any(node.kind == NodeKind.REGISTER and node.name == "ОстаткиТоваров" for node in snapshot.nodes)
assert any(edge.kind == EdgeKind.CALLS for edge in snapshot.edges)
assert any(edge.kind == EdgeKind.READS_TABLE for edge in snapshot.edges)
assert any(edge.kind == EdgeKind.WRITES for edge in snapshot.edges)
def test_index_project_builds_integration_endpoint_nodes(tmp_path: Path):
module = tmp_path / "integration.bsl"
module.write_text(
"""
Процедура Отправить()
Адрес = "https://api.example.local/orders";
Объект = Новый COMОбъект("V83.Application");
КонецПроцедуры
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="integrations")
assert any(node.kind == NodeKind.INTEGRATION_ENDPOINT for node in snapshot.nodes)
assert any(edge.kind == EdgeKind.USES_INTEGRATION for edge in snapshot.edges)
def test_index_project_extracts_inline_new_query(tmp_path: Path):
module = tmp_path / "query_module.bsl"
module.write_text(
"""
Процедура ПроверитьКонтрагента()
Запрос = Новый Запрос("ВЫБРАТЬ Контрагенты.Ссылка ИЗ Справочник.Контрагенты КАК Контрагенты");
КонецПроцедуры
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="inline-query")
query = next(node for node in snapshot.nodes if node.kind == NodeKind.QUERY)
assert "Справочник.Контрагенты" in query.attributes["query_text"]
assert any(
edge.kind == EdgeKind.READS_TABLE
and any(node.lineage_id == edge.target_lineage and node.qualified_name == "Справочник.Контрагенты" for node in snapshot.nodes)
for edge in snapshot.edges
)
def test_index_project_prefers_same_module_routine_for_duplicate_names(tmp_path: Path):
shared = tmp_path / "a_shared.bsl"
shared.write_text(
"""
Процедура ПроверитьОстатки()
КонецПроцедуры
""",
encoding="utf-8",
)
document_module = tmp_path / "z_document.bsl"
document_module.write_text(
"""
Процедура Проведение()
ПроверитьОстатки();
КонецПроцедуры
Процедура ПроверитьОстатки()
КонецПроцедуры
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="duplicate-routines")
local_target = next(
node for node in snapshot.nodes if node.qualified_name == "z_document.ПроверитьОстатки"
)
assert any(
edge.kind == EdgeKind.CALLS and edge.target_lineage == local_target.lineage_id
for edge in snapshot.edges
)
def test_index_project_records_malformed_bsl_diagnostics(tmp_path: Path):
module = tmp_path / "broken.bsl"
module.write_text(
"""
Процедура Проведение()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
Товары.Ссылка
ИЗ
Справочник.Номенклатура КАК Товары"
""",
encoding="utf-8",
)
snapshot = index_project(tmp_path, project_id="broken")
assert {diagnostic.code for diagnostic in snapshot.diagnostics} == {
"BSL_UNCLOSED_QUERY",
"BSL_UNCLOSED_ROUTINE",
}
def test_index_project_skips_invalid_xml_and_records_diagnostic(tmp_path: Path):
valid_xml = tmp_path / "valid.xml"
valid_xml.write_text(
"""
<Configuration>
<Catalog name="Контрагенты" qualifiedName="Справочник.Контрагенты" />
</Configuration>
""",
encoding="utf-8",
)
broken_xml = tmp_path / "broken.mdo"
broken_xml.write_text("<mdclass:Catalog xmlns:mdclass=", encoding="utf-8")
snapshot = index_project(tmp_path, project_id="broken-xml")
assert any(node.qualified_name == "Справочник.Контрагенты" for node in snapshot.nodes)
assert any(diagnostic.code == "XML_PARSE_ERROR" for diagnostic in snapshot.diagnostics)