diff --git a/d2oracle/edit.go b/d2oracle/edit.go index e5273dfe8..41ea13eb3 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -115,7 +115,7 @@ func Set(g *d2graph.Graph, boardPath []string, key string, tag, value *string) ( return recompile(g.AST) } -func ReconnectEdge(g *d2graph.Graph, edgeKey string, srcKey, dstKey *string) (_ *d2graph.Graph, err error) { +func ReconnectEdge(g *d2graph.Graph, boardPath []string, edgeKey string, srcKey, dstKey *string) (_ *d2graph.Graph, err error) { mk, err := d2parser.ParseMapKey(edgeKey) if err != nil { return nil, err @@ -130,10 +130,24 @@ func ReconnectEdge(g *d2graph.Graph, edgeKey string, srcKey, dstKey *string) (_ } edgeTrimCommon(mk) - obj := g.Root + + boardG := g + baseAST := g.AST + + if len(boardPath) > 0 { + // When compiling a nested board, we can read from boardG but only write to baseBoardG + boardG = GetBoardGraph(g, boardPath) + if boardG == nil { + return nil, fmt.Errorf("board %v not found", boardPath) + } + // TODO beter name + baseAST = boardG.BaseAST + } + + obj := boardG.Root if mk.Key != nil { var ok bool - obj, ok = g.Root.HasChild(d2graph.Key(mk.Key)) + obj, ok = boardG.Root.HasChild(d2graph.Key(mk.Key)) if !ok { return nil, errors.New("edge not found") } @@ -167,7 +181,7 @@ func ReconnectEdge(g *d2graph.Graph, edgeKey string, srcKey, dstKey *string) (_ if err != nil { return nil, err } - src, ok = g.Root.HasChild(d2graph.Key(srcmk.Key)) + src, ok = boardG.Root.HasChild(d2graph.Key(srcmk.Key)) if !ok { return nil, errors.New("newSrc not found") } @@ -177,18 +191,26 @@ func ReconnectEdge(g *d2graph.Graph, edgeKey string, srcKey, dstKey *string) (_ if err != nil { return nil, err } - dst, ok = g.Root.HasChild(d2graph.Key(dstmk.Key)) + dst, ok = boardG.Root.HasChild(d2graph.Key(dstmk.Key)) if !ok { return nil, errors.New("newDst not found") } } - ref := edge.References[0] + refs := edge.References + if baseAST != g.AST { + refs = getWriteableEdgeRefs(edge, baseAST) + if len(refs) == 0 || refs[0].ScopeAST != baseAST { + // TODO null + return nil, OutsideScopeError{} + } + } + ref := refs[0] // for loops where only one end is changing, node is always ensured if edge.Src != edge.Dst && (srcKey == nil || dstKey == nil) { var refEdges []*d2ast.Edge - for _, ref := range edge.References { + for _, ref := range refs { refEdges = append(refEdges, ref.Edge) } @@ -200,8 +222,8 @@ func ReconnectEdge(g *d2graph.Graph, edgeKey string, srcKey, dstKey *string) (_ } } - for i := range edge.References { - ref := edge.References[i] + for i := range refs { + ref := refs[i] // it's a chain if len(ref.MapKey.Edges) > 1 && ref.MapKey.EdgeIndex == nil { splitChain := true @@ -232,7 +254,7 @@ func ReconnectEdge(g *d2graph.Graph, edgeKey string, srcKey, dstKey *string) (_ if src != nil { srcmk, _ := d2parser.ParseMapKey(*srcKey) ref.Edge.Src = srcmk.Key - newPath, err := pathFromScopeObj(g, srcmk, ref.ScopeObj) + newPath, err := pathFromScopeObj(boardG, srcmk, ref.ScopeObj) if err != nil { return nil, err } @@ -241,7 +263,7 @@ func ReconnectEdge(g *d2graph.Graph, edgeKey string, srcKey, dstKey *string) (_ if dst != nil { dstmk, _ := d2parser.ParseMapKey(*dstKey) ref.Edge.Dst = dstmk.Key - newPath, err := pathFromScopeObj(g, dstmk, ref.ScopeObj) + newPath, err := pathFromScopeObj(boardG, dstmk, ref.ScopeObj) if err != nil { return nil, err } @@ -447,7 +469,7 @@ func _set(g *d2graph.Graph, baseAST *d2ast.Map, key string, tag, value *string) } refs := edge.References if baseAST != g.AST { - refs = getWriteablEdgeRefs(edge, baseAST) + refs = getWriteableEdgeRefs(edge, baseAST) } onlyInChain := true for _, ref := range refs { @@ -1380,6 +1402,7 @@ func deleteEdge(g *d2graph.Graph, scope *d2ast.Map, mk *d2ast.Key, i int) { } } +// ensureNode ensures that `k` exists in `scope` if `excludedEdges` were removed func ensureNode(g *d2graph.Graph, excludedEdges []*d2ast.Edge, scopeObj *d2graph.Object, scope *d2ast.Map, cursor *d2ast.Key, k *d2ast.KeyPath, before bool) { if k == nil || len(k.Path) == 0 { return @@ -3024,7 +3047,7 @@ func getWriteableRefs(obj *d2graph.Object, writeableAST *d2ast.Map) (out []d2gra return } -func getWriteablEdgeRefs(edge *d2graph.Edge, writeableAST *d2ast.Map) (out []d2graph.EdgeReference) { +func getWriteableEdgeRefs(edge *d2graph.Edge, writeableAST *d2ast.Map) (out []d2graph.EdgeReference) { for i, ref := range edge.References { if ref.ScopeAST == writeableAST { out = append(out, edge.References[i]) diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index 9acab23eb..d843a6bac 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -2012,11 +2012,12 @@ func TestReconnectEdge(t *testing.T) { t.Parallel() testCases := []struct { - name string - text string - edgeKey string - newSrc string - newDst string + name string + boardPath []string + text string + edgeKey string + newSrc string + newDst string expErr string exp string @@ -2283,6 +2284,96 @@ x newDst: "x", expErr: "newDst not found", }, + { + name: "layers-basic", + text: `a + +layers: { + x: { + b + c + a -> b + } +} +`, + boardPath: []string{"x"}, + edgeKey: `(a -> b)[0]`, + newDst: "c", + exp: `a + +layers: { + x: { + b + c + a -> c + } +} +`, + }, + { + name: "scenarios-basic", + text: `a + +scenarios: { + x: { + b + c + a -> b + } +} +`, + boardPath: []string{"x"}, + edgeKey: `(a -> b)[0]`, + newDst: "c", + exp: `a + +scenarios: { + x: { + b + c + a -> c + } +} +`, + }, + { + name: "scenarios-outer-scope", + text: `a + +scenarios: { + x: { + d -> b + } +} +`, + boardPath: []string{"x"}, + edgeKey: `(d -> b)[0]`, + newDst: "a", + exp: `a + +scenarios: { + x: { + d -> a + b + } +} +`, + }, + { + name: "scenarios-chain", + text: `a -> b -> c + +scenarios: { + x: { + d + } +} +`, + boardPath: []string{"x"}, + edgeKey: `(a -> b)[0]`, + newDst: "d", + expErr: `operation would modify AST outside of given scope`, + }, } for _, tc := range testCases { @@ -2301,7 +2392,7 @@ x if tc.newDst != "" { newDst = &tc.newDst } - return d2oracle.ReconnectEdge(g, tc.edgeKey, newSrc, newDst) + return d2oracle.ReconnectEdge(g, tc.boardPath, tc.edgeKey, newSrc, newDst) }, exp: tc.exp, diff --git a/testdata/d2oracle/TestReconnectEdge/layers-basic.exp.json b/testdata/d2oracle/TestReconnectEdge/layers-basic.exp.json new file mode 100644 index 000000000..6e537fb03 --- /dev/null +++ b/testdata/d2oracle/TestReconnectEdge/layers-basic.exp.json @@ -0,0 +1,589 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,0:0:0-9:0:49", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,0:0:0-0:1:1", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,2:0:3-8:1:48", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,2:0:3-2:6:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,2:0:3-2:6:9", + "value": [ + { + "string": "layers", + "raw_string": "layers" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,2:8:11-8:1:48", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,3:2:15-7:3:46", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,3:2:15-3:3:16", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,3:2:15-3:3:16", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,3:5:18-7:3:46", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,4:4:24-4:5:25", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,4:4:24-4:5:25", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,4:4:24-4:5:25", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,5:4:30-5:5:31", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,5:4:30-5:5:31", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,5:4:30-5:5:31", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,6:4:36-6:10:42", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,6:4:36-6:10:42", + "src": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,6:4:36-6:5:37", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,6:4:36-6:5:37", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,6:9:41-6:10:42", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,6:9:41-6:10:42", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "layers": [ + { + "name": "x", + "isFolderOnly": false, + "ast": { + "range": ",1:0:0-2:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "edges": [ + { + "range": ",0:0:0-0:0:0", + "src": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "a" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "c" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,4:4:24-4:5:25", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,4:4:24-4:5:25", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "c", + "id_val": "c", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,5:4:30-5:5:31", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,5:4:30-5:5:31", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,6:9:41-6:10:42", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,6:9:41-6:10:42", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "c" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,6:4:36-6:5:37", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/layers-basic.d2,6:4:36-6:5:37", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestReconnectEdge/scenarios-basic.exp.json b/testdata/d2oracle/TestReconnectEdge/scenarios-basic.exp.json new file mode 100644 index 000000000..983bd873c --- /dev/null +++ b/testdata/d2oracle/TestReconnectEdge/scenarios-basic.exp.json @@ -0,0 +1,609 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,0:0:0-9:0:52", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,0:0:0-0:1:1", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,2:0:3-8:1:51", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,2:0:3-2:9:12", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,2:0:3-2:9:12", + "value": [ + { + "string": "scenarios", + "raw_string": "scenarios" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,2:11:14-8:1:51", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,3:2:18-7:3:49", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,3:2:18-3:3:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,3:2:18-3:3:19", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,3:5:21-7:3:49", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,4:4:27-4:5:28", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,4:4:27-4:5:28", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,4:4:27-4:5:28", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,5:4:33-5:5:34", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,5:4:33-5:5:34", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,5:4:33-5:5:34", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,6:4:39-6:10:45", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,6:4:39-6:10:45", + "src": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,6:4:39-6:5:40", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,6:4:39-6:5:40", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,6:9:44-6:10:45", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,6:9:44-6:10:45", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "scenarios": [ + { + "name": "x", + "isFolderOnly": false, + "ast": { + "range": ",1:0:0-2:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "edges": [ + { + "range": ",0:0:0-0:0:0", + "src": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "a" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "c" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,6:4:39-6:5:40", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,6:4:39-6:5:40", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,4:4:27-4:5:28", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,4:4:27-4:5:28", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "c", + "id_val": "c", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,5:4:33-5:5:34", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,5:4:33-5:5:34", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,6:9:44-6:10:45", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-basic.d2,6:9:44-6:10:45", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "c" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestReconnectEdge/scenarios-chain.exp.json b/testdata/d2oracle/TestReconnectEdge/scenarios-chain.exp.json new file mode 100644 index 000000000..b9a53f907 --- /dev/null +++ b/testdata/d2oracle/TestReconnectEdge/scenarios-chain.exp.json @@ -0,0 +1,4 @@ +{ + "graph": null, + "err": "d2oracle.OutsideScopeError{}" +} diff --git a/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.exp.json b/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.exp.json new file mode 100644 index 000000000..0f368f97c --- /dev/null +++ b/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.exp.json @@ -0,0 +1,566 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,0:0:0-8:0:46", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,0:0:0-0:1:1", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,2:0:3-7:1:45", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,2:0:3-2:9:12", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,2:0:3-2:9:12", + "value": [ + { + "string": "scenarios", + "raw_string": "scenarios" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,2:11:14-7:1:45", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,3:2:18-6:3:43", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,3:2:18-3:3:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,3:2:18-3:3:19", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,3:5:21-6:3:43", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,4:4:27-4:10:33", + "edges": [ + { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,4:4:27-4:10:33", + "src": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,4:4:27-4:5:28", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,4:4:27-4:5:28", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,4:9:32-4:10:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,4:9:32-4:10:33", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,5:4:38-5:5:39", + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,5:4:38-5:5:39", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,5:4:38-5:5:39", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "scenarios": [ + { + "name": "x", + "isFolderOnly": false, + "ast": { + "range": ",1:0:0-2:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "d" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "edges": [ + { + "range": ",0:0:0-0:0:0", + "src": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "d" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "a" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,4:9:32-4:10:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,4:9:32-4:10:33", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "d", + "id_val": "d", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,4:4:27-4:5:28", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,4:4:27-4:5:28", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "d" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,5:4:38-5:5:39", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestReconnectEdge/scenarios-outer-scope.d2,5:4:38-5:5:39", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + } + ] + }, + "err": "" +}