Rename source dir

This commit is contained in:
Dion Moult
2024-08-13 23:09:50 +10:00
parent cc28f5a92b
commit 25071dfec6
930 changed files with 0 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
+309
View File
@@ -0,0 +1,309 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import sys
import json
import pytest
import blenderbim.core.tool
from typing import Any, Optional
from typing_extensions import Self
@pytest.fixture
def ifc():
prophet = Prophecy(blenderbim.core.tool.Ifc)
yield prophet
prophet.verify()
@pytest.fixture
def blender():
prophet = Prophecy(blenderbim.core.tool.Blender)
yield prophet
prophet.verify()
@pytest.fixture
def brick():
prophet = Prophecy(blenderbim.core.tool.Brick)
yield prophet
prophet.verify()
@pytest.fixture
def aggregate():
prophet = Prophecy(blenderbim.core.tool.Aggregate)
yield prophet
prophet.verify()
@pytest.fixture
def collector():
prophet = Prophecy(blenderbim.core.tool.Collector)
yield prophet
prophet.verify()
@pytest.fixture
def context():
prophet = Prophecy(blenderbim.core.tool.Context)
yield prophet
prophet.verify()
@pytest.fixture
def debug():
prophet = Prophecy(blenderbim.core.tool.Debug)
yield prophet
prophet.verify()
@pytest.fixture
def demo():
prophet = Prophecy(blenderbim.core.tool.Demo)
yield prophet
prophet.verify()
@pytest.fixture
def document():
prophet = Prophecy(blenderbim.core.tool.Document)
yield prophet
prophet.verify()
@pytest.fixture
def drawing():
prophet = Prophecy(blenderbim.core.tool.Drawing)
yield prophet
prophet.verify()
@pytest.fixture
def geometry():
prophet = Prophecy(blenderbim.core.tool.Geometry)
yield prophet
prophet.verify()
@pytest.fixture
def georeference():
prophet = Prophecy(blenderbim.core.tool.Georeference)
yield prophet
prophet.verify()
@pytest.fixture
def library():
prophet = Prophecy(blenderbim.core.tool.Library)
yield prophet
prophet.verify()
@pytest.fixture
def material():
prophet = Prophecy(blenderbim.core.tool.Material)
yield prophet
prophet.verify()
@pytest.fixture
def misc():
prophet = Prophecy(blenderbim.core.tool.Misc)
yield prophet
prophet.verify()
@pytest.fixture
def nest():
prophet = Prophecy(blenderbim.core.tool.Nest)
yield prophet
prophet.verify()
@pytest.fixture
def owner():
prophet = Prophecy(blenderbim.core.tool.Owner)
yield prophet
prophet.verify()
@pytest.fixture
def patch():
prophet = Prophecy(blenderbim.core.tool.Patch)
yield prophet
prophet.verify()
@pytest.fixture
def project():
prophet = Prophecy(blenderbim.core.tool.Project)
yield prophet
prophet.verify()
@pytest.fixture
def pset():
prophet = Prophecy(blenderbim.core.tool.Pset)
yield prophet
prophet.verify()
@pytest.fixture
def qto():
prophet = Prophecy(blenderbim.core.tool.Qto)
yield prophet
prophet.verify()
@pytest.fixture
def root():
prophet = Prophecy(blenderbim.core.tool.Root)
yield prophet
prophet.verify()
@pytest.fixture
def selector():
prophet = Prophecy(blenderbim.core.tool.Selector)
yield prophet
prophet.verify()
@pytest.fixture
def sequence():
prophet = Prophecy(blenderbim.core.tool.Sequence)
yield prophet
prophet.verify()
@pytest.fixture
def spatial():
prophet = Prophecy(blenderbim.core.tool.Spatial)
yield prophet
prophet.verify()
@pytest.fixture
def style():
prophet = Prophecy(blenderbim.core.tool.Style)
yield prophet
prophet.verify()
@pytest.fixture
def surveyor():
prophet = Prophecy(blenderbim.core.tool.Surveyor)
yield prophet
prophet.verify()
@pytest.fixture
def system():
prophet = Prophecy(blenderbim.core.tool.System)
yield prophet
prophet.verify()
@pytest.fixture
def type():
prophet = Prophecy(blenderbim.core.tool.Type)
yield prophet
prophet.verify()
@pytest.fixture
def unit():
prophet = Prophecy(blenderbim.core.tool.Unit)
yield prophet
prophet.verify()
@pytest.fixture
def voider():
prophet = Prophecy(blenderbim.core.tool.Voider)
yield prophet
prophet.verify()
class Prophecy:
def __init__(self, cls):
self.subject = cls
self.predictions: list[dict] = []
self.calls: list[dict] = []
self.return_values: dict[str, Any] = {}
self.should_call: Optional[dict] = None
def __getattr__(self, attr: str):
if not hasattr(self.subject, attr):
raise AttributeError(f"Prophecy {self.subject} has no attribute {attr}")
def decorate(*args, **kwargs):
call = {"name": attr, "args": args, "kwargs": kwargs}
# Ensure that signature is valid
getattr(self.subject, attr)(*args, **kwargs)
try:
key = json.dumps(call, sort_keys=True)
self.calls.append(call)
if key in self.return_values:
return self.return_values[key]
except:
pass
return self
return decorate
def should_be_called(self, number=None):
self.should_call = self.calls.pop()
self.predictions.append({"type": "SHOULD_BE_CALLED", "number": number, "call": self.should_call})
return self
def will_return(self, value: Any) -> Self:
key = json.dumps(self.should_call, sort_keys=True)
self.return_values[key] = value
return self
def verify(self) -> None:
predicted_calls = []
for prediction in self.predictions:
predicted_calls.append(prediction["call"])
if prediction["type"] == "SHOULD_BE_CALLED":
self.verify_should_be_called(prediction)
for call in self.calls:
if call not in predicted_calls:
raise Exception(f"Unpredicted call: {call}")
def verify_should_be_called(self, prediction: dict) -> None:
if prediction["number"]:
count = self.calls.count(prediction["call"])
if count != prediction["number"]:
raise Exception(f"Called {count}: {prediction}")
else:
if prediction["call"] not in self.calls:
error_msg = f"{self.subject} was not called with {prediction['call']['name']}:\n - {prediction}"
# Print all unprocessed calls if pytest was started in verbose mode.
if "-v" in sys.argv or "-vv" in sys.argv:
if not self.calls:
error_msg += "\nNo unprocessed calls."
else:
error_msg += "\nUnprocessed calls:"
for call in self.calls:
error_msg += f"\n - {call}"
raise Exception(error_msg)
+61
View File
@@ -0,0 +1,61 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.aggregate as subject
from test.core.bootstrap import ifc, aggregate, collector
class TestEnableEditingAggregate:
def test_run(self, aggregate):
aggregate.enable_editing("obj").should_be_called()
subject.enable_editing_aggregate(aggregate, obj="obj")
class TestDisableEditingAggregate:
def test_run(self, aggregate):
aggregate.disable_editing("obj").should_be_called()
subject.disable_editing_aggregate(aggregate, obj="obj")
class TestAssignObject:
def test_run(self, ifc, aggregate, collector):
aggregate.can_aggregate("relating_obj", "related_obj").should_be_called().will_return(True)
ifc.get_entity("relating_obj").should_be_called().will_return("relating_object")
aggregate.has_physical_body_representation("relating_object").should_be_called().will_return(False)
ifc.get_entity("related_obj").should_be_called().will_return("related_object")
ifc.run(
"aggregate.assign_object", products=["related_object"], relating_object="relating_object"
).should_be_called().will_return("rel")
aggregate.disable_editing("related_obj").should_be_called()
collector.assign("relating_obj").should_be_called()
collector.assign("related_obj").should_be_called()
assert (
subject.assign_object(ifc, aggregate, collector, relating_obj="relating_obj", related_obj="related_obj")
== "rel"
)
class TestUnassignObject:
def test_run(self, ifc, aggregate, collector):
ifc.get_entity("related_obj").should_be_called().will_return("element")
aggregate.get_container("element").should_be_called().will_return("container")
ifc.run("spatial.assign_container", products=["element"], relating_structure="container").should_be_called()
ifc.run("aggregate.unassign_object", products=["element"]).should_be_called()
collector.assign("relating_obj").should_be_called()
collector.assign("related_obj").should_be_called()
subject.unassign_object(ifc, aggregate, collector, relating_obj="relating_obj", related_obj="related_obj")
+31
View File
@@ -0,0 +1,31 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.attribute as subject
from test.core.bootstrap import ifc
class TestCopyAttributeToSelection:
def test_run(self, ifc):
ifc.get_entity("obj").should_be_called().will_return("element")
ifc.run("attribute.edit_attributes", product="element", attributes={"name": "value"}).should_be_called()
subject.copy_attribute_to_selection(ifc, name="name", value="value", obj="obj")
def test_do_nothing_if_object_is_not_an_element(self, ifc):
ifc.get_entity("obj").should_be_called().will_return(None)
subject.copy_attribute_to_selection(ifc, name="name", value="value", obj="obj")
+306
View File
@@ -0,0 +1,306 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.brick as subject
from test.core.bootstrap import ifc, brick
class TestLoadBrickProject:
def test_run(self, brick):
brick.load_brick_file("filepath").should_be_called()
brick.import_brick_classes("brick_root").should_be_called()
brick.import_brick_classes("brick_root", split_screen=True).should_be_called()
brick.set_active_brick_class("brick_root").should_be_called()
brick.set_active_brick_class("brick_root", split_screen=True).should_be_called()
subject.load_brick_project(brick, filepath="filepath", brick_root="brick_root")
class TestNewBrickFile:
def test_run(self, brick):
brick.new_brick_file().should_be_called()
brick.import_brick_classes("brick_root").should_be_called()
brick.import_brick_classes("brick_root", split_screen=True).should_be_called()
brick.set_active_brick_class("brick_root").should_be_called()
brick.set_active_brick_class("brick_root", split_screen=True).should_be_called()
subject.new_brick_file(brick, brick_root="brick_root")
class TestViewBrickClass:
def test_run(self, brick):
brick.add_brick_breadcrumb(split_screen=False).should_be_called()
brick.clear_brick_browser(split_screen=False).should_be_called()
brick.import_brick_classes("brick_class", split_screen=False).should_be_called()
brick.import_brick_items("brick_class", split_screen=False).should_be_called()
brick.set_active_brick_class("brick_class", split_screen=False).should_be_called()
subject.view_brick_class(brick, brick_class="brick_class", split_screen=False)
def test_split_screen(self, brick):
brick.add_brick_breadcrumb(split_screen=True).should_be_called()
brick.clear_brick_browser(split_screen=True).should_be_called()
brick.import_brick_classes("brick_class", split_screen=True).should_be_called()
brick.import_brick_items("brick_class", split_screen=True).should_be_called()
brick.set_active_brick_class("brick_class", split_screen=True).should_be_called()
subject.view_brick_class(brick, brick_class="brick_class", split_screen=True)
class TestViewBrickItem:
def test_run(self, brick):
brick.get_item_class("item").should_be_called().will_return("brick_class")
brick.run_view_brick_class(brick_class="brick_class", split_screen=False).should_be_called()
brick.select_browser_item("item", split_screen=False).should_be_called()
subject.view_brick_item(brick, item="item", split_screen=False)
def test_split_screen(self, brick):
brick.get_item_class("item").should_be_called().will_return("brick_class")
brick.run_view_brick_class(brick_class="brick_class", split_screen=True).should_be_called()
brick.select_browser_item("item", split_screen=True).should_be_called()
subject.view_brick_item(brick, item="item", split_screen=True)
class TestRewindBrickClass:
def test_run(self, brick):
brick.pop_brick_breadcrumb(split_screen=False).should_be_called().will_return("previous_class")
brick.clear_brick_browser(split_screen=False).should_be_called()
brick.import_brick_classes("previous_class", split_screen=False).should_be_called()
brick.import_brick_items("previous_class", split_screen=False).should_be_called()
brick.set_active_brick_class("previous_class", split_screen=False).should_be_called()
subject.rewind_brick_class(brick, split_screen=False)
def test_split_screen(self, brick):
brick.pop_brick_breadcrumb(split_screen=True).should_be_called().will_return("previous_class")
brick.clear_brick_browser(split_screen=True).should_be_called()
brick.import_brick_classes("previous_class", split_screen=True).should_be_called()
brick.import_brick_items("previous_class", split_screen=True).should_be_called()
brick.set_active_brick_class("previous_class", split_screen=True).should_be_called()
subject.rewind_brick_class(brick, split_screen=True)
class TestCloseBrickProject:
def test_run(self, brick):
brick.clear_project().should_be_called()
brick.clear_brick_browser().should_be_called()
brick.clear_brick_browser(split_screen=True).should_be_called()
brick.clear_breadcrumbs().should_be_called()
brick.clear_breadcrumbs(split_screen=True).should_be_called()
subject.close_brick_project(brick)
class TestConvertBrickProject:
def test_run(self, ifc, brick):
brick.get_brick_path_name().should_be_called().will_return("foo.ttl")
ifc.run("library.add_library", name="foo.ttl").should_be_called().will_return("library")
ifc.get_schema().should_be_called().will_return("IFC4")
brick.get_brick_path().should_be_called().will_return("/path/to/foo.ttl")
ifc.run(
"library.edit_library", library="library", attributes={"Location": "/path/to/foo.ttl"}
).should_be_called()
subject.convert_brick_project(ifc, brick)
def test_not_editing_in_ifc2x3(self, ifc, brick):
brick.get_brick_path_name().should_be_called().will_return("foo.ttl")
ifc.run("library.add_library", name="foo.ttl").should_be_called().will_return("library")
ifc.get_schema().should_be_called().will_return("IFC2X3")
subject.convert_brick_project(ifc, brick)
class TestAssignBrickReference:
def test_assigning_to_a_new_reference(self, ifc, brick):
brick.get_library_brick_reference("library", "brick_uri").should_be_called().will_return(None)
ifc.run("library.add_reference", library="library").should_be_called().will_return("reference")
brick.export_brick_attributes("brick_uri").should_be_called().will_return("attributes")
ifc.run("library.edit_reference", reference="reference", attributes="attributes").should_be_called()
ifc.run("library.assign_reference", products=["element"], reference="reference").should_be_called()
brick.get_brickifc_project().should_be_called().will_return("project")
brick.add_brickifc_reference("brick_uri", "element", "project").should_be_called()
subject.assign_brick_reference(ifc, brick, element="element", library="library", brick_uri="brick_uri")
def test_assigning_to_an_existing_reference(self, ifc, brick):
brick.get_library_brick_reference("library", "brick_uri").should_be_called().will_return("reference")
ifc.run("library.assign_reference", products=["element"], reference="reference").should_be_called()
brick.get_brickifc_project().should_be_called().will_return("project")
brick.add_brickifc_reference("brick_uri", "element", "project").should_be_called()
subject.assign_brick_reference(ifc, brick, element="element", library="library", brick_uri="brick_uri")
def test_adding_a_brickifc_project_if_it_doesnt_exist(self, ifc, brick):
brick.get_library_brick_reference("library", "brick_uri").should_be_called().will_return("reference")
ifc.run("library.assign_reference", products=["element"], reference="reference").should_be_called()
brick.get_brickifc_project().should_be_called().will_return(None)
brick.get_namespace("brick_uri").should_be_called().will_return("namespace")
brick.add_brickifc_project("namespace").should_be_called().will_return("project")
brick.add_brickifc_reference("brick_uri", "element", "project").should_be_called()
subject.assign_brick_reference(ifc, brick, element="element", library="library", brick_uri="brick_uri")
class TestAddBrick:
def test_adding_a_brick_from_an_element(self, ifc, brick):
brick.add_brick_from_element("element", "namespace", "brick_class").should_be_called().will_return("brick_uri")
brick.run_refresh_brick_viewer().should_be_called()
subject.add_brick(
ifc, brick, element="element", namespace="namespace", brick_class="brick_class", library=None, label="label"
)
def test_adding_a_brick_and_auto_assigning_it_to_the_ifc_element(self, ifc, brick):
brick.add_brick_from_element("element", "namespace", "brick_class").should_be_called().will_return("brick_uri")
brick.run_assign_brick_reference(element="element", library="library", brick_uri="brick_uri").should_be_called()
brick.run_refresh_brick_viewer().should_be_called()
subject.add_brick(
ifc,
brick,
element="element",
namespace="namespace",
brick_class="brick_class",
library="library",
label="label",
)
def test_adding_a_plain_brick(self, ifc, brick):
brick.add_brick("namespace", "brick_class", "label").should_be_called()
brick.run_refresh_brick_viewer().should_be_called()
subject.add_brick(
ifc, brick, element=None, namespace="namespace", brick_class="brick_class", library=None, label="label"
)
class TestAddBrickRelation:
def test_run(self, ifc, brick):
brick.add_relation("brick_uri", "predicate", "object").should_be_called()
brick.run_refresh_brick_viewer().should_be_called()
subject.add_brick_relation(brick, brick_uri="brick_uri", predicate="predicate", object="object")
class TestConvertIfcToBrick:
def test_run(self, brick):
brick.get_convertable_brick_spaces().should_be_called().will_return({"space", "parent"})
brick.get_brick_class("space").should_be_called().will_return("space_class")
brick.add_brick_from_element("space", "namespace", "space_class").should_be_called().will_return("space_uri")
brick.run_assign_brick_reference(element="space", library="library", brick_uri="space_uri").should_be_called()
brick.get_brick_class("parent").should_be_called().will_return("parent_class")
brick.add_brick_from_element("parent", "namespace", "parent_class").should_be_called().will_return("parent_uri")
brick.run_assign_brick_reference(element="parent", library="library", brick_uri="parent_uri").should_be_called()
brick.get_parent_space("space").should_be_called().will_return("parent")
brick.get_parent_space("parent").should_be_called().will_return(None)
brick.add_relation("parent_uri", "https://brickschema.org/schema/Brick#hasPart", "space_uri").should_be_called()
brick.get_convertable_brick_systems().should_be_called().will_return({"system"})
brick.get_brick_class("system").should_be_called().will_return("system_class")
brick.add_brick_from_element("system", "namespace", "system_class").should_be_called().will_return("system_uri")
brick.run_assign_brick_reference(element="system", library="library", brick_uri="system_uri").should_be_called()
brick.get_convertable_brick_elements().should_be_called().will_return({"element", "downstream_element"})
brick.get_brick_class("element").should_be_called().will_return("element_class")
brick.add_brick_from_element("element", "namespace", "element_class").should_be_called().will_return(
"element_uri"
)
brick.get_element_container("element").should_be_called().will_return("space")
brick.add_relation(
"element_uri", "https://brickschema.org/schema/Brick#hasLocation", "space_uri"
).should_be_called()
brick.get_element_systems("element").should_be_called().will_return(["system"])
brick.add_relation(
"system_uri", "https://brickschema.org/schema/Brick#hasPart", "element_uri"
).should_be_called()
brick.run_assign_brick_reference(
element="element", library="library", brick_uri="element_uri"
).should_be_called()
brick.get_brick_class("downstream_element").should_be_called().will_return("downstream_element_class")
brick.add_brick_from_element(
"downstream_element", "namespace", "downstream_element_class"
).should_be_called().will_return("downstream_element_uri")
brick.get_element_container("downstream_element").should_be_called().will_return("space")
brick.add_relation(
"downstream_element_uri", "https://brickschema.org/schema/Brick#hasLocation", "space_uri"
).should_be_called()
brick.get_element_systems("downstream_element").should_be_called().will_return(["system"])
brick.add_relation(
"system_uri", "https://brickschema.org/schema/Brick#hasPart", "downstream_element_uri"
).should_be_called()
brick.run_assign_brick_reference(
element="downstream_element", library="library", brick_uri="downstream_element_uri"
).should_be_called()
brick.get_element_feeds("element").should_be_called().will_return(["downstream_element"])
brick.get_element_feeds("downstream_element").should_be_called().will_return([])
brick.add_relation(
"element_uri", "https://brickschema.org/schema/Brick#feeds", "downstream_element_uri"
).should_be_called()
brick.run_refresh_brick_viewer().should_be_called()
subject.convert_ifc_to_brick(brick, namespace="namespace", library="library")
class TestRefreshBrickViewer:
def test_run(self, brick):
brick.get_active_brick_class().should_be_called().will_return("brick_class")
brick.run_view_brick_class(brick_class="brick_class").should_be_called()
brick.pop_brick_breadcrumb().should_be_called()
brick.get_active_brick_class(split_screen=True).should_be_called().will_return("brick_class")
brick.run_view_brick_class(brick_class="brick_class", split_screen=True).should_be_called()
brick.pop_brick_breadcrumb(split_screen=True).should_be_called()
subject.refresh_brick_viewer(brick)
class TestRemoveBrick:
def test_run(self, ifc, brick):
brick.get_library_brick_reference("library", "brick_uri").should_be_called().will_return("reference")
ifc.run("library.remove_reference", reference="reference").should_be_called()
brick.remove_brick("brick_uri").should_be_called()
brick.run_refresh_brick_viewer().should_be_called()
subject.remove_brick(ifc, brick, library="library", brick_uri="brick_uri")
def test_do_not_remove_reference_if_no_reference_exists(self, ifc, brick):
brick.get_library_brick_reference("library", "brick_uri").should_be_called().will_return(None)
brick.remove_brick("brick_uri").should_be_called()
brick.run_refresh_brick_viewer().should_be_called()
subject.remove_brick(ifc, brick, library="library", brick_uri="brick_uri")
def test_do_not_check_references_if_no_library_specified(self, ifc, brick):
brick.remove_brick("brick_uri").should_be_called()
brick.run_refresh_brick_viewer().should_be_called()
subject.remove_brick(ifc, brick, library=None, brick_uri="brick_uri")
class TestSerializeBrick:
def test_run(self, brick):
brick.serialize_brick().should_be_called()
subject.serialize_brick(brick)
class TestAddBrickNamespace:
def test_run(self, brick):
brick.add_namespace("alias", "uri").should_be_called()
subject.add_brick_namespace(brick, alias="alias", uri="uri")
class TestSetBrickListRoot:
def test_run(self, brick):
brick.run_view_brick_class(brick_class="brick_root", split_screen=False).should_be_called()
brick.clear_breadcrumbs(split_screen=False).should_be_called()
subject.set_brick_list_root(brick, brick_root="brick_root", split_screen=False)
def test_split_screen(self, brick):
brick.run_view_brick_class(brick_class="brick_root", split_screen=True).should_be_called()
brick.clear_breadcrumbs(split_screen=True).should_be_called()
subject.set_brick_list_root(brick, brick_root="brick_root", split_screen=True)
class TestRemoveBrickRelation:
def test_run(self, brick):
brick.remove_relation("brick_uri", "predicate", "object").should_be_called()
subject.remove_brick_relation(brick, brick_uri="brick_uri", predicate="predicate", object="object")
+74
View File
@@ -0,0 +1,74 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.context as subject
from test.core.bootstrap import ifc, context
class TestAddContext:
def test_adding_a_context(self, ifc):
ifc.run(
"context.add_context", context_type="Model", context_identifier=None, target_view=None, parent=None
).should_be_called().will_return("context")
assert (
subject.add_context(ifc, context_type="Model", context_identifier=None, target_view=None, parent=None)
== "context"
)
def test_adding_a_subcontext(self, ifc):
ifc.run(
"context.add_context",
context_type="Model",
context_identifier="Body",
target_view="MODEL_VIEW",
parent="parent",
).should_be_called().will_return("subcontext")
assert (
subject.add_context(
ifc, context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent="parent"
)
== "subcontext"
)
class TestRemoveContext:
def test_removing_a_context(self, ifc):
ifc.run("context.remove_context", context="context").should_be_called()
subject.remove_context(ifc, context="context")
class TestEnableEditingContext:
def test_run(self, context):
context.set_context("context").should_be_called()
context.import_attributes().should_be_called()
subject.enable_editing_context(context, context="context")
class TestDisableEditingContext:
def test_run(self, context):
context.clear_context().should_be_called()
subject.disable_editing_context(context)
class TestEditContext:
def test_run(self, ifc, context):
context.get_context().should_be_called().will_return("context")
context.export_attributes().should_be_called().will_return("attributes")
ifc.run("context.edit_context", context="context", attributes="attributes").should_be_called()
context.clear_context().should_be_called()
subject.edit_context(ifc, context)
+33
View File
@@ -0,0 +1,33 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.debug as subject
from test.core.bootstrap import debug
class TestParseExpress:
def test_run(self, debug):
debug.load_express("filename").should_be_called().will_return("schema")
debug.add_schema_identifier("schema").should_be_called()
subject.parse_express(debug, "filename")
class TestPurgeHdf5Cache:
def test_run(self, debug):
debug.purge_hdf5_cache().should_be_called()
subject.purge_hdf5_cache(debug)
+91
View File
@@ -0,0 +1,91 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
# ############################################################################ #
# Hey there! Welcome to the Bonsai code. Please feel free to reach
# out if you have any questions or need further guidance. Happy hacking!
# ############################################################################ #
# Note: these tests are commented out as they are for learning purposes only. If
# you want to run these tests, uncomment it :)
"""
# Testing the core might seem strange if you haven't written this type of
# abstract test before. You essentially want to test that things are called in
# the right sequence. This seems almost like writing the code twice, like in
# double entry bookkeeping in accounting. However, it guards against typos,
# helps document intention of different logical flows, and ensures that all
# permutations of logic flows meet sanity checks.
# We always call the module we're testing the "test subject". This makes our
# tests simple to read: just look for where the "subject" is called!
import blenderbim.core.demo as subject
# These are like mocks, stubs, or spy objects. They don't do anything, but they
# let us check our test expectations.
from test.core.bootstrap import ifc, demo
# Let's test the hello world function.
class TestDemonstrateHelloWorld:
# This function has only one logical flow, there is no benefit to describing
# it further, so we have a test_run function. We need to specify all the
# mock objects we need in the signature.
def test_run(self, demo):
# We set an expectation that in this default sequence of events, the
# demo tool should have the set_message called with the "Hello, World!"
# string as its argument. Notice how our test also reads like English.
demo.set_message("Hello, World!").should_be_called()
# After we've finished specifying our test expectations, let's run the
# test subject!
subject.demonstrate_hello_world(demo)
# Another test, but this time with two logical flows.
class TestDemonstrateRenameProject:
# The default logical flow is where we rename the project successfully.
def test_renaming_the_project(self, ifc, demo):
# This time, we describe an expectation that the demo tool should have
# its get_project() function called with no attributes. When it is
# called, we expect it to return "project" as a string.
# This might sound strange. How is get_project implemented? Does it
# actually return a string? We don't know, and we don't care. That's a
# detail that our core isn't interested in. All our core is interested
# in is that we get back a project - we're arbitrarily using a string to
# represent it.
demo.get_project().should_be_called().will_return("project")
# Here, again, we're not interested in the details. However, we are
# interested in checking that the project we previously retrieved is
# passed verbatim into the Ifc tool.
ifc.run("attribute.edit_attributes", product="project", attributes={"Name": "name"}).should_be_called()
demo.clear_name_field().should_be_called()
demo.hide_user_hints().should_be_called()
# Let's test our test subject! Notice that just like the arbitrary
# string "project", we've specified an arbitrary input string of "name".
subject.demonstrate_rename_project(ifc, demo, name="name")
# One alternative flow is when no name is provided. What happens then?
def test_showing_a_hint_if_no_name_provided(self, ifc, demo):
demo.show_user_hints().should_be_called()
subject.demonstrate_rename_project(ifc, demo, name=None)
"""
+143
View File
@@ -0,0 +1,143 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.document as subject
from test.core.bootstrap import ifc, document
class TestLoadProjectDocuments:
def test_run(self, document):
document.clear_document_tree().should_be_called()
document.import_project_documents().should_be_called()
document.clear_breadcrumbs().should_be_called()
document.enable_editing_ui().should_be_called()
subject.load_project_documents(document)
class TestLoadDocument:
def test_run(self, document):
document.clear_document_tree().should_be_called()
document.import_subdocuments("document").should_be_called()
document.import_references("document").should_be_called()
document.disable_editing_document().should_be_called()
document.add_breadcrumb("document").should_be_called()
subject.load_document(document, document="document")
class TestDisableDocumentEditingUi:
def test_run(self, document):
document.disable_editing_ui().should_be_called()
document.disable_editing_document().should_be_called()
subject.disable_document_editing_ui(document)
class TestEnableEditingDocument:
def test_run(self, document):
document.import_document_attributes("document").should_be_called()
document.set_active_document("document").should_be_called()
subject.enable_editing_document(document, document="document")
class TestDisableEditingDocument:
def test_run(self, document):
document.disable_editing_document().should_be_called()
subject.disable_editing_document(document)
class TestAddInformation:
def test_add_and_reload_tree_at_project_root(self, ifc, document):
document.clear_document_tree().should_be_called()
document.get_active_breadcrumb().should_be_called().will_return(None)
ifc.run("document.add_information", parent=None).should_be_called().will_return("information")
ifc.run("document.add_reference", information="information").should_be_called()
document.import_project_documents().should_be_called()
subject.add_information(ifc, document)
def test_add_and_reload_tree_at_current_parent(self, ifc, document):
document.clear_document_tree().should_be_called()
document.get_active_breadcrumb().should_be_called().will_return("parent")
ifc.run("document.add_information", parent="parent").should_be_called().will_return("information")
ifc.run("document.add_reference", information="information").should_be_called()
document.import_subdocuments("parent").should_be_called()
document.import_references("parent").should_be_called()
subject.add_information(ifc, document)
class TestAddReference:
def test_run(self, ifc, document):
document.get_active_breadcrumb().should_be_called().will_return("parent")
ifc.run("document.add_reference", information="parent").should_be_called()
document.clear_document_tree().should_be_called()
document.import_subdocuments("parent").should_be_called()
document.import_references("parent").should_be_called()
subject.add_reference(ifc, document)
class TestEditDocument:
def test_edit_information(self, ifc, document):
document.export_document_attributes().should_be_called().will_return("attributes")
document.is_document_information("document").should_be_called().will_return(True)
ifc.run("document.edit_information", information="document", attributes="attributes").should_be_called()
document.disable_editing_document().should_be_called()
document.clear_document_tree().should_be_called()
document.get_active_breadcrumb().should_be_called().will_return(None)
document.import_project_documents().should_be_called()
subject.edit_document(ifc, document, document="document")
def test_edit_reference(self, ifc, document):
document.export_document_attributes().should_be_called().will_return("attributes")
document.is_document_information("document").should_be_called().will_return(False)
ifc.run("document.edit_reference", reference="document", attributes="attributes").should_be_called()
document.disable_editing_document().should_be_called()
document.clear_document_tree().should_be_called()
document.get_active_breadcrumb().should_be_called().will_return("parent")
document.import_subdocuments("parent").should_be_called()
document.import_references("parent").should_be_called()
subject.edit_document(ifc, document, document="document")
class TestRemoveDocument:
def test_remove_information(self, ifc, document):
document.clear_document_tree().should_be_called()
document.is_document_information("document").should_be_called().will_return(True)
ifc.run("document.remove_information", information="document").should_be_called()
document.get_active_breadcrumb().should_be_called().will_return(None)
document.import_project_documents().should_be_called()
subject.remove_document(ifc, document, document="document")
def test_remove_reference(self, ifc, document):
document.clear_document_tree().should_be_called()
document.is_document_information("document").should_be_called().will_return(False)
ifc.run("document.remove_reference", reference="document").should_be_called()
document.get_active_breadcrumb().should_be_called().will_return("parent")
document.import_subdocuments("parent").should_be_called()
document.import_references("parent").should_be_called()
subject.remove_document(ifc, document, document="document")
class TestAssignDocument:
def test_run(self, ifc):
ifc.run("document.assign_document", products=["product"], document="document").should_be_called()
subject.assign_document(ifc, product="product", document="document")
class TestUnassignDocument:
def test_run(self, ifc):
ifc.run("document.unassign_document", products=["product"], document="document").should_be_called()
subject.unassign_document(ifc, product="product", document="document")
+557
View File
@@ -0,0 +1,557 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.drawing as subject
from test.core.bootstrap import ifc, drawing, collector
class TestEnableEditingText:
def test_run(self, drawing):
drawing.enable_editing_text("obj").should_be_called()
drawing.import_text_attributes("obj").should_be_called()
subject.enable_editing_text(drawing, obj="obj")
class TestDisableEditingText:
def test_run(self, drawing):
drawing.disable_editing_text("obj").should_be_called()
subject.disable_editing_text(drawing, obj="obj")
class TestEditText:
def test_run(self, ifc, drawing):
drawing.synchronise_ifc_and_text_attributes("obj").should_be_called()
drawing.update_text_size_pset("obj").should_be_called()
drawing.update_text_value("obj").should_be_called()
drawing.disable_editing_text("obj").should_be_called()
subject.edit_text(drawing, obj="obj")
class TestEnableEditingAssignedProduct:
def test_run(self, drawing):
drawing.enable_editing_assigned_product("obj").should_be_called()
drawing.import_assigned_product("obj").should_be_called()
subject.enable_editing_assigned_product(drawing, obj="obj")
class TestDisableEditingAssignedProduct:
def test_run(self, drawing):
drawing.disable_editing_assigned_product("obj").should_be_called()
subject.disable_editing_assigned_product(drawing, obj="obj")
class TestEditAssignedProduct:
def test_run(self, ifc, drawing):
ifc.get_entity("obj").should_be_called().will_return("element")
drawing.get_assigned_product("element").should_be_called().will_return("existing_product")
ifc.run(
"drawing.unassign_product", relating_product="existing_product", related_object="element"
).should_be_called()
ifc.run("drawing.assign_product", relating_product="product", related_object="element").should_be_called()
drawing.update_text_value("obj").should_be_called()
drawing.disable_editing_assigned_product("obj").should_be_called()
subject.edit_assigned_product(ifc, drawing, obj="obj", product="product")
class TestLoadSheets:
def test_run(self, drawing):
drawing.import_sheets().should_be_called()
drawing.enable_editing_sheets().should_be_called()
subject.load_sheets(drawing)
class TestDisableEditingSheets:
def test_run(self, drawing):
drawing.disable_editing_sheets().should_be_called()
subject.disable_editing_sheets(drawing)
class TestAddSheet:
def test_run(self, ifc, drawing):
ifc.run("document.add_information").should_be_called().will_return("sheet")
ifc.run("document.add_reference", information="sheet").should_be_called().will_return("reference")
drawing.generate_sheet_identification().should_be_called().will_return("identification")
drawing.ensure_unique_identification("identification").should_be_called().will_return("u_identification")
ifc.get_schema().should_be_called().will_return("IFC4")
drawing.get_default_layout_path("u_identification", "UNTITLED").should_be_called().will_return("layout_path")
drawing.get_default_titleblock_path("titleblock").should_be_called().will_return("titleblock_path")
ifc.run(
"document.edit_information",
information="sheet",
attributes={"Identification": "u_identification", "Name": "UNTITLED", "Scope": "SHEET"},
).should_be_called()
drawing.generate_reference_attributes(
"reference", Location="layout_path", Description="LAYOUT"
).should_be_called().will_return("attributes")
ifc.run(
"document.edit_reference",
reference="reference",
attributes="attributes",
).should_be_called()
drawing.generate_reference_attributes(
"reference", Location="titleblock_path", Description="TITLEBLOCK"
).should_be_called().will_return("attributes2")
ifc.run(
"document.edit_reference",
reference="reference",
attributes="attributes2",
).should_be_called()
drawing.create_svg_sheet("sheet", "titleblock").should_be_called()
drawing.import_sheets().should_be_called()
subject.add_sheet(ifc, drawing, titleblock="titleblock")
def test_using_a_document_id_in_ifc2x3(self, ifc, drawing):
ifc.run("document.add_information").should_be_called().will_return("sheet")
ifc.run("document.add_reference", information="sheet").should_be_called().will_return("reference")
drawing.generate_sheet_identification().should_be_called().will_return("identification")
drawing.ensure_unique_identification("identification").should_be_called().will_return("u_identification")
ifc.get_schema().should_be_called().will_return("IFC2X3")
drawing.get_default_layout_path("u_identification", "UNTITLED").should_be_called().will_return("layout_path")
drawing.get_default_titleblock_path("titleblock").should_be_called().will_return("titleblock_path")
ifc.run(
"document.edit_information",
information="sheet",
attributes={"DocumentId": "u_identification", "Name": "UNTITLED", "Scope": "SHEET"},
).should_be_called()
drawing.generate_reference_attributes(
"reference", Location="layout_path", Description="LAYOUT"
).should_be_called().will_return("attributes")
ifc.run(
"document.edit_reference",
reference="reference",
attributes="attributes",
).should_be_called()
drawing.generate_reference_attributes(
"reference", Location="titleblock_path", Description="TITLEBLOCK"
).should_be_called().will_return("attributes2")
ifc.run(
"document.edit_reference",
reference="reference",
attributes="attributes2",
).should_be_called()
drawing.create_svg_sheet("sheet", "titleblock").should_be_called()
drawing.import_sheets().should_be_called()
subject.add_sheet(ifc, drawing, titleblock="titleblock")
class TestOpenSheet:
def test_run(self, drawing):
drawing.get_document_uri("sheet", "LAYOUT").should_be_called().will_return("uri")
drawing.open_layout_svg("uri").should_be_called()
subject.open_sheet(drawing, sheet="sheet")
class TestRemoveSheet:
def test_run(self, ifc, drawing):
drawing.get_document_references("sheet").should_be_called().will_return(["reference"])
drawing.get_reference_description("reference").should_be_called().will_return("LAYOUT")
drawing.get_document_uri("reference").should_be_called().will_return("relative_uri")
ifc.resolve_uri("relative_uri").should_be_called().will_return("absolute_uri")
drawing.does_file_exist("absolute_uri").should_be_called().will_return(True)
drawing.delete_file("absolute_uri").should_be_called()
ifc.run("document.remove_information", information="sheet").should_be_called()
drawing.import_sheets().should_be_called()
subject.remove_sheet(ifc, drawing, sheet="sheet")
class TestLoadSchedules:
def test_run(self, drawing):
drawing.import_documents("SCHEDULE").should_be_called()
drawing.enable_editing_schedules().should_be_called()
subject.load_schedules(drawing)
class TestDisableEditingSchedules:
def test_run(self, drawing):
drawing.disable_editing_schedules().should_be_called()
subject.disable_editing_schedules(drawing)
class TestAddSchedule:
def test_run(self, ifc, drawing):
ifc.run("document.add_information").should_be_called().will_return("schedule")
drawing.get_path_filename("uri").should_be_called().will_return("UNTITLED")
ifc.run("document.add_reference", information="schedule").should_be_called().will_return("reference")
ifc.get_schema().should_be_called().will_return("IFC4")
ifc.run(
"document.edit_information",
information="schedule",
attributes={"Identification": "X", "Name": "UNTITLED", "Scope": "SCHEDULE"},
).should_be_called()
ifc.run("document.edit_reference", reference="reference", attributes={"Location": "uri"}).should_be_called()
drawing.import_documents("SCHEDULE").should_be_called()
subject.add_document(ifc, drawing, "SCHEDULE", uri="uri")
def test_using_a_document_id_in_ifc2x3(self, ifc, drawing):
ifc.run("document.add_information").should_be_called().will_return("schedule")
drawing.get_path_filename("uri").should_be_called().will_return("UNTITLED")
ifc.run("document.add_reference", information="schedule").should_be_called().will_return("reference")
ifc.get_schema().should_be_called().will_return("IFC2X3")
ifc.run(
"document.edit_information",
information="schedule",
attributes={"DocumentId": "X", "Name": "UNTITLED", "Scope": "SCHEDULE"},
).should_be_called()
ifc.run("document.edit_reference", reference="reference", attributes={"Location": "uri"}).should_be_called()
drawing.import_documents("SCHEDULE").should_be_called()
subject.add_document(ifc, drawing, "SCHEDULE", uri="uri")
class TestRemoveSchedule:
def test_run(self, ifc, drawing):
ifc.run("document.remove_information", information="schedule").should_be_called()
drawing.import_documents("SCHEDULE").should_be_called()
subject.remove_document(ifc, drawing, "SCHEDULE", document="schedule")
class TestOpenSchedule:
def test_run(self, drawing):
drawing.get_document_uri("schedule").should_be_called().will_return("uri")
drawing.open_spreadsheet("uri").should_be_called()
subject.open_schedule(drawing, schedule="schedule")
class TestUpdateScheduleName:
def test_do_not_update_if_name_unchanged(self, ifc, drawing):
drawing.get_name("schedule").should_be_called().will_return("name")
subject.update_document_name(ifc, drawing, document="schedule", name="name")
def test_run(self, ifc, drawing):
drawing.get_name("schedule").should_be_called().will_return("oldname")
ifc.run("document.edit_information", information="schedule", attributes={"Name": "name"}).should_be_called()
subject.update_document_name(ifc, drawing, document="schedule", name="name")
class TestLoadReferences:
def test_run(self, drawing):
drawing.import_documents("REFERENCE").should_be_called()
drawing.enable_editing_references().should_be_called()
subject.load_references(drawing)
class TestDisableEditingReferences:
def test_run(self, drawing):
drawing.disable_editing_references().should_be_called()
subject.disable_editing_references(drawing)
class TestAddReference:
def test_run(self, ifc, drawing):
ifc.run("document.add_information").should_be_called().will_return("reference")
drawing.get_path_filename("uri").should_be_called().will_return("UNTITLED")
ifc.run("document.add_reference", information="reference").should_be_called().will_return("reference")
ifc.get_schema().should_be_called().will_return("IFC4")
ifc.run(
"document.edit_information",
information="reference",
attributes={"Identification": "X", "Name": "UNTITLED", "Scope": "REFERENCE"},
).should_be_called()
ifc.run("document.edit_reference", reference="reference", attributes={"Location": "uri"}).should_be_called()
drawing.import_documents("REFERENCE").should_be_called()
subject.add_document(ifc, drawing, "REFERENCE", uri="uri")
def test_using_a_document_id_in_ifc2x3(self, ifc, drawing):
ifc.run("document.add_information").should_be_called().will_return("reference")
drawing.get_path_filename("uri").should_be_called().will_return("UNTITLED")
ifc.run("document.add_reference", information="reference").should_be_called().will_return("reference")
ifc.get_schema().should_be_called().will_return("IFC2X3")
ifc.run(
"document.edit_information",
information="reference",
attributes={"DocumentId": "X", "Name": "UNTITLED", "Scope": "REFERENCE"},
).should_be_called()
ifc.run("document.edit_reference", reference="reference", attributes={"Location": "uri"}).should_be_called()
drawing.import_documents("REFERENCE").should_be_called()
subject.add_document(ifc, drawing, "REFERENCE", uri="uri")
class TestRemoveReference:
def test_run(self, ifc, drawing):
ifc.run("document.remove_information", information="reference").should_be_called()
drawing.import_documents("REFERENCE").should_be_called()
subject.remove_document(ifc, drawing, "REFERENCE", document="reference")
class TestOpenReference:
def test_run(self, drawing):
drawing.get_document_uri("reference").should_be_called().will_return("uri")
drawing.open_svg("uri").should_be_called()
subject.open_reference(drawing, reference="reference")
class TestUpdateReferenceName:
def test_do_not_update_if_name_unchanged(self, ifc, drawing):
drawing.get_name("reference").should_be_called().will_return("name")
subject.update_document_name(ifc, drawing, document="reference", name="name")
def test_run(self, ifc, drawing):
drawing.get_name("reference").should_be_called().will_return("oldname")
ifc.run("document.edit_information", information="reference", attributes={"Name": "name"}).should_be_called()
subject.update_document_name(ifc, drawing, document="reference", name="name")
class TestLoadDrawings:
def test_run(self, drawing):
drawing.import_drawings().should_be_called()
drawing.enable_editing_drawings().should_be_called()
subject.load_drawings(drawing)
class TestDisableEditingDrawings:
def test_run(self, drawing):
drawing.disable_editing_drawings().should_be_called()
subject.disable_editing_drawings(drawing)
class TestAddDrawing:
def test_run(self, ifc, collector, drawing):
drawing.generate_drawing_name("target_view", "location_hint").should_be_called().will_return("drawing_name")
drawing.ensure_unique_drawing_name("drawing_name").should_be_called().will_return("name")
drawing.generate_drawing_matrix("target_view", "location_hint").should_be_called().will_return("matrix")
drawing.create_camera("name", "matrix", "location_hint").should_be_called().will_return("obj")
drawing.get_body_context().should_be_called().will_return("context")
drawing.run_root_assign_class(
obj="obj",
ifc_class="IfcAnnotation",
predefined_type="DRAWING",
should_add_representation=True,
context="context",
ifc_representation_class=None,
).should_be_called().will_return("element")
ifc.run("group.add_group").should_be_called().will_return("group")
ifc.run(
"group.edit_group", group="group", attributes={"Name": "name", "ObjectType": "DRAWING"}
).should_be_called()
ifc.run("group.assign_group", group="group", products=["element"]).should_be_called()
collector.assign("obj").should_be_called()
ifc.run("pset.add_pset", product="element", name="EPset_Drawing").should_be_called().will_return("pset")
drawing.get_default_drawing_resource_path("Stylesheet").should_be_called().will_return("stylesheet.css")
drawing.get_default_drawing_resource_path("Markers").should_be_called().will_return("markers.svg")
drawing.get_default_drawing_resource_path("Symbols").should_be_called().will_return("symbols.svg")
drawing.get_default_drawing_resource_path("Patterns").should_be_called().will_return("patterns.svg")
drawing.get_default_drawing_resource_path("ShadingStyles").should_be_called().will_return("shading_styles.json")
drawing.get_default_shading_style().should_be_called().will_return("Blender Default")
drawing.setup_shading_styles_path("shading_styles.json").should_be_called()
drawing.get_unit_system().should_be_called().will_return("METRIC")
ifc.run(
"pset.edit_pset",
pset="pset",
properties={
"TargetView": "target_view",
"Scale": "1/100",
"HumanScale": "1:100",
"HasUnderlay": False,
"HasLinework": True,
"HasAnnotation": True,
"GlobalReferencing": True,
"Stylesheet": "stylesheet.css",
"Markers": "markers.svg",
"Symbols": "symbols.svg",
"Patterns": "patterns.svg",
"ShadingStyles": "shading_styles.json",
"CurrentShadingStyle": "Blender Default",
},
).should_be_called()
drawing.get_default_drawing_path("name").should_be_called().will_return("uri")
ifc.run("document.add_information").should_be_called().will_return("information")
ifc.run("document.add_reference", information="information").should_be_called().will_return("reference")
ifc.get_schema().should_be_called().will_return("IFC4")
ifc.run(
"document.edit_information",
information="information",
attributes={"Identification": "X", "Name": "name", "Scope": "DRAWING"},
).should_be_called()
ifc.run("document.edit_reference", reference="reference", attributes={"Location": "uri"}).should_be_called()
ifc.run("document.assign_document", products=["element"], document="reference").should_be_called()
drawing.import_drawings().should_be_called()
subject.add_drawing(ifc, collector, drawing, target_view="target_view", location_hint="location_hint")
class TestDuplicateDrawing:
def test_run(self, ifc, drawing):
drawing.get_name("drawing").should_be_called().will_return("name")
drawing.ensure_unique_drawing_name("name").should_be_called().will_return("unique_name")
ifc.run("root.copy_class", product="drawing").should_be_called().will_return("new_drawing")
drawing.copy_representation("drawing", "new_drawing").should_be_called()
drawing.set_name("new_drawing", "unique_name").should_be_called()
drawing.get_drawing_group("new_drawing").should_be_called().will_return("group")
ifc.run("group.unassign_group", group="group", products=["new_drawing"]).should_be_called()
ifc.run("group.add_group").should_be_called().will_return("new_group")
ifc.run(
"group.edit_group", group="new_group", attributes={"Name": "unique_name", "ObjectType": "DRAWING"}
).should_be_called()
ifc.run("group.assign_group", group="new_group", products=["new_drawing"]).should_be_called()
drawing.get_group_elements("group").should_be_called().will_return(["drawing", "annotation"])
ifc.run("root.copy_class", product="annotation").should_be_called().will_return("new_annotation")
drawing.copy_representation("annotation", "new_annotation").should_be_called()
ifc.run("group.unassign_group", group="group", products=["new_annotation"]).should_be_called()
ifc.run("group.assign_group", group="new_group", products=["new_annotation"]).should_be_called()
drawing.get_drawing_document("new_drawing").should_be_called().will_return("old_reference")
ifc.run("document.unassign_document", products=["new_drawing"], document="old_reference").should_be_called()
ifc.run("document.add_information").should_be_called().will_return("information")
ifc.run("document.add_reference", information="information").should_be_called().will_return("reference")
ifc.get_schema().should_be_called().will_return("IFC4")
drawing.get_default_drawing_path("unique_name").should_be_called().will_return("drawing_path")
ifc.run(
"document.edit_information",
information="information",
attributes={"Identification": "X", "Name": "unique_name", "Scope": "DRAWING"},
).should_be_called()
ifc.run(
"document.edit_reference", reference="reference", attributes={"Location": "drawing_path"}
).should_be_called()
ifc.run("document.assign_document", products=["new_drawing"], document="reference").should_be_called()
drawing.import_drawings().should_be_called()
subject.duplicate_drawing(ifc, drawing, drawing="drawing", should_duplicate_annotations=True)
class TestRemoveDrawing:
def test_run(self, ifc, drawing):
drawing.is_active_drawing("drawing").should_be_called().will_return(True)
drawing.run_drawing_activate_model().should_be_called()
drawing.get_drawing_collection("drawing").should_be_called().will_return("collection")
drawing.get_drawing_group("drawing").should_be_called().will_return("group")
drawing.get_group_elements("group").should_be_called().will_return("elements")
drawing.delete_drawing_elements("elements").should_be_called()
ifc.run("group.remove_group", group="group").should_be_called()
drawing.delete_collection("collection").should_be_called()
drawing.get_drawing_references("drawing").should_be_called().will_return(["reference"])
ifc.get_object("reference").should_be_called().will_return("reference_obj")
drawing.delete_object("reference_obj").should_be_called()
ifc.run("root.remove_product", product="reference").should_be_called()
drawing.get_drawing_document("drawing").should_be_called().will_return("reference")
drawing.get_reference_document("reference").should_be_called().will_return("information")
drawing.get_document_uri("information").should_be_called().will_return("relative_uri")
ifc.resolve_uri("relative_uri").should_be_called().will_return("absolute_uri")
drawing.does_file_exist("absolute_uri").should_be_called().will_return(True)
drawing.delete_file("absolute_uri").should_be_called()
ifc.run("document.remove_information", information="information").should_be_called()
drawing.import_drawings().should_be_called()
subject.remove_drawing(ifc, drawing, drawing="drawing")
class TestUpdateDrawingName:
def test_do_not_update_if_name_unchanged(self, ifc, drawing):
drawing.get_name("drawing").should_be_called().will_return("name")
drawing.get_drawing_group("drawing").should_be_called().will_return("group")
drawing.get_name("group").should_be_called().will_return("name")
drawing.get_drawing_collection("drawing").should_be_called().will_return("collection")
drawing.set_drawing_collection_name("drawing", "collection").should_be_called()
drawing.get_drawing_document("drawing").should_be_called().will_return("reference")
drawing.get_reference_document("reference").should_be_called().will_return("information")
ifc.run("document.edit_information", information="information", attributes={"Name": "name"}).should_be_called()
drawing.get_reference_location("reference").should_be_called().will_return("location")
drawing.get_default_drawing_path("name").should_be_called().will_return("location")
subject.update_drawing_name(ifc, drawing, drawing="drawing", name="name")
def test_run(self, ifc, drawing):
drawing.get_name("drawing").should_be_called().will_return("oldname")
ifc.run("attribute.edit_attributes", product="drawing", attributes={"Name": "name"}).should_be_called()
drawing.get_drawing_group("drawing").should_be_called().will_return("group")
drawing.get_name("group").should_be_called().will_return("oldname")
ifc.run("attribute.edit_attributes", product="group", attributes={"Name": "name"}).should_be_called()
drawing.get_drawing_collection("drawing").should_be_called().will_return("collection")
drawing.set_drawing_collection_name("drawing", "collection").should_be_called()
drawing.get_drawing_document("drawing").should_be_called().will_return("reference")
drawing.get_reference_document("reference").should_be_called().will_return("information")
ifc.run("document.edit_information", information="information", attributes={"Name": "name"}).should_be_called()
drawing.get_reference_location("reference").should_be_called().will_return("old_location")
drawing.get_default_drawing_path("name").should_be_called().will_return("new_location")
ifc.run(
"document.edit_reference", reference="reference", attributes={"Location": "new_location"}
).should_be_called()
ifc.resolve_uri("old_location").should_be_called().will_return("old_uri")
drawing.does_file_exist("old_uri").should_be_called().will_return(True)
ifc.resolve_uri("new_location").should_be_called().will_return("new_uri")
drawing.move_file("old_uri", "new_uri").should_be_called()
drawing.get_references_with_location("old_location").should_be_called().will_return(
["reference_with_old_location"]
)
ifc.run(
"document.edit_reference", reference="reference_with_old_location", attributes={"Location": "new_location"}
).should_be_called()
drawing.get_reference_document("reference_with_old_location").should_be_called().will_return(
"sheet_with_old_location"
)
drawing.get_document_uri("sheet_with_old_location", "LAYOUT").should_be_called().will_return(
"relative_layout_uri"
)
ifc.resolve_uri("relative_layout_uri").should_be_called().will_return("absolute_layout_uri")
drawing.does_file_exist("absolute_layout_uri").should_be_called().will_return(True)
drawing.update_embedded_svg_location(
"absolute_layout_uri", "reference_with_old_location", "new_uri"
).should_be_called()
drawing.is_editing_sheets().should_be_called().will_return(True)
drawing.import_sheets().should_be_called()
subject.update_drawing_name(ifc, drawing, drawing="drawing", name="name")
class TestAddAnnotation:
def test_run(self, ifc, collector, drawing):
drawing.get_drawing_target_view("drawing").should_be_called().will_return("target_view")
drawing.get_annotation_context("target_view", "object_type").should_be_called().will_return("context")
drawing.show_decorations().should_be_called()
drawing.create_annotation_object("drawing", "object_type").should_be_called().will_return("obj")
ifc.get_entity("obj").should_be_called().will_return(None)
drawing.get_ifc_representation_class("object_type").should_be_called().will_return("ifc_representation_class")
drawing.run_root_assign_class(
obj="obj",
ifc_class="IfcAnnotation",
predefined_type="object_type",
should_add_representation=True,
context="context",
ifc_representation_class="ifc_representation_class",
).should_be_called().will_return("element")
drawing.get_drawing_group("drawing").should_be_called().will_return("group")
ifc.run("group.assign_group", group="group", products=["element"]).should_be_called()
collector.assign("obj").should_be_called()
drawing.enable_editing("obj").should_be_called()
subject.add_annotation(ifc, collector, drawing, drawing="drawing", object_type="object_type")
def test_create_a_missing_annotation_context_on_the_fly(self, ifc, collector, drawing):
drawing.get_drawing_target_view("drawing").should_be_called().will_return("target_view")
drawing.get_annotation_context("target_view", "object_type").should_be_called().will_return(None)
drawing.create_annotation_context("target_view", "object_type").should_be_called().will_return("context")
drawing.show_decorations().should_be_called()
drawing.create_annotation_object("drawing", "object_type").should_be_called().will_return("obj")
ifc.get_entity("obj").should_be_called().will_return(None)
drawing.get_ifc_representation_class("object_type").should_be_called().will_return("ifc_representation_class")
drawing.run_root_assign_class(
obj="obj",
ifc_class="IfcAnnotation",
predefined_type="object_type",
should_add_representation=True,
context="context",
ifc_representation_class="ifc_representation_class",
).should_be_called().will_return("element")
drawing.get_drawing_group("drawing").should_be_called().will_return("group")
ifc.run("group.assign_group", group="group", products=["element"]).should_be_called()
collector.assign("obj").should_be_called()
drawing.enable_editing("obj").should_be_called()
subject.add_annotation(ifc, collector, drawing, drawing="drawing", object_type="object_type")
+422
View File
@@ -0,0 +1,422 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.geometry as subject
import test.core.test_style
from test.core.bootstrap import ifc, surveyor, geometry, style
class TestEditObjectPlacement:
def predict(self, ifc, geometry, surveyor):
ifc.get_entity("obj").should_be_called().will_return("element")
geometry.clear_cache("element").should_be_called()
geometry.clear_scale("obj").should_be_called()
geometry.get_blender_offset_type("obj").should_be_called()
surveyor.get_absolute_matrix("obj").should_be_called().will_return("matrix")
ifc.run("geometry.edit_object_placement", product="element", matrix="matrix").should_be_called()
geometry.record_object_position("obj").should_be_called()
def test_run(self, ifc, geometry, surveyor):
self.predict(ifc, geometry, surveyor)
subject.edit_object_placement(ifc, geometry, surveyor, obj="obj")
class TestAddRepresentation:
def test_run(self, ifc, geometry, style, surveyor):
TestEditObjectPlacement.predict(self, ifc, geometry, surveyor)
# Add representation
geometry.get_object_data("obj").should_be_called().will_return("data")
geometry.get_cartesian_point_coordinate_offset("obj").should_be_called().will_return("coordinate_offset")
geometry.get_total_representation_items("obj").should_be_called().will_return(1)
geometry.should_force_faceted_brep().should_be_called().will_return(False)
geometry.should_force_triangulation().should_be_called().will_return(True)
geometry.should_generate_uvs("obj").should_be_called().will_return(True)
ifc.run(
"geometry.add_representation",
context="context",
blender_object="obj",
geometry="data",
coordinate_offset="coordinate_offset",
total_items=1,
should_force_faceted_brep=False,
should_force_triangulation=True,
should_generate_uvs=True,
ifc_representation_class="ifc_representation_class",
profile_set_usage="profile_set_usage",
).should_be_called().will_return("representation")
# Styles are relevant for body representations only (as a simplification)
geometry.is_body_representation("representation").should_be_called().will_return(True)
# Add styles
geometry.get_object_materials_without_styles("obj").should_be_called().will_return(["material"])
geometry.run_style_add_style(obj="material").should_be_called()
geometry.get_styles("obj").should_be_called().will_return(["style"])
# Link style to representation items
geometry.should_use_presentation_style_assignment().should_be_called().will_return(False)
ifc.run(
"style.assign_representation_styles",
shape_representation="representation",
styles=["style"],
should_use_presentation_style_assignment=False,
).should_be_called()
geometry.record_object_materials("obj").should_be_called()
# Assign representation to product
ifc.run("geometry.assign_representation", product="element", representation="representation").should_be_called()
# Update mesh
geometry.duplicate_object_data("obj").should_be_called().will_return("data")
geometry.change_object_data("obj", "data", is_global=True).should_be_called()
geometry.get_representation_name("representation").should_be_called().will_return("name")
geometry.rename_object("data", "name").should_be_called()
geometry.link("representation", "data").should_be_called()
assert (
subject.add_representation(
ifc,
geometry,
style,
surveyor,
obj="obj",
context="context",
ifc_representation_class="ifc_representation_class",
profile_set_usage="profile_set_usage",
)
== "representation"
)
def test_not_handling_styles_if_not_a_body_representation(self, ifc, geometry, style, surveyor):
TestEditObjectPlacement.predict(self, ifc, geometry, surveyor)
# Add representation
geometry.get_object_data("obj").should_be_called().will_return("data")
geometry.get_cartesian_point_coordinate_offset("obj").should_be_called().will_return("coordinate_offset")
geometry.get_total_representation_items("obj").should_be_called().will_return(1)
geometry.should_force_faceted_brep().should_be_called().will_return(False)
geometry.should_force_triangulation().should_be_called().will_return(True)
geometry.should_generate_uvs("obj").should_be_called().will_return(True)
ifc.run(
"geometry.add_representation",
context="context",
blender_object="obj",
geometry="data",
coordinate_offset="coordinate_offset",
total_items=1,
should_force_faceted_brep=False,
should_force_triangulation=True,
should_generate_uvs=True,
ifc_representation_class="ifc_representation_class",
profile_set_usage="profile_set_usage",
).should_be_called().will_return("representation")
# Styles are relevant for body representations only (as a simplification)
geometry.is_body_representation("representation").should_be_called().will_return(False)
# Assign representation to product
ifc.run("geometry.assign_representation", product="element", representation="representation").should_be_called()
# Update mesh
geometry.duplicate_object_data("obj").should_be_called().will_return("data")
geometry.change_object_data("obj", "data", is_global=True).should_be_called()
geometry.get_representation_name("representation").should_be_called().will_return("name")
geometry.rename_object("data", "name").should_be_called()
geometry.link("representation", "data").should_be_called()
assert (
subject.add_representation(
ifc,
geometry,
style,
surveyor,
obj="obj",
context="context",
ifc_representation_class="ifc_representation_class",
profile_set_usage="profile_set_usage",
)
== "representation"
)
def test_only_updating_the_placement_if_there_is_no_object_data(self, ifc, geometry, style, surveyor):
TestEditObjectPlacement.predict(self, ifc, geometry, surveyor)
# Add representation
geometry.get_object_data("obj").should_be_called().will_return(None)
assert (
subject.add_representation(
ifc,
geometry,
style,
surveyor,
obj="obj",
context="context",
ifc_representation_class="ifc_representation_class",
profile_set_usage="profile_set_usage",
)
is None
)
def test_doing_nothing_if_not_an_ifc_element(self, ifc, geometry, style, surveyor):
ifc.get_entity("obj").should_be_called().will_return(None)
assert (
subject.add_representation(
ifc,
geometry,
style,
surveyor,
obj="obj",
context="context",
ifc_representation_class="ifc_representation_class",
profile_set_usage="profile_set_usage",
)
is None
)
class TestSwitchRepresentation:
def test_switching_to_a_freshly_loaded_representation(self, ifc, geometry):
geometry.is_edited("obj").should_be_called().will_return(False)
geometry.get_object_data("obj").should_be_called().will_return("current_obj_data")
geometry.should_use_immediate_representation("element", True).should_be_called().will_return(False)
geometry.resolve_mapped_representation("mapped_rep").should_be_called().will_return("representation")
geometry.get_representation_data("representation").should_be_called().will_return(None)
geometry.import_representation("obj", "representation", apply_openings=True).should_be_called().will_return(
"new_data"
)
geometry.get_representation_name("representation").should_be_called().will_return("name")
geometry.rename_object("new_data", "name").should_be_called()
geometry.link("representation", "new_data").should_be_called()
geometry.change_object_data("obj", "new_data", is_global=True).should_be_called()
geometry.record_object_materials("obj").should_be_called()
geometry.clear_modifiers("obj").should_be_called()
ifc.get_entity("obj").should_be_called().will_return("element")
geometry.clear_cache("element").should_be_called()
subject.switch_representation(
ifc,
geometry,
obj="obj",
representation="mapped_rep",
should_reload=True,
is_global=True,
should_sync_changes_first=True,
apply_openings=True,
)
def test_switching_to_a_reloaded_representation_and_deleting_the_existing_data(self, ifc, geometry):
geometry.is_edited("obj").should_be_called().will_return(False)
geometry.get_object_data("obj").should_be_called().will_return("current_obj_data")
geometry.should_use_immediate_representation("element", True).should_be_called().will_return(False)
geometry.resolve_mapped_representation("mapped_rep").should_be_called().will_return("representation")
geometry.get_representation_data("representation").should_be_called().will_return("existing_data")
geometry.import_representation("obj", "representation", apply_openings=True).should_be_called().will_return(
"new_data"
)
geometry.get_representation_name("representation").should_be_called().will_return("name")
geometry.rename_object("new_data", "name").should_be_called()
geometry.link("representation", "new_data").should_be_called()
geometry.change_object_data("obj", "new_data", is_global=True).should_be_called()
geometry.record_object_materials("obj").should_be_called()
geometry.has_data_users("existing_data").should_be_called().will_return(False)
geometry.delete_data("existing_data").should_be_called()
geometry.clear_modifiers("obj").should_be_called()
ifc.get_entity("obj").should_be_called().will_return("element")
geometry.clear_cache("element").should_be_called()
subject.switch_representation(
ifc,
geometry,
obj="obj",
representation="mapped_rep",
should_reload=True,
is_global=True,
should_sync_changes_first=True,
apply_openings=True,
)
def test_switching_to_an_existing_representation(self, ifc, geometry):
geometry.is_edited("obj").should_be_called().will_return(False)
ifc.get_entity("obj").should_be_called().will_return("element")
geometry.get_object_data("obj").should_be_called().will_return("current_obj_data")
geometry.should_use_immediate_representation("element", True).should_be_called().will_return(False)
geometry.resolve_mapped_representation("mapped_rep").should_be_called().will_return("representation")
geometry.get_representation_data("representation").should_be_called().will_return("data")
geometry.change_object_data("obj", "data", is_global=True).should_be_called()
geometry.record_object_materials("obj").should_be_called()
geometry.clear_modifiers("obj").should_be_called()
geometry.clear_cache("element").should_be_called()
subject.switch_representation(
ifc,
geometry,
obj="obj",
representation="mapped_rep",
should_reload=False,
is_global=True,
should_sync_changes_first=True,
)
def test_switching_to_an_existing_representation_reuse_representation(self, ifc, geometry):
geometry.is_edited("obj").should_be_called().will_return(False)
ifc.get_entity("obj").should_be_called().will_return("element")
geometry.get_object_data("obj").should_be_called().will_return("current_obj_data")
geometry.should_use_immediate_representation("element", True).should_be_called().will_return(True)
geometry.unresolve_type_representation("mapped_rep", "element").should_be_called().will_return("representation")
geometry.get_representation_data("representation").should_be_called().will_return("data")
geometry.change_object_data("obj", "data", is_global=False).should_be_called()
geometry.record_object_materials("obj").should_be_called()
geometry.clear_modifiers("obj").should_be_called()
geometry.clear_cache("element").should_be_called()
subject.switch_representation(
ifc,
geometry,
obj="obj",
representation="mapped_rep",
should_reload=False,
is_global=True,
should_sync_changes_first=True,
)
def test_updating_a_representation_if_the_blender_object_has_been_edited_prior_to_switching(self, ifc, geometry):
geometry.is_edited("obj").should_be_called().will_return(True)
geometry.is_box_representation("mapped_rep").should_be_called().will_return(False)
geometry.get_representation_id("mapped_rep").should_be_called().will_return("representation_id")
geometry.run_geometry_update_representation(obj="obj").should_be_called()
geometry.does_representation_id_exist("representation_id").should_be_called().will_return(True)
geometry.get_object_data("obj").should_be_called().will_return("current_obj_data")
geometry.should_use_immediate_representation("element", True).should_be_called().will_return(False)
geometry.resolve_mapped_representation("mapped_rep").should_be_called().will_return("representation")
geometry.get_representation_data("representation").should_be_called().will_return("data")
geometry.change_object_data("obj", "data", is_global=False).should_be_called()
geometry.record_object_materials("obj").should_be_called()
geometry.clear_modifiers("obj").should_be_called()
ifc.get_entity("obj").should_be_called().will_return("element")
geometry.clear_cache("element").should_be_called()
subject.switch_representation(
ifc,
geometry,
obj="obj",
representation="mapped_rep",
should_reload=False,
is_global=False,
should_sync_changes_first=True,
)
def test_not_switching_if_an_updated_representation_is_the_same_one_we_were_going_to_switch_to(self, geometry):
geometry.is_edited("obj").should_be_called().will_return(True)
geometry.is_box_representation("mapped_rep").should_be_called().will_return(False)
geometry.get_representation_id("mapped_rep").should_be_called().will_return("representation_id")
geometry.run_geometry_update_representation(obj="obj").should_be_called()
geometry.does_representation_id_exist("representation_id").should_be_called().will_return(False)
subject.switch_representation(
ifc,
geometry,
obj="obj",
representation="mapped_rep",
should_reload=False,
is_global=False,
should_sync_changes_first=True,
)
class TestGetRepresentationIfcParameters:
def test_run(self, geometry):
geometry.get_object_data("obj").should_be_called().will_return("data")
geometry.import_representation_parameters("data").should_be_called()
subject.get_representation_ifc_parameters(geometry, obj="obj", should_sync_changes_first=False)
class TestRemoveRepresentation:
def test_removing_an_actively_used_mapped_representation_by_remapping_usages_to_an_empty(self, ifc, geometry):
ifc.get_entity("obj").should_be_called().will_return("element")
geometry.get_element_type("element").should_be_called().will_return("type")
geometry.is_mapped_representation("mapped_rep").should_be_called().will_return(False)
geometry.is_type_product("element").should_be_called().will_return(True)
geometry.resolve_mapped_representation("mapped_rep").should_be_called().will_return("representation")
geometry.get_representation_data("representation").should_be_called().will_return("data")
geometry.has_data_users("data").should_be_called().will_return(True)
geometry.get_elements_of_type("type").should_be_called().will_return(["element"])
ifc.get_object("element").should_be_called().will_return("obj")
geometry.switch_from_representation("obj", "representation").should_be_called()
ifc.get_object("type").should_be_called().will_return("type_obj")
geometry.switch_from_representation("type_obj", "representation").should_be_called()
ifc.run("geometry.unassign_representation", product="type", representation="representation").should_be_called()
ifc.run("geometry.remove_representation", representation="representation").should_be_called()
geometry.delete_data("data").should_be_called()
subject.remove_representation(ifc, geometry, obj="obj", representation="mapped_rep")
def test_removing_an_unused_mapped_representation(self, ifc, geometry):
ifc.get_entity("obj").should_be_called().will_return("element")
geometry.get_element_type("element").should_be_called().will_return("type")
geometry.is_mapped_representation("mapped_rep").should_be_called().will_return(True)
geometry.resolve_mapped_representation("mapped_rep").should_be_called().will_return("representation")
geometry.get_representation_data("representation").should_be_called().will_return(None)
ifc.run("geometry.unassign_representation", product="type", representation="representation").should_be_called()
ifc.run("geometry.remove_representation", representation="representation").should_be_called()
subject.remove_representation(ifc, geometry, obj="obj", representation="mapped_rep")
def test_remove_a_mapped_representation_by_an_element_with_no_type(self, ifc, geometry):
ifc.get_entity("obj").should_be_called().will_return("element")
geometry.get_element_type("element").should_be_called().will_return(None)
geometry.get_representation_data("representation").should_be_called().will_return("data")
geometry.has_data_users("data").should_be_called().will_return(True)
geometry.switch_from_representation("obj", "representation").should_be_called()
ifc.run(
"geometry.unassign_representation", product="element", representation="representation"
).should_be_called()
ifc.run("geometry.remove_representation", representation="representation").should_be_called()
geometry.delete_data("data").should_be_called()
subject.remove_representation(ifc, geometry, obj="obj", representation="representation")
def test_removing_an_actively_used_representation(self, ifc, geometry):
ifc.get_entity("obj").should_be_called().will_return("element")
geometry.get_element_type("element").should_be_called().will_return("type")
geometry.is_mapped_representation("representation").should_be_called().will_return(False)
geometry.is_type_product("element").should_be_called().will_return(False)
geometry.get_representation_data("representation").should_be_called().will_return("data")
geometry.has_data_users("data").should_be_called().will_return(True)
geometry.switch_from_representation("obj", "representation").should_be_called()
ifc.run(
"geometry.unassign_representation", product="element", representation="representation"
).should_be_called()
ifc.run("geometry.remove_representation", representation="representation").should_be_called()
geometry.delete_data("data").should_be_called()
subject.remove_representation(ifc, geometry, obj="obj", representation="representation")
def test_removing_an_unused_representation(self, ifc, geometry):
ifc.get_entity("obj").should_be_called().will_return("element")
geometry.get_element_type("element").should_be_called().will_return("type")
geometry.is_mapped_representation("representation").should_be_called().will_return(False)
geometry.is_type_product("element").should_be_called().will_return(False)
geometry.get_representation_data("representation").should_be_called().will_return(None)
ifc.run(
"geometry.unassign_representation", product="element", representation="representation"
).should_be_called()
ifc.run("geometry.remove_representation", representation="representation").should_be_called()
subject.remove_representation(ifc, geometry, obj="obj", representation="representation")
class TestSelectConnection:
def test_run(self, geometry):
geometry.select_connection("connection").should_be_called()
subject.select_connection(geometry, connection="connection")
class TestRemoveConnection:
def test_run(self, geometry):
geometry.remove_connection("connection").should_be_called()
subject.remove_connection(geometry, connection="connection")
+123
View File
@@ -0,0 +1,123 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.georeference as subject
from test.core.bootstrap import ifc, georeference
class TestAddGeoreferencing:
def test_run(self, georeference):
georeference.add_georeferencing().should_be_called()
subject.add_georeferencing(georeference)
class TestEnableEditingGeoreferencing:
def test_run(self, georeference):
georeference.import_projected_crs().should_be_called()
georeference.import_coordinate_operation().should_be_called()
georeference.enable_editing().should_be_called()
subject.enable_editing_georeferencing(georeference)
class TestRemoveGeoreferencing:
def test_run(self, ifc):
ifc.run("georeference.remove_georeferencing").should_be_called()
subject.remove_georeferencing(ifc)
class TestDisableEditingGeoreferencing:
def test_run(self, georeference):
georeference.disable_editing().should_be_called()
subject.disable_editing_georeferencing(georeference)
class TestEditGeoreferencing:
def test_run(self, ifc, georeference):
georeference.export_projected_crs().should_be_called().will_return("projected_crs_attributes")
georeference.export_coordinate_operation().should_be_called().will_return("coordinate_operation_attributes")
ifc.run(
"georeference.edit_georeferencing",
projected_crs="projected_crs_attributes",
coordinate_operation="coordinate_operation_attributes",
).should_be_called()
georeference.disable_editing().should_be_called()
georeference.set_model_origin().should_be_called()
subject.edit_georeferencing(ifc, georeference)
class TestGetCursorLocation:
def test_run(self, georeference):
georeference.get_cursor_location().should_be_called().will_return("coordinates")
georeference.has_blender_offset().should_be_called().will_return(False)
georeference.set_coordinates("local", "coordinates").should_be_called()
subject.get_cursor_location(georeference)
def test_with_a_blender_offset(self, georeference):
georeference.get_cursor_location().should_be_called().will_return("coordinates")
georeference.has_blender_offset().should_be_called().will_return(True)
georeference.set_coordinates("blender", "coordinates").should_be_called()
subject.get_cursor_location(georeference)
class TestEnableEditingWCS:
def test_run(self, georeference):
georeference.import_wcs().should_be_called()
georeference.enable_editing_wcs().should_be_called()
subject.enable_editing_wcs(georeference)
class TestDisableEditingWCS:
def test_run(self, georeference):
georeference.disable_editing_wcs().should_be_called()
subject.disable_editing_wcs(georeference)
class TestEditWCS:
def test_run(self, georeference):
georeference.export_wcs().should_be_called().will_return("wcs")
georeference.set_wcs("wcs").should_be_called()
georeference.disable_editing_wcs().should_be_called()
georeference.set_model_origin().should_be_called()
subject.edit_wcs(georeference)
class TestEnableEditingTrueNorth:
def test_run(self, georeference):
georeference.import_true_north().should_be_called()
georeference.enable_editing_true_north().should_be_called()
subject.enable_editing_true_north(georeference)
class TestDisableEditingTrueNorth:
def test_run(self, georeference):
georeference.disable_editing_true_north().should_be_called()
subject.disable_editing_true_north(georeference)
class TestEditTrueNorth:
def test_run(self, ifc, georeference):
georeference.get_true_north_attributes().should_be_called().will_return("true_north")
ifc.run("georeference.edit_true_north", true_north="true_north").should_be_called()
georeference.disable_editing_true_north().should_be_called()
subject.edit_true_north(ifc, georeference)
class TestRemoveTrueNorth:
def test_run(self, ifc):
ifc.run("georeference.edit_true_north", true_north=None).should_be_called()
subject.remove_true_north(ifc)
+125
View File
@@ -0,0 +1,125 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.library as subject
from test.core.bootstrap import ifc, library
class TestAddLibrary:
def test_run(self, ifc):
ifc.run("library.add_library", name="Unnamed").should_be_called().will_return("library")
assert subject.add_library(ifc) == "library"
class TestRemoveLibrary:
def test_run(self, ifc):
ifc.run("library.remove_library", library="library").should_be_called()
subject.remove_library(ifc, library="library")
class TestEnableEditingLibraryReferences:
def test_run(self, library):
library.set_editing_mode("REFERENCES").should_be_called()
library.set_active_library("library").should_be_called()
library.import_references("library").should_be_called()
subject.enable_editing_library_references(library, library="library")
class TestDisableEditingLibraryReferences:
def test_run(self, library):
library.clear_editing_mode().should_be_called()
subject.disable_editing_library_references(library)
class TestEnableEditingLibrary:
def test_run(self, library):
library.set_editing_mode("LIBRARY").should_be_called()
library.get_active_library().should_be_called().will_return("library")
library.import_library_attributes("library").should_be_called()
subject.enable_editing_library(library)
class TestDisableEditingLibrary:
def test_run(self, library):
library.set_editing_mode("REFERENCES").should_be_called()
subject.disable_editing_library(library)
class TestEditLibrary:
def test_run(self, ifc, library):
library.set_editing_mode("REFERENCES").should_be_called()
library.get_active_library().should_be_called().will_return("library")
library.export_library_attributes().should_be_called().will_return("attributes")
ifc.run("library.edit_library", library="library", attributes="attributes").should_be_called()
library.import_references("library").should_be_called()
subject.edit_library(ifc, library)
class TestAddLibraryReference:
def test_run(self, ifc, library):
library.get_active_library().should_be_called().will_return("library")
ifc.run("library.add_reference", library="library").should_be_called()
library.import_references("library").should_be_called()
subject.add_library_reference(ifc, library)
class TestRemoveLibraryReference:
def test_run(self, ifc, library):
ifc.run("library.remove_reference", reference="reference").should_be_called()
library.get_active_library().should_be_called().will_return("library")
library.import_references("library").should_be_called()
subject.remove_library_reference(ifc, library, reference="reference")
class TestEnableEditingLibraryReference:
def test_run(self, library):
library.set_editing_mode("REFERENCE").should_be_called()
library.set_active_reference("reference").should_be_called()
library.import_reference_attributes("reference").should_be_called()
subject.enable_editing_library_reference(library, reference="reference")
class TestDisableEditingLibraryReference:
def test_run(self, library):
library.set_editing_mode("REFERENCES").should_be_called()
subject.disable_editing_library_reference(library)
class TestEditLibraryReference:
def test_run(self, ifc, library):
library.set_editing_mode("REFERENCES").should_be_called()
library.get_active_reference().should_be_called().will_return("reference")
library.export_reference_attributes().should_be_called().will_return("attributes")
ifc.run("library.edit_reference", reference="reference", attributes="attributes").should_be_called()
library.get_active_library().should_be_called().will_return("library")
library.import_references("library").should_be_called()
subject.edit_library_reference(ifc, library)
class TestAssignLibraryReference:
def test_run(self, ifc):
ifc.get_entity("obj").should_be_called().will_return("product")
ifc.run("library.assign_reference", products=["product"], reference="reference").should_be_called()
subject.assign_library_reference(ifc, obj="obj", reference="reference")
class TestUnassignLibraryReference:
def test_run(self, ifc):
ifc.get_entity("obj").should_be_called().will_return("product")
ifc.run("library.unassign_reference", products=["product"], reference="reference").should_be_called()
subject.unassign_library_reference(ifc, obj="obj", reference="reference")
+111
View File
@@ -0,0 +1,111 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.material as subject
from test.core.bootstrap import ifc, material, style, spatial
class TestAddMaterial:
def test_add_a_material(self, ifc, material):
ifc.run(
"material.add_material", name="name", category="category", description="description"
).should_be_called().will_return("material")
material.is_editing_materials().should_be_called().will_return(False)
assert (
subject.add_material(ifc, material, name="name", category="category", description="description")
== "material"
)
def test_reloading_imported_materials_if_you_are_editing_scene_materials(self, ifc, material):
ifc.run(
"material.add_material", name="name", category="category", description="description"
).should_be_called().will_return("material")
material.is_editing_materials().should_be_called().will_return(True)
material.get_active_material_type().should_be_called().will_return("material_type")
material.import_material_definitions("material_type").should_be_called()
assert (
subject.add_material(ifc, material, name="name", category="category", description="description")
== "material"
)
class TestAddMaterialSet:
def test_adding_a_material_set(self, ifc, material):
ifc.run("material.add_material_set", name="Unnamed", set_type="set_type").should_be_called().will_return(
"material"
)
material.is_editing_materials().should_be_called().will_return(False)
assert subject.add_material_set(ifc, material, set_type="set_type") == "material"
def test_adding_a_material_set_and_reloading_imported_materials(self, ifc, material):
ifc.run("material.add_material_set", name="Unnamed", set_type="set_type").should_be_called().will_return(
"material"
)
material.is_editing_materials().should_be_called().will_return(True)
material.get_active_material_type().should_be_called().will_return("material_type")
material.import_material_definitions("material_type").should_be_called()
assert subject.add_material_set(ifc, material, set_type="set_type") == "material"
class TestRemoveMaterial:
def test_removing_a_material(self, ifc, material):
material.is_material_used_in_sets("material").should_be_called().will_return(False)
ifc.run("material.remove_material", material="material").should_be_called()
material.is_editing_materials().should_be_called().will_return(False)
subject.remove_material(ifc, material, material="material")
def test_removing_a_material_and_reloading_imported_materials(self, ifc, material):
material.is_material_used_in_sets("material").should_be_called().will_return(False)
ifc.run("material.remove_material", material="material").should_be_called()
material.is_editing_materials().should_be_called().will_return(True)
material.get_active_material_type().should_be_called().will_return("material_type")
material.import_material_definitions("material_type").should_be_called()
subject.remove_material(ifc, material, material="material")
def test_not_removing_a_material_if_it_is_used_in_a_material_set(self, ifc, material):
material.is_material_used_in_sets("material").should_be_called().will_return(True)
subject.remove_material(ifc, material, material="material")
class TestRemoveMaterialSet:
def test_run(self, ifc, material):
ifc.run("material.remove_material_set", material="material").should_be_called()
material.is_editing_materials().should_be_called().will_return(True)
material.get_active_material_type().should_be_called().will_return("material_type")
material.import_material_definitions("material_type").should_be_called()
subject.remove_material_set(ifc, material, material="material")
class TestLoadMaterials:
def test_run(self, material):
material.import_material_definitions("material_type").should_be_called()
material.enable_editing_materials().should_be_called()
subject.load_materials(material, "material_type")
class TestDisableEditingMaterials:
def test_run(self, material):
material.disable_editing_materials().should_be_called()
subject.disable_editing_materials(material)
class TestSelectByMaterial:
def test_run(self, material, spatial):
material.get_elements_by_material("material").should_be_called().will_return("elements")
spatial.select_products("elements").should_be_called()
subject.select_by_material(material, spatial, material="material")
+41
View File
@@ -0,0 +1,41 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.misc as subject
from test.core.bootstrap import misc
class TestResizeToStorey:
def test_run(self, misc):
misc.get_object_storey("obj").should_be_called().will_return("storey")
misc.get_storey_elevation_in_si("storey").should_be_called().will_return("elevation")
misc.get_storey_height_in_si("storey", 1).should_be_called().will_return("height")
misc.set_object_origin_to_bottom("obj").should_be_called()
misc.move_object_to_elevation("obj", "elevation").should_be_called()
misc.scale_object_to_height("obj", "height").should_be_called()
misc.mark_object_as_edited("obj").should_be_called()
subject.resize_to_storey(misc, obj="obj", total_storeys=1)
def test_doing_nothing_when_the_object_has_no_storey(self, misc):
misc.get_object_storey("obj").should_be_called().will_return(None)
subject.resize_to_storey(misc, obj="obj", total_storeys=1)
def test_doing_nothing_when_the_storey_has_no_height(self, misc):
misc.get_object_storey("obj").should_be_called().will_return("storey")
misc.get_storey_height_in_si("storey", 1).should_be_called().will_return(None)
subject.resize_to_storey(misc, obj="obj", total_storeys=1)
+59
View File
@@ -0,0 +1,59 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.nest as subject
from test.core.bootstrap import ifc, nest, collector
class TestEnableEditingNeset:
def test_run(self, nest):
nest.enable_editing("obj").should_be_called()
subject.enable_editing_nest(nest, obj="obj")
class TestDisableEditingNest:
def test_run(self, nest):
nest.disable_editing("obj").should_be_called()
subject.disable_editing_nest(nest, obj="obj")
class TestAssignObject:
def test_run(self, ifc, nest, collector):
nest.can_nest("relating_obj", "related_obj").should_be_called().will_return(True)
ifc.get_entity("relating_obj").should_be_called().will_return("relating_object")
ifc.get_entity("related_obj").should_be_called().will_return("related_object")
ifc.run(
"nest.assign_object", related_objects=["related_object"], relating_object="relating_object"
).should_be_called().will_return("rel")
nest.disable_editing("related_obj").should_be_called()
collector.assign("relating_obj").should_be_called()
collector.assign("related_obj").should_be_called()
assert (
subject.assign_object(ifc, nest, collector, relating_obj="relating_obj", related_obj="related_obj") == "rel"
)
class TestUnassignObject:
def test_run(self, ifc, nest, collector):
ifc.get_entity("related_obj").should_be_called().will_return("element")
nest.get_container("element").should_be_called().will_return("container")
ifc.run("spatial.assign_container", products=["element"], relating_structure="container").should_be_called()
ifc.run("nest.unassign_object", related_objects=["element"]).should_be_called().will_return("rel")
collector.assign("relating_obj").should_be_called()
collector.assign("related_obj").should_be_called()
subject.unassign_object(ifc, nest, collector, relating_obj="relating_obj", related_obj="related_obj")
+273
View File
@@ -0,0 +1,273 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.owner as subject
from test.core.bootstrap import ifc, owner
class TestAddPerson:
def test_run(self, ifc):
ifc.run("owner.add_person").should_be_called().will_return("person")
assert subject.add_person(ifc) == "person"
class TestRemovePerson:
def test_run(self, ifc):
ifc.run("owner.remove_person", person="person").should_be_called()
subject.remove_person(ifc, person="person")
class TestEnableEditingPerson:
def test_run(self, owner):
owner.set_person("person").should_be_called()
owner.import_person_attributes().should_be_called()
subject.enable_editing_person(owner, person="person")
class TestDisableEditingPerson:
def test_run(self, owner):
owner.clear_person().should_be_called()
subject.disable_editing_person(owner)
class TestEditPerson:
def test_run(self, ifc, owner):
owner.get_person().should_be_called().will_return("person")
owner.export_person_attributes().should_be_called().will_return("attributes")
ifc.run("owner.edit_person", person="person", attributes="attributes").should_be_called()
owner.clear_person().should_be_called()
subject.edit_person(ifc, owner)
class TestAddPersonAttribute:
def test_run(self, owner):
owner.add_person_attribute("name").should_be_called()
subject.add_person_attribute(owner, name="name")
class TestRemovePersonAttribute:
def test_run(self, owner):
owner.remove_person_attribute("name", "id").should_be_called()
subject.remove_person_attribute(owner, name="name", id="id")
class TestAddRole:
def test_run(self, ifc):
ifc.run("owner.add_role", assigned_object="parent").should_be_called().will_return("role")
assert subject.add_role(ifc, parent="parent") == "role"
class TestRemoveRole:
def test_run(self, ifc):
ifc.run("owner.remove_role", role="role").should_be_called()
subject.remove_role(ifc, role="role")
class TestEnableEditingRole:
def test_run(self, owner):
owner.set_role("role").should_be_called()
owner.import_role_attributes().should_be_called()
subject.enable_editing_role(owner, role="role")
class TestDisableEditingRole:
def test_run(self, owner):
owner.clear_role().should_be_called()
subject.disable_editing_role(owner)
class TestEditRole:
def test_run(self, ifc, owner):
owner.export_role_attributes().should_be_called().will_return("attributes")
owner.get_role().should_be_called().will_return("role")
ifc.run("owner.edit_role", role="role", attributes="attributes").should_be_called()
owner.clear_role().should_be_called()
subject.edit_role(ifc, owner)
class TestAddAddress:
def test_run(self, ifc):
ifc.run(
"owner.add_address", assigned_object="parent", ifc_class="IfcPostalAddress"
).should_be_called().will_return("address")
assert subject.add_address(ifc, parent="parent", ifc_class="IfcPostalAddress") == "address"
class TestRemoveAddress:
def test_run(self, ifc):
ifc.run("owner.remove_address", address="address").should_be_called()
subject.remove_address(ifc, address="address")
class TestEnableEditingAddress:
def test_run(self, owner):
owner.set_address("address").should_be_called()
owner.import_address_attributes().should_be_called()
subject.enable_editing_address(owner, address="address")
class TestDisableEditingAddress:
def test_run(self, owner):
owner.clear_address().should_be_called()
subject.disable_editing_address(owner)
class TestEditAddress:
def test_run(self, ifc, owner):
owner.get_address().should_be_called().will_return("address")
owner.export_address_attributes().should_be_called().will_return("attributes")
ifc.run("owner.edit_address", address="address", attributes="attributes").should_be_called()
owner.clear_address().should_be_called()
subject.edit_address(ifc, owner)
class TestAddAddressAttribute:
def test_run(self, owner):
owner.add_address_attribute("name").should_be_called()
subject.add_address_attribute(owner, name="name")
class TestRemoveAddressAttribute:
def test_run(self, owner):
owner.remove_address_attribute("name", "id").should_be_called()
subject.remove_address_attribute(owner, name="name", id="id")
class TestAddOrganisation:
def test_run(self, ifc):
ifc.run("owner.add_organisation").should_be_called().will_return("organisation")
assert subject.add_organisation(ifc) == "organisation"
class TestRemoveOrganisation:
def test_run(self, ifc):
ifc.run("owner.remove_organisation", organisation="organisation").should_be_called()
subject.remove_organisation(ifc, organisation="organisation")
class TestEnableEditingOrganisation:
def test_run(self, owner):
owner.set_organisation("organisation").should_be_called()
owner.import_organisation_attributes().should_be_called()
subject.enable_editing_organisation(owner, organisation="organisation")
class TestDisableEditingOrganisation:
def test_run(self, owner):
owner.clear_organisation().should_be_called()
subject.disable_editing_organisation(owner)
class TestEditOrganisation:
def test_run(self, ifc, owner):
owner.get_organisation().should_be_called().will_return("organisation")
owner.export_organisation_attributes().should_be_called().will_return("attributes")
ifc.run("owner.edit_organisation", organisation="organisation", attributes="attributes").should_be_called()
owner.clear_organisation().should_be_called()
subject.edit_organisation(ifc, owner)
class TestAddPersonAndOrganisation:
def test_run(self, ifc):
ifc.run(
"owner.add_person_and_organisation", person="person", organisation="organisation"
).should_be_called().will_return("person_and_organisation")
assert (
subject.add_person_and_organisation(ifc, person="person", organisation="organisation")
== "person_and_organisation"
)
class TestRemovePersonAndOrganisation:
def test_run(self, ifc, owner):
owner.get_user().should_be_called().will_return("user")
ifc.run(
"owner.remove_person_and_organisation", person_and_organisation="person_and_organisation"
).should_be_called()
subject.remove_person_and_organisation(ifc, owner, person_and_organisation="person_and_organisation")
def test_clearing_the_active_user_if_you_remove_it(self, ifc, owner):
owner.get_user().should_be_called().will_return("user")
owner.clear_user().should_be_called()
ifc.run("owner.remove_person_and_organisation", person_and_organisation="user").should_be_called()
subject.remove_person_and_organisation(ifc, owner, person_and_organisation="user")
class TestSetUser:
def test_run(self, owner):
owner.set_user("person_and_organisation").should_be_called()
subject.set_user(owner, user="person_and_organisation")
class TestGetUser:
def test_run(self, owner):
owner.get_user().should_be_called().will_return("person_and_organisation")
assert subject.get_user(owner) == "person_and_organisation"
class TestClearUser:
def test_run(self, owner):
owner.clear_user().should_be_called()
subject.clear_user(owner)
class TestAddActor:
def test_run(self, ifc):
ifc.run("owner.add_actor", ifc_class="IfcActor", actor="person").should_be_called().will_return("actor")
assert subject.add_actor(ifc, ifc_class="IfcActor", actor="person") == "actor"
class TestRemoveActor:
def test_run(self, ifc):
ifc.run("owner.remove_actor", actor="actor").should_be_called()
subject.remove_actor(ifc, actor="actor")
class TestEnableEditingActor:
def test_run(self, owner):
owner.set_actor("actor").should_be_called()
owner.import_actor_attributes("actor").should_be_called()
subject.enable_editing_actor(owner, actor="actor")
class TestDisableEditingActor:
def test_run(self, owner):
owner.clear_actor().should_be_called()
subject.disable_editing_actor(owner)
class TestEditActor:
def test_run(self, ifc, owner):
owner.get_actor().should_be_called().will_return("actor")
owner.export_actor_attributes().should_be_called().will_return("attributes")
ifc.run("owner.edit_actor", actor="actor", attributes="attributes").should_be_called()
owner.clear_actor().should_be_called()
subject.edit_actor(ifc, owner)
class TestAssignActor:
def test_run(self, ifc, owner):
ifc.run("owner.assign_actor", relating_actor="actor", related_object="element").should_be_called()
subject.assign_actor(ifc, actor="actor", element="element")
class TestUnassignActor:
def test_run(self, ifc, owner):
ifc.run("owner.unassign_actor", relating_actor="actor", related_object="element").should_be_called()
subject.unassign_actor(ifc, actor="actor", element="element")
+26
View File
@@ -0,0 +1,26 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.patch as subject
from test.core.bootstrap import patch
class TestRunMigratePatch:
def test_run(self, patch):
patch.run_migrate_patch("infile", "outfile", "schema").should_be_called()
subject.run_migrate_patch(patch, infile="infile", outfile="outfile", schema="schema")
+218
View File
@@ -0,0 +1,218 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.project as subject
from test.core.bootstrap import ifc, project, spatial, georeference
class TestCreateProject:
def test_do_nothing_if_a_project_already_exists(self, ifc, georeference, project, spatial):
ifc.get().should_be_called().will_return("ifc")
subject.create_project(ifc, georeference, project, spatial, schema="IFC4", template=None)
def check_contexts(self, project):
project.run_context_add_context(
context_type="Model", context_identifier="", target_view="", parent=0
).should_be_called().will_return("model")
project.run_context_add_context(
context_type="Model", context_identifier="Body", target_view="MODEL_VIEW", parent="model"
).should_be_called().will_return("body")
project.run_context_add_context(
context_type="Model", context_identifier="Axis", target_view="GRAPH_VIEW", parent="model"
).should_be_called()
project.run_context_add_context(
context_type="Model", context_identifier="Box", target_view="MODEL_VIEW", parent="model"
).should_be_called()
project.run_context_add_context(
context_type="Model", context_identifier="Annotation", target_view="SECTION_VIEW", parent="model"
).should_be_called()
project.run_context_add_context(
context_type="Model", context_identifier="Annotation", target_view="ELEVATION_VIEW", parent="model"
).should_be_called()
project.run_context_add_context(
context_type="Model", context_identifier="Annotation", target_view="MODEL_VIEW", parent="model"
).should_be_called()
project.run_context_add_context(
context_type="Model", context_identifier="Annotation", target_view="PLAN_VIEW", parent="model"
).should_be_called()
project.run_context_add_context(
context_type="Model", context_identifier="Profile", target_view="ELEVATION_VIEW", parent="model"
).should_be_called()
project.run_context_add_context(
context_type="Plan", context_identifier="", target_view="", parent=0
).should_be_called().will_return("plan")
project.run_context_add_context(
context_type="Plan", context_identifier="Axis", target_view="GRAPH_VIEW", parent="plan"
).should_be_called()
project.run_context_add_context(
context_type="Plan", context_identifier="Body", target_view="PLAN_VIEW", parent="plan"
).should_be_called()
project.run_context_add_context(
context_type="Plan", context_identifier="Annotation", target_view="PLAN_VIEW", parent="plan"
).should_be_called()
def test_create_an_ifc4_project(self, ifc, georeference, project, spatial):
ifc.get().should_be_called().will_return(None)
ifc.run("project.create_file", version="IFC4").should_be_called().will_return("ifc")
ifc.set("ifc").should_be_called()
project.create_empty("My Project").should_be_called().will_return("project")
project.create_empty("My Site").should_be_called().will_return("site")
project.create_empty("My Building").should_be_called().will_return("building")
project.create_empty("My Storey").should_be_called().will_return("storey")
project.run_root_assign_class(
obj="project", ifc_class="IfcProject", should_add_representation=False
).should_be_called()
project.run_unit_assign_scene_units().should_be_called()
self.check_contexts(project)
project.run_root_assign_class(obj="site", ifc_class="IfcSite", context="body").should_be_called()
project.run_root_assign_class(obj="building", ifc_class="IfcBuilding", context="body").should_be_called()
project.run_root_assign_class(obj="storey", ifc_class="IfcBuildingStorey", context="body").should_be_called()
project.run_aggregate_assign_object(relating_obj="project", related_obj="site").should_be_called()
project.run_aggregate_assign_object(relating_obj="site", related_obj="building").should_be_called()
project.run_aggregate_assign_object(relating_obj="building", related_obj="storey").should_be_called()
project.set_context("body").should_be_called()
spatial.run_spatial_import_spatial_decomposition().should_be_called()
spatial.guess_default_container().should_be_called().will_return(None)
project.load_default_thumbnails().should_be_called()
project.set_default_context().should_be_called()
project.set_default_modeling_dimensions().should_be_called()
georeference.set_model_origin().should_be_called()
subject.create_project(ifc, georeference, project, spatial, schema="IFC4", template=None)
def test_create_an_ifc4_project_with_guessing_default_container(self, ifc, georeference, project, spatial):
ifc.get().should_be_called().will_return(None)
ifc.run("project.create_file", version="IFC4").should_be_called().will_return("ifc")
ifc.set("ifc").should_be_called()
project.create_empty("My Project").should_be_called().will_return("project")
project.create_empty("My Site").should_be_called().will_return("site")
project.create_empty("My Building").should_be_called().will_return("building")
project.create_empty("My Storey").should_be_called().will_return("storey")
project.run_root_assign_class(
obj="project", ifc_class="IfcProject", should_add_representation=False
).should_be_called()
project.run_unit_assign_scene_units().should_be_called()
self.check_contexts(project)
project.run_root_assign_class(obj="site", ifc_class="IfcSite", context="body").should_be_called()
project.run_root_assign_class(obj="building", ifc_class="IfcBuilding", context="body").should_be_called()
project.run_root_assign_class(obj="storey", ifc_class="IfcBuildingStorey", context="body").should_be_called()
project.run_aggregate_assign_object(relating_obj="project", related_obj="site").should_be_called()
project.run_aggregate_assign_object(relating_obj="site", related_obj="building").should_be_called()
project.run_aggregate_assign_object(relating_obj="building", related_obj="storey").should_be_called()
project.set_context("body").should_be_called()
spatial.run_spatial_import_spatial_decomposition().should_be_called()
spatial.guess_default_container().should_be_called().will_return("default_container")
spatial.set_default_container("default_container").should_be_called()
project.load_default_thumbnails().should_be_called()
project.set_default_context().should_be_called()
project.set_default_modeling_dimensions().should_be_called()
georeference.set_model_origin().should_be_called()
subject.create_project(ifc, georeference, project, spatial, schema="IFC4", template=None)
def test_appending_project_template_types_if_specified(self, ifc, georeference, project, spatial):
ifc.get().should_be_called().will_return(None)
ifc.run("project.create_file", version="IFC4").should_be_called().will_return("ifc")
ifc.set("ifc").should_be_called()
project.create_empty("My Project").should_be_called().will_return("project")
project.create_empty("My Site").should_be_called().will_return("site")
project.create_empty("My Building").should_be_called().will_return("building")
project.create_empty("My Storey").should_be_called().will_return("storey")
project.run_root_assign_class(
obj="project", ifc_class="IfcProject", should_add_representation=False
).should_be_called()
project.run_unit_assign_scene_units().should_be_called()
self.check_contexts(project)
project.run_root_assign_class(obj="site", ifc_class="IfcSite", context="body").should_be_called()
project.run_root_assign_class(obj="building", ifc_class="IfcBuilding", context="body").should_be_called()
project.run_root_assign_class(obj="storey", ifc_class="IfcBuildingStorey", context="body").should_be_called()
project.run_aggregate_assign_object(relating_obj="project", related_obj="site").should_be_called()
project.run_aggregate_assign_object(relating_obj="site", related_obj="building").should_be_called()
project.run_aggregate_assign_object(relating_obj="building", related_obj="storey").should_be_called()
project.set_context("body").should_be_called()
spatial.run_spatial_import_spatial_decomposition().should_be_called()
spatial.guess_default_container().should_be_called().will_return(None)
project.append_all_types_from_template("template").should_be_called()
project.load_default_thumbnails().should_be_called()
project.set_default_context().should_be_called()
project.set_default_modeling_dimensions().should_be_called()
georeference.set_model_origin().should_be_called()
subject.create_project(ifc, georeference, project, spatial, schema="IFC4", template="template")
def test_create_an_ifc2x3_project_with_owner_defaults(self, ifc, georeference, project, spatial):
ifc.get().should_be_called().will_return(None)
ifc.run("project.create_file", version="IFC2X3").should_be_called().will_return("ifc")
ifc.set("ifc").should_be_called()
project.run_owner_add_person().should_be_called().will_return("person")
project.run_owner_add_organisation().should_be_called().will_return("organisation")
project.run_owner_add_person_and_organisation(
person="person", organisation="organisation"
).should_be_called().will_return("user")
project.run_owner_set_user(user="user").should_be_called()
project.create_empty("My Project").should_be_called().will_return("project")
project.create_empty("My Site").should_be_called().will_return("site")
project.create_empty("My Building").should_be_called().will_return("building")
project.create_empty("My Storey").should_be_called().will_return("storey")
project.run_root_assign_class(
obj="project", ifc_class="IfcProject", should_add_representation=False
).should_be_called()
project.run_unit_assign_scene_units().should_be_called()
self.check_contexts(project)
project.run_root_assign_class(obj="site", ifc_class="IfcSite", context="body").should_be_called()
project.run_root_assign_class(obj="building", ifc_class="IfcBuilding", context="body").should_be_called()
project.run_root_assign_class(obj="storey", ifc_class="IfcBuildingStorey", context="body").should_be_called()
project.run_aggregate_assign_object(relating_obj="project", related_obj="site").should_be_called()
project.run_aggregate_assign_object(relating_obj="site", related_obj="building").should_be_called()
project.run_aggregate_assign_object(relating_obj="building", related_obj="storey").should_be_called()
project.set_context("body").should_be_called()
spatial.run_spatial_import_spatial_decomposition().should_be_called()
spatial.guess_default_container().should_be_called().will_return(None)
project.load_default_thumbnails().should_be_called()
project.set_default_context().should_be_called()
project.set_default_modeling_dimensions().should_be_called()
georeference.set_model_origin().should_be_called()
subject.create_project(ifc, georeference, project, spatial, schema="IFC2X3", template=None)
+62
View File
@@ -0,0 +1,62 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.pset as subject
from test.core.bootstrap import ifc, pset
class TestCopyPropertyToSelection:
def test_doing_nothing_if_object_is_not_an_element(self, ifc, pset):
ifc.get_entity("obj").should_be_called().will_return(None)
subject.copy_property_to_selection(
ifc, pset, is_pset=True, obj="obj", pset_name="pset_name", prop_name="prop_name", prop_value="prop_value"
)
def test_copying_the_property_to_an_existing_pset(self, ifc, pset):
ifc.get_entity("obj").should_be_called().will_return("element")
pset.get_element_pset("element", "pset_name").should_be_called().will_return("pset")
ifc.run("pset.edit_pset", pset="pset", properties={"prop_name": "prop_value"}).should_be_called()
subject.copy_property_to_selection(
ifc, pset, is_pset=True, obj="obj", pset_name="pset_name", prop_name="prop_name", prop_value="prop_value"
)
def test_creating_a_new_pset_if_it_doesnt_exist(self, ifc, pset):
ifc.get_entity("obj").should_be_called().will_return("element")
pset.get_element_pset("element", "pset_name").should_be_called().will_return(None)
ifc.run("pset.add_pset", product="element", name="pset_name").should_be_called().will_return("pset")
ifc.run("pset.edit_pset", pset="pset", properties={"prop_name": "prop_value"}).should_be_called()
subject.copy_property_to_selection(
ifc, pset, is_pset=True, obj="obj", pset_name="pset_name", prop_name="prop_name", prop_value="prop_value"
)
def test_copying_the_quantity_to_an_existing_qto(self, ifc, pset):
ifc.get_entity("obj").should_be_called().will_return("element")
pset.get_element_pset("element", "qto_name").should_be_called().will_return("qto")
ifc.run("pset.edit_qto", qto="qto", properties={"prop_name": "prop_value"}).should_be_called()
subject.copy_property_to_selection(
ifc, pset, is_pset=False, obj="obj", pset_name="qto_name", prop_name="prop_name", prop_value="prop_value"
)
def test_creating_a_new_qto_if_it_doesnt_exist(self, ifc, pset):
ifc.get_entity("obj").should_be_called().will_return("element")
pset.get_element_pset("element", "qto_name").should_be_called().will_return(None)
ifc.run("pset.add_qto", product="element", name="qto_name").should_be_called().will_return("qto")
ifc.run("pset.edit_qto", qto="qto", properties={"prop_name": "prop_value"}).should_be_called()
subject.copy_property_to_selection(
ifc, pset, is_pset=False, obj="obj", pset_name="qto_name", prop_name="prop_name", prop_value="prop_value"
)
+27
View File
@@ -0,0 +1,27 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.qto as subject
from test.core.bootstrap import qto
class TestCalculateCircleRadius:
def test_run(self, qto):
qto.get_radius_of_selected_vertices("obj").should_be_called().will_return("radius")
qto.set_qto_result("radius").should_be_called()
assert subject.calculate_circle_radius(qto, obj="obj") == "radius"
+204
View File
@@ -0,0 +1,204 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.root as subject
import test.core.test_geometry
from test.core.bootstrap import ifc, collector, geometry, root
class TestCopyClass:
def test_doing_nothing_if_not_an_ifc_element(self, ifc, collector, root):
ifc.get_entity("obj").should_be_called().will_return(None)
subject.copy_class(ifc, collector, geometry, root, obj="obj")
def test_copy_with_new_geometry_derived_from_the_type(self, ifc, collector, root):
ifc.get_entity("obj").should_be_called().will_return("original_element")
root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(False)
root.get_object_representation("obj").should_be_called().will_return("representation")
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
ifc.link("element", "obj").should_be_called()
root.get_element_type("element").should_be_called().will_return("type")
root.does_type_have_representations("type").should_be_called().will_return(True)
ifc.run("type.map_type_representations", related_object="element", relating_type="type").should_be_called()
ifc.get_object("type").should_be_called().will_return("type_obj")
root.link_object_data("type_obj", "obj").should_be_called()
collector.assign("obj").should_be_called()
root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(False)
subject.copy_class(ifc, collector, geometry, root, obj="obj")
def test_copy_with_new_geometry_copied_from_the_old(self, ifc, collector, geometry, root):
# Originally, geometry was added fresh from the Blender mesh instead of
# copied. This was faster (though I cannot recreate it now) but had the
# bigger problem of not preserving non-mesh geometry and openings.
ifc.get_entity("obj").should_be_called().will_return("original_element")
root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(False)
root.get_object_representation("obj").should_be_called().will_return("representation")
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
ifc.link("element", "obj").should_be_called()
root.get_element_type("element").should_be_called().will_return("type")
root.does_type_have_representations("type").should_be_called().will_return(False)
root.copy_representation("original_element", "element").should_be_called()
root.get_representation_context("representation").should_be_called().will_return("context")
root.get_element_representation("element", "context").should_be_called().will_return("new_representation")
geometry.change_object_data("obj", "data", is_global=True).should_be_called()
geometry.get_representation_name("new_representation").should_be_called().will_return("name")
geometry.rename_object("data", "name").should_be_called()
geometry.link("new_representation", "data").should_be_called()
root.assign_body_styles("element", "obj").should_be_called()
geometry.duplicate_object_data("obj").should_be_called().will_return("data")
collector.assign("obj").should_be_called()
root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(False)
subject.copy_class(ifc, collector, geometry, root, obj="obj")
def test_copy_with_no_new_geometry(self, ifc, collector, geometry, root):
ifc.get_entity("obj").should_be_called().will_return("original_element")
root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(False)
root.get_object_representation("obj").should_be_called().will_return(None)
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
ifc.link("element", "obj").should_be_called()
root.get_element_type("element").should_be_called().will_return("type")
root.does_type_have_representations("type").should_be_called().will_return(False)
collector.assign("obj").should_be_called()
root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(False)
subject.copy_class(ifc, collector, geometry, root, obj="obj")
def test_copied_openings_are_tracked_for_special_visualiation(self, ifc, collector, geometry, root):
ifc.get_entity("obj").should_be_called().will_return("original_element")
root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(False)
root.get_object_representation("obj").should_be_called().will_return(None)
ifc.run("root.copy_class", product="original_element").should_be_called().will_return("element")
ifc.link("element", "obj").should_be_called()
root.get_element_type("element").should_be_called().will_return("type")
root.does_type_have_representations("type").should_be_called().will_return(True)
ifc.run("type.map_type_representations", related_object="element", relating_type="type").should_be_called()
ifc.get_object("type").should_be_called().will_return("type_obj")
root.link_object_data("type_obj", "obj").should_be_called()
collector.assign("obj").should_be_called()
root.is_element_a("element", "IfcOpeningElement").should_be_called().will_return(True)
root.add_tracked_opening("obj").should_be_called()
subject.copy_class(ifc, collector, geometry, root, obj="obj")
def test_copying_boundaries_are_dealt_with_specially(self, ifc, collector, geometry, root):
ifc.get_entity("obj").should_be_called().will_return("original_element")
root.is_element_a("original_element", "IfcRelSpaceBoundary").should_be_called().will_return(True)
ifc.run("boundary.copy_boundary", boundary="original_element").should_be_called().will_return("element")
ifc.link("element", "obj").should_be_called()
assert subject.copy_class(ifc, collector, geometry, root, obj="obj") == "element"
class TestAssignClass:
def test_do_nothing_if_already_assigned(self, ifc, collector, root):
ifc.get_entity("obj").should_be_called().will_return("entity")
subject.assign_class(
ifc,
collector,
root,
obj="obj",
ifc_class="ifc_class",
predefined_type="predefined_type",
should_add_representation=True,
context="context",
ifc_representation_class="ifc_representation_class",
)
def test_assign_a_class_with_geometry_and_autodetected_spatial_container_spatial_element(
self, ifc, collector, root
):
ifc.get_entity("obj").should_be_called().will_return(None)
root.get_object_name("obj").should_be_called().will_return("name")
ifc.run(
"root.create_entity", ifc_class="ifc_class", predefined_type="predefined_type", name="name"
).should_be_called().will_return("element")
root.set_object_name("obj", "element").should_be_called()
ifc.link("element", "obj").should_be_called()
root.run_geometry_add_representation(
obj="obj", context="context", ifc_representation_class="ifc_representation_class", profile_set_usage=None
).should_be_called()
root.get_default_container().should_be_called().will_return("default_container")
root.is_spatial_element("element").should_be_called().will_return(True)
ifc.run("aggregate.assign_object", products=["element"], relating_object="default_container").should_be_called()
collector.assign("obj").should_be_called()
subject.assign_class(
ifc,
collector,
root,
obj="obj",
ifc_class="ifc_class",
predefined_type="predefined_type",
should_add_representation=True,
context="context",
ifc_representation_class="ifc_representation_class",
)
def test_assign_a_class_with_geometry_and_autodetected_spatial_container_non_spatial_containable(
self, ifc, collector, root
):
ifc.get_entity("obj").should_be_called().will_return(None)
root.get_object_name("obj").should_be_called().will_return("name")
ifc.run(
"root.create_entity", ifc_class="ifc_class", predefined_type="predefined_type", name="name"
).should_be_called().will_return("element")
root.set_object_name("obj", "element").should_be_called()
ifc.link("element", "obj").should_be_called()
root.run_geometry_add_representation(
obj="obj", context="context", ifc_representation_class="ifc_representation_class", profile_set_usage=None
).should_be_called()
root.get_default_container().should_be_called().will_return("default_container")
root.is_spatial_element("element").should_be_called().will_return(False)
root.is_containable("element").should_be_called().will_return(True)
ifc.run(
"spatial.assign_container", products=["element"], relating_structure="default_container"
).should_be_called()
collector.assign("obj").should_be_called()
subject.assign_class(
ifc,
collector,
root,
obj="obj",
ifc_class="ifc_class",
predefined_type="predefined_type",
should_add_representation=True,
context="context",
ifc_representation_class="ifc_representation_class",
)
def test_not_adding_a_representation_if_requested_no_default_container(self, ifc, collector, root):
ifc.get_entity("obj").should_be_called().will_return(None)
root.get_object_name("obj").should_be_called().will_return("name")
ifc.run(
"root.create_entity", ifc_class="ifc_class", predefined_type="predefined_type", name="name"
).should_be_called().will_return("element")
root.set_object_name("obj", "element").should_be_called()
ifc.link("element", "obj").should_be_called()
root.get_default_container().should_be_called().will_return(None)
collector.assign("obj").should_be_called()
subject.assign_class(
ifc,
collector,
root,
obj="obj",
ifc_class="ifc_class",
predefined_type="predefined_type",
should_add_representation=False,
context="context",
ifc_representation_class="ifc_representation_class",
)
+57
View File
@@ -0,0 +1,57 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.sequence as subject
from test.core.bootstrap import ifc, sequence
class TestAddWorkPlan:
def test_run(self, ifc):
ifc.run("sequence.add_work_plan").should_be_called().will_return("work_plan")
assert subject.add_work_plan(ifc) == "work_plan"
class TestRemoveWorkPlan:
def test_run(self, ifc):
ifc.run("sequence.remove_work_plan", work_plan="work_plan").should_be_called()
subject.remove_work_plan(ifc, work_plan="work_plan")
class TestEnableEditingWorkPlan:
def test_run(self, sequence):
sequence.load_work_plan_attributes("work_plan").should_be_called()
sequence.enable_editing_work_plan("work_plan").should_be_called()
subject.enable_editing_work_plan(sequence, work_plan="work_plan")
class TestDisableEditingWorkPlan:
def test_run(self, sequence):
sequence.disable_editing_work_plan().should_be_called()
subject.disable_editing_work_plan(sequence)
class TestEditWorkPlan:
def test_run(self, ifc, sequence):
sequence.get_work_plan_attributes().should_be_called().will_return("attributes")
ifc.run("sequence.edit_work_plan", work_plan="work_plan", attributes="attributes").should_be_called()
sequence.disable_editing_work_plan().should_be_called()
subject.edit_work_plan(ifc, sequence, work_plan="work_plan")
# TODO continue writing tests
+120
View File
@@ -0,0 +1,120 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.spatial as subject
from test.core.bootstrap import ifc, collector, spatial
class TestReferenceStructure:
def test_run(self, ifc, spatial):
spatial.can_reference("structure", "element").should_be_called().will_return(True)
ifc.run("spatial.reference_structure", products=["element"], relating_structure="structure").should_be_called()
subject.reference_structure(ifc, spatial, structure="structure", element="element")
class TestDereferenceStructure:
def test_run(self, ifc, spatial):
spatial.can_reference("structure", "element").should_be_called().will_return(True)
ifc.run(
"spatial.dereference_structure", products=["element"], relating_structure="structure"
).should_be_called()
subject.dereference_structure(ifc, spatial, structure="structure", element="element")
class TestAssignContainer:
def test_run(self, ifc, collector, spatial):
spatial.can_contain("container", "element_obj").should_be_called().will_return(True)
ifc.get_entity("element_obj").should_be_called().will_return("element")
ifc.run(
"spatial.assign_container", products=["element"], relating_structure="container"
).should_be_called().will_return("rel")
spatial.disable_editing("element_obj").should_be_called()
collector.assign("element_obj").should_be_called()
assert (
subject.assign_container(ifc, collector, spatial, container="container", element_obj="element_obj") == "rel"
)
class TestEnableEditingContainer:
def test_run(self, spatial):
spatial.set_target_container_as_default().should_be_called()
spatial.enable_editing("obj").should_be_called()
subject.enable_editing_container(spatial, obj="obj")
class TestDisableEditingContainer:
def test_run(self, spatial):
spatial.disable_editing("obj").should_be_called()
subject.disable_editing_container(spatial, obj="obj")
class TestRemoveContainer:
def test_run(self, ifc, collector):
ifc.get_entity("obj").should_be_called().will_return("element")
ifc.run("spatial.unassign_container", products=["element"]).should_be_called()
collector.assign("obj").should_be_called()
subject.remove_container(ifc, collector, obj="obj")
class TestCopyToContainer:
def test_run(self, ifc, collector, spatial):
ifc.get_entity("obj").should_be_called().will_return("element")
spatial.get_container("element").should_be_called().will_return("container")
ifc.get_object("container").should_be_called().will_return("container_obj")
spatial.get_relative_object_matrix("obj", "container_obj").should_be_called().will_return("matrix")
ifc.get_object("to_container").should_be_called().will_return("to_container_obj")
spatial.duplicate_object_and_data("obj").should_be_called().will_return("new_obj")
spatial.set_relative_object_matrix("new_obj", "to_container_obj", "matrix").should_be_called()
spatial.run_root_copy_class(obj="new_obj").should_be_called()
spatial.run_spatial_assign_container(container="to_container", element_obj="new_obj").should_be_called()
spatial.disable_editing("obj").should_be_called()
subject.copy_to_container(ifc, collector, spatial, obj="obj", containers=["to_container"])
def test_using_an_absolute_matrix_if_there_is_no_from_container(self, ifc, collector, spatial):
ifc.get_entity("obj").should_be_called().will_return("element")
spatial.get_container("element").should_be_called().will_return(None)
spatial.get_object_matrix("obj").should_be_called().will_return("matrix")
ifc.get_object("to_container").should_be_called().will_return("to_container_obj")
spatial.duplicate_object_and_data("obj").should_be_called().will_return("new_obj")
spatial.set_relative_object_matrix("new_obj", "to_container_obj", "matrix").should_be_called()
spatial.run_root_copy_class(obj="new_obj").should_be_called()
spatial.run_spatial_assign_container(container="to_container", element_obj="new_obj").should_be_called()
spatial.disable_editing("obj").should_be_called()
subject.copy_to_container(ifc, collector, spatial, obj="obj", containers=["to_container"])
class TestSelectContainer:
def test_run(self, ifc, spatial):
ifc.get_object("container").should_be_called().will_return("container_obj")
spatial.set_active_object("container_obj").should_be_called()
subject.select_container(ifc, spatial, container="container")
class TestSelectSimilarContainer:
def test_run(self, ifc, spatial):
ifc.get_entity("obj").should_be_called().will_return("element")
spatial.get_container("element").should_be_called().will_return("container")
spatial.get_decomposed_elements("container").should_be_called().will_return(["contained_element"])
spatial.select_products(["contained_element"]).should_be_called()
subject.select_similar_container(ifc, spatial, obj="obj")
+231
View File
@@ -0,0 +1,231 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.style as subject
from test.core.bootstrap import ifc, material, style, spatial
class TestAddStyle:
def add_style_common(self, ifc, style):
style.get_name("obj").should_be_called().will_return("name")
ifc.run("style.add_style", name="name").should_be_called().will_return("element")
ifc.link("element", "obj").should_be_called()
def test_it_adds_a_style_with_rendering_attributes(self, ifc, style):
self.add_style_common(ifc, style)
style.can_support_rendering_style("obj").should_be_called().will_return(True)
style.get_surface_rendering_attributes("obj").should_be_called().will_return("attributes")
ifc.run(
"style.add_surface_style", style="element", ifc_class="IfcSurfaceStyleRendering", attributes="attributes"
).should_be_called()
assert subject.add_style(ifc, style, obj="obj") == "element"
def test_it_adds_a_style_with_shading_attributes(self, ifc, style):
self.add_style_common(ifc, style)
style.can_support_rendering_style("obj").should_be_called().will_return(False)
style.get_surface_shading_attributes("obj").should_be_called().will_return("attributes")
ifc.run(
"style.add_surface_style", style="element", ifc_class="IfcSurfaceStyleShading", attributes="attributes"
).should_be_called()
assert subject.add_style(ifc, style, obj="obj") == "element"
class TestRemoveStyle:
def remove_a_style_common(self, ifc, style):
ifc.get_object("style").should_be_called().will_return("obj")
ifc.unlink(element="style").should_be_called()
ifc.run("style.remove_style", style="style").should_be_called()
style.delete_object("obj").should_be_called()
style.get_active_style_type().should_be_called().will_return("style_type")
def test_removing_a_style(self, ifc, style):
self.remove_a_style_common(ifc, style)
style.is_editing_styles().should_be_called().will_return(False)
subject.remove_style(ifc, style, style="style")
def test_removing_a_style_and_reloading_imported_styles(self, ifc, style):
self.remove_a_style_common(ifc, style)
style.is_editing_styles().should_be_called().will_return(True)
style.import_presentation_styles("style_type").should_be_called()
subject.remove_style(ifc, style, style="style")
class TestUpdateStyleColours:
def test_updating_rendering_style_if_available(self, ifc, style):
style.get_style("obj").should_be_called().will_return("element")
style.can_support_rendering_style("obj").should_be_called().will_return(True)
style.get_surface_rendering_style("obj").should_be_called().will_return("rendering_style")
style.get_texture_style("obj").should_be_called().will_return("texture_style")
style.get_surface_rendering_attributes("obj", "verbose").should_be_called().will_return("attributes")
ifc.run("style.edit_surface_style", style="rendering_style", attributes="attributes").should_be_called()
ifc.run("style.add_surface_textures", material="obj").should_be_called().will_return("textures")
ifc.run(
"style.edit_surface_style", style="texture_style", attributes={"Textures": "textures"}
).should_be_called().will_return("textures")
subject.update_style_colours(ifc, style, obj="obj", verbose="verbose")
def test_adding_a_rendering_style_if_not_available(self, ifc, style):
style.get_style("obj").should_be_called().will_return("element")
style.can_support_rendering_style("obj").should_be_called().will_return(True)
style.get_surface_rendering_style("obj").should_be_called().will_return(None)
style.get_texture_style("obj").should_be_called().will_return(None)
style.get_surface_rendering_attributes("obj", "verbose").should_be_called().will_return("attributes")
ifc.run(
"style.add_surface_style", style="element", ifc_class="IfcSurfaceStyleRendering", attributes="attributes"
).should_be_called()
ifc.run("style.add_surface_textures", material="obj").should_be_called().will_return("textures")
ifc.run(
"style.add_surface_style",
style="element",
ifc_class="IfcSurfaceStyleWithTextures",
attributes={"Textures": "textures"},
).should_be_called()
subject.update_style_colours(ifc, style, obj="obj", verbose="verbose")
def test_updating_shading_style_as_a_fallback_if_available(self, ifc, style):
style.get_style("obj").should_be_called().will_return("element")
style.can_support_rendering_style("obj").should_be_called().will_return(False)
style.get_surface_shading_style("obj").should_be_called().will_return("style")
style.get_surface_shading_attributes("obj").should_be_called().will_return("attributes")
ifc.run("style.edit_surface_style", style="style", attributes="attributes").should_be_called()
subject.update_style_colours(ifc, style, obj="obj")
def test_adding_a_shading_style_as_a_fallback_if_not_available(self, ifc, style):
style.get_style("obj").should_be_called().will_return("element")
style.can_support_rendering_style("obj").should_be_called().will_return(False)
style.get_surface_shading_style("obj").should_be_called().will_return(None)
style.get_surface_shading_attributes("obj").should_be_called().will_return("attributes")
ifc.run(
"style.add_surface_style", style="element", ifc_class="IfcSurfaceStyleShading", attributes="attributes"
).should_be_called()
subject.update_style_colours(ifc, style, obj="obj")
class TestUpdateStyleTextures:
def test_updating_an_existing_texture_style(self, ifc, style):
style.get_style("obj").should_be_called().will_return("element")
style.get_uv_maps("representation").should_be_called().will_return("uv_maps")
ifc.run("style.add_surface_textures", material="obj", uv_maps="uv_maps").should_be_called().will_return(
"textures"
)
style.get_surface_texture_style("obj").should_be_called().will_return("style")
ifc.run("style.remove_surface_style", style="style").should_be_called()
ifc.run(
"style.add_surface_style",
style="element",
ifc_class="IfcSurfaceStyleWithTextures",
attributes={"Textures": "textures"},
).should_be_called()
subject.update_style_textures(ifc, style, obj="obj", representation="representation")
def test_adding_a_fresh_texture_style(self, ifc, style):
style.get_style("obj").should_be_called().will_return("element")
style.get_uv_maps("representation").should_be_called().will_return("uv_maps")
ifc.run("style.add_surface_textures", material="obj", uv_maps="uv_maps").should_be_called().will_return(
"textures"
)
style.get_surface_texture_style("obj").should_be_called().will_return(None)
ifc.run(
"style.add_surface_style",
style="element",
ifc_class="IfcSurfaceStyleWithTextures",
attributes={"Textures": "textures"},
).should_be_called()
subject.update_style_textures(ifc, style, obj="obj", representation="representation")
def test_removing_an_texture_if_no_textures_can_be_added(self, ifc, style):
style.get_style("obj").should_be_called().will_return("element")
style.get_uv_maps("representation").should_be_called().will_return("uv_maps")
ifc.run("style.add_surface_textures", material="obj", uv_maps="uv_maps").should_be_called().will_return(None)
style.get_surface_texture_style("obj").should_be_called().will_return("style")
ifc.run("style.remove_surface_style", style="style").should_be_called()
subject.update_style_textures(ifc, style, obj="obj", representation="representation")
def test_doing_nothing_if_no_existing_texture_and_we_cannot_add_a_new_texture(self, ifc, style):
style.get_style("obj").should_be_called().will_return("element")
style.get_uv_maps("representation").should_be_called().will_return("uv_maps")
ifc.run("style.add_surface_textures", material="obj", uv_maps="uv_maps").should_be_called().will_return(None)
style.get_surface_texture_style("obj").should_be_called().will_return(None)
subject.update_style_textures(ifc, style, obj="obj", representation="representation")
class TestUnlinkStyle:
def test_run(self, ifc):
ifc.unlink(element="style").should_be_called()
subject.unlink_style(ifc, style="style")
class TestEnableEditingStyle:
def test_run(self, style):
style.enable_editing("style_element").should_be_called()
style.import_surface_attributes("style_element").should_be_called()
subject.enable_editing_style(style, style="style_element")
class TestDisableEditingStyle:
def test_run(self, style):
style.get_currently_edited_material().should_be_called().will_return("obj")
style.reload_material_from_ifc("obj").should_be_called()
style.disable_editing().should_be_called()
style.reload_material_from_ifc("obj").should_be_called()
subject.disable_editing_style(style)
class TestEditStyle:
def test_run(self, ifc, style):
style.get_currently_edited_material().should_be_called().will_return("obj")
style.get_style("obj").should_be_called().will_return("style_element")
style.export_surface_attributes().should_be_called().will_return("attributes")
ifc.run("style.edit_presentation_style", style="style_element", attributes="attributes").should_be_called()
style.disable_editing().should_be_called()
style.get_active_style_type().should_be_called().will_return("style_type")
# Calling core.load_styles.
style.import_presentation_styles("style_type").should_be_called()
style.enable_editing_styles().should_be_called()
subject.edit_style(ifc, style)
class TestLoadStyles:
def test_run(self, style):
style.import_presentation_styles("style_type").should_be_called()
style.enable_editing_styles().should_be_called()
subject.load_styles(style, style_type="style_type")
class TestDisableEditingStyles:
def test_run(self, style):
style.disable_editing_styles().should_be_called()
subject.disable_editing_styles(style)
class TestSelectByStyle:
def test_run(self, style, spatial):
style.get_elements_by_style("style").should_be_called().will_return("elements")
spatial.select_products("elements").should_be_called()
subject.select_by_style(style, spatial, style="style")
+171
View File
@@ -0,0 +1,171 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.system as subject
from test.core.bootstrap import ifc, system, spatial
class TestLoadSystems:
def test_run(self, system):
system.import_systems().should_be_called()
system.enable_system_editing_ui().should_be_called()
system.disable_editing_system().should_be_called()
subject.load_systems(system)
class TestDisableSystemEditingUI:
def test_run(self, system):
system.disable_editing_system().should_be_called()
system.disable_system_editing_ui().should_be_called()
subject.disable_system_editing_ui(system)
class TestAddSystem:
def test_run(self, ifc, system):
ifc.run("system.add_system", ifc_class="ifc_class").should_be_called()
system.import_systems().should_be_called()
subject.add_system(ifc, system, ifc_class="ifc_class")
class TestEditSystem:
def test_run(self, ifc, system):
system.export_system_attributes().should_be_called().will_return("attributes")
ifc.run("system.edit_system", system="system", attributes="attributes").should_be_called()
system.disable_editing_system().should_be_called()
system.import_systems().should_be_called()
subject.edit_system(ifc, system, system="system")
class TestRemoveSystem:
def test_run(self, ifc, system):
ifc.run("system.remove_system", system="system").should_be_called()
system.import_systems().should_be_called()
subject.remove_system(ifc, system, system="system")
class TestEnableEditingSystem:
def test_run(self, system):
system.import_system_attributes("system").should_be_called()
system.set_active_edited_system("system").should_be_called()
subject.enable_editing_system(system, system="system")
class TestDisableEditingSystem:
def test_run(self, system):
system.disable_editing_system().should_be_called()
subject.disable_editing_system(system)
class TestAssignSystem:
def test_run(self, ifc):
ifc.run("system.assign_system", products=["product"], system="system").should_be_called()
subject.assign_system(ifc, system="system", product="product")
class TestUnassignSystem:
def test_run(self, ifc):
ifc.run("system.unassign_system", products=["product"], system="system").should_be_called()
subject.unassign_system(ifc, system="system", product="product")
class TestSelectSystemProducts:
def test_run(self, system):
system.select_system_products("system").should_be_called()
system.set_active_system("system").should_be_called()
subject.select_system_products(system, system="system")
class TestShowPorts:
def test_run(self, ifc, system, spatial):
ifc.get_object("element").should_be_called().will_return("obj")
ifc.is_moved("obj").should_be_called().will_return(False)
system.get_ports("element").should_be_called().will_return(["port"])
system.load_ports("element", ["port"]).should_be_called()
spatial.select_products(["port"]).should_be_called()
subject.show_ports(ifc, system, spatial, element="element")
def test_syncing_locations_if_objects_moved_prior_to_showing_ports(self, ifc, system, spatial):
ifc.get_object("element").should_be_called().will_return("obj")
ifc.is_moved("obj").should_be_called().will_return(True)
system.run_geometry_edit_object_placement(obj="obj").should_be_called()
system.get_ports("element").should_be_called().will_return(["port"])
system.load_ports("element", ["port"]).should_be_called()
spatial.select_products(["port"]).should_be_called()
subject.show_ports(ifc, system, spatial, element="element")
class TestHidePorts:
def test_run(self, ifc, system):
ifc.get_object("element").should_be_called().will_return("obj")
ifc.is_moved("obj").should_be_called().will_return(False)
system.get_ports("element").should_be_called().will_return(["port"])
ifc.get_object("port").should_be_called().will_return("port_obj")
ifc.is_moved("port_obj").should_be_called().will_return(True)
system.run_geometry_edit_object_placement(obj="port_obj").should_be_called()
system.delete_element_objects(["port"]).should_be_called()
subject.hide_ports(ifc, system, element="element")
def test_syncing_locations_if_objects_moved_prior_to_hiding_ports(self, ifc, system):
ifc.get_object("element").should_be_called().will_return("obj")
ifc.is_moved("obj").should_be_called().will_return(True)
system.run_geometry_edit_object_placement(obj="obj").should_be_called()
system.get_ports("element").should_be_called().will_return(["port"])
ifc.get_object("port").should_be_called().will_return("port_obj")
ifc.is_moved("port_obj").should_be_called().will_return(True)
system.run_geometry_edit_object_placement(obj="port_obj").should_be_called()
system.delete_element_objects(["port"]).should_be_called()
subject.hide_ports(ifc, system, element="element")
class TestAddPort:
def test_run(self, ifc, system):
system.get_ports("element").should_be_called().will_return(["port"])
system.load_ports("element", ["port"]).should_be_called()
system.create_empty_at_cursor_with_element_orientation("element").should_be_called().will_return("obj")
system.run_root_assign_class(
obj="obj", ifc_class="IfcDistributionPort", should_add_representation=False
).should_be_called().will_return("port")
ifc.run("system.assign_port", element="element", port="port").should_be_called()
subject.add_port(ifc, system, element="element")
class TestRemovePort:
def test_run(self, ifc, system):
system.delete_element_objects(["port"]).should_be_called()
ifc.run("root.remove_product", product="port").should_be_called()
subject.remove_port(ifc, system, port="port")
class TestSetFlowDirection:
def test_run(self, ifc, system):
system.get_connected_port("port").should_be_called().will_return("port2")
ifc.run("system.connect_port", port1="port", port2="port2", direction="direction").should_be_called()
subject.set_flow_direction(ifc, system, port="port", direction="direction")
def test_do_not_set_a_direction_if_port_is_not_connected(self, ifc, system):
system.get_connected_port("port").should_be_called().will_return(None)
subject.set_flow_direction(ifc, system, port="port", direction="direction")
+57
View File
@@ -0,0 +1,57 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.type as subject
from test.core.bootstrap import ifc, type, geometry
class TestAssignType:
def test_assigning_and_switching_to_an_existing_type_data(self, ifc, type):
ifc.run("type.assign_type", related_objects=["element"], relating_type="type").should_be_called()
type.has_material_usage("element").should_be_called().will_return(False)
ifc.get_object("type").should_be_called().will_return("type_obj")
type.get_object_data("type_obj").should_be_called().will_return("type_obj_data")
type.change_object_data("obj", "type_obj_data", is_global=False).should_be_called()
ifc.get_object("element").should_be_called().will_return("obj")
type.disable_editing("obj").should_be_called()
subject.assign_type(ifc, type, element="element", type="type")
def test_assigning_and_not_changing_data_if_the_type_has_no_data(self, ifc, type):
ifc.run("type.assign_type", related_objects=["element"], relating_type="type").should_be_called()
type.has_material_usage("element").should_be_called().will_return(False)
ifc.get_object("type").should_be_called().will_return("type_obj")
type.get_object_data("type_obj").should_be_called().will_return(None)
ifc.get_object("element").should_be_called().will_return("obj")
type.disable_editing("obj").should_be_called()
subject.assign_type(ifc, type, element="element", type="type")
class TestPurgeUnusedTypes:
def test_purge_types_obj_found(self, ifc, type, geometry):
type.get_model_types().should_be_called().will_return(["element_type"])
type.get_type_occurrences("element_type").should_be_called().will_return([])
ifc.get_object("element_type").should_be_called().will_return("obj")
geometry.delete_ifc_object("obj").should_be_called()
subject.purge_unused_types(ifc, type, geometry)
def test_purge_types_obj_not_found(self, ifc, type, geometry):
type.get_model_types().should_be_called().will_return(["element_type"])
type.get_type_occurrences("element_type").should_be_called().will_return([])
ifc.get_object("element_type").should_be_called().will_return(None)
ifc.run("root.remove_product", product="element_type").should_be_called()
subject.purge_unused_types(ifc, type, geometry)
+164
View File
@@ -0,0 +1,164 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
#
# This file is part of Bonsai.
#
# Bonsai 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.
#
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blenderbim.core.unit as subject
from test.core.bootstrap import ifc, unit
class TestAssignSceneUnits:
def test_creating_and_assigning_metric_units(self, ifc, unit):
unit.is_scene_unit_metric().should_be_called().will_return(True)
unit.get_scene_unit_si_prefix("LENGTHUNIT").should_be_called().will_return("prefix")
unit.get_scene_unit_si_prefix("AREAUNIT").should_be_called().will_return("prefix")
unit.get_scene_unit_si_prefix("VOLUMEUNIT").should_be_called().will_return("prefix")
ifc.run("unit.add_si_unit", unit_type="LENGTHUNIT", prefix="prefix").should_be_called().will_return(
"lengthunit"
)
ifc.run("unit.add_si_unit", unit_type="AREAUNIT", prefix="prefix").should_be_called().will_return("areaunit")
ifc.run("unit.add_si_unit", unit_type="VOLUMEUNIT", prefix="prefix").should_be_called().will_return(
"volumeunit"
)
ifc.run("unit.add_conversion_based_unit", name="degree").should_be_called().will_return("planeangleunit")
ifc.run("unit.assign_unit", units=["lengthunit", "areaunit", "volumeunit", "planeangleunit"]).should_be_called()
subject.assign_scene_units(ifc, unit)
def test_creating_and_assigning_imperial_units(self, ifc, unit):
unit.is_scene_unit_metric().should_be_called().will_return(False)
unit.get_scene_unit_name("LENGTHUNIT").should_be_called().will_return("lengthname")
ifc.run("unit.add_conversion_based_unit", name="lengthname").should_be_called().will_return("lengthunit")
unit.get_scene_unit_name("AREAUNIT").should_be_called().will_return("areaname")
ifc.run("unit.add_conversion_based_unit", name="areaname").should_be_called().will_return("areaunit")
unit.get_scene_unit_name("VOLUMEUNIT").should_be_called().will_return("volumename")
ifc.run("unit.add_conversion_based_unit", name="volumename").should_be_called().will_return("volumeunit")
ifc.run("unit.add_conversion_based_unit", name="degree").should_be_called().will_return("planeangleunit")
ifc.run("unit.assign_unit", units=["lengthunit", "areaunit", "volumeunit", "planeangleunit"]).should_be_called()
subject.assign_scene_units(ifc, unit)
class TestAssignUnit:
def test_run(self, ifc, unit):
ifc.run("unit.assign_unit", units=["unit"]).should_be_called()
unit.import_units().should_be_called()
subject.assign_unit(ifc, unit, unit="unit")
class TestUnassignUnit:
def test_run(self, ifc, unit):
ifc.run("unit.unassign_unit", units=["unit"]).should_be_called()
unit.import_units().should_be_called()
subject.unassign_unit(ifc, unit, unit="unit")
class TestLoadUnits:
def test_run(self, unit):
unit.import_units().should_be_called()
unit.enable_editing_units().should_be_called()
subject.load_units(unit)
class TestDisableUnitEditingUI:
def test_run(self, unit):
unit.disable_editing_units().should_be_called()
subject.disable_unit_editing_ui(unit)
class TestRemoveUnit:
def test_run(self, ifc, unit):
ifc.run("unit.remove_unit", unit="unit").should_be_called()
unit.import_units().should_be_called()
subject.remove_unit(ifc, unit, unit="unit")
class TestAddMonetaryUnit:
def test_run(self, ifc, unit):
ifc.run("unit.add_monetary_unit").should_be_called().will_return("unit")
unit.import_units().should_be_called()
assert subject.add_monetary_unit(ifc, unit) == "unit"
class TestAddSIUnit:
def test_run(self, ifc, unit):
ifc.run("unit.add_si_unit", unit_type="unit_type").should_be_called().will_return("unit")
unit.import_units().should_be_called()
assert subject.add_si_unit(ifc, unit, unit_type="unit_type") == "unit"
class TestAddContextDependentUnit:
def test_run(self, ifc, unit):
ifc.run("unit.add_context_dependent_unit", unit_type="unit_type", name="name").should_be_called().will_return(
"unit"
)
unit.import_units().should_be_called()
assert subject.add_context_dependent_unit(ifc, unit, unit_type="unit_type", name="name") == "unit"
class TestAddConversionBasedUnit:
def test_run(self, ifc, unit):
ifc.run("unit.add_conversion_based_unit", name="name").should_be_called().will_return("unit")
unit.import_units().should_be_called()
assert subject.add_conversion_based_unit(ifc, unit, name="name") == "unit"
class TestEnableEditingUnit:
def test_run(self, unit):
unit.set_active_unit("unit").should_be_called()
unit.import_unit_attributes("unit").should_be_called()
subject.enable_editing_unit(unit, unit="unit")
class TestDisableEditingUnit:
def test_run(self, unit):
unit.clear_active_unit().should_be_called()
subject.disable_editing_unit(unit)
class TestEditUnit:
def test_editing_monetary_units(self, ifc, unit):
unit.export_unit_attributes().should_be_called().will_return("attributes")
unit.is_unit_class("unit", "IfcMonetaryUnit").should_be_called().will_return(True)
ifc.run("unit.edit_monetary_unit", unit="unit", attributes="attributes").should_be_called()
unit.import_units().should_be_called()
unit.clear_active_unit().should_be_called()
subject.edit_unit(ifc, unit, unit="unit")
def test_editing_derived_units(self, ifc, unit):
unit.export_unit_attributes().should_be_called().will_return("attributes")
unit.is_unit_class("unit", "IfcMonetaryUnit").should_be_called().will_return(False)
unit.is_unit_class("unit", "IfcDerivedUnit").should_be_called().will_return(True)
ifc.run("unit.edit_derived_unit", unit="unit", attributes="attributes").should_be_called()
unit.import_units().should_be_called()
unit.clear_active_unit().should_be_called()
subject.edit_unit(ifc, unit, unit="unit")
def test_editing_named_units(self, ifc, unit):
unit.export_unit_attributes().should_be_called().will_return("attributes")
unit.is_unit_class("unit", "IfcMonetaryUnit").should_be_called().will_return(False)
unit.is_unit_class("unit", "IfcDerivedUnit").should_be_called().will_return(False)
unit.is_unit_class("unit", "IfcNamedUnit").should_be_called().will_return(True)
ifc.run("unit.edit_named_unit", unit="unit", attributes="attributes").should_be_called()
unit.import_units().should_be_called()
unit.clear_active_unit().should_be_called()
subject.edit_unit(ifc, unit, unit="unit")