Tidy: black formatting + PR7a test docstrings

Wraps three over-length lines black wanted on the merge-filter +
fillet-lock commit (wall.py's ``either_is_fillet`` chain rewraps the
right-hand ``or`` operand; test_disconnect_elements.py patch-stacks
break each ``patch(`` onto its own continuation line).

Adds per-test docstrings to test_wall_props_resync_on_dim_change.py
and test_wall_split_filled_opening.py so the contract each pins is
visible on grep / on test-run failure output without scrolling to
the module-level docstring. Drops a flip_object sibling-symbol
mention from the module docstring per CLAUDE.md §4a.

Generated with the assistance of an AI coding tool.
This commit is contained in:
Gorgious56
2026-06-15 14:56:46 +02:00
parent 13c89ace83
commit 7cd7db0c2b
4 changed files with 44 additions and 24 deletions
+3 -3
View File
@@ -391,9 +391,9 @@ class DisconnectElements(_CommitWallDraftsFirstMixin, bpy.types.Operator, tool.I
# without rebuilding the source walls' miter cuts. Deleting the corner
# wall is the supported teardown, which cascades back to the source
# walls via the connection-cleanup handler.
either_is_fillet = tool.Parametric.is_fillet_corner_wall(
elem_a
) or tool.Parametric.is_fillet_corner_wall(elem_b)
either_is_fillet = tool.Parametric.is_fillet_corner_wall(elem_a) or tool.Parametric.is_fillet_corner_wall(
elem_b
)
if either_is_fillet and any(k == "path" for _, k in rels):
self.report(
{"INFO"},
@@ -231,7 +231,9 @@ def test_disconnect_dispatches_one_call_per_rel():
return_value=[(rel1, "path"), (rel2, "element-top")],
), patch("bonsai.bim.module.model.wall.bonsai.core.connection.disconnect_rel") as dispatch, patch(
"bonsai.bim.module.model.wall.tool.Ifc.get_object", return_value=Mock()
), patch("bonsai.bim.module.model.wall._resync_walls_after_mutation"), patch(
), patch(
"bonsai.bim.module.model.wall._resync_walls_after_mutation"
), patch(
"bonsai.bim.module.model.wall.tool.Parametric.is_fillet_corner_wall", return_value=False
):
DisconnectElements._perform(op, context=MagicMock())
@@ -239,9 +241,7 @@ def test_disconnect_dispatches_one_call_per_rel():
assert dispatch.call_count == 2
# Both rels dispatch with elem=elem_a, partner=elem_b regardless of orientation
# — orient_element_top inside disconnect_rel recovers the wall/slab roles.
for call, expected_rel, expected_kind in zip(
dispatch.call_args_list, [rel1, rel2], ["path", "element-top"]
):
for call, expected_rel, expected_kind in zip(dispatch.call_args_list, [rel1, rel2], ["path", "element-top"]):
kw = call.kwargs
assert kw["rel"] is expected_rel
assert kw["kind"] == expected_kind
@@ -271,7 +271,9 @@ def test_disconnect_resyncs_path_objs_once_for_path_kind():
), patch(
"bonsai.bim.module.model.wall.tool.Ifc.get_object",
side_effect=lambda e: {elem_a: obj_a, elem_b: obj_b}[e],
), patch("bonsai.bim.module.model.wall.bonsai.core.connection.disconnect_rel"), patch(
), patch(
"bonsai.bim.module.model.wall.bonsai.core.connection.disconnect_rel"
), patch(
"bonsai.bim.module.model.wall._resync_walls_after_mutation"
) as resync, patch(
"bonsai.bim.module.model.wall.tool.Parametric.is_fillet_corner_wall", return_value=False
@@ -298,7 +300,9 @@ def test_disconnect_skips_resync_for_non_path_kind():
"bonsai.bim.module.model.wall.tool.Connection.find_rels", return_value=[(rel, "element-top")]
), patch("bonsai.bim.module.model.wall.tool.Ifc.get_object", return_value=Mock()), patch(
"bonsai.bim.module.model.wall.bonsai.core.connection.disconnect_rel"
), patch("bonsai.bim.module.model.wall._resync_walls_after_mutation") as resync, patch(
), patch(
"bonsai.bim.module.model.wall._resync_walls_after_mutation"
) as resync, patch(
"bonsai.bim.module.model.wall.tool.Parametric.is_fillet_corner_wall", return_value=False
):
DisconnectElements._perform(op, context=MagicMock())
@@ -328,7 +332,9 @@ def test_disconnect_gizmo_direction_symmetry():
"bonsai.bim.module.model.wall.tool.Connection.find_rels", return_value=[(rel, "element-top")]
), patch("bonsai.bim.module.model.wall.tool.Ifc.get_object", return_value=Mock()), patch(
"bonsai.bim.module.model.wall.bonsai.core.connection.disconnect_rel"
) as dispatch, patch("bonsai.bim.module.model.wall._resync_walls_after_mutation"), patch(
) as dispatch, patch(
"bonsai.bim.module.model.wall._resync_walls_after_mutation"
), patch(
"bonsai.bim.module.model.wall.tool.Parametric.is_fillet_corner_wall", return_value=False
):
DisconnectElements._perform(op, context=MagicMock())
@@ -409,7 +415,9 @@ def test_disconnect_refuses_path_kind_when_either_side_is_fillet():
), patch(
"bonsai.bim.module.model.wall.tool.Parametric.is_fillet_corner_wall",
side_effect=lambda e: e is fillet,
), patch("bonsai.bim.module.model.wall.bonsai.core.connection.disconnect_rel") as dispatch:
), patch(
"bonsai.bim.module.model.wall.bonsai.core.connection.disconnect_rel"
) as dispatch:
DisconnectElements._perform(op, context=MagicMock())
dispatch.assert_not_called()
@@ -437,9 +445,13 @@ def test_disconnect_allows_slab_kind_even_when_wall_is_fillet():
), patch(
"bonsai.bim.module.model.wall.tool.Parametric.is_fillet_corner_wall",
side_effect=lambda e: e is fillet,
), patch("bonsai.bim.module.model.wall.tool.Ifc.get_object", return_value=Mock()), patch(
), patch(
"bonsai.bim.module.model.wall.tool.Ifc.get_object", return_value=Mock()
), patch(
"bonsai.bim.module.model.wall.bonsai.core.connection.disconnect_rel"
) as dispatch, patch("bonsai.bim.module.model.wall._resync_walls_after_mutation"):
) as dispatch, patch(
"bonsai.bim.module.model.wall._resync_walls_after_mutation"
):
DisconnectElements._perform(op, context=MagicMock())
dispatch.assert_called_once()
@@ -40,18 +40,25 @@ def _execute_source(operator_cls):
def test_change_extrusion_depth_resyncs_wall_props():
"""Height mutation must re-prime ``BIMWallProperties.height`` so
gizmo icons positioned from ``props.height`` track the post-mutation
wall top in the same redraw."""
from bonsai.bim.module.model.wall import ChangeExtrusionDepth
assert "_resync_walls_after_mutation" in _execute_source(ChangeExtrusionDepth)
def test_change_extrusion_x_angle_resyncs_wall_props():
"""Slope mutation must re-prime ``BIMWallProperties.x_angle`` so
slope-driven gizmo positions track the new angle."""
from bonsai.bim.module.model.wall import ChangeExtrusionXAngle
assert "_resync_walls_after_mutation" in _execute_source(ChangeExtrusionXAngle)
def test_change_layer_length_resyncs_wall_props():
"""Length mutation must re-prime ``BIMWallProperties.length`` so
horizontal gizmo X positions track the new axis extent."""
from bonsai.bim.module.model.wall import ChangeLayerLength
assert "_resync_walls_after_mutation" in _execute_source(ChangeLayerLength)
@@ -22,9 +22,9 @@
1. Side classification reads the opening's axis-projected midpoint, not
the filling's ``matrix_world.translation``. The filling origin is
flip-fragile ``flip_object`` rotates the filler 180° + translates so
the bbox stays visually in place, which would mis-classify a flipped
door centred over the cut.
flip-fragile flipping rotates the filler 180° + translates so the
bbox stays visually in place, which would mis-classify a flipped door
centred over the cut.
2. When the void straddles the cut and the filling moves to element2,
the void copy for element1 is taken from the ORIGINAL opening (whose
``ObjectPlacement`` still references element1), not the rebound
@@ -44,23 +44,24 @@ def _split_source():
def test_side_classification_uses_opening_midpoint_not_filling_origin():
"""Side classification must read the opening's axis-projected
midpoint, not the filling's world translation — the latter shifts
under flipping and would mis-classify a flipped door centred over
the cut."""
source = _split_source()
assert "opening_midpoint" in source
# The pre-fix code projected the filling's world translation onto the
# axis to classify; that path must be gone.
assert "filling_obj.matrix_world.translation" not in source
def test_void_copy_reads_from_original_opening_before_remove():
"""When the filling moves to element2 and the void straddles the
cut, element1's pure-void copy must come from the original opening
BEFORE the cleanup that destroys it the rebound ``new_opening``
references element2's frame and would shift the void to element1's
origin in element2's local coords."""
source = _split_source()
# Locate the "filling moves to element2" branch via the opening
# midpoint check; the void-copy and the trailing remove_feature both
# live inside this branch, after the prior unfilled-opening loops.
branch_start = source.index("if opening_midpoint > cut_percentage:")
branch = source[branch_start:]
add_idx = branch.index("_add_void_copy(element1, opening)")
remove_idx = branch.index("feature.remove_feature(tool.Ifc.get(), feature=opening)")
# Read-from-original is the whole point — the rebound ``new_opening``
# references element2's frame and would shift the void to element1's
# origin in element2's local coords.
assert add_idx < remove_idx