diff --git a/src/ifctester/ifctester/facet.py b/src/ifctester/ifctester/facet.py index 9f7356ee95..cc265583ca 100644 --- a/src/ifctester/ifctester/facet.py +++ b/src/ifctester/ifctester/facet.py @@ -56,8 +56,7 @@ def get_psets(element): class Facet: def __init__(self, *parameters): self.status = None - self.failed_entities: List[Facet] = [] - self.failed_reasons: List[str] = [] + self.failures = [] for i, name in enumerate(self.parameters): setattr(self, name.replace("@", ""), parameters[i]) @@ -96,7 +95,7 @@ class Facet: templates = self.applicability_templates elif clause_type == "requirement": is_prohibited = False - if specification.cardinality == "prohibited": + if specification.maxOccurs == 0: is_prohibited = not is_prohibited if requirement.cardinality == "prohibited": is_prohibited = not is_prohibited diff --git a/src/ifctester/ifctester/ids.py b/src/ifctester/ifctester/ids.py index aaa74120df..255ccb5a1f 100644 --- a/src/ifctester/ifctester/ids.py +++ b/src/ifctester/ifctester/ids.py @@ -193,7 +193,7 @@ class Specification: self.description = ids_dict.get("@description", "") self.instructions = ids_dict.get("@instructions", "") self.minOccurs = ids_dict.get("applicability", {}).get("@minOccurs", 0) - self.maxOccurs = ids_dict.get("applicability", {}).get("@minOccurs", "unbounded") + self.maxOccurs = ids_dict.get("applicability", {}).get("@maxOccurs", "unbounded") self.ifcVersion = ids_dict["@ifcVersion"] self.applicability = ( self.parse_clause(ids_dict["applicability"]) if ids_dict.get("applicability", None) is not None else [] @@ -221,7 +221,7 @@ class Specification: self.failed_entities: Set[Entity] = set() for facet in self.requirements: facet.status = None - facet.failed_entities.clear() + facet.failures.clear() self.status = None def validate(self, ifc_file, filter_version=False): @@ -250,16 +250,15 @@ class Specification: result = facet(element) if not bool(result): self.failed_entities.add(element) - facet.failed_entities.append(element) - facet.failed_reasons.append(str(result)) + facet.failures.append({"element": element, "reason": str(result)}) for facet in self.requirements: if facet.cardinality == "required": - facet.status = not bool(facet.failed_entities) + facet.status = not bool(facet.failures) elif facet.cardinality == "optional": facet.status = True elif facet.cardinality == "prohibited": - facet.status = bool(facet.failed_entities) + facet.status = bool(facet.failures) self.status = True if self.minOccurs != 0: diff --git a/src/ifctester/ifctester/reporter.py b/src/ifctester/ifctester/reporter.py index 9b96eff57c..ae4a3f5bee 100644 --- a/src/ifctester/ifctester/reporter.py +++ b/src/ifctester/ifctester/reporter.py @@ -105,19 +105,19 @@ class Console(Reporter): for requirement in specification.requirements: self.set_style("reset") - self.set_style("red") if requirement.failed_entities else self.set_style("green") + self.set_style("red") if requirement.failures else self.set_style("green") self.print(" " * 8 + requirement.to_string("requirement", specification, requirement)) self.set_style("reset") - for i, element in enumerate(requirement.failed_entities[0:10]): + for failure in requirement.failures[0:10]: self.print(" " * 12, end="") - self.report_reason(requirement.failed_reasons[i], element) - if len(requirement.failed_entities) > 10: - self.print(" " * 12 + f"... {len(requirement.failed_entities)} in total ...") + self.report_reason(failure) + if len(requirement.failures) > 10: + self.print(" " * 12 + f"... {len(requirement.failures)} in total ...") self.set_style("reset") - def report_reason(self, reason, element): + def report_reason(self, failure): is_bold = False - for substring in reason.split('"'): + for substring in failure["reason"].split('"'): if is_bold: self.set_style("purple") else: @@ -125,7 +125,7 @@ class Console(Reporter): self.print(substring, end="") is_bold = not is_bold self.set_style("grey") - self.print(" - " + str(element)) + self.print(" - " + str(failure["element"])) self.set_style("reset") def set_style(self, *colours): @@ -212,7 +212,7 @@ class Json(Reporter): total_checks_pass = 0 requirements = [] for requirement in specification.requirements: - total_fail = len(requirement.failed_entities) + total_fail = len(requirement.failures) total_pass = total_applicable - total_fail percent_pass = math.floor((total_pass / total_applicable) * 100) if total_applicable else "N/A" total_checks += total_applicable @@ -254,18 +254,18 @@ class Json(Reporter): def report_failed_entities(self, requirement): return [ { - "reason": requirement.failed_reasons[i], - "element": str(e), - "element_type": str(ifcopenshell.util.element.get_type(e)), - "class": e.is_a(), - "predefined_type": ifcopenshell.util.element.get_predefined_type(e), - "name": getattr(e, "Name", None), - "description": getattr(e, "Description", None), - "id": e.id(), - "global_id": getattr(e, "GlobalId", None), - "tag": getattr(e, "Tag", None), + "reason": f["reason"], + "element": str(f["element"]), + "element_type": str(ifcopenshell.util.element.get_type(f["element"])), + "class": f["element"].is_a(), + "predefined_type": ifcopenshell.util.element.get_predefined_type(f["element"]), + "name": getattr(f["element"], "Name", None), + "description": getattr(f["element"], "Description", None), + "id": f["element"].id(), + "global_id": getattr(f["element"], "GlobalId", None), + "tag": getattr(f["element"], "Tag", None), } - for i, e in enumerate(requirement.failed_entities) + for f in requirement.failures ] def to_string(self):