diff --git a/src/ifctester/ifctester/facet.py b/src/ifctester/ifctester/facet.py index b4df337dcd..fa2e5349a7 100644 --- a/src/ifctester/ifctester/facet.py +++ b/src/ifctester/ifctester/facet.py @@ -231,7 +231,12 @@ class Attribute(Facet): break elif isinstance(self.value, str): cast_value = cast_to_value(self.value, value) - if value != cast_value: + if isinstance(value, float) and isinstance(cast_value, float): + if value < cast_value * (1. - 1e-6) or value > cast_value * (1. + 1e-6): + is_pass = False + reason = {"type": "VALUE", "actual": value} + break + elif value != cast_value: is_pass = False reason = {"type": "VALUE", "actual": value} break @@ -420,7 +425,12 @@ class Property(Facet): break elif isinstance(self.value, str): cast_value = cast_to_value(self.value, value) - if value != cast_value: + if isinstance(value, float) and isinstance(cast_value, float): + if value < cast_value * (1. - 1e-6) or value > cast_value * (1. + 1e-6): + is_pass = False + reason = {"type": "VALUE", "actual": value} + break + elif value != cast_value: is_pass = False reason = {"type": "VALUE", "actual": value} break diff --git a/src/ifctester/test/test_facet.py b/src/ifctester/test/test_facet.py index dee1a98986..3b7f5e67d7 100644 --- a/src/ifctester/test/test_facet.py +++ b/src/ifctester/test/test_facet.py @@ -487,6 +487,33 @@ class TestAttribute: expected=True, ) + facet = Attribute(name="RefractionIndex", value="42.") + ifc = ifcopenshell.file() + run( + "Floating point numbers are compared with a 1e-6 tolerance 1/4", + facet=facet, + inst=ifc.createIfcSurfaceStyleRefraction(RefractionIndex=42. * (1. + 1e-6)), + expected=True, + ) + run( + "Floating point numbers are compared with a 1e-6 tolerance 2/4", + facet=facet, + inst=ifc.createIfcSurfaceStyleRefraction(RefractionIndex=42. * (1. - 1e-6)), + expected=True, + ) + run( + "Floating point numbers are compared with a 1e-6 tolerance 3/4", + facet=facet, + inst=ifc.createIfcSurfaceStyleRefraction(RefractionIndex=42. * (1. + 2e-6)), + expected=False, + ) + run( + "Floating point numbers are compared with a 1e-6 tolerance 4/4", + facet=facet, + inst=ifc.createIfcSurfaceStyleRefraction(RefractionIndex=42. * (1. - 2e-6)), + expected=False, + ) + facet = Attribute(name="NumberOfRisers", value="42") ifc = ifcopenshell.file() run( @@ -903,6 +930,16 @@ class TestProperty: facet = Property(propertySet="Foo_Bar", name="Foo", value="1.2345E3") run("Only specifically formatted numbers are allowed 4/4", facet=facet, inst=element, expected=True) + facet = Property(propertySet="Foo_Bar", name="Foo", value="42.") + ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42. * (1. + 1e-6))}) + run("Floating point numbers are compared with a 1e-6 tolerance 1/4", facet=facet, inst=element, expected=True) + ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42. * (1. - 1e-6))}) + run("Floating point numbers are compared with a 1e-6 tolerance 2/4", facet=facet, inst=element, expected=True) + ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42. * (1. + 2e-6))}) + run("Floating point numbers are compared with a 1e-6 tolerance 3/4", facet=facet, inst=element, expected=False) + ifcopenshell.api.run("pset.edit_pset", ifc, pset=pset, properties={"Foo": ifc.createIfcReal(42. * (1. - 2e-6))}) + 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") 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)