From 81fdf63bd03bfdf0eb2b6ded2f35a4d7b8131451 Mon Sep 17 00:00:00 2001 From: falken10vdl Date: Thu, 21 Aug 2025 12:05:41 +0200 Subject: [PATCH] adapted to get pytest -p no:pytest-blender test/core/test_document.py working. Black formating --- .../bonsai/bim/module/document/operator.py | 2 + src/bonsai/bonsai/bim/module/document/ui.py | 3 +- src/bonsai/bonsai/core/document.py | 4 +- src/bonsai/bonsai/core/tool.py | 14 ++++ src/bonsai/bonsai/tool/document.py | 24 ++++--- src/bonsai/test/core/test_document.py | 70 +++++++++++++------ src/bonsai/test/tool/test_document.py | 18 +++-- 7 files changed, 91 insertions(+), 44 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/document/operator.py b/src/bonsai/bonsai/bim/module/document/operator.py index f63b5e1693..447d3b1693 100644 --- a/src/bonsai/bonsai/bim/module/document/operator.py +++ b/src/bonsai/bonsai/bim/module/document/operator.py @@ -23,6 +23,7 @@ import bonsai.tool as tool import bonsai.core.document as core from bonsai.bim.module.document.data import DocumentData, ObjectDocumentData + class LoadProjectDocuments(bpy.types.Operator): bl_idname = "bim.load_project_documents" bl_label = "Load Project Documents" @@ -287,6 +288,7 @@ class OpenIFCDocument(bpy.types.Operator): return {"FINISHED"} + class ToggleDocument(bpy.types.Operator): bl_idname = "bim.toggle_document" bl_label = "Toggle Document" diff --git a/src/bonsai/bonsai/bim/module/document/ui.py b/src/bonsai/bonsai/bim/module/document/ui.py index 68a9c5adb2..c382f1c721 100644 --- a/src/bonsai/bonsai/bim/module/document/ui.py +++ b/src/bonsai/bonsai/bim/module/document/ui.py @@ -22,6 +22,7 @@ from bpy.types import Panel, UIList from bonsai.bim.helper import draw_attributes from bonsai.bim.module.document.data import DocumentData, ObjectDocumentData + class BIM_PT_documents(Panel): bl_label = "Documents" bl_idname = "BIM_PT_documents" @@ -43,7 +44,7 @@ class BIM_PT_documents(Panel): row = self.layout.row(align=True) row.label(text="{} Documents found".format(DocumentData.data["total_documents"]), icon="FILE") - + if self.props.is_editing: row.operator("bim.disable_document_editing_ui", text="", icon="CANCEL") else: diff --git a/src/bonsai/bonsai/core/document.py b/src/bonsai/bonsai/core/document.py index 7b42295500..ac49fee10d 100644 --- a/src/bonsai/bonsai/core/document.py +++ b/src/bonsai/bonsai/core/document.py @@ -53,7 +53,7 @@ def add_information(ifc: tool.Ifc, document: tool.Document, parent=None) -> ifco document.clear_document_tree() if parent is None: - parent = document.get_default_parent_for_information(ifc) + parent = document.get_default_parent_for_information() information = ifc.run("document.add_information", parent=parent) ifc.run("document.add_reference", information=information) @@ -66,7 +66,7 @@ def add_information(ifc: tool.Ifc, document: tool.Document, parent=None) -> ifco def add_reference(ifc: tool.Ifc, document: tool.Document) -> None: - parent = document.get_selected_document_information(ifc) + parent = document.get_selected_document_information() if parent: reference = ifc.run("document.add_reference", information=parent) diff --git a/src/bonsai/bonsai/core/tool.py b/src/bonsai/bonsai/core/tool.py index 4061914bee..36afd7d66c 100644 --- a/src/bonsai/bonsai/core/tool.py +++ b/src/bonsai/bonsai/core/tool.py @@ -289,6 +289,7 @@ class Debug: class Document: def clear_document_tree(cls): pass def disable_editing_document(cls): pass + def disable_object_editing_ui(cls): pass def disable_editing_ui(cls): pass def enable_editing_ui(cls): pass def export_document_attributes(cls): pass @@ -296,6 +297,19 @@ class Document: def import_project_documents(cls): pass def is_document_information(cls, document): pass def set_active_document(cls, document): pass + def clear_active_document(cls): pass + def clear_document_attributes(cls): pass + def expand_document(cls, document): pass + def get_default_parent_for_information(cls): pass + def get_selected_document_information(cls): pass + def get_document_information_id(cls, document): pass + def set_document_information_id(cls, document, value): pass + def get_external_reference_id(cls, reference): pass + def set_external_reference_id(cls, reference, value): pass + def get_document_references(cls, document): pass + def refresh_document_data(cls): pass + def load_document_objects_into_props(cls, document_id): pass + def update_document_objects(cls, document_id): pass @interface diff --git a/src/bonsai/bonsai/tool/document.py b/src/bonsai/bonsai/tool/document.py index f8f45fffcf..bf8e4d17b8 100644 --- a/src/bonsai/bonsai/tool/document.py +++ b/src/bonsai/bonsai/tool/document.py @@ -173,14 +173,18 @@ class Document(bonsai.core.tool.Document): new.tree_depth = depth new.name = document.Name or "" - new.identification = cls.get_document_information_id(document) if new.document_type == "INFORMATION" else cls.get_external_reference_id(document) + new.identification = ( + cls.get_document_information_id(document) + if new.document_type == "INFORMATION" + else cls.get_external_reference_id(document) + ) new.identification = new.identification or "" new.description = document.Description or "" new.location = document.Location or "" - + if new.document_type == "INFORMATION": new.name = document.Name or "Unnamed" - + elif new.document_type == "REFERENCE": file = document.file if file.schema == "IFC2X3": @@ -200,12 +204,12 @@ class Document(bonsai.core.tool.Document): info_children = natsorted( [d for d in children if d.is_a("IfcDocumentInformation")], - key=lambda doc: (cls.get_document_information_id(doc) or "", doc.Name or "") + key=lambda doc: (cls.get_document_information_id(doc) or "", doc.Name or ""), ) ref_children = natsorted( [d for d in children if not d.is_a("IfcDocumentInformation")], - key=lambda doc: (cls.get_external_reference_id(doc) or "", doc.Description or doc.Name or "") + key=lambda doc: (cls.get_external_reference_id(doc) or "", doc.Description or doc.Name or ""), ) for child in info_children + ref_children: @@ -272,16 +276,18 @@ class Document(bonsai.core.tool.Document): props.json_string = json.dumps(expanded_docs) @classmethod - def get_default_parent_for_information(cls, ifc) -> Union[ifcopenshell.entity_instance, None]: - projects = ifc.get().by_type("IfcProject") + def get_default_parent_for_information(cls) -> Union[ifcopenshell.entity_instance, None]: + file = tool.Ifc.get() + projects = file.by_type("IfcProject") return projects[0] if projects else None @classmethod - def get_selected_document_information(cls, ifc) -> Union[ifcopenshell.entity_instance, None]: + def get_selected_document_information(cls) -> Union[ifcopenshell.entity_instance, None]: props = cls.get_document_props() if props.active_document and props.active_document.document_type == "INFORMATION": - return ifc.get().by_id(props.active_document.ifc_definition_id) + file = tool.Ifc.get() + return file.by_id(props.active_document.ifc_definition_id) return None @classmethod diff --git a/src/bonsai/test/core/test_document.py b/src/bonsai/test/core/test_document.py index ab3563551d..5baf3e709f 100644 --- a/src/bonsai/test/core/test_document.py +++ b/src/bonsai/test/core/test_document.py @@ -16,7 +16,6 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . - import bonsai.core.document as subject from test.core.bootstrap import ifc, document @@ -29,14 +28,6 @@ class TestLoadProjectDocuments: subject.load_project_documents(document) -class TestLoadDocument: - def test_run(self, document): - document.clear_document_tree().should_be_called() - document.disable_editing_document().should_be_called() - document.add_breadcrumb("document").should_be_called() - subject.load_document(document, document="document") - - class TestDisableDocumentEditingUi: def test_run(self, document): document.disable_editing_ui().should_be_called() @@ -44,38 +35,71 @@ class TestDisableDocumentEditingUi: subject.disable_document_editing_ui(document) +class TestDisableObjectDocumentEditingUi: + def test_run(self, document): + document.disable_object_editing_ui().should_be_called() + subject.disable_object_document_editing_ui(document) + + class TestEnableEditingDocument: def test_run(self, document): - document.import_document_attributes("document").should_be_called() document.set_active_document("document").should_be_called() - subject.enable_editing_document(document, document="document") + document.import_document_attributes("document").should_be_called() + subject.enable_editing_document(document, ifc_document="document") class TestDisableEditingDocument: def test_run(self, document): - document.disable_editing_document().should_be_called() + document.clear_active_document().should_be_called() + document.clear_document_attributes().should_be_called() subject.disable_editing_document(document) class TestAddInformation: def test_add_and_reload_tree_at_project_root(self, ifc, document): document.clear_document_tree().should_be_called() - ifc.run("document.add_information", parent=None).should_be_called().will_return("information") + document.get_default_parent_for_information().should_be_called().will_return("default_parent") + ifc.run("document.add_information", parent="default_parent").should_be_called().will_return("information") ifc.run("document.add_reference", information="information").should_be_called() + document.is_document_information("default_parent").should_be_called().will_return(True) + document.expand_document("default_parent").should_be_called() document.import_project_documents().should_be_called() + subject.add_information(ifc, document) def test_add_and_reload_tree_at_current_parent(self, ifc, document): document.clear_document_tree().should_be_called() ifc.run("document.add_information", parent="parent").should_be_called().will_return("information") ifc.run("document.add_reference", information="information").should_be_called() - subject.add_information(ifc, document) + document.is_document_information("parent").should_be_called().will_return(True) + document.expand_document("parent").should_be_called() + document.import_project_documents().should_be_called() + + subject.add_information(ifc, document, parent="parent") + + def test_add_without_expanding_if_parent_is_not_information(self, ifc, document): + document.clear_document_tree().should_be_called() + ifc.run("document.add_information", parent="parent").should_be_called().will_return("information") + ifc.run("document.add_reference", information="information").should_be_called() + document.is_document_information("parent").should_be_called().will_return(False) + document.import_project_documents().should_be_called() + + subject.add_information(ifc, document, parent="parent") class TestAddReference: - def test_run(self, ifc, document): + def test_run_with_selected_parent(self, ifc, document): + document.get_selected_document_information().should_be_called().will_return("parent") ifc.run("document.add_reference", information="parent").should_be_called() - document.clear_document_tree().should_be_called() + document.expand_document("parent").should_be_called() + document.import_project_documents().should_be_called() + + subject.add_reference(ifc, document) + + def test_run_without_selected_parent(self, ifc, document): + document.get_selected_document_information().should_be_called().will_return(None) + document.import_project_documents().should_be_called() + subject.add_reference(ifc, document) @@ -87,7 +111,7 @@ class TestEditDocument: document.disable_editing_document().should_be_called() document.clear_document_tree().should_be_called() document.import_project_documents().should_be_called() - subject.edit_document(ifc, document, document="document") + subject.edit_document(ifc, document, ifc_document="document") def test_edit_reference(self, ifc, document): document.export_document_attributes().should_be_called().will_return("attributes") @@ -95,7 +119,8 @@ class TestEditDocument: ifc.run("document.edit_reference", reference="document", attributes="attributes").should_be_called() document.disable_editing_document().should_be_called() document.clear_document_tree().should_be_called() - subject.edit_document(ifc, document, document="document") + document.import_project_documents().should_be_called() + subject.edit_document(ifc, document, ifc_document="document") class TestRemoveDocument: @@ -104,22 +129,23 @@ class TestRemoveDocument: document.is_document_information("document").should_be_called().will_return(True) ifc.run("document.remove_information", information="document").should_be_called() document.import_project_documents().should_be_called() - subject.remove_document(ifc, document, document="document") + subject.remove_document(ifc, document, ifc_document="document") def test_remove_reference(self, ifc, document): document.clear_document_tree().should_be_called() document.is_document_information("document").should_be_called().will_return(False) ifc.run("document.remove_reference", reference="document").should_be_called() - subject.remove_document(ifc, document, document="document") + document.import_project_documents().should_be_called() + subject.remove_document(ifc, document, ifc_document="document") class TestAssignDocument: def test_run(self, ifc): ifc.run("document.assign_document", products=["product"], document="document").should_be_called() - subject.assign_document(ifc, product="product", document="document") + subject.assign_document(ifc, product="product", ifc_document="document") class TestUnassignDocument: def test_run(self, ifc): ifc.run("document.unassign_document", products=["product"], document="document").should_be_called() - subject.unassign_document(ifc, product="product", document="document") + subject.unassign_document(ifc, product="product", ifc_document="document") diff --git a/src/bonsai/test/tool/test_document.py b/src/bonsai/test/tool/test_document.py index 628f040923..64ec2791b0 100644 --- a/src/bonsai/test/tool/test_document.py +++ b/src/bonsai/test/tool/test_document.py @@ -148,24 +148,23 @@ class TestImportProjectDocumentsExpanded(NewFile): document = ifcopenshell.api.document.add_information(ifc) reference = ifcopenshell.api.document.add_reference(ifc, information=document) - props = tool.Document.get_document_props() expanded_docs = [document.id()] # Mark document as expanded props.json_string = json.dumps(expanded_docs) - + subject.import_project_documents() props = tool.Document.get_document_props() # Should have project root + document + reference = 3 total assert len(props.documents) == 3 - + assert props.documents[0].ifc_definition_id == -project.id() assert props.documents[0].document_type == "PROJECT" - + doc_info = next((d for d in props.documents if d.ifc_definition_id == document.id()), None) assert doc_info is not None assert doc_info.document_type == "INFORMATION" - + doc_ref = next((d for d in props.documents if d.ifc_definition_id == reference.id()), None) assert doc_ref is not None assert doc_ref.location == "" @@ -180,24 +179,23 @@ class TestImportProjectDocumentsCollapsed(NewFile): project = ifc.createIfcProject() document = ifcopenshell.api.document.add_information(ifc) reference = ifcopenshell.api.document.add_reference(ifc, information=document) - props = tool.Document.get_document_props() props.json_string = json.dumps([]) # Empty expanded list - + subject.import_project_documents() props = tool.Document.get_document_props() # Should have project root + document = 2 total (reference not imported because parent is collapsed) assert len(props.documents) == 2 - + assert props.documents[0].ifc_definition_id == -project.id() assert props.documents[0].document_type == "PROJECT" - + doc_info = next((d for d in props.documents if d.ifc_definition_id == document.id()), None) assert doc_info is not None assert doc_info.document_type == "INFORMATION" - + doc_ref = next((d for d in props.documents if d.ifc_definition_id == reference.id()), None) assert doc_ref is None