From 0c41f0c32ce7caa50adec15dc7792b0cd87186da Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 4 Feb 2025 13:36:28 +1100 Subject: [PATCH] Fix #6094. Fix failing core tests. --- src/bonsai/bonsai/core/tool.py | 13 ++++++-- src/bonsai/test/core/bootstrap.py | 11 +++---- src/bonsai/test/core/test_attribute.py | 29 +++++++++++++++--- src/bonsai/test/core/test_drawing.py | 42 ++++++++++++++++++++------ src/bonsai/test/core/test_library.py | 1 + src/bonsai/test/core/test_root.py | 37 +++++------------------ src/bonsai/test/core/test_style.py | 3 ++ 7 files changed, 83 insertions(+), 53 deletions(-) diff --git a/src/bonsai/bonsai/core/tool.py b/src/bonsai/bonsai/core/tool.py index acfb9fd1fd..1acae9d15d 100644 --- a/src/bonsai/bonsai/core/tool.py +++ b/src/bonsai/bonsai/core/tool.py @@ -90,7 +90,7 @@ class Blender: def get_name(cls, ifc_class, name): pass def get_obj_ifc_definition_id(cls, obj=None, obj_type=None, context=None): pass def get_object_bounding_box(cls, obj): pass - def get_selected_objects(cls): pass + def get_selected_objects(cls, include_active=False): pass def get_viewport_context(cls): pass def is_ifc_class_active(cls, ifc_class): pass def is_ifc_object(cls, obj): pass @@ -183,7 +183,7 @@ class Classification: @interface class Collector: - def assign(cls, obj): pass + def assign(cls, obj, should_clean_users_collection=False): pass @interface @@ -323,8 +323,10 @@ class Drawing: def export_text_literal_attributes(cls, obj): pass def generate_drawing_matrix(cls, target_view, location_hint): pass def generate_drawing_name(cls, target_view, location_hint): pass + def generate_reference_attributes(cls, reference, **attributes): pass def generate_sheet_identification(cls): pass def get_annotation_context(cls, target_view, object_type=None): pass + def get_annotation_representation(cls, element_type): pass def get_assigned_product(cls, element): pass def get_body_context(cls): pass def get_default_drawing_path(cls, name): pass @@ -345,10 +347,10 @@ class Drawing: def get_name(cls, element): pass def get_path_filename(cls, uri): pass def get_reference_description(cls, reference): pass - def generate_reference_attributes(cls, reference, **attributes): pass def get_reference_document(cls, reference): pass def get_reference_location(cls, reference): pass def get_references_with_location(cls, location): pass + def get_representation(cls, element, context): pass def get_text_literal(cls, obj): pass def get_unit_system(cls): pass def import_assigned_product(cls, obj): pass @@ -365,9 +367,11 @@ class Drawing: def open_layout_svg(cls, uri): pass def open_spreadsheet(cls, uri): pass def open_svg(cls, filepath): pass + def reload_representation(cls, obj, representation): pass def remove_literal_from_annotation(cls, obj, literal): pass def run_drawing_activate_model(cls): pass def run_root_assign_class(cls, obj=None, ifc_class=None, predefined_type=None, should_add_representation=True, context=None, ifc_representation_class=None): pass + def run_type_assign_type(cls, element=None, relating_type=None): pass def select_assigned_product(cls, drawing): pass def set_drawing_collection_name(cls, drawing, collection): pass def set_name(cls, element, name): pass @@ -377,6 +381,7 @@ class Drawing: def sync_object_placement(cls, obj): pass def synchronise_ifc_and_text_attributes(cls, obj): pass def update_embedded_svg_location(cls, uri, old_location, new_location): pass + def update_newline_at(cls, obj): pass def update_text_size_pset(cls, obj): pass def update_text_value(cls, obj): pass @@ -756,6 +761,8 @@ class Root: def is_containable(cls, element): pass def is_drawing_annotation(cls, element): pass def is_element_a(cls, element, ifc_class): pass + def is_in_aggregate_mode(cls, element): pass + def is_in_nest_mode(cls, element): pass def is_spatial_element(cls, element): pass def link_object_data(cls, source_obj, destination_obj): pass def recreate_decompositions(cls, relationships, old_to_new): pass diff --git a/src/bonsai/test/core/bootstrap.py b/src/bonsai/test/core/bootstrap.py index efbe209f70..9b89b81f6e 100644 --- a/src/bonsai/test/core/bootstrap.py +++ b/src/bonsai/test/core/bootstrap.py @@ -257,13 +257,10 @@ class Prophecy: call = {"name": attr, "args": args, "kwargs": kwargs} # Ensure that signature is valid getattr(self.subject, attr)(*args, **kwargs) - try: - key = json.dumps(call, sort_keys=True) - self.calls.append(call) - if key in self.return_values: - return self.return_values[key] - except: - pass + key = json.dumps(call, sort_keys=True) + self.calls.append(call) + if key in self.return_values: + return self.return_values[key] return self return decorate diff --git a/src/bonsai/test/core/test_attribute.py b/src/bonsai/test/core/test_attribute.py index b16ce677bd..aba74e1a4e 100644 --- a/src/bonsai/test/core/test_attribute.py +++ b/src/bonsai/test/core/test_attribute.py @@ -17,15 +17,34 @@ # along with Bonsai. If not, see . import bonsai.core.attribute as subject -from test.core.bootstrap import ifc +from test.core.bootstrap import ifc, blender, root, spatial class TestCopyAttributeToSelection: - def test_run(self, ifc): + def test_run(self, ifc, blender, root, spatial): + blender.get_selected_objects(include_active=False).should_be_called().will_return(["obj"]) ifc.get_entity("obj").should_be_called().will_return("element") ifc.run("attribute.edit_attributes", product="element", attributes={"name": "value"}).should_be_called() - subject.copy_attribute_to_selection(ifc, name="name", value="value", obj="obj") + assert subject.copy_attribute_to_selection(ifc, blender, root, spatial, name="name", value="value") == 1 - def test_do_nothing_if_object_is_not_an_element(self, ifc): + def test_do_nothing_if_object_is_not_an_element(self, ifc, blender, root, spatial): + blender.get_selected_objects(include_active=False).should_be_called().will_return(["obj"]) ifc.get_entity("obj").should_be_called().will_return(None) - subject.copy_attribute_to_selection(ifc, name="name", value="value", obj="obj") + assert subject.copy_attribute_to_selection(ifc, blender, root, spatial, name="name", value="value") == 0 + + def test_changing_object_name_in_blender_if_attribute_changed(self, ifc, blender, root, spatial): + blender.get_selected_objects(include_active=False).should_be_called().will_return(["obj"]) + ifc.get_entity("obj").should_be_called().will_return("element") + ifc.run("attribute.edit_attributes", product="element", attributes={"Name": "value"}).should_be_called() + root.set_object_name("obj", "element").should_be_called() + root.is_spatial_element("element").should_be_called().will_return(False) + assert subject.copy_attribute_to_selection(ifc, blender, root, spatial, name="Name", value="value") == 1 + + def test_refreshing_spatial_decomposition_if_identification_changed(self, ifc, blender, root, spatial): + blender.get_selected_objects(include_active=False).should_be_called().will_return(["obj"]) + ifc.get_entity("obj").should_be_called().will_return("element") + ifc.run("attribute.edit_attributes", product="element", attributes={"Name": "value"}).should_be_called() + root.set_object_name("obj", "element").should_be_called() + root.is_spatial_element("element").should_be_called().will_return(True) + spatial.import_spatial_decomposition().should_be_called() + assert subject.copy_attribute_to_selection(ifc, blender, root, spatial, name="Name", value="value") == 1 diff --git a/src/bonsai/test/core/test_drawing.py b/src/bonsai/test/core/test_drawing.py index e97197eff0..cbfb56b652 100644 --- a/src/bonsai/test/core/test_drawing.py +++ b/src/bonsai/test/core/test_drawing.py @@ -34,9 +34,10 @@ class TestDisableEditingText: class TestEditText: - def test_run(self, ifc, drawing): + def test_run(self, drawing): drawing.synchronise_ifc_and_text_attributes("obj").should_be_called() drawing.update_text_size_pset("obj").should_be_called() + drawing.update_newline_at("obj").should_be_called() drawing.update_text_value("obj").should_be_called() drawing.disable_editing_text("obj").should_be_called() subject.edit_text(drawing, obj="obj") @@ -161,11 +162,11 @@ class TestAddSheet: subject.add_sheet(ifc, drawing, titleblock="titleblock") -class TestOpenSheet: +class TestOpenLayout: def test_run(self, drawing): drawing.get_document_uri("sheet", "LAYOUT").should_be_called().will_return("uri") drawing.open_layout_svg("uri").should_be_called() - subject.open_sheet(drawing, sheet="sheet") + subject.open_layout(drawing, sheet="sheet") class TestRemoveSheet: @@ -532,19 +533,30 @@ class TestAddAnnotation: drawing.create_annotation_object("drawing", "object_type").should_be_called().will_return("obj") ifc.get_entity("obj").should_be_called().will_return(None) drawing.get_ifc_representation_class("object_type").should_be_called().will_return("ifc_representation_class") + drawing.get_annotation_representation("element_type").should_be_called().will_return("type_rep") drawing.run_root_assign_class( obj="obj", ifc_class="IfcAnnotation", predefined_type="object_type", - should_add_representation=True, + should_add_representation=False, context="context", ifc_representation_class="ifc_representation_class", ).should_be_called().will_return("element") drawing.get_drawing_group("drawing").should_be_called().will_return("group") + drawing.run_type_assign_type(element="element", relating_type="element_type").should_be_called() ifc.run("group.assign_group", group="group", products=["element"]).should_be_called() - collector.assign("obj").should_be_called() - drawing.enable_editing("obj").should_be_called() - subject.add_annotation(ifc, collector, drawing, drawing="drawing", object_type="object_type") + drawing.get_representation("element", "context").should_be_called().will_return("rep") + drawing.reload_representation(obj="obj", representation="rep").should_be_called() + collector.assign("obj", should_clean_users_collection=True).should_be_called() + subject.add_annotation( + ifc, + collector, + drawing, + drawing="drawing", + object_type="object_type", + relating_type="element_type", + enable_editing=False, + ) def test_create_a_missing_annotation_context_on_the_fly(self, ifc, collector, drawing): drawing.get_drawing_target_view("drawing").should_be_called().will_return("target_view") @@ -554,6 +566,7 @@ class TestAddAnnotation: drawing.create_annotation_object("drawing", "object_type").should_be_called().will_return("obj") ifc.get_entity("obj").should_be_called().will_return(None) drawing.get_ifc_representation_class("object_type").should_be_called().will_return("ifc_representation_class") + drawing.get_annotation_representation("element_type").should_be_called().will_return(None) drawing.run_root_assign_class( obj="obj", ifc_class="IfcAnnotation", @@ -562,8 +575,19 @@ class TestAddAnnotation: context="context", ifc_representation_class="ifc_representation_class", ).should_be_called().will_return("element") + drawing.run_type_assign_type(element="element", relating_type="element_type").should_be_called() drawing.get_drawing_group("drawing").should_be_called().will_return("group") ifc.run("group.assign_group", group="group", products=["element"]).should_be_called() - collector.assign("obj").should_be_called() + drawing.get_representation("element", "context").should_be_called().will_return("rep") + drawing.reload_representation(obj="obj", representation="rep").should_be_called() + collector.assign("obj", should_clean_users_collection=True).should_be_called() drawing.enable_editing("obj").should_be_called() - subject.add_annotation(ifc, collector, drawing, drawing="drawing", object_type="object_type") + subject.add_annotation( + ifc, + collector, + drawing, + drawing="drawing", + object_type="object_type", + relating_type="element_type", + enable_editing=True, + ) diff --git a/src/bonsai/test/core/test_library.py b/src/bonsai/test/core/test_library.py index f1f40a337e..301b5b4b2c 100644 --- a/src/bonsai/test/core/test_library.py +++ b/src/bonsai/test/core/test_library.py @@ -43,6 +43,7 @@ class TestEnableEditingLibraryReferences: class TestDisableEditingLibraryReferences: def test_run(self, library): library.clear_editing_mode().should_be_called() + library.set_active_library(None).should_be_called() subject.disable_editing_library_references(library) diff --git a/src/bonsai/test/core/test_root.py b/src/bonsai/test/core/test_root.py index d61b099832..7d922627ac 100644 --- a/src/bonsai/test/core/test_root.py +++ b/src/bonsai/test/core/test_root.py @@ -38,13 +38,10 @@ class TestCopyClass: ifc.get_object("type").should_be_called().will_return("type_obj") root.link_object_data("type_obj", "obj").should_be_called() collector.assign("obj").should_be_called() - root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(False) subject.copy_class(ifc, collector, geometry, root, obj="obj") - def test_copy_with_new_geometry_copied_from_the_old(self, ifc, collector, geometry, root): - # Originally, geometry was added fresh from the Blender mesh instead of - # copied. This was faster (though I cannot recreate it now) but had the - # bigger problem of not preserving non-mesh geometry and openings. + # def test_copy_with_new_geometry_copied_from_the_old(self, ifc, collector, geometry, root): + def test_AAAAAAAAAAAA(self, ifc, collector, geometry, root): ifc.get_entity("obj").should_be_called().will_return("original_element") root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(False) root.get_object_representation("obj").should_be_called().will_return("representation") @@ -52,18 +49,15 @@ class TestCopyClass: ifc.link("element", "obj").should_be_called() root.get_element_type("element").should_be_called().will_return("type") root.does_type_have_representations("type").should_be_called().will_return(False) - root.copy_representation("original_element", "element").should_be_called() - root.get_representation_context("representation").should_be_called().will_return("context") - root.get_element_representation("element", "context").should_be_called().will_return("new_representation") + root.copy_representation("original_element", "element").should_be_called().will_return("copied_entities") + geometry.copy_data_links("data", "copied_entities").should_be_called() geometry.change_object_data("obj", "data", is_global=True).should_be_called() + geometry.duplicate_object_data("obj").should_be_called().will_return("data") + ifc.get_entity("data").should_be_called().will_return("new_representation") geometry.get_representation_name("new_representation").should_be_called().will_return("name") geometry.rename_object("data", "name").should_be_called() - geometry.link("new_representation", "data").should_be_called() - geometry.reload_representation_item_ids("new_representation", "data").should_be_called() root.assign_body_styles("element", "obj").should_be_called() - geometry.duplicate_object_data("obj").should_be_called().will_return("data") collector.assign("obj").should_be_called() - root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(False) subject.copy_class(ifc, collector, geometry, root, obj="obj") def test_copy_with_no_new_geometry(self, ifc, collector, geometry, root): @@ -75,23 +69,6 @@ class TestCopyClass: root.get_element_type("element").should_be_called().will_return("type") root.does_type_have_representations("type").should_be_called().will_return(False) collector.assign("obj").should_be_called() - root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(False) - subject.copy_class(ifc, collector, geometry, root, obj="obj") - - def test_copied_openings_are_tracked_for_special_visualiation(self, ifc, collector, geometry, root): - ifc.get_entity("obj").should_be_called().will_return("original_element") - root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(False) - root.get_object_representation("obj").should_be_called().will_return(None) - ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element") - ifc.link("element", "obj").should_be_called() - root.get_element_type("element").should_be_called().will_return("type") - root.does_type_have_representations("type").should_be_called().will_return(True) - ifc.run("type.map_type_representations", related_object="element", relating_type="type").should_be_called() - ifc.get_object("type").should_be_called().will_return("type_obj") - root.link_object_data("type_obj", "obj").should_be_called() - collector.assign("obj").should_be_called() - root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(True) - root.add_tracked_opening("obj").should_be_called() subject.copy_class(ifc, collector, geometry, root, obj="obj") def test_copying_boundaries_are_dealt_with_specially(self, ifc, collector, geometry, root): @@ -167,6 +144,8 @@ class TestAssignClass: root.get_default_container().should_be_called().will_return("default_container") root.is_spatial_element("element").should_be_called().will_return(False) root.is_containable("element").should_be_called().will_return(True) + root.is_in_aggregate_mode("element").should_be_called().will_return(False) + root.is_in_nest_mode("element").should_be_called().will_return(False) ifc.run( "spatial.assign_container", products=["element"], relating_structure="default_container" ).should_be_called() diff --git a/src/bonsai/test/core/test_style.py b/src/bonsai/test/core/test_style.py index 7c1ba69063..ca8fc6b962 100644 --- a/src/bonsai/test/core/test_style.py +++ b/src/bonsai/test/core/test_style.py @@ -50,6 +50,9 @@ class TestAddStyle: class TestRemoveStyle: def remove_a_style_common(self, ifc, style): + style.is_editing_style().should_be_called().will_return(True) + style.get_currently_edited_material().should_be_called().will_return("obj") + style.disable_editing().should_be_called() ifc.get_object("style").should_be_called().will_return("obj") ifc.unlink(element="style").should_be_called() ifc.run("style.remove_style", style="style").should_be_called()