From 87736b1f11d5c7cfa279519c55753b0327bcc6a5 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Wed, 8 Nov 2023 14:56:46 -0800 Subject: [PATCH] d2ir: fix glob edge with common glob --- ci/release/changelogs/next.md | 1 + d2compiler/compile_test.go | 17 + d2ir/d2ir.go | 2 +- .../globs/creating-node-bug.exp.json | 435 ++++++++++++++++++ 4 files changed, 454 insertions(+), 1 deletion(-) create mode 100644 testdata/d2compiler/TestCompile2/globs/creating-node-bug.exp.json diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index e10f25c48..817448349 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -24,3 +24,4 @@ - Fixes panic when spread substitution referenced a nonexistant var. [#1695](https://github.com/terrastruct/d2/pull/1695) - Fixes incorrect appendix icon numbering. [#1704](https://github.com/terrastruct/d2/pull/1704) - Fixes crash when using `--watch` and navigating to an invalid board path [#1693](https://github.com/terrastruct/d2/pull/1693) +- Fixes edge case where nested edge globs were creating excess shapes [#1713](https://github.com/terrastruct/d2/pull/1713) diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 3c4a83c6f..4ba50f013 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -4297,6 +4297,23 @@ x: { `, `d2/testdata/d2compiler/TestCompile2/globs/double-glob-override-err-val.d2:6:2: invalid "near" field`) }, }, + { + name: "creating-node-bug", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +*.*a -> *.*b + +container_1: { + a +} + +container_2: { + b +} +`, ``) + assert.Equal(t, 4, len(g.Objects)) + }, + }, } for _, tc := range tca { diff --git a/d2ir/d2ir.go b/d2ir/d2ir.go index 23e5aa8f8..5a21c549e 100644 --- a/d2ir/d2ir.go +++ b/d2ir/d2ir.go @@ -435,7 +435,7 @@ func (eid *EdgeID) resolve(m *Map) (_ *EdgeID, _ *Map, common []string, _ error) } for len(eid.SrcPath) > 1 && len(eid.DstPath) > 1 { - if !strings.EqualFold(eid.SrcPath[0], eid.DstPath[0]) { + if !strings.EqualFold(eid.SrcPath[0], eid.DstPath[0]) || eid.SrcPath[0] == "*" { return eid, m, common, nil } common = append(common, eid.SrcPath[0]) diff --git a/testdata/d2compiler/TestCompile2/globs/creating-node-bug.exp.json b/testdata/d2compiler/TestCompile2/globs/creating-node-bug.exp.json new file mode 100644 index 000000000..665feb37a --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/creating-node-bug.exp.json @@ -0,0 +1,435 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,0:0:0-10:0:56", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,1:0:1-1:12:13", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,1:0:1-1:12:13", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,1:0:1-1:4:5", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,1:0:1-1:1:2", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,1:2:3-1:4:5", + "value": [ + { + "string": "*a", + "raw_string": "*a" + } + ], + "pattern": [ + "*", + "a" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,1:8:9-1:12:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,1:8:9-1:9:10", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,1:10:11-1:12:13", + "value": [ + { + "string": "*b", + "raw_string": "*b" + } + ], + "pattern": [ + "*", + "b" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,3:0:15-5:1:34", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,3:0:15-3:11:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,3:0:15-3:11:26", + "value": [ + { + "string": "container_1", + "raw_string": "container_1" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,3:13:28-5:1:34", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,4:1:31-4:2:32", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,4:1:31-4:2:32", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,4:1:31-4:2:32", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,7:0:36-9:1:55", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,7:0:36-7:11:47", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,7:0:36-7:11:47", + "value": [ + { + "string": "container_2", + "raw_string": "container_2" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,7:13:49-9:1:55", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,8:1:52-8:2:53", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,8:1:52-8:2:53", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,8:1:52-8:2:53", + "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": [ + { + "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": "container_1", + "id_val": "container_1", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,3:0:15-3:11:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,3:0:15-3:11:26", + "value": [ + { + "string": "container_1", + "raw_string": "container_1" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "container_1" + }, + "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/d2compiler/TestCompile2/globs/creating-node-bug.d2,4:1:31-4:2:32", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,4:1:31-4:2:32", + "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 + }, + { + "id": "container_2", + "id_val": "container_2", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,7:0:36-7:11:47", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,7:0:36-7:11:47", + "value": [ + { + "string": "container_2", + "raw_string": "container_2" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "container_2" + }, + "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/d2compiler/TestCompile2/globs/creating-node-bug.d2,8:1:52-8:2:53", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/creating-node-bug.d2,8:1:52-8:2:53", + "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": null +}