Fix failing tests in preparation for release.

This commit is contained in:
Dion Moult
2023-05-06 11:05:13 +10:00
parent 34d947c51f
commit 1fb6dac6fb
12 changed files with 88 additions and 62 deletions
+7 -7
View File
@@ -312,13 +312,13 @@ def update_drawing_name(ifc, drawing_tool, drawing=None, name=None):
if drawing_tool.does_file_exist(resolved_old_location):
drawing_tool.move_file(resolved_old_location, ifc.resolve_uri(new_location))
for reference in drawing_tool.get_references_with_location(old_location):
ifc.run("document.edit_reference", reference=reference, attributes={"Location": new_location})
sheet = drawing_tool.get_reference_document(reference)
if not sheet:
uri = ifc.resolve_uri(drawing_tool.get_document_uri(sheet, "LAYOUT"))
if drawing_tool.does_file_exist(uri):
drawing_tool.update_embedded_svg_location(uri, old_location, new_location)
for reference in drawing_tool.get_references_with_location(old_location):
ifc.run("document.edit_reference", reference=reference, attributes={"Location": new_location})
sheet = drawing_tool.get_reference_document(reference)
if sheet:
uri = ifc.resolve_uri(drawing_tool.get_document_uri(sheet, "LAYOUT"))
if drawing_tool.does_file_exist(uri):
drawing_tool.update_embedded_svg_location(uri, old_location, new_location)
def add_annotation(ifc, collector, drawing_tool, drawing=None, object_type=None):
+1
View File
@@ -314,6 +314,7 @@ class Drawing:
def show_decorations(cls): pass
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_text_size_pset(cls, obj): pass
def update_text_value(cls, obj): pass
+2 -1
View File
@@ -1457,7 +1457,8 @@ class Drawing(blenderbim.core.tool.Drawing):
drawing = tool.Ifc.get_entity(camera)
# Running operators is much more efficient in this scenario than looping through each element
bpy.ops.object.hide_view_clear()
if not bpy.app.background:
bpy.ops.object.hide_view_clear()
filtered_elements = cls.get_drawing_elements(drawing) | cls.get_drawing_spaces(drawing)
hidden_objs = [o for o in bpy.context.visible_objects if tool.Ifc.get_entity(o) not in filtered_elements]
@@ -23,7 +23,7 @@ Scenario: Create drawing
And I press "bim.add_drawing"
And the variable "drawing" is "IfcStore.get_file().by_type('IfcAnnotation')[0].id()"
And I set "scene.DocProperties.active_drawing_index" to "0"
And I press "bim.activate_view(drawing={drawing})"
And I press "bim.activate_drawing(drawing={drawing})"
When I press "bim.create_drawing"
Then nothing happens
@@ -41,7 +41,7 @@ Scenario: Create drawing after deleting a duplicated object
And I press "bim.add_drawing"
And the variable "drawing" is "IfcStore.get_file().by_type('IfcAnnotation')[0].id()"
And I set "scene.DocProperties.active_drawing_index" to "0"
And I press "bim.activate_view(drawing={drawing})"
And I press "bim.activate_drawing(drawing={drawing})"
And I press "bim.create_drawing"
And the object "IfcWall/Cube" is selected
And I press "object.delete(use_global=False)"
@@ -194,8 +194,8 @@ Scenario: Change the height of a wall
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
And I press "bim.hotkey(hotkey='S_A')"
And the object "IfcWall/Wall" is selected
And I set "scene.BIMModelProperties.extrusion_depth" to "2000.0"
When I press "bim.change_extrusion_depth(depth=2000.0)"
And I set "scene.BIMModelProperties.extrusion_depth" to "2.0"
When I press "bim.change_extrusion_depth(depth=2.0)"
Then the object "IfcWall/Wall" dimensions are "1,0.1,2"
Scenario: Change the length of a wall
@@ -206,8 +206,8 @@ Scenario: Change the length of a wall
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
And I press "bim.hotkey(hotkey='S_A')"
And the object "IfcWall/Wall" is selected
And I set "scene.BIMModelProperties.length" to "2000.0"
When I press "bim.change_layer_length(length=2000.0)"
And I set "scene.BIMModelProperties.length" to "2.0"
When I press "bim.change_layer_length(length=2.0)"
Then the object "IfcWall/Wall" dimensions are "2,0.1,3"
Scenario: Flip a wall
@@ -438,8 +438,8 @@ Scenario: Change the length of a beam
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
And I press "bim.hotkey(hotkey='S_A')"
And the object "IfcBeam/Beam" is selected
And I set "scene.BIMModelProperties.extrusion_depth" to "2000.0"
When I press "bim.change_profile_depth(depth=2000.0)"
And I set "scene.BIMModelProperties.extrusion_depth" to "2.0"
When I press "bim.change_profile_depth(depth=2.0)"
Then the object "IfcBeam/Beam" dimensions are "0.1,0.2,2"
Scenario: Rotate a beam by 90 degrees
+3 -4
View File
@@ -47,7 +47,7 @@ Scenario: Execute qto method - side formwork areas
And I press "bim.execute_qto_method"
Then "scene.BIMQtoProperties.qto_result" is "16.0"
Scenario: Execute assign_objects_base_qto
Scenario: Assign objects base qto
Given an empty IFC project
And I add a cube
And the object "Cube" is selected
@@ -55,7 +55,7 @@ Scenario: Execute qto method - side formwork areas
When I press "bim.assign_objects_base_qto"
Then "active_object.PsetProperties.qto_name" is "Qto_WallBaseQuantities"
Scenario: Execute calculate_all_quantities
Scenario: Calculate all quantities
Given an empty IFC project
And I add a cube
And the object "Cube" is selected
@@ -65,5 +65,4 @@ Scenario: Execute calculate_all_quantities
And I press "bim.enable_pset_editing(pset_id={qset_id}, obj='IfcWall/Cube', obj_type='Object')"
And I press "bim.disable_pset_editing(obj='IfcWall/Cube', obj_type='Object')"
Then "active_object.PsetProperties.qto_name" is "Qto_WallBaseQuantities"
Then "active_object.PsetProperties.properties['Length'].metadata.float_value" is "2.0"
Then "active_object.PsetProperties.properties['Length'].metadata.float_value" is "2000.0"
+2 -2
View File
@@ -25,8 +25,8 @@ Scenario: Unlink object
And I press "bim.add_material"
When I press "bim.unlink_object(obj='IfcWall/Cube')"
Then the object "Cube" is not an IFC element
And the material "Material" is not an IFC material
And the material "Material" is not an IFC style
And the material "Material" is an IFC style
And the material "Material.001" is not an IFC style
Scenario: Copy class
Given an empty IFC project
+22 -11
View File
@@ -431,8 +431,9 @@ def the_object_name_is_an_ifc_class(name, ifc_class):
@then(parsers.parse('the object "{name}" is not an IFC element'))
def the_object_name_is_not_an_ifc_element(name):
id = the_object_name_exists(name).BIMObjectProperties.ifc_definition_id
assert id == 0, f"The ID is {id}"
obj = the_object_name_exists(name)
ifc_definition_id = obj.BIMObjectProperties.ifc_definition_id
assert ifc_definition_id == 0, f"The object {obj} has an ID of {ifc_definition_id}"
@then(parsers.parse('the object "{name}" has no data'))
@@ -447,21 +448,31 @@ def the_object_name_is_not_an_ifc_element(name):
@then(parsers.parse('the material "{name}" is an IFC material'))
def the_material_name_is_not_an_ifc_material(name):
id = the_material_name_exists(name).BIMObjectProperties.ifc_definition_id
assert id != 0, f"The ID is {id}"
def the_material_name_is_an_ifc_material(name):
obj = the_material_name_exists(name)
ifc_definition_id = obj.BIMObjectProperties.ifc_definition_id
assert ifc_definition_id != 0, f"The material {obj} has no ID: {ifc_definition_id}"
@then(parsers.parse('the material "{name}" is not an IFC material'))
def the_material_name_is_not_an_ifc_material(name):
id = the_material_name_exists(name).BIMObjectProperties.ifc_definition_id
assert id == 0, f"The ID is {id}"
obj = the_material_name_exists(name)
ifc_definition_id = obj.BIMObjectProperties.ifc_definition_id
assert ifc_definition_id == 0, f"The material {obj} has an ID of {ifc_definition_id}"
@then(parsers.parse('the material "{name}" is an IFC style'))
def the_material_name_is_an_ifc_style(name):
obj = the_material_name_exists(name)
ifc_definition_id = obj.BIMMaterialProperties.ifc_style_id
assert ifc_definition_id != 0, f"The material {obj} has a style ID of {ifc_definition_id}"
@then(parsers.parse('the material "{name}" is not an IFC style'))
def the_material_name_is_not_an_ifc_material(name):
id = the_material_name_exists(name).BIMMaterialProperties.ifc_style_id
assert id == 0, f"The ID is {id}"
def the_material_name_is_not_an_ifc_style(name):
obj = the_material_name_exists(name)
ifc_definition_id = obj.BIMMaterialProperties.ifc_style_id
assert ifc_definition_id == 0, f"The material {obj} has a style ID of {ifc_definition_id}"
@then(parsers.parse('the material "{name}" colour is "{colour}"'))
@@ -636,7 +647,7 @@ def the_object_name_dimensions_are_dimensions(name, dimensions):
actual_dimensions = list(the_object_name_exists(name).dimensions)
expected_dimensions = [float(co) for co in dimensions.split(",")]
for i, number in enumerate(actual_dimensions):
assert is_x(number, expected_dimensions[i])
assert is_x(number, expected_dimensions[i]), f"Expected {actual_dimensions[i]} but got {number}"
@then(parsers.parse('the object "{name}" top right corner is at "{location}"'))
+18
View File
@@ -391,6 +391,7 @@ class TestUpdateDrawingName:
ifc.run("document.edit_information", information="information", attributes={"Name": "name"}).should_be_called()
drawing.get_reference_location("reference").should_be_called().will_return("old_location")
drawing.get_default_drawing_path("name").should_be_called().will_return("new_location")
ifc.run(
"document.edit_reference", reference="reference", attributes={"Location": "new_location"}
).should_be_called()
@@ -399,6 +400,23 @@ class TestUpdateDrawingName:
ifc.resolve_uri("new_location").should_be_called().will_return("new_uri")
drawing.move_file("old_uri", "new_uri").should_be_called()
drawing.get_references_with_location("old_location").should_be_called().will_return(
["reference_with_old_location"]
)
ifc.run(
"document.edit_reference", reference="reference_with_old_location", attributes={"Location": "new_location"}
).should_be_called()
drawing.get_reference_document("reference_with_old_location").should_be_called().will_return(
"sheet_with_old_location"
)
drawing.get_document_uri("sheet_with_old_location", "LAYOUT").should_be_called().will_return(
"relative_layout_uri"
)
ifc.resolve_uri("relative_layout_uri").should_be_called().will_return("absolute_layout_uri")
drawing.does_file_exist("absolute_layout_uri").should_be_called().will_return(True)
drawing.update_embedded_svg_location("absolute_layout_uri", "old_location", "new_location").should_be_called()
subject.update_drawing_name(ifc, drawing, drawing="drawing", name="name")
+2 -2
View File
@@ -135,8 +135,8 @@ class TestGetRepresentationContext(NewFile):
class TestIsElementA(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
assert subject.is_a(ifc.createIfcWall(), "IfcSlab") is False
assert subject.is_a(ifc.createIfcOpeningElement(), "IfcOpeningElement") is True
assert subject.is_element_a(ifc.createIfcWall(), "IfcSlab") is False
assert subject.is_element_a(ifc.createIfcOpeningElement(), "IfcOpeningElement") is True
class TestLinkObjectData(NewFile):
@@ -21,36 +21,36 @@ import ifcopenshell.util.date
def get_productivity(resource, should_inherit=True):
productivity = ifcopenshell.util.element.get_psets(
resource
).get("EPset_Productivity", None)
productivity = ifcopenshell.util.element.get_psets(resource).get("EPset_Productivity", None)
if should_inherit and not productivity:
# Proposal for Schema - If instance doesn't have any productivity, inherit it's parent's productivity
if not resource.Nests:
return None
else:
parent_resource = resource.Nests[0].RelatingObject
productivity = ifcopenshell.util.element.get_psets(
parent_resource
).get("EPset_Productivity", None)
productivity = ifcopenshell.util.element.get_psets(parent_resource).get("EPset_Productivity", None)
return productivity
def get_unit_consumed(productivity):
duration = productivity.get("BaseQuantityConsumed", None)
if not duration:
return
return ifcopenshell.util.date.ifc2datetime(duration)
def get_quantity_produced(productivity):
if not productivity:
return 0
return productivity.get("BaseQuantityProducedValue", 0)
def get_quantity_produced_name(productivity):
if not productivity:
return ""
return productivity.get("BaseQuantityProducedName", "")
def get_total_quantity_produced(resource, quantity_name_in_process):
def get_product_quantity(product, quantity_name):
psets = ifcopenshell.util.element.get_psets(product)
@@ -65,9 +65,10 @@ def get_total_quantity_produced(resource, quantity_name_in_process):
total = len(products)
else:
for product in products:
total += get_product_quantity(product, quantity_name_in_process)
total += get_product_quantity(product, quantity_name_in_process) or 0
return total
def get_parametric_resource_products(resource):
products = []
for rel in resource.HasAssignments or []:
@@ -79,6 +80,7 @@ def get_parametric_resource_products(resource):
products.append(rel2.RelatingProduct)
return products
def get_resource_required_work(resource):
productivity = get_productivity(resource)
if productivity:
@@ -92,11 +94,11 @@ def get_resource_required_work(resource):
if "T" in productivity.get("BaseQuantityConsumed", ""):
seconds = (time_consumed.days * 24 * 60 * 60) + time_consumed.seconds
productivity_ratio = seconds / quantity_produced
required_work = total_quantity_to_produce * productivity_ratio
required_work = total_quantity_to_produce * productivity_ratio
iso_string = f"PT{required_work / 60 / 60}H"
else:
days = time_consumed.days + (time_consumed.seconds / (24 * 60 * 60))
productivity_ratio = days / quantity_produced
productivity_ratio = days / quantity_produced
required_work = total_quantity_to_produce * productivity_ratio
iso_string = f"P{required_work}D"
return iso_string
return iso_string
@@ -159,9 +159,7 @@ class Selector:
if not inverse_relationship:
return results
return cls.parse_inverse_relationship(
results, inverse_relationship.children[0].data
)
return cls.parse_inverse_relationship(results, inverse_relationship.children[0].data)
@classmethod
def parse_inverse_relationship(cls, elements, inverse_relationship):
@@ -193,13 +191,8 @@ class Selector:
if cls.elements is None:
elements = cls.file.by_type(class_selector.children[0])
else:
elements = [
e for e in cls.elements if e.is_a(class_selector.children[0])
]
if (
len(class_selector.children) > 1
and class_selector.children[1].data == "filter"
):
elements = [e for e in cls.elements if e.is_a(class_selector.children[0])]
if len(class_selector.children) > 1 and class_selector.children[1].data == "filter":
return cls.filter_elements(elements, class_selector.children[1])
return elements
@@ -227,9 +220,7 @@ class Selector:
element_value = cls.get_element_value(element, filter_query["keys"], is_regex=filter_query["is_regex"])
if element_value is None and value is not None and "not" not in comparison:
continue
if comparison and cls.filter_element(
element, element_value, comparison, value
):
if comparison and cls.filter_element(element, element_value, comparison, value):
results.append(element)
elif not comparison and element_value:
results.append(element)
@@ -243,9 +234,9 @@ class Selector:
keys = [keys]
elif keys.data == "keys_regex":
is_regex = True
keys = [k[1:-1].replace("\\\"", '"') for k in keys.children]
keys = [k[1:-1].replace('\\"', '"') for k in keys.children]
elif keys.data == "keys_quoted":
keys = [k[1:-1].replace("\\\"", '"') for k in keys.children]
keys = [k[1:-1].replace('\\"', '"') for k in keys.children]
elif keys.data == "keys_simple":
keys = keys.children
return {"keys": keys, "is_regex": is_regex}
@@ -273,6 +264,9 @@ class Selector:
elif key == "class":
value = value.is_a()
elif isinstance(value, ifcopenshell.entity_instance):
if key == "Name" and value.is_a("IfcMaterialLayerSet"):
key = "LayerSetName" # This oddity in the IFC spec is annoying so we account for it.
attribute = value.get_info().get(key, None)
if attribute is not None:
@@ -290,7 +284,7 @@ class Selector:
result = ifcopenshell.util.element.get_pset(value, key)
value = result
elif isinstance(value, dict): # Such as from the result of a prior get_pset
elif isinstance(value, dict): # Such as from the result of a prior get_pset
if is_regex:
results = []
for prop_name, prop_value in value.items():
@@ -302,7 +296,7 @@ class Selector:
value = results
else:
value = value.get(key, None)
elif isinstance(value, (list, tuple)): # If we use regex
elif isinstance(value, (list, tuple)): # If we use regex
if key.isnumeric():
try:
value = value[int(key)]