mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Show percentage results in BIMTester, add tests for element existance, attributes from a list, and more generic attribute checking
This commit is contained in:
@@ -9,6 +9,8 @@ import os
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
import csv
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
def run_tests(args):
|
||||
@@ -45,13 +47,17 @@ def generate_report(args):
|
||||
'time': line.strip().split(' ... ')[1],
|
||||
'is_success': is_success
|
||||
})
|
||||
total_passes = len([s for s in steps if s['is_success'] == True])
|
||||
total_steps = len(steps)
|
||||
pass_rate = round((total_passes / total_steps) * 100)
|
||||
data['testcases'].append({
|
||||
'name': testcase.get('name'),
|
||||
'is_success': testcase.get('status') == 'passed',
|
||||
'time': testcase.get('time'),
|
||||
'steps': steps,
|
||||
'total_passes': len([s for s in steps if s['is_success'] == True]),
|
||||
'total_steps': len(steps)
|
||||
'total_passes': total_passes,
|
||||
'total_steps': total_steps,
|
||||
'pass_rate': pass_rate
|
||||
})
|
||||
with open('report/{}.html'.format(file[0:-4]), 'w') as out:
|
||||
with open('features/template.html') as template:
|
||||
|
||||
@@ -41,11 +41,6 @@ def step_impl(context, file):
|
||||
pass
|
||||
|
||||
|
||||
@given('that an IFC file is loaded')
|
||||
def step_impl(context):
|
||||
assert IfcFile.get()
|
||||
|
||||
|
||||
@then('the file should be an {schema} file')
|
||||
def step_impl(context, schema):
|
||||
assert IfcFile.get().schema == schema
|
||||
@@ -62,10 +57,15 @@ def step_impl(context, id, reason):
|
||||
|
||||
|
||||
@then('the file is exempt from auditing because {reason}')
|
||||
def step_impl(context, id, reason):
|
||||
def step_impl(context, reason):
|
||||
pass
|
||||
|
||||
|
||||
@given(u'there is at least one {ifc_class} element')
|
||||
def step_impl(context, ifc_class):
|
||||
assert len(IfcFile.get().by_type(ifc_class)) >= 1
|
||||
|
||||
|
||||
@then('all {ifc_class} elements have a name matching the pattern "{pattern}"')
|
||||
def step_impl(context, ifc_class, pattern):
|
||||
import re
|
||||
@@ -147,6 +147,25 @@ def step_impl(context, ifc_class, attribute, pattern):
|
||||
assert re.search(pattern, value)
|
||||
|
||||
|
||||
@then('all (?P<ifc_class>.*) elements have an? (?P<attributes>.*) taken from the list in "(?P<list_file>.*)"')
|
||||
def step_impl(context, ifc_class, attributes, list_file):
|
||||
import csv
|
||||
values = []
|
||||
with open(list_file) as csvfile:
|
||||
reader = csv.reader(csvfile)
|
||||
for row in reader:
|
||||
values.append(row)
|
||||
elements = IfcFile.get().by_type(ifc_class)
|
||||
for element in elements:
|
||||
attribute_values = []
|
||||
for attribute in attributes.split(','):
|
||||
if not hasattr(element, attribute):
|
||||
assert False, f'Failed at element {element.GlobalId}'
|
||||
attribute_values.append(getattr(element, attribute))
|
||||
if attribute_values not in values:
|
||||
assert False, f'Failed at element {element.GlobalId}'
|
||||
|
||||
|
||||
use_step_matcher('parse')
|
||||
@then('all {ifc_class} elements have a {qto_name}.{quantity_name} quantity')
|
||||
def step_impl(context, ifc_class, qto_name, quantity_name):
|
||||
@@ -201,29 +220,19 @@ def step_impl(context, attribute, value):
|
||||
|
||||
|
||||
use_step_matcher('parse')
|
||||
@then(u'the project name is "{name}"')
|
||||
def step_impl(context, name):
|
||||
project_name = IfcFile.get().by_type('IfcProject')[0].Name
|
||||
assert project_name == name, f'The name was {project_name}'
|
||||
|
||||
|
||||
@then(u'there is a site named "{name}"')
|
||||
def step_impl(context, name):
|
||||
@then(u'the project has a {attribute_name} attribute with a value of "{attribute_value}"')
|
||||
def step_impl(context, attribute_name, attribute_value):
|
||||
project = IfcFile.get().by_type('IfcProject')[0]
|
||||
if not project.IsDecomposedBy:
|
||||
assert False
|
||||
for relationship in project.IsDecomposedBy:
|
||||
for part in relationship.RelatedObjects:
|
||||
if part.is_a('IfcSite'):
|
||||
assert part.Name == name, f'The name was {part.Name}'
|
||||
assert getattr(project, attribute_name) == attribute_value
|
||||
|
||||
|
||||
@then(u'there is a building named "{name}"')
|
||||
def step_impl(context, name):
|
||||
for building in IfcFile.get().by_type('IfcBuilding'):
|
||||
if building.Name == name:
|
||||
@then(u'there is an {ifc_class} element with a {attribute_name} attribute with a value of "{attribute_value}"')
|
||||
def step_impl(context, ifc_class, attribute_name, attribute_value):
|
||||
elements = IfcFile.get().by_type(ifc_class)
|
||||
for element in elements:
|
||||
if hasattr(element, attribute_name) \
|
||||
and getattr(element, attribute_name) == attribute_value:
|
||||
return
|
||||
print(f'A building named {building.Name} was found.')
|
||||
assert False
|
||||
|
||||
|
||||
@@ -232,8 +241,3 @@ def step_impl(context):
|
||||
for building in IfcFile.get().by_type('IfcBuilding'):
|
||||
if not building.BuildingAddress:
|
||||
assert False, f'The building "{building.Name}" has no address.'
|
||||
|
||||
|
||||
@then(u'all the IFC files have the same building storeys')
|
||||
def step_impl(context):
|
||||
raise NotImplementedError(u'STEP: Then all the IFC files have the same building storeys')
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<h2>{{name}}</h2>
|
||||
<p>
|
||||
<span class="{{#is_success}}success{{/is_success}}{{^is_success}}failure{{/is_success}}">{{#is_success}}Success{{/is_success}}{{^is_success}}Failure{{/is_success}}</span>
|
||||
Tests passed: <strong>{{total_passes}} / {{total_steps}}</strong>
|
||||
Tests passed: <strong>{{total_passes}} / {{total_steps}}</strong> ({{pass_rate}}%)
|
||||
<span class="time">
|
||||
Time taken: {{time}} seconds
|
||||
</span>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/python
|
||||
# This can be packaged with `pyinstaller --onefile --clean --icon=icon.ico diff.py`
|
||||
# This can be packaged with `pyinstaller --onefile --clean --icon=icon.ico ifcdiff.py`
|
||||
|
||||
import ifcopenshell
|
||||
from deepdiff import DeepDiff
|
||||
|
||||
Reference in New Issue
Block a user