From 7be93b53869d87bb1f2a117b1e9578a711449144 Mon Sep 17 00:00:00 2001 From: carlos Date: Fri, 15 Jul 2022 01:09:08 +0200 Subject: [PATCH] Add testing to construction type previews --- .../blenderbim/bim/module/model/data.py | 6 +- src/blenderbim/test/bim/feature/model.feature | 15 ++++ src/blenderbim/test/bim/test_feature.py | 68 +++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/blenderbim/blenderbim/bim/module/model/data.py b/src/blenderbim/blenderbim/bim/module/model/data.py index b27d49963f..0e426b7766 100644 --- a/src/blenderbim/blenderbim/bim/module/model/data.py +++ b/src/blenderbim/blenderbim/bim/module/model/data.py @@ -112,8 +112,8 @@ class AuthoringData: constr_type_info = cls.constr_type_info(constr_class) _ = cls.new_constr_type_info(constr_class) if constr_type_info is None else constr_type_info constr_class_occurrences = cls.constr_class_entities(constr_class) + preview_constr_types = cls.data["preview_constr_types"] for constr_class_entity in constr_class_occurrences: - preview_constr_types = cls.data["preview_constr_types"] ### handle asset regeneration when library entity is updated ¿? if (constr_class not in preview_constr_types @@ -190,6 +190,10 @@ class AuthoringData: return None return constr_class_entity.Name if constr_class_entity.is_a() == constr_class else None + def constr_type_id_by_name(cls, constr_class, constr_type): + constr_types = [ct for ct in cls.constr_types(constr_class=constr_class) if ct.Name == constr_type] + return None if len(constr_types) == 0 else constr_types[0] + @classmethod def consolidate_constr_type(cls): props = bpy.context.scene.BIMModelProperties diff --git a/src/blenderbim/test/bim/feature/model.feature b/src/blenderbim/test/bim/feature/model.feature index 49b85e9641..7bb0a45e13 100644 --- a/src/blenderbim/test/bim/feature/model.feature +++ b/src/blenderbim/test/bim/feature/model.feature @@ -48,6 +48,21 @@ Scenario: Add type instance - add a mesh where existing instances have changed c Then the object "IfcWall/Wall" data is a "Annotation2D" representation of "Plan/Annotation/PLAN_VIEW" And the object "IfcWall/Wall.001" data is a "Annotation2D" representation of "Plan/Annotation/PLAN_VIEW" +Scenario: Assetize one object + Given I load the demo construction library + And I set "scene.BIMModelProperties.constr_class" to "IfcBeamType" + And I set "scene.BIMModelProperties.constr_class" to "DEMO1" + When I make an asset from the selected construction type + Then the object "IfcBeam/Beam" does not exist + And the construction type "IfcBeamType"/"DEMO1" has a preview + +Scenario: Assetize one class + Given I load the demo construction library + And I set "scene.BIMModelProperties.constr_class" to "IfcWallType" + When I make assets from the selected construction class + Then objects starting with "IfcWall/" do not exist + And all construction types for "IfcWallType" have a preview + Scenario: Add grid Given an empty IFC project When I press "mesh.add_grid" diff --git a/src/blenderbim/test/bim/test_feature.py b/src/blenderbim/test/bim/test_feature.py index 4cd6dbcd5a..bfd8a8bc87 100644 --- a/src/blenderbim/test/bim/test_feature.py +++ b/src/blenderbim/test/bim/test_feature.py @@ -23,6 +23,7 @@ import ifcopenshell import blenderbim.tool as tool import blenderbim.bim from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.module.model.data import AuthoringData from pytest_bdd import scenarios, given, when, then, parsers from mathutils import Vector @@ -251,6 +252,19 @@ def the_object_name_exists(name) -> bpy.types.Object: assert False, f'The object "{name}" does not exist' return obj +@then(parsers.parse('the object "{name}" does not exist')) +def the_object_name_not_exists(name): + obj = bpy.data.objects.get(name) + if obj: + assert False, f'The object "{name}" exists' + assert True + +@then(parsers.parse('objects starting with "{name}" do not exist')) +def objects_not_exist_starting_with(name): + objs = [obj for obj in bpy.data.objects if obj.name.startswith(name)] + if len(objs) > 0: + assert False, f'{len(objs)} objects starting with "{name}" exist' + assert True @then(parsers.parse('the object "{name1}" and "{name2}" are different elements')) def the_object_name1_and_name2_are_different_elements(name1, name2): @@ -552,3 +566,57 @@ def the_file_name_should_contain_value(name, value): @then(parsers.parse('the object "{name}" has no modifiers')) def the_object_name_has_no_modifiers(name): assert len(the_object_name_exists(name).modifiers) == 0 + + +@then(parsers.parse('the construction type "{constr_class}"/"{constr_type}" has a preview')) +def the_construction_type_has_a_preview(constr_class, constr_type): + if "preview_constr_types" not in AuthoringData: + assert False, 'There are no previews loaded' + preview_constr_types = AuthoringData.data["preview_constr_types"] + if constr_class not in preview_constr_types: + assert False, f'Construction class {constr_class} has no available previews' + constr_type_id = AuthoringData.constr_type_id_by_name(constr_class, constr_type) + if constr_type_id is None: + assert False, f'No construction type {constr_class}/{constr_type} was found' + if constr_type_id not in preview_constr_types[constr_class]: + assert False, f'Construction type {constr_class}/{constr_type} has no available previews' + preview_data = preview_constr_types[constr_class][constr_type_id] + if 'icon_id' not in preview_data: + assert False, f'Construction type {constr_class}/{constr_type} has a preview, but no assigned icon_id' + icon_id = preview_data["icon_id"] + if type(icon_id) is not int: + assert False, f'Construction type {constr_class}/{constr_type} has an invalid icon_id {icon_id}' + if icon_id == 0: + assert False, f'Construction type {constr_class}/{constr_type} has the default null value for icon_id' + assert True + + +@then(parsers.parse('all construction types for "{constr_class}" have a preview')) +def all_construction_types_have_a_preview(constr_class): + if "preview_constr_types" not in AuthoringData: + assert False, 'There are no previews loaded' + preview_constr_types = AuthoringData.data["preview_constr_types"] + if constr_class not in preview_constr_types: + assert False, f'Construction class {constr_class} has no available previews' + constr_class_occurrences = AuthoringData.constr_class_entities(constr_class) + for constr_class_entity in constr_class_occurrences: + the_construction_type_has_a_preview(constr_class, constr_class_entity.Name) + + +@given("I load the demo construction library") +@when("I load the demo construction library") +def i_add_a_construction_library(): + lib_path = '../../blenderbim/bim/data/libraries/IFC4 Demo Library.ifc' + bpy.ops.bim.select_library_file(filepath=lib_path, append_all=True) + + +@given("I make an asset from the selected construction type") +@when("I make an asset from the selected construction type") +def i_assetize_from_selected_constr_type(): + AuthoringData.assetize_constr_type_from_selection() + + +@given("I make assets from the selected construction class") +@when("I make assets from the selected construction class") +def i_assetize_from_selected_constr_class(): + AuthoringData.assetize_constr_class()