diff --git a/capellambse_context_diagrams/collectors/default.py b/capellambse_context_diagrams/collectors/default.py index e1e113e7..ff09590a 100644 --- a/capellambse_context_diagrams/collectors/default.py +++ b/capellambse_context_diagrams/collectors/default.py @@ -42,8 +42,10 @@ def collector( if is_hierarchical := exchanges.is_hierarchical(ex, centerbox): if not diagram.include_inner_objects: continue - - elkdata: _elkjs.ELKInputData = centerbox + elif not diagram.display_parent_relation: + elkdata = data + else: + elkdata = centerbox else: elkdata = data try: @@ -56,6 +58,8 @@ def collector( continue global_boxes = {centerbox["id"]: centerbox} made_boxes = {centerbox["id"]: centerbox} + to_delete = set() + to_delete.add(centerbox["id"]) if diagram.display_parent_relation and diagram.target.owner: box = _make_box_and_update_globals( diagram.target.owner, @@ -68,7 +72,6 @@ def collector( del data["children"][0] all_owners = generic.get_all_owners(diagram.target) start = 0 - end = len(all_owners) - 1 common_owner = diagram.target stack_heights: dict[str, float | int] = { @@ -114,15 +117,17 @@ def collector( no_symbol=diagram.display_symbols_as_boxes, layout_options=makers.DEFAULT_LABEL_LAYOUT_OPTIONS, ) + new_box = global_boxes.get(current.uuid, current) for box in (children := parent_box.setdefault("children", [])): if box["id"] == current.uuid: - box = global_boxes.pop(current.uuid) + box = new_box break else: - children.append(global_boxes.pop(current.uuid)) + children.append(new_box) + to_delete.add(current.uuid) current = current.owner try: - if all_owners.index(current.uuid, start, end) > start: + if all_owners.index(current.uuid, start) > start: common_owner = current except ValueError: pass @@ -153,7 +158,8 @@ def collector( current = current.owner - del global_boxes[centerbox["id"]] + for uuid in to_delete: + del global_boxes[uuid] data["children"].extend(global_boxes.values()) if diagram.display_parent_relation: owner_boxes: dict[str, _elkjs.ELKInputChild] = { diff --git a/capellambse_context_diagrams/serializers.py b/capellambse_context_diagrams/serializers.py index 38494285..f9526e0e 100644 --- a/capellambse_context_diagrams/serializers.py +++ b/capellambse_context_diagrams/serializers.py @@ -59,7 +59,7 @@ def __init__(self, elk_diagram: context.ContextDiagram) -> None: self.model = elk_diagram.target._model self._diagram = elk_diagram self._cache: dict[str, diagram.Box | diagram.Edge] = {} - self._edges: list[EdgeContext] = [] + self._edges: dict[str, EdgeContext] = {} def make_diagram( self, @@ -87,7 +87,7 @@ def make_diagram( for child in data["children"]: self.deserialize_child(child, diagram.Vector2D(), None) - for edge, ref, parent in self._edges: + for edge, ref, parent in self._edges.values(): self.deserialize_child(edge, ref, parent) self.diagram.calculate_viewport() @@ -248,7 +248,7 @@ class type that stores all previously named classes. for i in child.get("children", []): # type: ignore if i["type"] == "edge": - self._edges.append((i, ref, parent)) + self._edges.setdefault(i["id"], (i, ref, element)) else: self.deserialize_child(i, ref, element) diff --git a/tests/test_context_diagrams.py b/tests/test_context_diagrams.py index 8bbeb5ce..a8632e6f 100644 --- a/tests/test_context_diagrams.py +++ b/tests/test_context_diagrams.py @@ -8,6 +8,12 @@ TEST_HUMAN_ACTOR_SIZING_UUID = "e95847ae-40bb-459e-8104-7209e86ea2d1" TEST_ACTOR_SIZING_UUID = "6c8f32bf-0316-477f-a23b-b5239624c28d" TEST_HIERARCHY_UUID = "16b4fcc5-548d-4721-b62a-d3d5b1c1d2eb" +TEST_HIERARCHY_PARENTS_UUIDS = { + "84c0978d-9a32-4f5b-8013-5b0b6adbfd73", + "0d2edb8f-fa34-4e73-89ec-fb9a63001440", + "99a1d711-74af-4db7-af08-4dbd91c281ce", + "53558f58-270e-4206-8fc7-3cf9e788fac9", +} TEST_HIERARCHY_CHILDREN_UUIDS = { "31bc2326-5a55-45f9-9967-f1957bcd3f89", "99a1d711-74af-4db7-af08-4dbd91c281ce", @@ -144,20 +150,29 @@ def test_hierarchy_in_context_diagram(model: capellambse.MelodyModel) -> None: assert uuid in children -def test_context_diagram_pass_params_to_render( +def test_parent_relation_in_context_diagram( model: capellambse.MelodyModel, ) -> None: obj = model.by_uuid(TEST_HIERARCHY_UUID) - diag = obj.context_diagram - without_hierarchy = diag.render(None, include_inner_objects=False) - with_hierarchy = diag.render(None, include_inner_objects=True) - for uuid in TEST_HIERARCHY_CHILDREN_UUIDS: - assert with_hierarchy[uuid] + hide_relation = diag.render(None, display_parent_relation=False) + diag.render( + "svgdiagram", + display_parent_relation=False, + ).save(pretty=True) + + display_relation = diag.render(None, display_parent_relation=True) + diag.render( + "svgdiagram", + display_parent_relation=True, + ).save(pretty=True) + + for uuid in TEST_HIERARCHY_PARENTS_UUIDS: + assert display_relation[uuid] with pytest.raises(KeyError): - without_hierarchy[uuid] # pylint: disable=pointless-statement + hide_relation[uuid] # pylint: disable=pointless-statement @pytest.mark.parametrize("uuid", TEST_ACTIVITY_UUIDS)