From c7428dd1604ccd259180472b683c8c9cbb236b6d Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 30 Jan 2022 14:42:26 +1100 Subject: [PATCH] Fix bug where syncing an object removed from the collection tree breaks. --- .../blenderbim/bim/module/spatial/ui.py | 2 +- src/blenderbim/blenderbim/tool/collector.py | 3 + src/blenderbim/test/bim/feature/demo.feature | 77 ++++++++++--------- src/blenderbim/test/bim/test_feature.py | 2 +- src/blenderbim/test/core/test_demo.py | 7 ++ src/blenderbim/test/tool/test_brick.py | 8 +- src/blenderbim/test/tool/test_collector.py | 8 ++ src/blenderbim/test/tool/test_demo.py | 7 ++ 8 files changed, 71 insertions(+), 43 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/spatial/ui.py b/src/blenderbim/blenderbim/bim/module/spatial/ui.py index a944b45a3b..8f0e78ecf4 100644 --- a/src/blenderbim/blenderbim/bim/module/spatial/ui.py +++ b/src/blenderbim/blenderbim/bim/module/spatial/ui.py @@ -27,7 +27,7 @@ class BIM_PT_spatial(Panel): bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "object" - bl_parent_id = "BIM_PT_geometry_object" + bl_parent_id = "BIM_PT_object_metadata" @classmethod def poll(cls, context): diff --git a/src/blenderbim/blenderbim/tool/collector.py b/src/blenderbim/blenderbim/tool/collector.py index b17ed8bd68..0e09c72bac 100644 --- a/src/blenderbim/blenderbim/tool/collector.py +++ b/src/blenderbim/blenderbim/tool/collector.py @@ -32,6 +32,9 @@ class Collector(blenderbim.core.tool.Collector): if element.is_a("IfcProject") or element.is_a("IfcGridAxis"): return + if not obj.users_collection: + return + object_collection = None collection_collection = None diff --git a/src/blenderbim/test/bim/feature/demo.feature b/src/blenderbim/test/bim/feature/demo.feature index 637b38cae6..616ee06352 100644 --- a/src/blenderbim/test/bim/feature/demo.feature +++ b/src/blenderbim/test/bim/feature/demo.feature @@ -5,41 +5,44 @@ # ############################################################################ # -# This allows us to write full integration tests that test how all systems work -# as a whole. Whilst other tests focus on portions of the software, these tests -# simulate what happens when a user opens Blender, presses buttons, and does -# things. +# Note: these tests are commented out as they are for learning purposes only. If +# you want to run these tests, uncomment it :) -# These tests read like english. You can see all the possible sentences defined -# in test_feature.py. Most of the time, there is already a sentence defined for -# what you want to test. - -@demo -Feature: Demo - -# Every operator has at least one scenario associated with it to test it. -Scenario: Demonstrate hello world - Given an empty IFC project - When I press "bim.demonstrate_hello_world" - # Blender doesn't have a way of testing that things are visible in the - # interface and layout. We can check properties, and whats in the 3D - # scenegraph, but not layout. There is no "DOM" like in web applications. - # Too bad, we can't check the results, but we still write the test, that way - # we can still check for errors like crashes or Python errors, like a "smoke - # test". - Then nothing happens - -# This operator has two scenarios because there are two possibilities of a user -# interacting with it. -Scenario: Demonstrate rename project - with a name provided - Given an empty IFC project - When I set "scene.BIMDemoProperties.name" to "Foobar" - And I press "bim.demonstrate_rename_project" - Then the object "IfcProject/Foobar" is an "IfcProject" - -# This is the other possible scenario for the rename project operator. -Scenario: Demonstrate rename project - with no name - Given an empty IFC project - When I set "scene.BIMDemoProperties.name" to "" - And I press "bim.demonstrate_rename_project" - Then the object "IfcProject/My Project" is an "IfcProject" +#|# This allows us to write full integration tests that test how all systems work +#|# as a whole. Whilst other tests focus on portions of the software, these tests +#|# simulate what happens when a user opens Blender, presses buttons, and does +#|# things. +#| +#|# These tests read like english. You can see all the possible sentences defined +#|# in test_feature.py. Most of the time, there is already a sentence defined for +#|# what you want to test. +#| +#|@demo +#|Feature: Demo +#| +#|# Every operator has at least one scenario associated with it to test it. +#|Scenario: Demonstrate hello world +#| Given an empty IFC project +#| When I press "bim.demonstrate_hello_world" +#| # Blender doesn't have a way of testing that things are visible in the +#| # interface and layout. We can check properties, and whats in the 3D +#| # scenegraph, but not layout. There is no "DOM" like in web applications. +#| # Too bad, we can't check the results, but we still write the test, that way +#| # we can still check for errors like crashes or Python errors, like a "smoke +#| # test". +#| Then nothing happens +#| +#|# This operator has two scenarios because there are two possibilities of a user +#|# interacting with it. +#|Scenario: Demonstrate rename project - with a name provided +#| Given an empty IFC project +#| When I set "scene.BIMDemoProperties.name" to "Foobar" +#| And I press "bim.demonstrate_rename_project" +#| Then the object "IfcProject/Foobar" is an "IfcProject" +#| +#|# This is the other possible scenario for the rename project operator. +#|Scenario: Demonstrate rename project - with no name +#| Given an empty IFC project +#| When I set "scene.BIMDemoProperties.name" to "" +#| And I press "bim.demonstrate_rename_project" +#| Then the object "IfcProject/My Project" is an "IfcProject" diff --git a/src/blenderbim/test/bim/test_feature.py b/src/blenderbim/test/bim/test_feature.py index dc014ca8b9..c28da88105 100644 --- a/src/blenderbim/test/bim/test_feature.py +++ b/src/blenderbim/test/bim/test_feature.py @@ -184,7 +184,7 @@ def the_object_name_is_placed_in_the_collection_collection(name, collection): def additionally_the_object_name_is_selected(name): obj = bpy.context.scene.objects.get(name) if not obj: - assert False, 'The object "{name}" could not be selected' + assert False, f'The object "{name}" could not be selected' bpy.context.view_layer.objects.active = obj obj.select_set(True) diff --git a/src/blenderbim/test/core/test_demo.py b/src/blenderbim/test/core/test_demo.py index 786e6fd3b2..f435bea39a 100644 --- a/src/blenderbim/test/core/test_demo.py +++ b/src/blenderbim/test/core/test_demo.py @@ -23,6 +23,11 @@ # ############################################################################ # +# 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 @@ -82,3 +87,5 @@ class TestDemonstrateRenameProject: 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) + +""" diff --git a/src/blenderbim/test/tool/test_brick.py b/src/blenderbim/test/tool/test_brick.py index 7fd59987d4..1fc2a9b962 100644 --- a/src/blenderbim/test/tool/test_brick.py +++ b/src/blenderbim/test/tool/test_brick.py @@ -37,8 +37,8 @@ class TestImplementsTool(NewFile): class TestAddBrick(NewFile): def test_run(self): BrickStore.graph = brickschema.Graph() - result = subject.add_brick("http://example.org/digitaltwin#", "https://brickschema.org/schema/Brick#Equipment") - assert "http://example.org/digitaltwin#" in result + result = subject.add_brick("https://example.org/digitaltwin#", "https://brickschema.org/schema/Brick#Equipment") + assert "https://example.org/digitaltwin#" in result assert list( BrickStore.graph.triples( (URIRef(result), RDF.type, URIRef("https://brickschema.org/schema/Brick#Equipment")) @@ -250,7 +250,7 @@ class TestGetConvertableBrickElements(NewFile): class TestGetItemClass(NewFile): def test_run(self): TestLoadBrickFile().test_run() - assert subject.get_item_class("http://example.org/digitaltwin#floor") == "Floor" + assert subject.get_item_class("https://example.org/digitaltwin#floor") == "Floor" class TestGetLibraryBrickReference(NewFile): @@ -300,7 +300,7 @@ class TestImportBrickItems(NewFile): brick = bpy.context.scene.BIMBrickProperties.bricks[0] assert brick.name == "bldg" assert brick.label == "My Building" - assert brick.uri == "http://example.org/digitaltwin#bldg" + assert brick.uri == "https://example.org/digitaltwin#bldg" assert brick.total_items == 0 diff --git a/src/blenderbim/test/tool/test_collector.py b/src/blenderbim/test/tool/test_collector.py index faf7aa523c..ff16ae60e3 100644 --- a/src/blenderbim/test/tool/test_collector.py +++ b/src/blenderbim/test/tool/test_collector.py @@ -249,6 +249,14 @@ class TestAssign(NewFile): class TestSync(NewFile): + def test_doing_nothing_if_the_object_has_no_collection(self): + bpy.ops.bim.create_project() + wall_obj = bpy.data.objects.new("Object", None) + wall_element = tool.Ifc.get().createIfcWall() + tool.Ifc.link(wall_element, wall_obj) + subject.sync(wall_obj) + assert not wall_obj.users_collection + def test_in_decomposition_mode_elements_can_be_in_spatial_containers(self): bpy.ops.bim.create_project() wall_obj = bpy.data.objects.new("Object", None) diff --git a/src/blenderbim/test/tool/test_demo.py b/src/blenderbim/test/tool/test_demo.py index a14a594fb5..6387c34b0a 100644 --- a/src/blenderbim/test/tool/test_demo.py +++ b/src/blenderbim/test/tool/test_demo.py @@ -23,6 +23,11 @@ # ############################################################################ # +# Note: these tests are commented out as they are for learning purposes only. If +# you want to run these tests, uncomment it :) + +""" + # Because our tools have well defined, isolated functions, it means we can test # them very easily in isolation. Tests are fun, fast, and easy to setup! @@ -85,3 +90,5 @@ class TestShowUserHints(NewFile): bpy.context.scene.BIMDemoProperties.show_hints = False subject.show_user_hints() assert bpy.context.scene.BIMDemoProperties.show_hints == True + +"""