From 15f6b3803f0c9925e34882f5cbc80c82d0d0410e Mon Sep 17 00:00:00 2001
From: Dion Moult
Date: Fri, 2 Aug 2024 22:02:56 +1000
Subject: [PATCH] Fix #4986. IfcTester now determines whether a spec is
relevant to the ifc version
---
src/ifctester/ifctester/ids.py | 16 +-
src/ifctester/ifctester/reporter.py | 2 +
src/ifctester/ifctester/templates/report.html | 225 +++++++++---------
3 files changed, 133 insertions(+), 110 deletions(-)
diff --git a/src/ifctester/ifctester/ids.py b/src/ifctester/ifctester/ids.py
index 06f37ef23c..7242c2f812 100644
--- a/src/ifctester/ifctester/ids.py
+++ b/src/ifctester/ifctester/ids.py
@@ -139,7 +139,9 @@ class Ids:
ET.ElementTree(get_schema().encode(self.asdict())).write(filepath, encoding="utf-8", xml_declaration=True)
return get_schema().is_valid(filepath)
- def validate(self, ifc_file: ifcopenshell.file, filter_version=False, filepath: Optional[str] = None) -> None:
+ def validate(
+ self, ifc_file: ifcopenshell.file, should_filter_version: bool = False, filepath: Optional[str] = None
+ ) -> None:
if filepath:
self.filepath = filepath
self.filename = os.path.basename(filepath)
@@ -149,7 +151,8 @@ class Ids:
get_psets.cache_clear()
for specification in self.specifications:
specification.reset_status()
- specification.validate(ifc_file, filter_version=filter_version)
+ specification.check_ifc_version(ifc_file)
+ specification.validate(ifc_file, should_filter_version=should_filter_version)
class Specification:
@@ -177,6 +180,7 @@ class Specification:
self.passed_entities: set[ifcopenshell.entity_instance] = set()
self.failed_entities: set[ifcopenshell.entity_instance] = set()
self.status = None
+ self.is_ifc_version = None
def asdict(self):
results = {
@@ -246,8 +250,12 @@ class Specification:
facet.failures.clear()
self.status = None
- def validate(self, ifc_file: ifcopenshell.file, filter_version=False) -> None:
- if filter_version and ifc_file.schema not in self.ifcVersion:
+ def check_ifc_version(self, ifc_file: ifcopenshell.file) -> bool:
+ self.is_ifc_version = ifc_file.schema_identifier in self.ifcVersion
+ return self.is_ifc_version
+
+ def validate(self, ifc_file: ifcopenshell.file, should_filter_version: bool = False) -> None:
+ if should_filter_version and not self.is_ifc_version:
return
elements = None
diff --git a/src/ifctester/ifctester/reporter.py b/src/ifctester/ifctester/reporter.py
index 779d3376e7..d38d23a484 100644
--- a/src/ifctester/ifctester/reporter.py
+++ b/src/ifctester/ifctester/reporter.py
@@ -76,6 +76,7 @@ class ResultsSpecification(TypedDict):
description: str
instructions: str
status: bool
+ is_ifc_version: bool
total_applicable: int
total_applicable_pass: int
total_applicable_fail: int
@@ -359,6 +360,7 @@ class Json(Reporter):
description=specification.description,
instructions=specification.instructions,
status=specification.status,
+ is_ifc_version=specification.is_ifc_version,
total_applicable=total_applicable,
total_applicable_pass=total_applicable_pass,
total_applicable_fail=total_applicable - total_applicable_pass,
diff --git a/src/ifctester/ifctester/templates/report.html b/src/ifctester/ifctester/templates/report.html
index 1ecaaec7dc..c98e28f9e8 100644
--- a/src/ifctester/ifctester/templates/report.html
+++ b/src/ifctester/ifctester/templates/report.html
@@ -43,7 +43,7 @@
p.unspecified { background-color: #994f00; padding: 5px; border-radius: 5px; color: #fff; }
p.skipped { background-color: #8b8d8f; padding: 5px; border-radius: 5px; color: #fff; }
p.description { background-color: #eee; border-radius: 5px; padding: 20px; margin-left: auto; margin-right: auto; display: inline-block; font-weight: bold;}
- li { padding: 10px; font-family: monospace; }
+ li { padding: 10px; font-family: monospace; border-radius: 5px; margin-bottom: 5px; }
li.pass { background-color: var(--light-green); color: #333; }
li.fail { background-color: var(--light-red); color: #900; }
li.unspecified { background-color: #ffd37f; color: #a30; }
@@ -69,6 +69,8 @@
tbody tr:nth-child(odd) { background-color: rgba(1, 1, 1, 0.05); }
tbody tr:nth-child(even) { background-color: rgba(1, 1, 1, 0.1); }
tbody tr:hover { background-color: rgba(0, 0, 0, 0); }
+ div.info { float: left; width: 30%; }
+ div.results { float: left; width: calc(70% - 20px); margin-left: 20px; padding: 20px; border-radius: 5px; background-color: #fafafa; }
@@ -94,113 +96,124 @@
{{#specifications}}
-
- {{name}}
- {{#description}}
- {{description}}
- {{/description}}
- {{#instructions}}
- {{instructions}}
- {{/instructions}}
+
+
+
{{name}}
+ {{#description}}
+
{{description}}
+ {{/description}}
+ {{#instructions}}
+
{{instructions}}
+ {{/instructions}}
-
-
{{percent_checks_pass}}%
+
+
{{percent_checks_pass}}%
+
+
+ {{#status}}Pass{{/status}}{{^status}}Fail{{/status}}
+
+ Checks passed: {{total_checks_pass}} / {{total_checks}}
+
+
+ Elements passed: {{total_applicable_pass}} / {{total_applicable}}
+
+
+ {{^is_ifc_version}}
+
+
+ Warning: specification does not apply to this IFC version
+
+
+ {{/is_ifc_version}}
+
+
+
+ Applicability
+
+
+ {{#applicability}}
+ - {{.}}
+ {{/applicability}}
+
+
+ Requirements
+
+
+ {{#requirements}}
+ -
+
+
+ {{description}}
+
+ {{#total_pass}}
+
+
+
+ | Class |
+ PredefinedType |
+ Name |
+ Description |
+ GlobalId |
+ Tag |
+
+
+
+ {{#passed_entities}}
+
+ | {{class}} |
+ {{predefined_type}} |
+ {{name}} |
+ {{description}} |
+ {{global_id}} |
+ {{tag}} |
+
+ {{/passed_entities}}
+ {{#has_omitted_passes}}
+
+ | ... {{total_omitted_passes}} more passing elements not shown out of {{total_passed_entities}} total ... |
+
+ {{/has_omitted_passes}}
+
+
+ {{/total_pass}}
+ {{#total_fail}}
+
+
+
+ | Class |
+ PredefinedType |
+ Name |
+ Description |
+ Warning |
+ GlobalId |
+ Tag |
+
+
+
+ {{#failed_entities}}
+
+ | {{class}} |
+ {{predefined_type}} |
+ {{name}} |
+ {{description}} |
+ {{reason}} |
+ {{global_id}} |
+ {{tag}} |
+
+ {{/failed_entities}}
+ {{#has_omitted_failures}}
+
+ | ... {{total_omitted_failures}} more failing elements not shown out of {{total_failed_entities}} total ... |
+
+ {{/has_omitted_failures}}
+
+
+ {{/total_fail}}
+
+
+ {{/requirements}}
+
-
- {{#status}}Pass{{/status}}{{^status}}Fail{{/status}}
-
- Checks passed: {{total_checks_pass}} / {{total_checks}}
-
-
- Elements passed: {{total_applicable_pass}} / {{total_applicable}}
-
-
-
- Applicability
-
-
- {{#applicability}}
- - {{.}}
- {{/applicability}}
-
-
- Requirements
-
-
- {{#requirements}}
- -
-
-
- {{description}}
-
- {{#total_pass}}
-
-
-
- | Class |
- PredefinedType |
- Name |
- Description |
- GlobalId |
- Tag |
-
-
-
- {{#passed_entities}}
-
- | {{class}} |
- {{predefined_type}} |
- {{name}} |
- {{description}} |
- {{global_id}} |
- {{tag}} |
-
- {{/passed_entities}}
- {{#has_omitted_passes}}
-
- | ... {{total_omitted_passes}} more passing elements not shown out of {{total_passed_entities}} total ... |
-
- {{/has_omitted_passes}}
-
-
- {{/total_pass}}
- {{#total_fail}}
-
-
-
- | Class |
- PredefinedType |
- Name |
- Description |
- Warning |
- GlobalId |
- Tag |
-
-
-
- {{#failed_entities}}
-
- | {{class}} |
- {{predefined_type}} |
- {{name}} |
- {{description}} |
- {{reason}} |
- {{global_id}} |
- {{tag}} |
-
- {{/failed_entities}}
- {{#has_omitted_failures}}
-
- | ... {{total_omitted_failures}} more failing elements not shown out of {{total_failed_entities}} total ... |
-
- {{/has_omitted_failures}}
-
-
- {{/total_fail}}
-
-
- {{/requirements}}
-
{{/specifications}}