diff --git a/src/ifcbimtester/bimtester/features/steps/geometric_detail.py b/src/ifcbimtester/bimtester/features/steps/geometric_detail.py index 930e511d0e..594b42b4e6 100644 --- a/src/ifcbimtester/bimtester/features/steps/geometric_detail.py +++ b/src/ifcbimtester/bimtester/features/steps/geometric_detail.py @@ -1,6 +1,9 @@ from behave import step +from geometric_detail_methods import class_geometric_representation +from utils import assert_elements from utils import IfcFile +from utils import switch_locale @step("All elements must be under {number} polygons") @@ -29,3 +32,9 @@ def step_impl(context, number): for error in errors: message += "Polygons: {} - {}\n".format(error[0], error[1]) assert False, message + + +@step("all {ifc_class} elements have an {representation_class} representation") +def step_impl(context, ifc_class, representation_class): + switch_locale(context.localedir, "en") + class_geometric_representation(context, ifc_class, representation_class) diff --git a/src/ifcbimtester/bimtester/features/steps/geometric_detail_de.py b/src/ifcbimtester/bimtester/features/steps/geometric_detail_de.py new file mode 100644 index 0000000000..bb574db3f5 --- /dev/null +++ b/src/ifcbimtester/bimtester/features/steps/geometric_detail_de.py @@ -0,0 +1,10 @@ +from behave import step + +from geometric_detail_methods import class_geometric_representation +from utils import switch_locale + + +step("Alle {ifc_class} Bauteile müssen eine geometrische Repräsentation der Klasse {representation_class} verwenden") +def step_impl(context, ifc_class, representation_class): + switch_locale(context.localedir, "de") + class_geometric_representation(context, ifc_class, representation_class) diff --git a/src/ifcbimtester/bimtester/features/steps/geometric_detail_methods.py b/src/ifcbimtester/bimtester/features/steps/geometric_detail_methods.py new file mode 100644 index 0000000000..5a321abc32 --- /dev/null +++ b/src/ifcbimtester/bimtester/features/steps/geometric_detail_methods.py @@ -0,0 +1,54 @@ +import gettext # noqa +from utils import assert_elements +from utils import IfcFile + + +def class_geometric_representation(context, ifc_class, representation_class): + + def is_item_a_representation(item, representation): + if "/" in representation: + for cls in representation.split("/"): + if item.is_a(cls): + return True + elif item.is_a(representation): + return True + + context.falseelems = [] + context.falseguids = [] + context.falseprops = {} + rep = None + + elements = IfcFile.get().by_type(ifc_class) + for elem in elements: + if not elem.Representation: + continue + has_representation = False + for representation in elem.Representation.Representations: + for item in representation.Items: + if item.is_a("IfcMappedItem"): + # We only check one more level deep. + for item2 in item.MappingSource.MappedRepresentation.Items: + if is_item_a_representation(item2, representation_class): + has_representation = True + rep = item2 + else: + if is_item_a_representation(item, representation_class): + has_representation = True + rep = item + if not has_representation: + context.falseelems.append(str(elem)) + context.falseguids.append(elem.GlobalId) + context.falseprops[elem.id()] = str(rep) + + context.elemcount = len(elements) + context.falsecount = len(context.falseelems) + assert_elements( + ifc_class, + context.elemcount, + context.falsecount, + context.falseelems, + message_all_falseelems=_("All {elemcount} {ifc_class} elements are not a {parameter} representation."), + message_some_falseelems=_("The following {falsecount} of {elemcount} {ifc_class} elements are not a {parameter} representation: {falseelems}"), + message_no_elems=_("There are no {ifc_class} elements in the IFC file."), + parameter=representation_class + ) diff --git a/src/ifcbimtester/bimtester/features/steps/steps.py b/src/ifcbimtester/bimtester/features/steps/steps.py index 8627efd419..9990a9ef97 100644 --- a/src/ifcbimtester/bimtester/features/steps/steps.py +++ b/src/ifcbimtester/bimtester/features/steps/steps.py @@ -18,35 +18,6 @@ def step_impl(context, ifc_class, pattern): assert False -@step("all {ifc_class} elements have an {representation_class} representation") -def step_impl(context, ifc_class, representation_class): - def is_item_a_representation(item, representation): - if "/" in representation: - for cls in representation.split("/"): - if item.is_a(cls): - return True - elif item.is_a(representation): - return True - - elements = IfcFile.get().by_type(ifc_class) - for element in elements: - if not element.Representation: - continue - has_representation = False - for representation in element.Representation.Representations: - for item in representation.Items: - if item.is_a("IfcMappedItem"): - # We only check one more level deep. - for item2 in item.MappingSource.MappedRepresentation.Items: - if is_item_a_representation(item2, representation_class): - has_representation = True - else: - if is_item_a_representation(item, representation_class): - has_representation = True - if not has_representation: - assert False - - use_step_matcher("re") diff --git a/src/ifcbimtester/bimtester/features/steps/utils.py b/src/ifcbimtester/bimtester/features/steps/utils.py index 30a79c5b60..f3078f8e61 100644 --- a/src/ifcbimtester/bimtester/features/steps/utils.py +++ b/src/ifcbimtester/bimtester/features/steps/utils.py @@ -1,3 +1,4 @@ +import gettext import ifcopenshell import ifcopenshell.express import ifcopenshell.util @@ -99,9 +100,66 @@ def assert_pset(element, pset_name, prop_name=None, value=None): ) +def assert_elements( + ifc_class, + elemcount, + falsecount, + falseelems, + message_all_falseelems, + message_some_falseelems, + message_no_elems, + parameter=None +): + if elemcount > 0 and falsecount == 0: + return # Test OK + elif elemcount == 0: + assert False, ( + message_no_elems.format( + ifc_class=ifc_class + ) + ) + elif falsecount == elemcount: + if parameter is None: + assert False, ( + message_all_falseelems.format( + elemcount=elemcount, + ifc_class=ifc_class + ) + ) + else: + assert False, ( + message_all_falseelems.format( + elemcount=elemcount, + ifc_class=ifc_class, + parameter=parameter + ) + ) + elif falsecount > 0 and falsecount < elemcount: + if parameter is None: + assert False, ( + message_some_falseelems.format( + falsecount=falsecount, + elemcount=elemcount, + ifc_class=ifc_class, + falseelems=falseelems, + ) + ) + else: + assert False, ( + message_some_falseelems.format( + falsecount=falsecount, + elemcount=elemcount, + ifc_class=ifc_class, + falseelems=falseelems, + parameter=parameter + ) + ) + else: + assert False, _("Error in falsecount, something went wrong.") + + def switch_locale(locale_dir, locale_id="en"): - from gettext import translation - newlang = translation( + newlang = gettext.translation( "messages", localedir=locale_dir, languages=[locale_id]