mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Add smoke tests for colour by property feature
This commit is contained in:
@@ -84,12 +84,13 @@ class ColourByPropertyData:
|
||||
|
||||
@classmethod
|
||||
def colourscheme_key(cls):
|
||||
default = [("QUERY", "Custom Query", "Specify a custom query to colour by"), None]
|
||||
obj = bpy.context.active_object
|
||||
if not obj:
|
||||
return []
|
||||
return default
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
return []
|
||||
return default
|
||||
keys = [a.name() for a in element.wrapped_data.declaration().as_entity().all_attributes()]
|
||||
psets = ifcopenshell.util.element.get_psets(element)
|
||||
for pset, properties in psets.items():
|
||||
@@ -100,7 +101,7 @@ class ColourByPropertyData:
|
||||
else:
|
||||
keys.extend([f"{pset}.{name}" for name in properties.keys() if name != "id"])
|
||||
results = [(k, k, "") for k in keys]
|
||||
return [("QUERY", "Custom Query", "Specify a custom query to colour by"), None] + results
|
||||
return default + results
|
||||
|
||||
|
||||
class SelectSimilarData:
|
||||
|
||||
@@ -124,6 +124,7 @@ class EditFilterQuery(Operator, tool.Ifc.Operator):
|
||||
bl_description = "Edit the underlying filter query for advanced users"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
query: StringProperty(name="Query")
|
||||
old_query: StringProperty(name="Old Query")
|
||||
module: StringProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
|
||||
@@ -5,12 +5,53 @@ Scenario: Select all walls
|
||||
Given an empty IFC project
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_product" to "IfcElement"
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcWall"
|
||||
And I press "bim.assign_class"
|
||||
And I press "bim.add_filter_group(module='search')"
|
||||
And I set "scene.BIMSearchProperties.facet" to "entity"
|
||||
And I press "bim.add_filter(index=0, type='entity', module='search')"
|
||||
And I set "scene.BIMSearchProperties.filter_groups[0].filters[0].value" to "IfcWall"
|
||||
When I press "bim.search(property_group='BIMSearchProperties')"
|
||||
And I look at the "Class" panel
|
||||
And I set the "Products" property to "IfcElement"
|
||||
And I set the "Class" property to "IfcWall"
|
||||
And I click "Assign IFC Class"
|
||||
When I look at the "Search" panel
|
||||
And I click "Add Search Group"
|
||||
And I click "Add Filter"
|
||||
And I set the "FILE_3D" property to "IfcWall"
|
||||
And I click "Search"
|
||||
Then the object "IfcWall/Cube" is selected
|
||||
|
||||
Scenario: Edit filter query
|
||||
Given an empty IFC project
|
||||
When I look at the "Search" panel
|
||||
And I click "FILTER"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Colour by property - default class query
|
||||
Given an empty IFC project
|
||||
When I look at the "Colour By Property" panel
|
||||
And I click "Colour by Property"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Colour by property - no query
|
||||
Given an empty IFC project
|
||||
When I look at the "Colour By Property" panel
|
||||
And I set the "Query" property to " "
|
||||
And I click "Colour by Property" and expect error "Error: No Query Provided"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Reset colours
|
||||
Given an empty IFC project
|
||||
And I look at the "Colour By Property" panel
|
||||
And I click "Colour by Property"
|
||||
When I click "Reset Colours"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Flat colours
|
||||
Given an empty IFC project
|
||||
And I look at the "Colour By Property" panel
|
||||
And I click "Colour by Property"
|
||||
When I click "SHADING_RENDERED"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Select by property
|
||||
Given an empty IFC project
|
||||
And I look at the "Colour By Property" panel
|
||||
And I click "Colour by Property"
|
||||
When I click "RESTRICT_SELECT_OFF"
|
||||
Then nothing happens
|
||||
|
||||
@@ -71,6 +71,10 @@ class PanelSpy:
|
||||
def __call__(self, *args, **kwargs):
|
||||
if self.spied_attr in ("row", "column", "box"):
|
||||
return self
|
||||
elif self.spied_attr == "template_list":
|
||||
return lambda *args, **kwargs: None # Handle UI list spies
|
||||
elif self.spied_attr == "context_pointer_set":
|
||||
return lambda *args, **kwargs: None
|
||||
elif self.spied_attr == "label":
|
||||
self.spied_labels.append(kwargs["text"])
|
||||
return self
|
||||
@@ -105,7 +109,10 @@ class OperatorSpy:
|
||||
self.spied_data = spied_data
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name != "spied_data":
|
||||
if name == "spied_data":
|
||||
# Allow direct setting of spied_data only during initialization
|
||||
super().__setattr__(name, value)
|
||||
else:
|
||||
self.spied_data["kwargs"][name] = value
|
||||
|
||||
|
||||
@@ -186,6 +193,8 @@ def i_look_at_the_panel_panel(panel):
|
||||
panel_name_cache[panel_type.bl_label] = panel_type.bl_idname
|
||||
except:
|
||||
pass
|
||||
if panel not in panel_name_cache:
|
||||
assert False, f"Panel {panel} not found in {panel_name_cache}"
|
||||
panel_spy = PanelSpy(getattr(bpy.types, panel_name_cache[panel]))
|
||||
panel_spy.refresh_spy()
|
||||
|
||||
@@ -244,6 +253,7 @@ def i_see_the_prop_property_is_value(prop, value):
|
||||
@when(parsers.parse('I set the "{prop}" property to "{value}"'))
|
||||
@then(parsers.parse('I set the "{prop}" property to "{value}"'))
|
||||
def i_set_the_prop_property_to_value(prop, value):
|
||||
value = value.strip()
|
||||
panel_spy.refresh_spy()
|
||||
for spied_prop in panel_spy.spied_props:
|
||||
if prop in (spied_prop["name"], spied_prop["text"], spied_prop["icon"]):
|
||||
@@ -390,7 +400,7 @@ def i_click_button(button):
|
||||
panel_spy.refresh_spy()
|
||||
for spied_operator in panel_spy.spied_operators:
|
||||
if spied_operator["text"] == button or spied_operator["icon"] == button:
|
||||
spied_operator["operator"](**spied_operator["kwargs"])
|
||||
spied_operator["operator"]("INVOKE_DEFAULT", **spied_operator["kwargs"])
|
||||
panel_spy.is_spy_dirty = True
|
||||
return
|
||||
# Users can also "click" on booleans to toggle them
|
||||
@@ -402,6 +412,21 @@ def i_click_button(button):
|
||||
assert False, f"Could not find {button} in {panel_spy.spied_operators}"
|
||||
|
||||
|
||||
@given(parsers.parse('I click "{button}" and expect error "{error_msg}"'))
|
||||
@when(parsers.parse('I click "{button}" and expect error "{error_msg}"'))
|
||||
def i_click_button_and_expect_error_error_msg(button, error_msg):
|
||||
try:
|
||||
i_click_button(button)
|
||||
except Exception as e:
|
||||
actual_error_msg = str(e).strip()
|
||||
if str(e).strip() != error_msg:
|
||||
traceback.print_exc()
|
||||
msg = f"Got different exception clickign {button} - '{actual_error_msg}' instead of '{error_msg}'"
|
||||
assert False, msg
|
||||
return
|
||||
assert False, f"No error message {error_msg} raised when I pressed {button}"
|
||||
|
||||
|
||||
@given(parsers.parse('I evaluate expression "{expression}"'))
|
||||
@when(parsers.parse('I evaluate expression "{expression}"'))
|
||||
def i_evaluate_expression(expression):
|
||||
|
||||
Reference in New Issue
Block a user