bimstester: features, move element class attributes tests from examples to implemented steps

This commit is contained in:
Bernd Hahnebach
2021-12-07 12:59:50 +01:00
parent c658f7610e
commit 85d76c084b
6 changed files with 304 additions and 212 deletions
@@ -4,6 +4,9 @@ from bimtester.features.steps.aggregation import en
use_step_matcher("parse")
from bimtester.features.steps.application import en
use_step_matcher("parse")
from bimtester.features.steps.attributes_eleclasses import en, de
use_step_matcher("parse")
from bimtester.features.steps.attributes_psets import en, de
@@ -0,0 +1,31 @@
from behave import step
@step('Es sind keine "{ifc_class}" Bauteile vorhanden')
def step_impl(context, ifc_class):
context.execute_steps(f'* There are no "{ifc_class}" elements')
@step('Aus folgendem Grund gibt es keine "{ifc_class}" Bauteile: {reason}')
def step_impl(context, ifc_class, reason):
context.execute_steps(f'* There are no "{ifc_class}" elements because "{reason}"')
@step('Alle "{ifc_class}" Bauteilklassenattribute haben einen Wert')
def step_impl(context, ifc_class):
context.execute_steps(f'* All "{ifc_class}" elements class attributes have a value')
@step('Bei allen "{ifc_class}" Bauteilen ist der Name angegeben')
def step_impl(context, ifc_class):
context.execute_steps(f'* All "{ifc_class}" elements have a name given')
@step('Bei allen "{ifc_class}" Bauteilen ist die Beschreibung angegeben')
def step_impl(context, ifc_class):
context.execute_steps(f'* All "{ifc_class}" elements have a description given')
@step('Es sind ausschliesslich "{ifc_classes}" Bauteile vorhanden')
def step_impl(context, ifc_classes):
context.execute_steps(f'* There are exclusively "{ifc_class}" elements only')
@@ -0,0 +1,270 @@
import ifcopenshell.util.element as eleutils
from behave import step
from bimtester import util
from bimtester.ifc import IfcStore
from bimtester.lang import _
@step('There are no "{ifc_class}" elements')
def step_impl(context, ifc_class):
no_eleclass(
context,
ifc_class
)
@step('There are no "{ifc_class}" elements because "{reason}"')
def step_impl(context, ifc_class, reason):
no_eleclass(
context,
ifc_class
)
@step('All "{ifc_class}" elements class attributes have a value')
def step_impl(context, ifc_class):
eleclass_have_class_attributes_with_a_value(
context,
ifc_class
)
@step('All "{ifc_class}" elements have a name given')
def step_impl(context, ifc_class):
eleclass_has_name_with_a_value(
context,
ifc_class
)
@step('All "{ifc_class}" elements have a description given')
def step_impl(context, ifc_class):
eleclass_has_description_with_a_value(
context,
ifc_class
)
@step('There are exclusively "{ifc_class}" elements only')
def step_impl(context, ifc_classes):
only_eleclasses(
context,
ifc_classes
)
@step('All "{ifc_class}" elements have a name matching the pattern "{pattern}"')
def step_impl(context, ifc_class, pattern):
import re
elements = IfcStore.file.by_type(ifc_class)
for element in elements:
if not re.search(pattern, element.Name):
assert False
@step('There is an "{ifc_class}" element with a "{attribute_name}" attribute with a value of "{attribute_value}"')
def step_impl(context, ifc_class, attribute_name, attribute_value):
elements = IfcStore.file.by_type(ifc_class)
for element in elements:
if hasattr(element, attribute_name) and getattr(element, attribute_name) == attribute_value:
return
assert False
# ************************************************************************************************
# helper
def only_eleclasses(
context, ifc_classes
):
context.falseelems = []
context.falseguids = []
# get the list of ifc_classes
target_ifc_classes = ifc_classes.replace(" ","").split(",")
# ToDo test if they exist in ifc standard, should be possible with ifcos
all_elements = IfcStore.file.by_type("IfcBuildingElement")
context.elemcount = len(all_elements)
false_elements = []
for elem in all_elements:
if elem.is_a() not in target_ifc_classes:
context.falseelems.append(str(elem))
context.falseguids.append(elem.GlobalId)
out_falseelems = "\n"
for e in context.falseelems:
out_falseelems += e + "\n"
context.falsecount = len(context.falseelems)
# print(context.falsecount)
# print(context.elemcount)
if context.falsecount == 0:
return # Test OK, thus we can not use the assert_elements method ... really ?
elif context.falsecount == context.elemcount:
assert False, (
_("All {elemcount} false elements in the file are {ifc_classes}.")
.format(
elemcount=context.elemcount,
ifc_classes=ifc_classes
)
)
elif context.falsecount > 0 and context.falsecount < context.elemcount:
assert False, (
_("{falsecount} of {elemcount} false_elements are {ifc_classes} false_elements: {falseelems}")
.format(
falsecount=context.falsecount,
elemcount=context.elemcount,
ifc_classes=ifc_classes,
falseelems=out_falseelems,
)
)
else:
assert False, _("Error in falsecount, something went wrong.")
def no_eleclass(
context, ifc_class
):
context.falseelems = []
context.falseguids = []
elements = IfcStore.file.by_type(ifc_class)
context.elemcount = len(IfcStore.file.by_type("IfcBuildingElement"))
for elem in elements:
context.falseelems.append(str(elem))
context.falseguids.append(elem.GlobalId)
out_falseelems = "\n"
for e in context.falseelems:
out_falseelems += e + "\n"
context.falsecount = len(context.falseelems)
# print(context.falsecount)
# print(context.elemcount)
if context.falsecount == 0:
return # Test OK, thus we can not use the assert_elements method ... really ?
elif context.falsecount == context.elemcount:
assert False, (
_("All {elemcount} elements in the file are {ifc_class}.")
.format(
elemcount=context.elemcount,
ifc_class=ifc_class
)
)
elif context.falsecount > 0 and context.falsecount < context.elemcount:
assert False, (
_("{falsecount} of {elemcount} elements are {ifc_class} elements: {falseelems}")
.format(
falsecount=context.falsecount,
elemcount=context.elemcount,
ifc_class=ifc_class,
falseelems=out_falseelems,
)
)
else:
assert False, _("Error in falsecount, something went wrong.")
def eleclass_have_class_attributes_with_a_value(
context, ifc_class
):
from ifcopenshell.ifcopenshell_wrapper import schema_by_name
# schema = schema_by_name("IFC2X3")
schema = schema_by_name(IfcStore.file.schema)
class_attributes = []
for cl_attrib in schema.declaration_by_name(ifc_class).all_attributes():
class_attributes.append(cl_attrib.name())
# print(class_attributes)
context.falseelems = []
context.falseguids = []
context.falseprops = {}
elements = IfcStore.file.by_type(ifc_class)
for elem in elements:
failed_attribs = []
elem_failed = False
for cl_attrib in class_attributes:
attrib_value = getattr(elem, cl_attrib)
if not attrib_value:
elem_failed = True
failed_attribs.append(cl_attrib)
# print(attrib_value)
if elem_failed is True:
context.falseelems.append(str(elem))
context.falseguids.append(elem.GlobalId)
context.falseprops[elem.id()] = failed_attribs
context.elemcount = len(elements)
context.falsecount = len(context.falseelems)
util.assert_elements(
ifc_class,
context.elemcount,
context.falsecount,
context.falseelems,
message_all_falseelems=_("For all {elemcount} {ifc_class} elements at least one of these class attributes {parameter} has no value."),
message_some_falseelems=_("For the following {falsecount} out of {elemcount} {ifc_class} elements at least one of these class attributes {parameter} has no value: {falseelems}"),
message_no_elems=_("There are no {ifc_class} elements in the IFC file."),
parameter=failed_attribs
)
def eleclass_has_name_with_a_value(context, ifc_class):
context.falseelems = []
context.falseguids = []
elements = IfcStore.file.by_type(ifc_class)
for elem in elements:
# print(elem.Name)
if not elem.Name:
context.falseelems.append(str(elem))
context.falseguids.append(elem.GlobalId)
context.elemcount = len(elements)
context.falsecount = len(context.falseelems)
util.assert_elements(
ifc_class,
context.elemcount,
context.falsecount,
context.falseelems,
message_all_falseelems=_("The name of all {elemcount} {elemcount} elements is not set."),
message_some_falseelems=_("The name of {falsecount} out of {elemcount} {ifc_class} elements is not set: {falseelems}"),
message_no_elems=_("There are no {ifc_class} elements in the IFC file."),
)
def eleclass_has_description_with_a_value(
context, ifc_class
):
context.falseelems = []
context.falseguids = []
elements = IfcStore.file.by_type(ifc_class)
for elem in elements:
# print(elem.Description)
if not elem.Description:
context.falseelems.append(str(elem))
context.falseguids.append(elem.GlobalId)
context.elemcount = len(elements)
context.falsecount = len(context.falseelems)
util.assert_elements(
ifc_class,
context.elemcount,
context.falsecount,
context.falseelems,
message_all_falseelems=_("The description of all {elemcount} {elemcount} elements is not set."),
message_some_falseelems=_("The description of {falsecount} out of {elemcount} {ifc_class} elements is not set: {falseelems}"),
message_no_elems=_("There are no {ifc_class} elements in the IFC file."),
)
@@ -1,54 +1,8 @@
from behave import step
import attributes_eleclasses_methods as aem
from utils import assert_elements
from utils import IfcFile
@step("There are no {ifc_class} elements")
def step_impl(context, ifc_class):
aem.no_eleclass(context, ifc_class)
@step("There are no {ifc_class} elements because {reason}")
def step_impl(context, ifc_class, reason):
aem.no_eleclass(context, ifc_class)
@step("All {ifc_class} elements class attributes have a value")
def step_impl(context, ifc_class):
aem.eleclass_have_class_attributes_with_a_value(context, ifc_class)
@step("All {ifc_class} elements have a name given")
def step_impl(context, ifc_class):
aem.eleclass_has_name_with_a_value(context, ifc_class)
@step("All {ifc_class} elements have a description given")
def step_impl(context, ifc_class):
aem.eleclass_has_description_with_a_value(context, ifc_class)
@step('all {ifc_class} elements have a name matching the pattern "{pattern}"')
def step_impl(context, ifc_class, pattern):
import re
elements = IfcFile.get().by_type(ifc_class)
for element in elements:
if not re.search(pattern, element.Name):
assert False
@step('there is an {ifc_class} element with a {attribute_name} attribute with a value of "{attribute_value}"')
def step_impl(context, ifc_class, attribute_name, attribute_value):
elements = IfcFile.get().by_type(ifc_class)
for element in elements:
if hasattr(element, attribute_name) and getattr(element, attribute_name) == attribute_value:
return
assert False
use_step_matcher("re")
@@ -1,26 +0,0 @@
from behave import step
@step("Es sind keine {ifc_class} Bauteile vorhanden")
def step_impl(context, ifc_class):
context.execute_steps(f"* There are no {ifc_class} elements")
@step("Aus folgendem Grund gibt es keine {ifc_class} Bauteile: {reason}")
def step_impl(context, ifc_class, reason):
context.execute_steps(f"* There are no {ifc_class} elements because {reason}")
@step("Alle {ifc_class} Bauteilklassenattribute haben einen Wert")
def step_impl(context, ifc_class):
context.execute_steps(f"* All {ifc_class} elements class attributes have a value")
@step("Bei allen {ifc_class} Bauteile ist der Name angegeben")
def step_impl(context, ifc_class):
context.execute_steps(f"* All {ifc_class} elements have a name given")
@step("Bei allen {ifc_class} Bauteile ist die Beschreibung angegeben")
def step_impl(context, ifc_class):
context.execute_steps(f"* All {ifc_class} elements have a description given")
@@ -1,140 +0,0 @@
import gettext # noqa
from utils import assert_elements
from utils import IfcFile
def no_eleclass(
context, ifc_class
):
context.falseelems = []
context.falseguids = []
elements = IfcFile.get().by_type(ifc_class)
for elem in elements:
context.falseelems.append(str(elem))
context.falseguids.append(elem.GlobalId)
context.elemcount = len(elements)
context.falsecount = len(context.falseelems)
if context.elemcount == 0 and context.falsecount == 0:
return # Test OK, thus we can not use the assert_elements method
elif context.falsecount == context.elemcount:
assert False, (
_("All {elemcount} elements in the file are {ifc_class}.")
.format(
elemcount=context.elemcount,
ifc_class=ifc_class
)
)
elif context.falsecount > 0 and fcontext.alsecount < context.elemcount:
assert False, (
_("{falsecount} of {elemcount} element are {ifc_class} elements: {falseelems}")
.format(
falsecount=context.falsecount,
elemcount=context.elemcount,
ifc_class=ifc_class,
falseelems=context.falseelems,
)
)
else:
assert False, _("Error in falsecount, something went wrong.")
def eleclass_have_class_attributes_with_a_value(
context, ifc_class
):
from ifcopenshell.ifcopenshell_wrapper import schema_by_name
# schema = schema_by_name("IFC2X3")
schema = schema_by_name(IfcFile.get().schema)
class_attributes = []
for cl_attrib in schema.declaration_by_name(ifc_class).all_attributes():
class_attributes.append(cl_attrib.name())
# print(class_attributes)
context.falseelems = []
context.falseguids = []
context.falseprops = {}
elements = IfcFile.get().by_type(ifc_class)
for elem in elements:
failed_attribs = []
elem_failed = False
for cl_attrib in class_attributes:
attrib_value = getattr(elem, cl_attrib)
if not attrib_value:
elem_failed = True
failed_attribs.append(cl_attrib)
# print(attrib_value)
if elem_failed is True:
context.falseelems.append(str(elem))
context.falseguids.append(elem.GlobalId)
context.falseprops[elem.id()] = failed_attribs
context.elemcount = len(elements)
context.falsecount = len(context.falseelems)
assert_elements(
ifc_class,
context.elemcount,
context.falsecount,
context.falseelems,
message_all_falseelems=_("For all {elemcount} {ifc_class} elements at least one of these class attributes {parameter} has no value."),
message_some_falseelems=_("For the following {falsecount} out of {elemcount} {ifc_class} elements at least one of these class attributes {parameter} has no value: {falseelems}"),
message_no_elems=_("There are no {ifc_class} elements in the IFC file."),
parameter=failed_attribs
)
def eleclass_has_name_with_a_value(context, ifc_class):
context.falseelems = []
context.falseguids = []
elements = IfcFile.get().by_type(ifc_class)
for elem in elements:
# print(elem.Name)
if not elem.Name:
context.falseelems.append(str(elem))
context.falseguids.append(elem.GlobalId)
context.elemcount = len(elements)
context.falsecount = len(context.falseelems)
assert_elements(
ifc_class,
context.elemcount,
context.falsecount,
context.falseelems,
message_all_falseelems=_("The name of all {elemcount} {elemcount} elements is not set."),
message_some_falseelems=_("The name of {falsecount} out of {elemcount} {ifc_class} elements is not set: {falseelems}"),
message_no_elems=_("There are no {ifc_class} elements in the IFC file."),
)
def eleclass_has_description_with_a_value(
context, ifc_class
):
context.falseelems = []
context.falseguids = []
elements = IfcFile.get().by_type(ifc_class)
for elem in elements:
# print(elem.Description)
if not elem.Description:
context.falseelems.append(str(elem))
context.falseguids.append(elem.GlobalId)
context.elemcount = len(elements)
context.falsecount = len(context.falseelems)
assert_elements(
ifc_class,
context.elemcount,
context.falsecount,
context.falseelems,
message_all_falseelems=_("The description of all {elemcount} {elemcount} elements is not set."),
message_some_falseelems=_("The description of {falsecount} out of {elemcount} {ifc_class} elements is not set: {falseelems}"),
message_no_elems=_("There are no {ifc_class} elements in the IFC file."),
)