Fix #1727. BIMTester now runs within the BlenderBIM Add-on, implement attribute checking in IDS, and fix some minor IDS bugs.

This commit is contained in:
Dion Moult
2021-09-08 20:16:39 +10:00
parent b9084ad0f5
commit d0eb716738
10 changed files with 129 additions and 61 deletions
+23 -3
View File
@@ -17,14 +17,19 @@
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import os
import re
import bpy
import pytest
import webbrowser
import blenderbim
import ifcopenshell
import ifcopenshell.util.representation
from blenderbim.bim.ifc import IfcStore
# Monkey-patch webbrowser opening since we want to test headlessly
webbrowser.open = lambda x: True
class NewFile:
@pytest.fixture(autouse=True)
@@ -64,8 +69,15 @@ def the_object_name_is_selected(name):
obj.select_set(True)
def i_select_value_in_prop(value, prop):
exec(f'bpy.context.{prop} = "{value}"')
def i_set_prop_to_value(prop, value):
try:
exec(f'bpy.context.{prop} = "{value}"')
except:
exec(f"bpy.context.{prop} = {value}")
def i_enable_prop(prop):
exec(f"bpy.context.{prop} = True")
def i_press_operator(operator):
@@ -136,11 +148,17 @@ def the_object_name1_and_name2_are_different_elements(name1, name2):
assert element1 != element2, f"Objects {name1} and {name2} have same elements {element1} and {element2}"
def the_file_name_should_contain_value(name, value):
with open(name, "r") as f:
assert value in f.read()
definitions = {
"an empty IFC project": an_empty_ifc_project,
"I add a cube": i_add_a_cube,
'the object "(.*)" is selected': the_object_name_is_selected,
'I select "(.*)" in "(.*)"': i_select_value_in_prop,
'I set "(.*)" to "(.*)"': i_set_prop_to_value,
'I enable "(.*)"': i_enable_prop,
'I press "(.*)"': i_press_operator,
'the object "(.*)" is an "(.*)"': the_object_name_is_an_ifc_class,
'the object "(.*)" is in the collection "(.*)"': the_object_name_is_in_the_collection_collection,
@@ -151,6 +169,7 @@ definitions = {
'the object "(.*)" is contained in "(.*)"': the_object_name_is_contained_in_container_name,
"I duplicate the selected objects": i_duplicate_the_selected_objects,
'the object "(.*)" and "(.*)" are different elements': the_object_name1_and_name2_are_different_elements,
'the file "(.*)" should contain "(.*)"': the_file_name_should_contain_value,
}
@@ -158,6 +177,7 @@ definitions = {
def run(scenario):
for line in scenario.split("\n"):
line = line.strip()
line = line.replace("{cwd}", os.getcwd())
if not line:
continue
match = None
@@ -0,0 +1,31 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import test.bim.bootstrap
class TestExecuteBIMTester(test.bim.bootstrap.NewFile):
@test.bim.bootstrap.scenario
def test_executing_bimtester(self):
return """
Given an empty IFC project
When I enable "scene.BimTesterProperties.should_load_from_memory"
And I set "scene.BimTesterProperties.feature" to "{cwd}/test/files/sample-ids.xml"
And I press "bim.execute_bim_tester"
Then the file "{cwd}/test/files/sample-ids.xml.html" should contain "Tests passed: <strong>1 / 1</strong> (100%)"
"""
@@ -26,7 +26,7 @@ class TestAssignClass(test.bim.bootstrap.NewFile):
Given an empty IFC project
When I add a cube
And the object "Cube" is selected
And I select "IfcWall" in "scene.BIMRootProperties.ifc_class"
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
And I press "bim.assign_class"
Then the object "IfcWall/Cube" is an "IfcWall"
And the object "IfcWall/Cube" is in the collection "Collection"
@@ -39,8 +39,8 @@ class TestAssignClass(test.bim.bootstrap.NewFile):
Given an empty IFC project
When I add a cube
And the object "Cube" is selected
And I select "IfcElementType" in "scene.BIMRootProperties.ifc_product"
And I select "IfcWallType" in "scene.BIMRootProperties.ifc_class"
And I set "scene.BIMRootProperties.ifc_product" to "IfcElementType"
And I set "scene.BIMRootProperties.ifc_class" to "IfcWallType"
And I press "bim.assign_class"
Then the object "IfcWallType/Cube" is an "IfcWallType"
And the object "IfcWallType/Cube" is in the collection "Types"
@@ -53,8 +53,8 @@ class TestAssignClass(test.bim.bootstrap.NewFile):
Given an empty IFC project
When I add a cube
And the object "Cube" is selected
And I select "IfcSpatialElement" in "scene.BIMRootProperties.ifc_product"
And I select "IfcBuilding" in "scene.BIMRootProperties.ifc_class"
And I set "scene.BIMRootProperties.ifc_product" to "IfcSpatialElement"
And I set "scene.BIMRootProperties.ifc_class" to "IfcBuilding"
And I press "bim.assign_class"
Then the object "IfcBuilding/Cube" is an "IfcBuilding"
And the object "IfcBuilding/Cube" is in the collection "IfcBuilding/Cube"
@@ -67,8 +67,8 @@ class TestAssignClass(test.bim.bootstrap.NewFile):
Given an empty IFC project
When I add a cube
And the object "Cube" is selected
And I select "IfcElement" in "scene.BIMRootProperties.ifc_product"
And I select "IfcOpeningElement" in "scene.BIMRootProperties.ifc_class"
And I set "scene.BIMRootProperties.ifc_product" to "IfcElement"
And I set "scene.BIMRootProperties.ifc_class" to "IfcOpeningElement"
And I press "bim.assign_class"
Then the object "IfcOpeningElement/Cube" is an "IfcOpeningElement"
And the object "IfcOpeningElement/Cube" is in the collection "IfcOpeningElements"
@@ -82,7 +82,7 @@ class TestAssignClass(test.bim.bootstrap.NewFile):
When I add a cube
And the object "Cube" is selected
And the object "Cube" is placed in the collection "IfcBuildingStorey/My Storey"
And I select "IfcWall" in "scene.BIMRootProperties.ifc_class"
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
And I press "bim.assign_class"
Then the object "IfcWall/Cube" is contained in "My Storey"
"""
@@ -95,7 +95,7 @@ class TestCopyClass(test.bim.bootstrap.NewFile):
Given an empty IFC project
When I add a cube
And the object "Cube" is selected
And I select "IfcWall" in "scene.BIMRootProperties.ifc_class"
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
And I press "bim.assign_class"
And I duplicate the selected objects
Then the object "IfcWall/Cube" and "IfcWall/Cube.001" are different elements
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<ids xmlns="http://standards.buildingsmart.org/IDS" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://standards.buildingsmart.org/IDS ids_04.xsd">
<specification name="Sample IDS" necessity="required">
<applicability>
<entity>
<name><simpleValue>IfcBuilding</simpleValue></name>
</entity>
</applicability>
<requirements>
<property location="any">
<propertyset><simpleValue>attribute</simpleValue></propertyset>
<name><simpleValue>name</simpleValue></name>
<value><simpleValue>My Building</simpleValue></value>
</property>
</requirements>
</specification>
<info/>
</ids>