IfcTester now supports mandatory measures for properties

This commit is contained in:
Dion Moult
2022-09-12 11:21:39 +10:00
parent 88893a8c2c
commit f745222d37
2 changed files with 49 additions and 45 deletions
+15 -16
View File
@@ -437,25 +437,24 @@ class Property(Facet):
reason = {"type": "NOVALUE"}
break
if self.measure:
pset_entity = inst.wrapped_data.file.by_id(pset_props["id"])
for prop_entity in pset_entity.HasProperties:
if (
prop_entity.Name not in props[pset_name].keys()
or not prop_entity.is_a("IfcPropertySingleValue")
or prop_entity.NominalValue is None
):
continue
pset_entity = inst.wrapped_data.file.by_id(pset_props["id"])
for prop_entity in pset_entity.HasProperties:
if (
prop_entity.Name not in props[pset_name].keys()
or not prop_entity.is_a("IfcPropertySingleValue")
or prop_entity.NominalValue is None
):
continue
data_type = prop_entity.NominalValue.is_a()
data_type = prop_entity.NominalValue.is_a()
if data_type != self.measure:
is_pass = False
reason = {"type": "MEASURE", "actual": data_type}
break
unit = ifcopenshell.util.unit.get_property_unit(prop_entity, inst.wrapped_data.file)
if data_type != self.measure:
is_pass = False
reason = {"type": "MEASURE", "actual": data_type}
break
unit = ifcopenshell.util.unit.get_property_unit(prop_entity, inst.wrapped_data.file)
if unit:
props[pset_name][prop_entity.Name] = ifcopenshell.util.unit.convert(
prop_entity.NominalValue.wrappedValue,
getattr(unit, "Prefix", None),
+34 -29
View File
@@ -849,7 +849,7 @@ class TestProperty:
timeunit = ifcopenshell.api.run("unit.add_si_unit", ifc, unit_type="TIMEUNIT", name="SECOND")
ifcopenshell.api.run("unit.assign_unit", ifc, units=[lengthunit, areaunit, volumeunit, timeunit])
facet = Property(propertySet="Foo_Bar", name="Foo")
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcLabel")
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
run("Elements with no properties always fail", facet=facet, inst=element, expected=False)
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar")
@@ -860,11 +860,14 @@ class TestProperty:
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"})
run("A name check will match any property with any string value", facet=facet, inst=element, expected=True)
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ""})
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcLogical")
run("An empty string is considered falsey and will not pass", facet=facet, inst=element, expected=False)
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcLogical("UNKNOWN")})
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcDuration")
run("A logical unknown is considered falsey and will not pass", facet=facet, inst=element, expected=False)
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcDuration("P0D")})
run("A zero duration will pass", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcBoolean")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcBoolean(True)})
run("A property set to true will pass a name check", facet=facet, inst=element, expected=True)
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": False})
@@ -875,7 +878,7 @@ class TestProperty:
expected=True,
)
facet = Property(propertySet="Foo_Bar", name="Foo", value="Bar")
facet = Property(propertySet="Foo_Bar", name="Foo", value="Bar", measure="IfcLabel")
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"})
@@ -885,52 +888,54 @@ class TestProperty:
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Baz"})
run("Specifying a value fails against different values", facet=facet, inst=element, expected=False)
facet = Property(propertySet="Foo_Bar", name="Foo", value="")
facet = Property(propertySet="Foo_Bar", name="Foo", value="", measure="IfcLabel")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ""})
run("Non-ascii characters are treated without encoding", facet=facet, inst=element, expected=True)
identifier = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345"
facet = Property(propertySet="Foo_Bar", name="Foo", value=identifier + "_extra_characters")
facet = Property(
propertySet="Foo_Bar", name="Foo", value=identifier + "_extra_characters", measure="IfcIdentifier"
)
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcIdentifier(identifier)})
run("IDS does not handle string truncation such as for identifiers", facet=facet, inst=element, expected=False)
facet = Property(propertySet="Foo_Bar", name="Foo", value="1")
facet = Property(propertySet="Foo_Bar", name="Foo", value="1", measure="IfcLabel")
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "1"})
run("A number specified as a string is treated as a string", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", value="42")
facet = Property(propertySet="Foo_Bar", name="Foo", value="42", measure="IfcInteger")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcInteger(42)})
run("Integer values are checked using type casting 1/4", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.")
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.", measure="IfcInteger")
run("Integer values are checked using type casting 2/4", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.0")
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.0", measure="IfcInteger")
run("Integer values are checked using type casting 3/4", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.3")
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.3", measure="IfcInteger")
run("Integer values are checked using type casting 4/4", facet=facet, inst=element, expected=False)
facet = Property(propertySet="Foo_Bar", name="Foo", value="42")
facet = Property(propertySet="Foo_Bar", name="Foo", value="42", measure="IfcReal")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0)})
run("Real values are checked using type casting 1/3", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.0")
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.0", measure="IfcReal")
run("Real values are checked using type casting 2/3", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.3")
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.3", measure="IfcReal")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.3)})
run("Real values are checked using type casting 3/3", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", value="42,3")
facet = Property(propertySet="Foo_Bar", name="Foo", value="42,3", measure="IfcReal")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.3)})
run("Only specifically formatted numbers are allowed 1/4", facet=facet, inst=element, expected=False)
facet = Property(propertySet="Foo_Bar", name="Foo", value="123,4.5")
facet = Property(propertySet="Foo_Bar", name="Foo", value="123,4.5", measure="IfcReal")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(1234.5)})
run("Only specifically formatted numbers are allowed 2/4", facet=facet, inst=element, expected=False)
facet = Property(propertySet="Foo_Bar", name="Foo", value="1.2345e3")
facet = Property(propertySet="Foo_Bar", name="Foo", value="1.2345e3", measure="IfcReal")
run("Only specifically formatted numbers are allowed 3/4", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", value="1.2345E3")
facet = Property(propertySet="Foo_Bar", name="Foo", value="1.2345E3", measure="IfcReal")
run("Only specifically formatted numbers are allowed 4/4", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.")
facet = Property(propertySet="Foo_Bar", name="Foo", value="42.", measure="IfcReal")
ifcopenshell.api.run(
"pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42.0 * (1.0 + 1e-6))}
)
@@ -948,15 +953,15 @@ class TestProperty:
)
run("Floating point numbers are compared with a 1e-6 tolerance 4/4", facet=facet, inst=element, expected=False)
facet = Property(propertySet="Foo_Bar", name="Foo", value="TRUE")
facet = Property(propertySet="Foo_Bar", name="Foo", value="TRUE", measure="IfcBoolean")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcBoolean(False)})
run("Booleans must be specified as uppercase strings 1/3", facet=facet, inst=element, expected=False)
facet = Property(propertySet="Foo_Bar", name="Foo", value="FALSE")
facet = Property(propertySet="Foo_Bar", name="Foo", value="FALSE", measure="IfcBoolean")
run("Booleans must be specified as uppercase strings 2/3", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", value="False")
facet = Property(propertySet="Foo_Bar", name="Foo", value="False", measure="IfcBoolean")
run("Booleans must be specified as uppercase strings 3/3", facet=facet, inst=element, expected=False)
facet = Property(propertySet="Foo_Bar", name="Foo", value="2022-01-01")
facet = Property(propertySet="Foo_Bar", name="Foo", value="2022-01-01", measure="IfcDate")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcDate("2022-01-01")})
run("Dates are treated as strings 1/2", facet=facet, inst=element, expected=True)
ifcopenshell.api.run(
@@ -964,14 +969,14 @@ class TestProperty:
)
run("Dates are treated as strings 2/2", facet=facet, inst=element, expected=False)
facet = Property(propertySet="Foo_Bar", name="Foo", value="PT16H")
facet = Property(propertySet="Foo_Bar", name="Foo", value="PT16H", measure="IfcDuration")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcDuration("PT16H")})
run("Durations are treated as strings 1/2", facet=facet, inst=element, expected=True)
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcDuration("P2D")})
run("Durations are treated as strings 1/2", facet=facet, inst=element, expected=False)
restriction = Restriction(options="Foo_.*", type="pattern")
facet = Property(propertySet=restriction, name="Foo")
facet = Property(propertySet=restriction, name="Foo", measure="IfcLabel")
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"})
@@ -983,7 +988,7 @@ class TestProperty:
run("All matching property sets must satisfy requirements 3/3", facet=facet, inst=element, expected=True)
restriction = Restriction(options="Foo.*", type="pattern")
facet = Property(propertySet="Foo_Bar", name=restriction, value="x")
facet = Property(propertySet="Foo_Bar", name=restriction, value="x", measure="IfcLabel")
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foobar": "x"})
@@ -995,7 +1000,7 @@ class TestProperty:
restriction1 = Restriction(options="Foo.*", type="pattern")
restriction2 = Restriction(options=["x", "y"], type="enumeration")
facet = Property(propertySet="Foo_Bar", name=restriction1, value=restriction2)
facet = Property(propertySet="Foo_Bar", name=restriction1, value=restriction2, measure="IfcLabel")
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foobar": "x", "Foobaz": "y"})
@@ -1017,9 +1022,9 @@ class TestProperty:
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=element, name="Foo_Bar")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcMassMeasure(2)})
run("Measure may be used to specify an IFC data type 1/2", facet=facet, inst=element, expected=False)
run("Measures are used to specify an IFC data type 1/2", facet=facet, inst=element, expected=False)
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcTimeMeasure(2)})
run("Measure may be used to specify an IFC data type 2/2", facet=facet, inst=element, expected=True)
run("Measures are used to specify an IFC data type 2/2", facet=facet, inst=element, expected=True)
facet = Property(propertySet="Foo_Bar", name="Foo", value="2", measure="IfcLengthMeasure")
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcWall")
@@ -1044,7 +1049,7 @@ class TestProperty:
ifcopenshell.api.run("type.assign_type", ifc, related_object=wall, relating_type=wall_type)
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall_type, name="Foo_Bar")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"})
facet = Property(propertySet="Foo_Bar", name="Foo")
facet = Property(propertySet="Foo_Bar", name="Foo", measure="IfcLabel")
run("Properties can be inherited from the type 1/2", facet=facet, inst=wall, expected=True)
run("Properties can be inherited from the type 2/2", facet=facet, inst=wall_type, expected=True)
@@ -1055,7 +1060,7 @@ class TestProperty:
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Baz"})
pset = ifcopenshell.api.run("pset.add_pset", ifc, product=wall, name="Foo_Bar")
ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": "Bar"})
facet = Property(propertySet="Foo_Bar", name="Foo", value="Bar")
facet = Property(propertySet="Foo_Bar", name="Foo", value="Bar", measure="IfcLabel")
run("Properties can be overriden by an occurrence 1/2", facet=facet, inst=wall, expected=True)
run("Properties can be overriden by an occurrence 2/2", facet=facet, inst=wall_type, expected=False)