diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 385a6b2ed..d1a06cf52 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -1586,3 +1586,13 @@ func (g *Graph) SortEdgesByAST() { }) g.Edges = edges } + +func (obj *Object) IsDescendantOf(ancestor *Object) bool { + if obj == ancestor { + return true + } + if obj.Parent == nil { + return false + } + return obj.Parent.IsDescendantOf(ancestor) +} diff --git a/d2plugin/plugin_elk.go b/d2plugin/plugin_elk.go index 3b2113c6d..d28fba3cb 100644 --- a/d2plugin/plugin_elk.go +++ b/d2plugin/plugin_elk.go @@ -89,6 +89,7 @@ func (p elkPlugin) Info(ctx context.Context) (*PluginInfo, error) { Type: "bundled", Features: []PluginFeature{ CONTAINER_DIMENSIONS, + DESCENDANT_EDGES, }, ShortHelp: "Eclipse Layout Kernel (ELK) with the Layered algorithm.", LongHelp: fmt.Sprintf(`ELK is a layout engine offered by Eclipse. diff --git a/d2plugin/plugin_features.go b/d2plugin/plugin_features.go index f41462b37..76e1825b4 100644 --- a/d2plugin/plugin_features.go +++ b/d2plugin/plugin_features.go @@ -18,6 +18,9 @@ const CONTAINER_DIMENSIONS PluginFeature = "container_dimensions" // When this is true, objects can specify their `top` and `left` keywords const TOP_LEFT PluginFeature = "top_left" +// When this is true, containers can have connections to descendants +const DESCENDANT_EDGES PluginFeature = "descendant_edges" + func FeatureSupportCheck(info *PluginInfo, g *d2graph.Graph) error { // Older version of plugin. Skip checking. if info.Features == nil { @@ -50,5 +53,22 @@ func FeatureSupportCheck(info *PluginInfo, g *d2graph.Graph) error { } } } + if _, ok := featureMap[DESCENDANT_EDGES]; !ok { + for _, e := range g.Edges { + // descendant edges are ok in sequence diagrams + if e.Src.OuterSequenceDiagram() != nil || e.Dst.OuterSequenceDiagram() != nil { + continue + } + if !e.Src.IsContainer() && !e.Dst.IsContainer() { + continue + } + if e.Src == e.Dst { + return fmt.Errorf(`Connection "%s" is a self loop on a container, but layout engine "%s" does not support this.`, e.AbsID(), info.Name) + } + if e.Src.IsDescendantOf(e.Dst) || e.Dst.IsDescendantOf(e.Src) { + return fmt.Errorf(`Connection "%s" goes from a container to a descendant, but layout engine "%s" does not support this.`, e.AbsID(), info.Name) + } + } + } return nil } diff --git a/e2etests/e2e_test.go b/e2etests/e2e_test.go index ab4059cd4..0f3ba0ac8 100644 --- a/e2etests/e2e_test.go +++ b/e2etests/e2e_test.go @@ -24,6 +24,7 @@ import ( "oss.terrastruct.com/d2/d2layouts/d2near" "oss.terrastruct.com/d2/d2layouts/d2sequence" "oss.terrastruct.com/d2/d2lib" + "oss.terrastruct.com/d2/d2plugin" "oss.terrastruct.com/d2/d2renderers/d2svg" "oss.terrastruct.com/d2/d2target" "oss.terrastruct.com/d2/lib/log" @@ -73,12 +74,14 @@ a -> c } type testCase struct { - name string - script string - mtexts []*d2target.MText - assertions func(t *testing.T, diagram *d2target.Diagram) - skip bool - expErr string + name string + script string + mtexts []*d2target.MText + assertions func(t *testing.T, diagram *d2target.Diagram) + skip bool + dagreFeatureError string + elkFeatureError string + expErr string } func runa(t *testing.T, tcs []testCase) { @@ -136,16 +139,20 @@ func run(t *testing.T, tc testCase) { for _, layoutName := range layoutsTested { var layout func(context.Context, *d2graph.Graph) error + var plugin d2plugin.Plugin if layoutName == "dagre" { layout = d2dagrelayout.DefaultLayout + plugin = &d2plugin.DagrePlugin } else if layoutName == "elk" { // If measured texts exists, we are specifically exercising text measurements, no need to run on both layouts if tc.mtexts != nil { continue } layout = d2elklayout.DefaultLayout + plugin = &d2plugin.ELKPlugin } - diagram, _, err := d2lib.Compile(ctx, tc.script, &d2lib.CompileOptions{ + + diagram, g, err := d2lib.Compile(ctx, tc.script, &d2lib.CompileOptions{ Ruler: ruler, MeasuredTexts: tc.mtexts, ThemeID: 0, @@ -160,6 +167,26 @@ func run(t *testing.T, tc testCase) { assert.Success(t, err) } + pluginInfo, err := plugin.Info(ctx) + assert.Success(t, err) + + err = d2plugin.FeatureSupportCheck(pluginInfo, g) + switch layoutName { + case "dagre": + if tc.dagreFeatureError != "" { + assert.Error(t, err) + assert.ErrorString(t, err, tc.dagreFeatureError) + return + } + case "elk": + if tc.elkFeatureError != "" { + assert.Error(t, err) + assert.ErrorString(t, err, tc.elkFeatureError) + return + } + } + assert.Success(t, err) + if tc.assertions != nil { t.Run("assertions", func(t *testing.T) { tc.assertions(t, diagram) diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go index 169d1ad1e..615dff3ec 100644 --- a/e2etests/stable_test.go +++ b/e2etests/stable_test.go @@ -448,6 +448,7 @@ eee.shape: document eee <- aaa.ccc (eee <- aaa.ccc)[0]: '222' `, + dagreFeatureError: `Connection "(aaa.ccc -- aaa)[0]" goes from a container to a descendant, but layout engine "dagre" does not support this.`, }, { name: "chaos2", @@ -1792,6 +1793,7 @@ c: { a } `, + dagreFeatureError: `Object "a" has attribute "width" and/or "height" set, but layout engine "dagre" does not support dimensions set on containers.`, }, { name: "crow_foot_arrowhead", diff --git a/e2etests/testdata/stable/chaos1/dagre/board.exp.json b/e2etests/testdata/stable/chaos1/dagre/board.exp.json deleted file mode 100644 index 79f84598b..000000000 --- a/e2etests/testdata/stable/chaos1/dagre/board.exp.json +++ /dev/null @@ -1,309 +0,0 @@ -{ - "name": "", - "fontFamily": "SourceSansPro", - "shapes": [ - { - "id": "aaa", - "type": "rectangle", - "pos": { - "x": 0, - "y": 41 - }, - "width": 173, - "height": 389, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#E3E9FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "aaa", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 41, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "aaa.bbb", - "type": "callout", - "pos": { - "x": 40, - "y": 309 - }, - "width": 72, - "height": 91, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#FFFFFF", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "bbb", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 27, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "aaa.ccc", - "type": "rectangle", - "pos": { - "x": 64, - "y": 96 - }, - "width": 68, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "ccc", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 23, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "ddd", - "type": "cylinder", - "pos": { - "x": 213, - "y": 50 - }, - "width": 73, - "height": 118, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "ddd", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 28, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "eee", - "type": "document", - "pos": { - "x": 213, - "y": 297 - }, - "width": 70, - "height": 76, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "eee", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 25, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - } - ], - "connections": [ - { - "id": "(aaa.ccc -- aaa)[0]", - "src": "aaa.ccc", - "srcArrow": "none", - "srcLabel": "", - "dst": "aaa", - "dstArrow": "none", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "#0D32B2", - "label": "111", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#676C7E", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 23, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "labelPercentage": 0, - "route": [ - { - "x": 91.92468619246861, - "y": 162.5 - }, - { - "x": 79.18493723849372, - "y": 231.7 - }, - { - "x": 76, - "y": 261.1 - }, - { - "x": 76, - "y": 309.5 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(eee <- aaa.ccc)[0]", - "src": "eee", - "srcArrow": "triangle", - "srcLabel": "", - "dst": "aaa.ccc", - "dstArrow": "none", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "#0D32B2", - "label": "222", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#676C7E", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 25, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "labelPercentage": 0, - "route": [ - { - "x": 213, - "y": 305 - }, - { - "x": 138.6, - "y": 243.8 - }, - { - "x": 116.8, - "y": 215.2 - }, - { - "x": 104, - "y": 162 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - } - ] -} diff --git a/e2etests/testdata/stable/chaos1/dagre/sketch.exp.svg b/e2etests/testdata/stable/chaos1/dagre/sketch.exp.svg deleted file mode 100644 index d2fcaff3c..000000000 --- a/e2etests/testdata/stable/chaos1/dagre/sketch.exp.svg +++ /dev/null @@ -1,67 +0,0 @@ - -aaadddeeebbbccc111 222 - - - - \ No newline at end of file diff --git a/e2etests/testdata/stable/container_dimensions/dagre/board.exp.json b/e2etests/testdata/stable/container_dimensions/dagre/board.exp.json deleted file mode 100644 index 317bd2d40..000000000 --- a/e2etests/testdata/stable/container_dimensions/dagre/board.exp.json +++ /dev/null @@ -1,473 +0,0 @@ -{ - "name": "", - "fontFamily": "SourceSansPro", - "shapes": [ - { - "id": "a", - "type": "rectangle", - "pos": { - "x": 0, - "y": 41 - }, - "width": 680, - "height": 575, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#E3E9FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "a.b", - "type": "rectangle", - "pos": { - "x": 140, - "y": 73 - }, - "width": 400, - "height": 61, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": 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": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.c", - "type": "rectangle", - "pos": { - "x": 40, - "y": 406 - }, - "width": 600, - "height": 61, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "b", - "type": "rectangle", - "pos": { - "x": 853, - "y": 41 - }, - "width": 241, - "height": 575, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#E3E9FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 13, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "b.b", - "type": "rectangle", - "pos": { - "x": 893, - "y": 70 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": 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": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "b.c", - "type": "rectangle", - "pos": { - "x": 893, - "y": 403 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "b.e", - "type": "rectangle", - "pos": { - "x": 1006, - "y": 286 - }, - "width": 48, - "height": 300, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "e", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "c", - "type": "rectangle", - "pos": { - "x": 700, - "y": 41 - }, - "width": 133, - "height": 125, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#E3E9FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "c.a", - "type": "rectangle", - "pos": { - "x": 740, - "y": 70 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": 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": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - } - ], - "connections": [ - { - "id": "a.(b -> c)[0]", - "src": "a.b", - "srcArrow": "none", - "srcLabel": "", - "dst": "a.c", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "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": 340, - "y": 135 - }, - { - "x": 340, - "y": 176.2 - }, - { - "x": 340, - "y": 270.4 - }, - { - "x": 340, - "y": 406 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "b.(b -> c)[0]", - "src": "b.b", - "srcArrow": "none", - "srcLabel": "", - "dst": "b.c", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "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": 919.5, - "y": 136.5 - }, - { - "x": 919.5, - "y": 176.5 - }, - { - "x": 919.5, - "y": 269.9 - }, - { - "x": 919.5, - "y": 403.5 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - } - ] -} diff --git a/e2etests/testdata/stable/container_dimensions/dagre/sketch.exp.svg b/e2etests/testdata/stable/container_dimensions/dagre/sketch.exp.svg deleted file mode 100644 index eb78ff58d..000000000 --- a/e2etests/testdata/stable/container_dimensions/dagre/sketch.exp.svg +++ /dev/null @@ -1,59 +0,0 @@ - -abcbcbcea - - - \ No newline at end of file diff --git a/e2etests/testdata/todo/child_parent_edges/dagre/board.exp.json b/e2etests/testdata/todo/child_parent_edges/dagre/board.exp.json deleted file mode 100644 index d0ff5aa83..000000000 --- a/e2etests/testdata/todo/child_parent_edges/dagre/board.exp.json +++ /dev/null @@ -1,379 +0,0 @@ -{ - "name": "", - "fontFamily": "SourceSansPro", - "shapes": [ - { - "id": "a", - "type": "rectangle", - "pos": { - "x": 0, - "y": 41 - }, - "width": 274, - "height": 325, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#E3E9FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "a", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "a.b", - "type": "rectangle", - "pos": { - "x": 20, - "y": 106 - }, - "width": 234, - "height": 230, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "b", - "fontSize": 24, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 12, - "labelHeight": 31, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.b.c", - "type": "rectangle", - "pos": { - "x": 40, - "y": 169 - }, - "width": 194, - "height": 135, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#F7F8FE", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 20, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 9, - "labelHeight": 26, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 3 - }, - { - "id": "a.b.c.d", - "type": "rectangle", - "pos": { - "x": 80, - "y": 204 - }, - "width": 54, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#FFFFFF", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "d", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 9, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 4 - } - ], - "connections": [ - { - "id": "(a.b -> a)[0]", - "src": "a.b", - "srcArrow": "none", - "srcLabel": "", - "dst": "a", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "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": 134, - "y": 222.8975155279503 - }, - { - "x": 155.33333333333331, - "y": 180.97950310559006 - }, - { - "x": 162, - "y": 170.5 - }, - { - "x": 164, - "y": 170.5 - }, - { - "x": 166, - "y": 170.5 - }, - { - "x": 168.66666666666669, - "y": 177.1 - }, - { - "x": 170.66666666666669, - "y": 187 - }, - { - "x": 172.66666666666666, - "y": 196.9 - }, - { - "x": 172.66666666666666, - "y": 210.1 - }, - { - "x": 170.66666666666669, - "y": 220 - }, - { - "x": 168.66666666666669, - "y": 229.9 - }, - { - "x": 155.33333333333331, - "y": 233.22049689440993 - }, - { - "x": 134, - "y": 220.1024844720497 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "a.(b -> b.c)[0]", - "src": "a.b", - "srcArrow": "none", - "srcLabel": "", - "dst": "a.b.c", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "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": 134, - "y": 208.20149253731344 - }, - { - "x": 166, - "y": 192.4402985074627 - }, - { - "x": 176, - "y": 188.5 - }, - { - "x": 179, - "y": 188.5 - }, - { - "x": 182, - "y": 188.5 - }, - { - "x": 186, - "y": 195.1 - }, - { - "x": 189, - "y": 205 - }, - { - "x": 192, - "y": 214.9 - }, - { - "x": 192, - "y": 228.1 - }, - { - "x": 189, - "y": 238 - }, - { - "x": 186, - "y": 247.9 - }, - { - "x": 166, - "y": 256.7597014925373 - }, - { - "x": 134, - "y": 265.79850746268653 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "a.(b.c.d -> b)[0]", - "src": "a.b.c.d", - "srcArrow": "none", - "srcLabel": "", - "dst": "a.b", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "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": 134.33333333333334, - "y": 248 - }, - { - "x": 134, - "y": 232.59128630705393 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - } - ] -} diff --git a/e2etests/testdata/todo/child_parent_edges/dagre/sketch.exp.svg b/e2etests/testdata/todo/child_parent_edges/dagre/sketch.exp.svg deleted file mode 100644 index 6ee251f44..000000000 --- a/e2etests/testdata/todo/child_parent_edges/dagre/sketch.exp.svg +++ /dev/null @@ -1,59 +0,0 @@ - -abcd - - - \ No newline at end of file diff --git a/e2etests/testdata/todo/container_child_edge/dagre/board.exp.json b/e2etests/testdata/todo/container_child_edge/dagre/board.exp.json deleted file mode 100644 index 3957f8df7..000000000 --- a/e2etests/testdata/todo/container_child_edge/dagre/board.exp.json +++ /dev/null @@ -1,227 +0,0 @@ -{ - "name": "", - "fontFamily": "SourceSansPro", - "shapes": [ - { - "id": "container", - "type": "rectangle", - "pos": { - "x": 0, - "y": 41 - }, - "width": 175, - "height": 312, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#E3E9FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "container", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 112, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "container.first", - "type": "rectangle", - "pos": { - "x": 50, - "y": 70 - }, - "width": 75, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "first", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 30, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "container.second", - "type": "rectangle", - "pos": { - "x": 40, - "y": 257 - }, - "width": 95, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "second", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 50, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - } - ], - "connections": [ - { - "id": "container.(first -> second)[0]", - "src": "container.first", - "srcArrow": "none", - "srcLabel": "", - "dst": "container.second", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "#0D32B2", - "label": "1->2", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#676C7E", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 29, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "labelPercentage": 0, - "route": [ - { - "x": 78.1470588235294, - "y": 136.5 - }, - { - "x": 64.42941176470588, - "y": 184.9 - }, - { - "x": 64.4, - "y": 209.2 - }, - { - "x": 78, - "y": 258 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(container -> container.second)[0]", - "src": "container", - "srcArrow": "none", - "srcLabel": "", - "dst": "container.second", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "#0D32B2", - "label": "c->2", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#676C7E", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 28, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "labelPercentage": 0, - "route": [ - { - "x": 96.94117647058823, - "y": 136.5 - }, - { - "x": 110.78823529411764, - "y": 184.9 - }, - { - "x": 110.85, - "y": 209.2 - }, - { - "x": 97.25, - "y": 258 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - } - ] -} diff --git a/e2etests/testdata/todo/container_child_edge/dagre/sketch.exp.svg b/e2etests/testdata/todo/container_child_edge/dagre/sketch.exp.svg deleted file mode 100644 index b4fe3bc2b..000000000 --- a/e2etests/testdata/todo/container_child_edge/dagre/sketch.exp.svg +++ /dev/null @@ -1,67 +0,0 @@ - -containerfirstsecond 1->2c->2 - - - - \ No newline at end of file diff --git a/e2etests/testdata/todo/container_label_loop/dagre/board.exp.json b/e2etests/testdata/todo/container_label_loop/dagre/board.exp.json deleted file mode 100644 index 35ff0b882..000000000 --- a/e2etests/testdata/todo/container_label_loop/dagre/board.exp.json +++ /dev/null @@ -1,263 +0,0 @@ -{ - "name": "", - "fontFamily": "SourceSansPro", - "shapes": [ - { - "id": "a", - "type": "rectangle", - "pos": { - "x": 0, - "y": 41 - }, - "width": 153, - "height": 291, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#E3E9FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "If we were meant to fly, we wouldn't keep losing our luggage", - "fontSize": 28, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": false, - "underline": false, - "labelWidth": 702, - "labelHeight": 36, - "labelPosition": "OUTSIDE_TOP_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "a.b", - "type": "rectangle", - "pos": { - "x": 40, - "y": 70 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": 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": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - }, - { - "id": "a.c", - "type": "rectangle", - "pos": { - "x": 40, - "y": 236 - }, - "width": 53, - "height": 66, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "#EDF0FD", - "stroke": "#0D32B2", - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "c", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "#0A0F25", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 8, - "labelHeight": 21, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 2 - } - ], - "connections": [ - { - "id": "a.(b -> c)[0]", - "src": "a.b", - "srcArrow": "none", - "srcLabel": "", - "dst": "a.c", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "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": 66.5, - "y": 136.5 - }, - { - "x": 66.5, - "y": 176.5 - }, - { - "x": 66.5, - "y": 196.5 - }, - { - "x": 66.5, - "y": 236.5 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(a -> a)[0]", - "src": "a", - "srcArrow": "none", - "srcLabel": "", - "dst": "a", - "dstArrow": "triangle", - "dstLabel": "", - "opacity": 1, - "strokeDash": 0, - "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": 93, - "y": 107.55172413793103 - }, - { - "x": 114.33333333333334, - "y": 94.3103448275862 - }, - { - "x": 121, - "y": 91 - }, - { - "x": 123, - "y": 91 - }, - { - "x": 125.00000000000001, - "y": 91 - }, - { - "x": 127.66666666666667, - "y": 97.6 - }, - { - "x": 129.66666666666669, - "y": 107.5 - }, - { - "x": 131.66666666666666, - "y": 117.4 - }, - { - "x": 131.66666666666666, - "y": 130.6 - }, - { - "x": 129.66666666666669, - "y": 140.5 - }, - { - "x": 127.66666666666667, - "y": 150.4 - }, - { - "x": 114.33333333333334, - "y": 153.68965517241378 - }, - { - "x": 93, - "y": 140.44827586206895 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - } - ] -} diff --git a/e2etests/testdata/todo/container_label_loop/dagre/sketch.exp.svg b/e2etests/testdata/todo/container_label_loop/dagre/sketch.exp.svg deleted file mode 100644 index a7cf0d257..000000000 --- a/e2etests/testdata/todo/container_label_loop/dagre/sketch.exp.svg +++ /dev/null @@ -1,59 +0,0 @@ - -If we were meant to fly, we wouldn't keep losing our luggagebc - - - \ No newline at end of file diff --git a/e2etests/todo_test.go b/e2etests/todo_test.go index 5d5953cdd..17903edbd 100644 --- a/e2etests/todo_test.go +++ b/e2etests/todo_test.go @@ -14,12 +14,14 @@ func testTodo(t *testing.T) { container.first -> container.second: 1->2 container -> container.second: c->2 `, + dagreFeatureError: `Connection "(container -> container.second)[0]" goes from a container to a descendant, but layout engine "dagre" does not support this.`, }, { name: "child_parent_edges", script: `a.b -> a a.b -> a.b.c a.b.c.d -> a.b`, + dagreFeatureError: `Connection "(a.b -> a)[0]" goes from a container to a descendant, but layout engine "dagre" does not support this.`, }, { name: "container_label_loop", @@ -27,6 +29,7 @@ a.b.c.d -> a.b`, b -> c } a -> a`, + dagreFeatureError: `Connection "(a -> a)[0]" is a self loop on a container, but layout engine "dagre" does not support this.`, }, { // as nesting gets deeper, the groups advance towards `c` and may overlap its lifeline