diff --git a/d2ast/d2ast.go b/d2ast/d2ast.go index 3d209be6a..9562cad13 100644 --- a/d2ast/d2ast.go +++ b/d2ast/d2ast.go @@ -650,9 +650,14 @@ func (mk1 *Key) Equals(mk2 *Key) bool { } if mk1.Value.Unbox() != nil { - if mk1.Value.ScalarBox().Unbox().ScalarString() != mk2.Value.ScalarBox().Unbox().ScalarString() { + if (mk1.Value.ScalarBox().Unbox() == nil) != (mk2.Value.ScalarBox().Unbox() == nil) { return false } + if mk1.Value.ScalarBox().Unbox() != nil { + if mk1.Value.ScalarBox().Unbox().ScalarString() != mk2.Value.ScalarBox().Unbox().ScalarString() { + return false + } + } } return true diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index 3f10dfe4a..0d1e27f36 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -1858,6 +1858,32 @@ func TestMove(t *testing.T) { assert.JSON(t, g.Objects[1].ID, "c") }, }, + { + name: "duplicate", + + text: `a: { + b: { + shape: cylinder + } +} + +a: { + b: { + shape: cylinder + } +} +`, + key: `a.b`, + newKey: `b`, + + exp: `a + +a +b: { + shape: cylinder +} +`, + }, { name: "rename_2", diff --git a/testdata/d2oracle/TestMove/duplicate.exp.json b/testdata/d2oracle/TestMove/duplicate.exp.json new file mode 100644 index 000000000..9364aa80e --- /dev/null +++ b/testdata/d2oracle/TestMove/duplicate.exp.json @@ -0,0 +1,262 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,0:0:0-6:0:30", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,0:0:0-0:1:1", + "key": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,2:0:3-2:1:4", + "key": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,2:0:3-2:1:4", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,2:0:3-2:1:4", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,3:0:5-5:1:29", + "key": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,3:0:5-3:1:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,3:0:5-3:1:6", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,3:3:8-5:0:28", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,4:2:12-4:17:27", + "key": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,4:2:12-4:7:17", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,4:2:12-4:7:17", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,4:9:19-4:17:27", + "value": [ + { + "string": "cylinder", + "raw_string": "cylinder" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "attributes": { + "label": { + "value": "" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.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/TestMove/duplicate.d2,2:0:3-2:1:4", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,2:0:3-2:1:4", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "label_dimensions": { + "width": 0, + "height": 0 + }, + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,3:0:5-3:1:6", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestMove/duplicate.d2,3:0:5-3:1:6", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "style": {}, + "near_key": null, + "shape": { + "value": "cylinder" + }, + "direction": { + "value": "" + }, + "constraint": { + "value": "" + } + }, + "zIndex": 0 + } + ] + }, + "err": "" +}