Initial SFERA platform baseline
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user