diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 0d163a20c..9366912b5 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -4,5 +4,7 @@ #### Bugfixes ⛑️ +- Fixed crash when sequence diagrams had no messages + [https://github.com/terrastruct/d2/pull/427](https://github.com/terrastruct/d2/pull/427) - Fixed serialization affecting binary plugins (TALA). [https://github.com/terrastruct/d2/pull/426](https://github.com/terrastruct/d2/pull/426) diff --git a/d2layouts/d2sequence/sequence_diagram.go b/d2layouts/d2sequence/sequence_diagram.go index 4eeac153a..b05ea10a6 100644 --- a/d2layouts/d2sequence/sequence_diagram.go +++ b/d2layouts/d2sequence/sequence_diagram.go @@ -299,14 +299,19 @@ func (sd *sequenceDiagram) placeActors() { // │ // │ func (sd *sequenceDiagram) addLifelineEdges() { - lastRoute := sd.messages[len(sd.messages)-1].Route endY := 0. - for _, p := range lastRoute { - endY = math.Max(endY, p.Y) + if len(sd.messages) > 0 { + lastRoute := sd.messages[len(sd.messages)-1].Route + for _, p := range lastRoute { + endY = math.Max(endY, p.Y) + } } for _, note := range sd.notes { endY = math.Max(endY, note.TopLeft.Y+note.Height) } + for _, actor := range sd.actors { + endY = math.Max(endY, actor.TopLeft.Y+actor.Height) + } endY += sd.yStep for _, actor := range sd.actors { diff --git a/e2etests/regression_test.go b/e2etests/regression_test.go index a7eef68c1..7c627be74 100644 --- a/e2etests/regression_test.go +++ b/e2etests/regression_test.go @@ -34,6 +34,11 @@ A->B`, script: `shape: sequence_diagram b.1 -> b.1 b.1 -> b.1`, + }, { + name: "sequence_diagram_no_message", + script: `shape: sequence_diagram +a: A +b: B`, }, } diff --git a/e2etests/testdata/regression/sequence_diagram_no_message/dagre/board.exp.json b/e2etests/testdata/regression/sequence_diagram_no_message/dagre/board.exp.json new file mode 100644 index 000000000..5f1267bc6 --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_no_message/dagre/board.exp.json @@ -0,0 +1,165 @@ +{ + "name": "", + "shapes": [ + { + "id": "a", + "type": "", + "pos": { + "x": 24, + "y": 74 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "A", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 14, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "", + "pos": { + "x": 274, + "y": 74 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "B", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -- )[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "a-lifeline-end-2251863791", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 99, + "y": 200 + }, + { + "x": 99, + "y": 330 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(b -- )[0]", + "src": "b", + "srcArrow": "none", + "srcLabel": "", + "dst": "b-lifeline-end-668380428", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 349, + "y": 200 + }, + { + "x": 349, + "y": 330 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + } + ] +} diff --git a/e2etests/testdata/regression/sequence_diagram_no_message/dagre/sketch.exp.svg b/e2etests/testdata/regression/sequence_diagram_no_message/dagre/sketch.exp.svg new file mode 100644 index 000000000..04f0e8b4e --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_no_message/dagre/sketch.exp.svg @@ -0,0 +1,28 @@ + +AB \ No newline at end of file diff --git a/e2etests/testdata/regression/sequence_diagram_no_message/elk/board.exp.json b/e2etests/testdata/regression/sequence_diagram_no_message/elk/board.exp.json new file mode 100644 index 000000000..5f1267bc6 --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_no_message/elk/board.exp.json @@ -0,0 +1,165 @@ +{ + "name": "", + "shapes": [ + { + "id": "a", + "type": "", + "pos": { + "x": 24, + "y": 74 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "A", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 14, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "", + "pos": { + "x": 274, + "y": 74 + }, + "width": 150, + "height": 126, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "B", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a -- )[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "a-lifeline-end-2251863791", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 99, + "y": 200 + }, + { + "x": 99, + "y": 330 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + }, + { + "id": "(b -- )[0]", + "src": "b", + "srcArrow": "none", + "srcLabel": "", + "dst": "b-lifeline-end-668380428", + "dstArrow": "none", + "dstLabel": "", + "opacity": 1, + "strokeDash": 6, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 349, + "y": 200 + }, + { + "x": 349, + "y": 330 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 1 + } + ] +} diff --git a/e2etests/testdata/regression/sequence_diagram_no_message/elk/sketch.exp.svg b/e2etests/testdata/regression/sequence_diagram_no_message/elk/sketch.exp.svg new file mode 100644 index 000000000..04f0e8b4e --- /dev/null +++ b/e2etests/testdata/regression/sequence_diagram_no_message/elk/sketch.exp.svg @@ -0,0 +1,28 @@ + +AB \ No newline at end of file