Fix #6094. Fix failing core tests.

This commit is contained in:
Dion Moult
2025-02-04 13:36:28 +11:00
parent a35ef32ee6
commit 0c41f0c32c
7 changed files with 83 additions and 53 deletions
+10 -3
View File
@@ -90,7 +90,7 @@ class Blender:
def get_name(cls, ifc_class, name): pass 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_obj_ifc_definition_id(cls, obj=None, obj_type=None, context=None): pass
def get_object_bounding_box(cls, obj): 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 get_viewport_context(cls): pass
def is_ifc_class_active(cls, ifc_class): pass def is_ifc_class_active(cls, ifc_class): pass
def is_ifc_object(cls, obj): pass def is_ifc_object(cls, obj): pass
@@ -183,7 +183,7 @@ class Classification:
@interface @interface
class Collector: class Collector:
def assign(cls, obj): pass def assign(cls, obj, should_clean_users_collection=False): pass
@interface @interface
@@ -323,8 +323,10 @@ class Drawing:
def export_text_literal_attributes(cls, obj): pass def export_text_literal_attributes(cls, obj): pass
def generate_drawing_matrix(cls, target_view, location_hint): pass def generate_drawing_matrix(cls, target_view, location_hint): pass
def generate_drawing_name(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 generate_sheet_identification(cls): pass
def get_annotation_context(cls, target_view, object_type=None): 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_assigned_product(cls, element): pass
def get_body_context(cls): pass def get_body_context(cls): pass
def get_default_drawing_path(cls, name): pass def get_default_drawing_path(cls, name): pass
@@ -345,10 +347,10 @@ class Drawing:
def get_name(cls, element): pass def get_name(cls, element): pass
def get_path_filename(cls, uri): pass def get_path_filename(cls, uri): pass
def get_reference_description(cls, reference): 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_document(cls, reference): pass
def get_reference_location(cls, reference): pass def get_reference_location(cls, reference): pass
def get_references_with_location(cls, location): 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_text_literal(cls, obj): pass
def get_unit_system(cls): pass def get_unit_system(cls): pass
def import_assigned_product(cls, obj): pass def import_assigned_product(cls, obj): pass
@@ -365,9 +367,11 @@ class Drawing:
def open_layout_svg(cls, uri): pass def open_layout_svg(cls, uri): pass
def open_spreadsheet(cls, uri): pass def open_spreadsheet(cls, uri): pass
def open_svg(cls, filepath): pass def open_svg(cls, filepath): pass
def reload_representation(cls, obj, representation): pass
def remove_literal_from_annotation(cls, obj, literal): pass def remove_literal_from_annotation(cls, obj, literal): pass
def run_drawing_activate_model(cls): 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_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 select_assigned_product(cls, drawing): pass
def set_drawing_collection_name(cls, drawing, collection): pass def set_drawing_collection_name(cls, drawing, collection): pass
def set_name(cls, element, name): pass def set_name(cls, element, name): pass
@@ -377,6 +381,7 @@ class Drawing:
def sync_object_placement(cls, obj): pass def sync_object_placement(cls, obj): pass
def synchronise_ifc_and_text_attributes(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_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_size_pset(cls, obj): pass
def update_text_value(cls, obj): pass def update_text_value(cls, obj): pass
@@ -756,6 +761,8 @@ class Root:
def is_containable(cls, element): pass def is_containable(cls, element): pass
def is_drawing_annotation(cls, element): pass def is_drawing_annotation(cls, element): pass
def is_element_a(cls, element, ifc_class): 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 is_spatial_element(cls, element): pass
def link_object_data(cls, source_obj, destination_obj): pass def link_object_data(cls, source_obj, destination_obj): pass
def recreate_decompositions(cls, relationships, old_to_new): pass def recreate_decompositions(cls, relationships, old_to_new): pass
+4 -7
View File
@@ -257,13 +257,10 @@ class Prophecy:
call = {"name": attr, "args": args, "kwargs": kwargs} call = {"name": attr, "args": args, "kwargs": kwargs}
# Ensure that signature is valid # Ensure that signature is valid
getattr(self.subject, attr)(*args, **kwargs) getattr(self.subject, attr)(*args, **kwargs)
try: key = json.dumps(call, sort_keys=True)
key = json.dumps(call, sort_keys=True) self.calls.append(call)
self.calls.append(call) if key in self.return_values:
if key in self.return_values: return self.return_values[key]
return self.return_values[key]
except:
pass
return self return self
return decorate return decorate
+24 -5
View File
@@ -17,15 +17,34 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bonsai.core.attribute as subject import bonsai.core.attribute as subject
from test.core.bootstrap import ifc from test.core.bootstrap import ifc, blender, root, spatial
class TestCopyAttributeToSelection: 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.get_entity("obj").should_be_called().will_return("element")
ifc.run("attribute.edit_attributes", product="element", attributes={"name": "value"}).should_be_called() 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) 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
+33 -9
View File
@@ -34,9 +34,10 @@ class TestDisableEditingText:
class TestEditText: class TestEditText:
def test_run(self, ifc, drawing): def test_run(self, drawing):
drawing.synchronise_ifc_and_text_attributes("obj").should_be_called() drawing.synchronise_ifc_and_text_attributes("obj").should_be_called()
drawing.update_text_size_pset("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.update_text_value("obj").should_be_called()
drawing.disable_editing_text("obj").should_be_called() drawing.disable_editing_text("obj").should_be_called()
subject.edit_text(drawing, obj="obj") subject.edit_text(drawing, obj="obj")
@@ -161,11 +162,11 @@ class TestAddSheet:
subject.add_sheet(ifc, drawing, titleblock="titleblock") subject.add_sheet(ifc, drawing, titleblock="titleblock")
class TestOpenSheet: class TestOpenLayout:
def test_run(self, drawing): def test_run(self, drawing):
drawing.get_document_uri("sheet", "LAYOUT").should_be_called().will_return("uri") drawing.get_document_uri("sheet", "LAYOUT").should_be_called().will_return("uri")
drawing.open_layout_svg("uri").should_be_called() drawing.open_layout_svg("uri").should_be_called()
subject.open_sheet(drawing, sheet="sheet") subject.open_layout(drawing, sheet="sheet")
class TestRemoveSheet: class TestRemoveSheet:
@@ -532,19 +533,30 @@ class TestAddAnnotation:
drawing.create_annotation_object("drawing", "object_type").should_be_called().will_return("obj") drawing.create_annotation_object("drawing", "object_type").should_be_called().will_return("obj")
ifc.get_entity("obj").should_be_called().will_return(None) 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_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( drawing.run_root_assign_class(
obj="obj", obj="obj",
ifc_class="IfcAnnotation", ifc_class="IfcAnnotation",
predefined_type="object_type", predefined_type="object_type",
should_add_representation=True, should_add_representation=False,
context="context", context="context",
ifc_representation_class="ifc_representation_class", ifc_representation_class="ifc_representation_class",
).should_be_called().will_return("element") ).should_be_called().will_return("element")
drawing.get_drawing_group("drawing").should_be_called().will_return("group") 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() 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.enable_editing("obj").should_be_called() drawing.reload_representation(obj="obj", representation="rep").should_be_called()
subject.add_annotation(ifc, collector, drawing, drawing="drawing", object_type="object_type") 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): 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") 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") drawing.create_annotation_object("drawing", "object_type").should_be_called().will_return("obj")
ifc.get_entity("obj").should_be_called().will_return(None) 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_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( drawing.run_root_assign_class(
obj="obj", obj="obj",
ifc_class="IfcAnnotation", ifc_class="IfcAnnotation",
@@ -562,8 +575,19 @@ class TestAddAnnotation:
context="context", context="context",
ifc_representation_class="ifc_representation_class", ifc_representation_class="ifc_representation_class",
).should_be_called().will_return("element") ).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") drawing.get_drawing_group("drawing").should_be_called().will_return("group")
ifc.run("group.assign_group", group="group", products=["element"]).should_be_called() 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() 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,
)
+1
View File
@@ -43,6 +43,7 @@ class TestEnableEditingLibraryReferences:
class TestDisableEditingLibraryReferences: class TestDisableEditingLibraryReferences:
def test_run(self, library): def test_run(self, library):
library.clear_editing_mode().should_be_called() library.clear_editing_mode().should_be_called()
library.set_active_library(None).should_be_called()
subject.disable_editing_library_references(library) subject.disable_editing_library_references(library)
+8 -29
View File
@@ -38,13 +38,10 @@ class TestCopyClass:
ifc.get_object("type").should_be_called().will_return("type_obj") ifc.get_object("type").should_be_called().will_return("type_obj")
root.link_object_data("type_obj", "obj").should_be_called() root.link_object_data("type_obj", "obj").should_be_called()
collector.assign("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") subject.copy_class(ifc, collector, geometry, root, obj="obj")
def test_copy_with_new_geometry_copied_from_the_old(self, ifc, collector, geometry, root): # 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 def test_AAAAAAAAAAAA(self, ifc, collector, geometry, root):
# copied. This was faster (though I cannot recreate it now) but had the
# bigger problem of not preserving non-mesh geometry and openings.
ifc.get_entity("obj").should_be_called().will_return("original_element") 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.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(False)
root.get_object_representation("obj").should_be_called().will_return("representation") root.get_object_representation("obj").should_be_called().will_return("representation")
@@ -52,18 +49,15 @@ class TestCopyClass:
ifc.link("element", "obj").should_be_called() ifc.link("element", "obj").should_be_called()
root.get_element_type("element").should_be_called().will_return("type") root.get_element_type("element").should_be_called().will_return("type")
root.does_type_have_representations("type").should_be_called().will_return(False) root.does_type_have_representations("type").should_be_called().will_return(False)
root.copy_representation("original_element", "element").should_be_called() root.copy_representation("original_element", "element").should_be_called().will_return("copied_entities")
root.get_representation_context("representation").should_be_called().will_return("context") geometry.copy_data_links("data", "copied_entities").should_be_called()
root.get_element_representation("element", "context").should_be_called().will_return("new_representation")
geometry.change_object_data("obj", "data", is_global=True).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.get_representation_name("new_representation").should_be_called().will_return("name")
geometry.rename_object("data", "name").should_be_called() 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() 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() 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") subject.copy_class(ifc, collector, geometry, root, obj="obj")
def test_copy_with_no_new_geometry(self, ifc, collector, geometry, root): 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.get_element_type("element").should_be_called().will_return("type")
root.does_type_have_representations("type").should_be_called().will_return(False) root.does_type_have_representations("type").should_be_called().will_return(False)
collector.assign("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_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") subject.copy_class(ifc, collector, geometry, root, obj="obj")
def test_copying_boundaries_are_dealt_with_specially(self, ifc, collector, geometry, root): 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.get_default_container().should_be_called().will_return("default_container")
root.is_spatial_element("element").should_be_called().will_return(False) root.is_spatial_element("element").should_be_called().will_return(False)
root.is_containable("element").should_be_called().will_return(True) 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( ifc.run(
"spatial.assign_container", products=["element"], relating_structure="default_container" "spatial.assign_container", products=["element"], relating_structure="default_container"
).should_be_called() ).should_be_called()
+3
View File
@@ -50,6 +50,9 @@ class TestAddStyle:
class TestRemoveStyle: class TestRemoveStyle:
def remove_a_style_common(self, ifc, style): 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.get_object("style").should_be_called().will_return("obj")
ifc.unlink(element="style").should_be_called() ifc.unlink(element="style").should_be_called()
ifc.run("style.remove_style", style="style").should_be_called() ifc.run("style.remove_style", style="style").should_be_called()