Fix #4986. IfcTester now determines whether a spec is relevant to the ifc version

This commit is contained in:
Dion Moult
2024-08-02 22:02:56 +10:00
parent 8514a426bb
commit 15f6b3803f
3 changed files with 133 additions and 110 deletions
+12 -4
View File
@@ -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
+2
View File
@@ -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,
+119 -106
View File
@@ -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; }
</style>
</head>
<body>
@@ -94,113 +96,124 @@
</p>
<hr>
{{#specifications}}
<section>
<h2>{{name}}</h2>
{{#description}}
<p>{{description}}</p>
{{/description}}
{{#instructions}}
<p><em>{{instructions}}</em></p>
{{/instructions}}
<section style="clear: both; overflow: hidden;">
<div class="info">
<h2>{{name}}</h2>
{{#description}}
<p>{{description}}</p>
{{/description}}
{{#instructions}}
<p><em>{{instructions}}</em></p>
{{/instructions}}
<div class="container">
<div class="{{#status}}pass{{/status}}{{^status}}fail{{/status}} percent" style="width: {{percent_checks_pass}}%;">{{percent_checks_pass}}%</div>
<div class="container">
<div class="{{#status}}pass{{/status}}{{^status}}fail{{/status}} percent" style="width: {{percent_checks_pass}}%;">{{percent_checks_pass}}%</div>
</div>
<p>
<span class="item {{#status}}pass{{/status}}{{^status}}fail{{/status}}">{{#status}}Pass{{/status}}{{^status}}Fail{{/status}}</span>
<span class="item">
Checks passed: <strong>{{total_checks_pass}}</strong> / <strong>{{total_checks}}</strong>
</span>
<span class="item">
Elements passed: <strong>{{total_applicable_pass}}</strong> / <strong>{{total_applicable}}</strong>
</span>
</p>
{{^is_ifc_version}}
<p>
<span class="item">
<strong>Warning:</strong> specification does not apply to this IFC version
</span>
</p>
{{/is_ifc_version}}
</div>
<div class="results">
<p>
<strong>Applicability</strong>
</p>
<ul>
{{#applicability}}
<li>{{.}}</li>
{{/applicability}}
</ul>
<p>
<strong>Requirements</strong>
</p>
<ol>
{{#requirements}}
<li class="{{#status}}pass{{/status}}{{^status}}fail{{/status}}">
<details>
<summary>
{{description}}
</summary>
{{#total_pass}}
<table class="pass">
<thead>
<tr>
<th>Class</th>
<th>PredefinedType</th>
<th>Name</th>
<th>Description</th>
<th>GlobalId</th>
<th>Tag</th>
</tr>
</thead>
<tbody>
{{#passed_entities}}
<tr>
<td>{{class}}</td>
<td>{{predefined_type}}</td>
<td>{{name}}</td>
<td>{{description}}</td>
<td>{{global_id}}</td>
<td>{{tag}}</td>
</tr>
{{/passed_entities}}
{{#has_omitted_passes}}
<tr>
<td colspan="7"> ... {{total_omitted_passes}} more passing elements not shown out of {{total_passed_entities}} total ...</td>
</tr>
{{/has_omitted_passes}}
</tbody>
</table>
{{/total_pass}}
{{#total_fail}}
<table class="fail">
<thead>
<tr>
<th>Class</th>
<th>PredefinedType</th>
<th>Name</th>
<th>Description</th>
<th>Warning</th>
<th>GlobalId</th>
<th>Tag</th>
</tr>
</thead>
<tbody>
{{#failed_entities}}
<tr>
<td>{{class}}</td>
<td>{{predefined_type}}</td>
<td>{{name}}</td>
<td>{{description}}</td>
<td>{{reason}}</td>
<td>{{global_id}}</td>
<td>{{tag}}</td>
</tr>
{{/failed_entities}}
{{#has_omitted_failures}}
<tr>
<td colspan="7"> ... {{total_omitted_failures}} more failing elements not shown out of {{total_failed_entities}} total ...</td>
</tr>
{{/has_omitted_failures}}
</tbody>
</table>
{{/total_fail}}
</details>
</li>
{{/requirements}}
</ol>
</div>
<p>
<span class="item {{#status}}pass{{/status}}{{^status}}fail{{/status}}">{{#status}}Pass{{/status}}{{^status}}Fail{{/status}}</span>
<span class="item">
Checks passed: <strong>{{total_checks_pass}}</strong> / <strong>{{total_checks}}</strong>
</span>
<span class="item">
Elements passed: <strong>{{total_applicable_pass}}</strong> / <strong>{{total_applicable}}</strong>
</span>
</p>
<p>
<strong>Applicability</strong>
</p>
<ul>
{{#applicability}}
<li>{{.}}</li>
{{/applicability}}
</ul>
<p>
<strong>Requirements</strong>
</p>
<ol>
{{#requirements}}
<li class="{{#status}}pass{{/status}}{{^status}}fail{{/status}}">
<details>
<summary>
{{description}}
</summary>
{{#total_pass}}
<table class="pass">
<thead>
<tr>
<th>Class</th>
<th>PredefinedType</th>
<th>Name</th>
<th>Description</th>
<th>GlobalId</th>
<th>Tag</th>
</tr>
</thead>
<tbody>
{{#passed_entities}}
<tr>
<td>{{class}}</td>
<td>{{predefined_type}}</td>
<td>{{name}}</td>
<td>{{description}}</td>
<td>{{global_id}}</td>
<td>{{tag}}</td>
</tr>
{{/passed_entities}}
{{#has_omitted_passes}}
<tr>
<td colspan="7"> ... {{total_omitted_passes}} more passing elements not shown out of {{total_passed_entities}} total ...</td>
</tr>
{{/has_omitted_passes}}
</tbody>
</table>
{{/total_pass}}
{{#total_fail}}
<table class="fail">
<thead>
<tr>
<th>Class</th>
<th>PredefinedType</th>
<th>Name</th>
<th>Description</th>
<th>Warning</th>
<th>GlobalId</th>
<th>Tag</th>
</tr>
</thead>
<tbody>
{{#failed_entities}}
<tr>
<td>{{class}}</td>
<td>{{predefined_type}}</td>
<td>{{name}}</td>
<td>{{description}}</td>
<td>{{reason}}</td>
<td>{{global_id}}</td>
<td>{{tag}}</td>
</tr>
{{/failed_entities}}
{{#has_omitted_failures}}
<tr>
<td colspan="7"> ... {{total_omitted_failures}} more failing elements not shown out of {{total_failed_entities}} total ...</td>
</tr>
{{/has_omitted_failures}}
</tbody>
</table>
{{/total_fail}}
</details>
</li>
{{/requirements}}
</ol>
</section>
{{/specifications}}
<hr>