from pathlib import Path from semantic_kernel import index_project from sir import EdgeKind, NodeKind from ui_semantics import form_semantics def test_index_project_extracts_xml_ui_semantics(tmp_path: Path): xml = tmp_path / "form.xml" xml.write_text( """
""", encoding="utf-8", ) snapshot = index_project(tmp_path, project_id="demo") assert any(node.kind == NodeKind.FORM for node in snapshot.nodes) assert any(edge.kind == EdgeKind.HAS_COMMAND for edge in snapshot.edges) assert form_semantics(snapshot)[0].commands[0].name == "Провести" def test_index_project_extracts_1c_metadata_objects(tmp_path: Path): xml = tmp_path / "metadata.xml" xml.write_text( """
ОбменСКассовымУзлом РегламентноеЗадание.ОбменСКассовымУзлом
""", encoding="utf-8", ) snapshot = index_project(tmp_path, project_id="metadata") assert any(node.kind == NodeKind.CATALOG and node.name == "Номенклатура" for node in snapshot.nodes) assert any(node.kind == NodeKind.DOCUMENT and node.name == "ЗаказПокупателя" for node in snapshot.nodes) assert any(node.kind == NodeKind.TABULAR_SECTION and node.name == "Товары" for node in snapshot.nodes) assert any(node.kind == NodeKind.ROLE and node.name == "Менеджер" for node in snapshot.nodes) assert any(node.kind == NodeKind.SCHEDULED_JOB for node in snapshot.nodes) assert any(edge.kind == EdgeKind.HAS_ATTRIBUTE for edge in snapshot.edges) assert any(edge.kind == EdgeKind.HAS_TABULAR_SECTION for edge in snapshot.edges) tabular_section = next(node for node in snapshot.nodes if node.kind == NodeKind.TABULAR_SECTION) column = next(node for node in snapshot.nodes if node.kind == NodeKind.ATTRIBUTE and node.name == "Номенклатура") assert any( edge.kind == EdgeKind.HAS_ATTRIBUTE and edge.source_lineage == tabular_section.lineage_id and edge.target_lineage == column.lineage_id for edge in snapshot.edges ) assert any(edge.kind == EdgeKind.HAS_FORM for edge in snapshot.edges) assert any(edge.kind == EdgeKind.HAS_COMMAND for edge in snapshot.edges) def test_index_project_remaps_edges_from_duplicate_metadata_nodes(tmp_path: Path): first = tmp_path / "first.xml" first.write_text( """ СвойстваОбъектов ПланВидовХарактеристик.СвойстваОбъектов """, encoding="utf-8", ) second = tmp_path / "second.xml" second.write_text( """ СвойстваОбъектов ПланВидовХарактеристик.СвойстваОбъектов """, encoding="utf-8", ) snapshot = index_project(tmp_path, project_id="metadata-duplicates") chart = next(node for node in snapshot.nodes if node.kind == NodeKind.CHART_OF_CHARACTERISTIC_TYPES) attribute = next(node for node in snapshot.nodes if node.kind == NodeKind.ATTRIBUTE) assert any( edge.kind == EdgeKind.HAS_ATTRIBUTE and edge.source_lineage == chart.lineage_id and edge.target_lineage == attribute.lineage_id for edge in snapshot.edges ) def test_index_project_links_document_metadata_to_object_module(tmp_path: Path): xml = tmp_path / "metadata.xml" xml.write_text( """ """, encoding="utf-8", ) module = tmp_path / "Documents" / "ЗаказПокупателя" / "Ext" / "ObjectModule.bsl" module.parent.mkdir(parents=True) module.write_text( """ Процедура Проведение() КонецПроцедуры """, encoding="utf-8", ) snapshot = index_project(tmp_path, project_id="metadata-links") document = next(node for node in snapshot.nodes if node.kind == NodeKind.DOCUMENT) module_node = next(node for node in snapshot.nodes if node.kind == NodeKind.MODULE) link = next( edge for edge in snapshot.edges if edge.kind == EdgeKind.CONTAINS and edge.source_lineage == document.lineage_id and edge.target_lineage == module_node.lineage_id ) assert link.attributes["module_role"] == "OBJECT_MODULE" def test_index_project_links_common_module_metadata_to_bsl_module(tmp_path: Path): xml = tmp_path / "metadata.xml" xml.write_text( """ """, encoding="utf-8", ) module = tmp_path / "CommonModules" / "ИнтеграцияСКассой" / "Module.bsl" module.parent.mkdir(parents=True) module.write_text( """ Процедура ОтправитьЧек() КонецПроцедуры """, encoding="utf-8", ) snapshot = index_project(tmp_path, project_id="common-module-links") common_module = next(node for node in snapshot.nodes if node.kind == NodeKind.COMMON_MODULE) bsl_module = next(node for node in snapshot.nodes if node.kind == NodeKind.MODULE) assert any( edge.kind == EdgeKind.CONTAINS and edge.source_lineage == common_module.lineage_id and edge.target_lineage == bsl_module.lineage_id for edge in snapshot.edges ) def test_index_project_reads_edt_mdo_metadata(tmp_path: Path): catalog_dir = tmp_path / "src" / "Catalogs" / "Товары" catalog_dir.mkdir(parents=True) (catalog_dir / "Товары.mdo").write_text( """ Товары Артикул ФормаЭлемента """, encoding="utf-8", ) report_dir = tmp_path / "src" / "Reports" / "АнализПродаж" report_dir.mkdir(parents=True) (report_dir / "АнализПродаж.mdo").write_text( """ АнализПродаж """, encoding="utf-8", ) snapshot = index_project(tmp_path, project_id="edt-mdo") catalog = next(node for node in snapshot.nodes if node.kind == NodeKind.CATALOG) attribute = next(node for node in snapshot.nodes if node.kind == NodeKind.ATTRIBUTE and node.name == "Артикул") form = next(node for node in snapshot.nodes if node.kind == NodeKind.FORM) report = next(node for node in snapshot.nodes if node.kind == NodeKind.REPORT) assert catalog.qualified_name == "Справочник.Товары" assert attribute.qualified_name == "Справочник.Товары.Артикул" assert form.qualified_name == "Справочник.Товары.ФормаЭлемента" assert report.qualified_name == "Отчет.АнализПродаж" assert any(edge.kind == EdgeKind.HAS_ATTRIBUTE and edge.source_lineage == catalog.lineage_id for edge in snapshot.edges) assert any(edge.kind == EdgeKind.HAS_FORM and edge.source_lineage == catalog.lineage_id for edge in snapshot.edges) def test_index_project_preserves_register_dimension_and_resource_roles(tmp_path: Path): register_dir = tmp_path / "src" / "AccumulationRegisters" / "ОстаткиТоваров" register_dir.mkdir(parents=True) (register_dir / "ОстаткиТоваров.mdo").write_text( """ ОстаткиТоваров Номенклатура Количество """, encoding="utf-8", ) snapshot = index_project(tmp_path, project_id="register-fields") register = next(node for node in snapshot.nodes if node.kind == NodeKind.REGISTER) dimension = next(node for node in snapshot.nodes if node.kind == NodeKind.ATTRIBUTE and node.name == "Номенклатура") resource = next(node for node in snapshot.nodes if node.kind == NodeKind.ATTRIBUTE and node.name == "Количество") assert dimension.attributes["attribute_role"] == "DIMENSION" assert resource.attributes["attribute_role"] == "RESOURCE" assert any( edge.kind == EdgeKind.HAS_ATTRIBUTE and edge.source_lineage == register.lineage_id and edge.target_lineage == dimension.lineage_id for edge in snapshot.edges ) assert any( edge.kind == EdgeKind.HAS_ATTRIBUTE and edge.source_lineage == register.lineage_id and edge.target_lineage == resource.lineage_id for edge in snapshot.edges ) def test_index_project_links_role_rights_to_metadata_objects(tmp_path: Path): xml = tmp_path / "roles.xml" xml.write_text( """ """, encoding="utf-8", ) snapshot = index_project(tmp_path, project_id="role-rights") role = next(node for node in snapshot.nodes if node.kind == NodeKind.ROLE) document = next(node for node in snapshot.nodes if node.kind == NodeKind.DOCUMENT) right = next(edge for edge in snapshot.edges if edge.kind == EdgeKind.GRANTS_ACCESS) assert right.source_lineage == role.lineage_id assert right.target_lineage == document.lineage_id assert right.attributes["post"] == "true" def test_index_project_links_child_element_command_action_and_role_right(tmp_path: Path): xml = tmp_path / "metadata.xml" xml.write_text( """ ЗаказПокупателя Документ.ЗаказПокупателя
ФормаДокумента Провести ПровестиКоманда
Менеджер Документ.ЗаказПокупателя
""", encoding="utf-8", ) module = tmp_path / "form_module.bsl" module.write_text("Процедура ПровестиКоманда()\nКонецПроцедуры\n", encoding="utf-8") snapshot = index_project(tmp_path, project_id="child-element-metadata") document = next(node for node in snapshot.nodes if node.kind == NodeKind.DOCUMENT) role = next(node for node in snapshot.nodes if node.kind == NodeKind.ROLE) command = next(node for node in snapshot.nodes if node.kind == NodeKind.COMMAND) assert any( edge.kind == EdgeKind.GRANTS_ACCESS and edge.source_lineage == role.lineage_id and edge.target_lineage == document.lineage_id for edge in snapshot.edges ) assert any( edge.kind == EdgeKind.HANDLES and edge.source_lineage == command.lineage_id and edge.attributes["handler_name"] == "ПровестиКоманда" for edge in snapshot.edges ) def test_index_project_links_form_command_to_handler(tmp_path: Path): xml = tmp_path / "form.xml" xml.write_text( """
""", encoding="utf-8", ) module = tmp_path / "form_module.bsl" module.write_text("Процедура ПровестиКоманда()\nКонецПроцедуры\n", encoding="utf-8") snapshot = index_project(tmp_path, project_id="ui-handlers") assert any(edge.kind == EdgeKind.HANDLES for edge in snapshot.edges) def test_index_project_extracts_managed_form_items_without_layouts(tmp_path: Path): xml = tmp_path / "form.xml" xml.write_text( """
Основное Номер Объект.Номер """, encoding="utf-8", ) snapshot = index_project(tmp_path, project_id="ui-form-items") form = form_semantics(snapshot)[0] assert [element.name for element in form.elements] == ["Основное", "Номер"] assert all(element.kind == NodeKind.FORM_ELEMENT for element in form.elements) assert form.elements[1].attributes["dataPath"] == "Объект.Номер" assert not any(element.name == "ПечатнаяФорма" for element in form.elements) def test_index_project_extracts_edt_form_items_from_form_file_path(tmp_path: Path): form_dir = tmp_path / "src" / "Catalogs" / "ВидыЗаказовПокупателей" / "Forms" / "ФормаСписка" form_dir.mkdir(parents=True) (form_dir / "Form.form").write_text( """ Список Список Наименование Список.Description """, encoding="utf-8", ) snapshot = index_project(tmp_path, project_id="edt-form-items") form = next(item for item in form_semantics(snapshot) if item.form.name == "ФормаСписка") assert form.form.qualified_name == "Справочник.ВидыЗаказовПокупателей.ФормаСписка" assert [element.name for element in form.elements] == ["Список", "Наименование"] assert form.elements[0].attributes["control_kind"] == "Table" assert form.elements[1].attributes["dataPath"] == "Список.Description" def test_index_project_links_form_events_to_handlers(tmp_path: Path): xml = tmp_path / "form.xml" xml.write_text( """
""", encoding="utf-8", ) module = tmp_path / "form_module.bsl" module.write_text( """ Процедура ПриСозданииНаСервере() КонецПроцедуры Процедура ПередЗаписью() КонецПроцедуры """, encoding="utf-8", ) snapshot = index_project(tmp_path, project_id="ui-form-events") form = next(node for node in snapshot.nodes if node.kind == NodeKind.FORM) handlers = { edge.attributes["handler_name"]: edge for edge in snapshot.edges if edge.kind == EdgeKind.HANDLES and edge.source_lineage == form.lineage_id } assert set(handlers) == {"ПриСозданииНаСервере", "ПередЗаписью"} assert {edge.attributes["link_type"] for edge in handlers.values()} == {"FORM_EVENT"}