Implement attribute facet for IDS

This commit is contained in:
Dion Moult
2022-05-10 16:23:07 +10:00
parent 12e7ed356c
commit 083d9d3e3e
2 changed files with 86 additions and 0 deletions
@@ -523,6 +523,69 @@ class entity(facet):
return facet_evaluation(inst.is_a(self.name), self.message % {"name": inst.is_a()})
class attribute(facet):
"""The IDS attribute facet"""
parameters = ["name", "value", "location"]
@staticmethod
def create(name=None, value=None, location="any"):
"""Create an attribute facet that can be added to applicability or requirements of IDS specification.
:param name: Attribute name, such as "Description"
:type name: str
:param value: Attribute value
:type value: str, optional
:param location: Where to check for the parameter. One of "any"|"instance"|"type", defaults to "any"
:type location: str, optional
:return: entity object
:rtype: entity
"""
inst = attribute()
inst.name = name
inst.value = value
inst.location = location
return inst
def asdict(self):
"""Converts object to a dictionary, adding required attributes.
:return: Xmlschema compliant dictionary.
:rtype: dict
"""
fac_dict = {"name": parameter_asdict(self.name)}
if self.value:
fac_dict["value"] = parameter_asdict(self.value)
if self.location:
fac_dict["@location"] = self.location
return fac_dict
def __call__(self, inst, logger):
"""Validate an ifc instance against that entity facet.
:param inst: IFC entity element
:type inst: IFC entity
:param logger: Logging object
:type logger: logging
:return: result of the validation as bool and message
:rtype: facet_evaluation(bool, str)
"""
element_type = ifcopenshell.util.element.get_type(inst)
if self.location == "instance":
value = getattr(inst, self.name, None)
elif self.location == "type":
value = getattr(element_type, self.name, None) if element_type else None
elif self.location == "any":
value = getattr(element_type, self.name, None) if element_type else None
value = getattr(inst, self.name, value)
if self.value:
self.message = "foo"
return facet_evaluation(value == self.value, f"an entity with {self.name} set to '{value}'")
else:
return facet_evaluation(value, f"an entity with {self.name}")
class classification(facet):
"""
The IDS classification facet by traversing the HasAssociations inverse attribute
+23
View File
@@ -152,11 +152,34 @@ class TestIdsAuthoring(unittest.TestCase):
"""Creating basic IDS"""
def test_creating_a_minimal_ids_and_validating(self):
specs = ids.ids(title="Title")
spec = ids.specification(name="Name")
spec.add_applicability(ids.entity.create(name="IfcWall"))
spec.add_requirement(ids.attribute.create(name="Name", value="Waldo"))
specs.specifications.append(spec)
assert "http://standards.buildingsmart.org/IDS" in specs.to_string()
model = ifcopenshell.file()
model.createIfcWall(Name="Waldo")
specs.validate(model)
# TODO test this without resorting to hooking into logger output
def test_entity_create(self):
e = ids.entity.create(name="Test_Name", predefinedType="Test_PredefinedType")
self.assertEqual(e.name, "Test_Name")
self.assertEqual(e.predefinedType, "Test_PredefinedType")
def test_attribute_create(self):
attribute = ids.attribute.create(name="Name", value="Value")
assert attribute.name == "Name"
assert attribute.value == "Value"
assert attribute.asdict() == {
"name": {"simpleValue": "Name"},
"value": {"simpleValue": "Value"},
"@location": "any",
}
def test_classification_create(self):
c = ids.classification.create(location="any", value="Test_Value", system="Test_System")
self.assertEqual(c.location, "any")