Fix #6960. String reporting of cardinality did not match upstream docs.

The meaning of the upstream docs changed subtly a year ago and I never
caught up. There is still work to do.
This commit is contained in:
Dion Moult
2025-09-28 20:35:49 +10:00
parent 0532ceb029
commit db7c3e3b01
2 changed files with 35 additions and 7 deletions
+9 -7
View File
@@ -126,14 +126,16 @@ class Facet:
) -> str: ) -> str:
if clause_type == "applicability": if clause_type == "applicability":
templates = self.applicability_templates templates = self.applicability_templates
elif clause_type == "requirement":
is_prohibited = False
if specification and specification.maxOccurs == 0: if specification and specification.maxOccurs == 0:
is_prohibited = not is_prohibited templates = self.prohibited_templates
if requirement and requirement.cardinality == "prohibited": elif clause_type == "requirement":
is_prohibited = not is_prohibited if specification and specification.maxOccurs == 0:
templates = self.prohibited_templates if is_prohibited else self.requirement_templates return "The requirement is not applicable"
if requirement and requirement.cardinality == "optional": if (not requirement) or isinstance(requirement, Entity) or requirement.cardinality == "required":
templates = self.requirement_templates
elif requirement.cardinality == "prohibited":
templates = self.prohibited_templates
elif requirement.cardinality == "optional":
templates = [ templates = [
t.replace("shall", "may").replace("Shall", "May").replace("must", "may") for t in templates t.replace("shall", "may").replace("Shall", "May").replace("must", "may") for t in templates
] ]
+26
View File
@@ -32,6 +32,7 @@ import ifcopenshell.api.type
import ifcopenshell.api.unit import ifcopenshell.api.unit
import ifcopenshell.guid import ifcopenshell.guid
import ifcopenshell.util.pset import ifcopenshell.util.pset
import ifctester.ids
import ifctester.facet import ifctester.facet
from ifctester.facet import Entity, Attribute, Classification, Property, PartOf, Material, Restriction from ifctester.facet import Entity, Attribute, Classification, Property, PartOf, Material, Restriction
@@ -229,6 +230,31 @@ class TestEntity:
wall3 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall", predefined_type="BAZFOO") wall3 = ifcopenshell.api.root.create_entity(ifc, ifc_class="IfcWall", predefined_type="BAZFOO")
run("Restrictions an be specified for the predefined type 3/3", facet=facet, inst=wall3, expected=False) run("Restrictions an be specified for the predefined type 3/3", facet=facet, inst=wall3, expected=False)
def test_to_string_required_applicability(self):
spec = ifctester.ids.Specification(name="Foo", minOccurs=1, maxOccurs="unbounded")
facet = Entity(name="IFCWALL")
assert facet.to_string("applicability", spec) == "All IFCWALL data"
def test_to_string_optional_applicability(self):
spec = ifctester.ids.Specification(name="Foo", minOccurs=0, maxOccurs="unbounded")
facet = Entity(name="IFCWALL")
assert facet.to_string("applicability", spec) == "All IFCWALL data"
def test_to_string_prohibited_applicability(self):
spec = ifctester.ids.Specification(name="Foo", minOccurs=0, maxOccurs=0)
facet = Entity(name="IFCWALL")
assert facet.to_string("applicability", spec) == "Shall not be IFCWALL data"
def test_to_string_ignored_requirement(self):
spec = ifctester.ids.Specification(name="Foo", minOccurs=0, maxOccurs=0)
facet = Entity(name="IFCWALL")
assert facet.to_string("requirement", spec) == "The requirement is not applicable"
def test_to_string_required_requirement(self):
spec = ifctester.ids.Specification(name="Foo")
facet = Entity(name="IFCWALL")
assert facet.to_string("requirement", spec) == "Shall be IFCWALL data"
class TestAttribute: class TestAttribute:
def test_creating_an_attribute_facet(self): def test_creating_an_attribute_facet(self):