2024-09-19 14:32:48 +00:00
|
|
|
package d2lsp_test
|
|
|
|
|
|
|
|
|
|
import (
|
2024-11-13 05:55:17 +00:00
|
|
|
"slices"
|
2024-09-19 14:32:48 +00:00
|
|
|
"testing"
|
|
|
|
|
|
2024-11-13 05:38:21 +00:00
|
|
|
"oss.terrastruct.com/d2/d2ast"
|
2024-09-19 14:32:48 +00:00
|
|
|
"oss.terrastruct.com/d2/d2lsp"
|
|
|
|
|
"oss.terrastruct.com/util-go/assert"
|
|
|
|
|
)
|
|
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
func TestGetFieldRanges(t *testing.T) {
|
2024-09-19 14:32:48 +00:00
|
|
|
script := `x
|
|
|
|
|
x.a
|
|
|
|
|
a.x
|
|
|
|
|
x -> y`
|
|
|
|
|
fs := map[string]string{
|
2024-10-11 20:09:51 +00:00
|
|
|
"index.d2": script,
|
2024-09-19 14:32:48 +00:00
|
|
|
}
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, _, err := d2lsp.GetRefRanges("index.d2", fs, nil, "x")
|
2024-09-19 14:32:48 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 3, len(ranges))
|
|
|
|
|
assert.Equal(t, 0, ranges[0].Start.Line)
|
|
|
|
|
assert.Equal(t, 1, ranges[1].Start.Line)
|
|
|
|
|
assert.Equal(t, 3, ranges[2].Start.Line)
|
2024-09-19 14:32:48 +00:00
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, _, err = d2lsp.GetRefRanges("index.d2", fs, nil, "a.x")
|
2024-09-19 14:32:48 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 1, len(ranges))
|
|
|
|
|
assert.Equal(t, 2, ranges[0].Start.Line)
|
2024-09-19 14:32:48 +00:00
|
|
|
}
|
2024-10-11 20:09:51 +00:00
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
func TestGetEdgeRanges(t *testing.T) {
|
2024-10-12 19:35:32 +00:00
|
|
|
script := `x
|
|
|
|
|
x.a
|
|
|
|
|
a.x
|
|
|
|
|
x -> y
|
|
|
|
|
y -> z
|
|
|
|
|
x -> z
|
|
|
|
|
b: {
|
|
|
|
|
x -> y
|
|
|
|
|
}
|
|
|
|
|
`
|
|
|
|
|
fs := map[string]string{
|
|
|
|
|
"index.d2": script,
|
|
|
|
|
}
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, _, err := d2lsp.GetRefRanges("index.d2", fs, nil, "x -> y")
|
2024-10-12 19:35:32 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 1, len(ranges))
|
|
|
|
|
assert.Equal(t, 3, ranges[0].Start.Line)
|
2024-10-12 19:35:32 +00:00
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, _, err = d2lsp.GetRefRanges("index.d2", fs, nil, "y -> z")
|
2024-10-12 19:35:32 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 1, len(ranges))
|
|
|
|
|
assert.Equal(t, 4, ranges[0].Start.Line)
|
2024-10-12 19:35:32 +00:00
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, _, err = d2lsp.GetRefRanges("index.d2", fs, nil, "x -> z")
|
2024-10-12 19:35:32 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 1, len(ranges))
|
|
|
|
|
assert.Equal(t, 5, ranges[0].Start.Line)
|
2024-10-12 19:35:32 +00:00
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, _, err = d2lsp.GetRefRanges("index.d2", fs, nil, "a -> b")
|
2024-10-12 19:35:32 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 0, len(ranges))
|
2024-10-12 19:35:32 +00:00
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, _, err = d2lsp.GetRefRanges("index.d2", fs, nil, "b.(x -> y)")
|
2024-10-12 19:35:32 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 1, len(ranges))
|
|
|
|
|
assert.Equal(t, 7, ranges[0].Start.Line)
|
2024-10-12 19:35:32 +00:00
|
|
|
}
|
|
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
func TestGetRangesImported(t *testing.T) {
|
2024-10-11 20:09:51 +00:00
|
|
|
fs := map[string]string{
|
|
|
|
|
"index.d2": `
|
|
|
|
|
...@ok
|
|
|
|
|
hi
|
2024-10-19 05:56:00 +00:00
|
|
|
hey: @ok
|
2024-10-11 20:09:51 +00:00
|
|
|
`,
|
|
|
|
|
"ok.d2": `
|
2024-10-19 05:56:00 +00:00
|
|
|
what
|
|
|
|
|
lala
|
2024-10-11 20:09:51 +00:00
|
|
|
okay
|
|
|
|
|
`,
|
|
|
|
|
}
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, importRanges, err := d2lsp.GetRefRanges("index.d2", fs, nil, "hi")
|
2024-10-11 20:09:51 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 1, len(ranges))
|
|
|
|
|
assert.Equal(t, 2, ranges[0].Start.Line)
|
|
|
|
|
assert.Equal(t, 0, len(importRanges))
|
2024-10-11 20:09:51 +00:00
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, importRanges, err = d2lsp.GetRefRanges("index.d2", fs, nil, "okay")
|
2024-10-11 20:09:51 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 1, len(ranges))
|
|
|
|
|
assert.Equal(t, "ok.d2", ranges[0].Path)
|
|
|
|
|
assert.Equal(t, 1, len(importRanges))
|
|
|
|
|
assert.Equal(t, 1, importRanges[0].Start.Line)
|
2024-10-11 20:09:51 +00:00
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, importRanges, err = d2lsp.GetRefRanges("index.d2", fs, nil, "hey.okay")
|
2024-10-11 20:09:51 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 1, len(ranges))
|
|
|
|
|
assert.Equal(t, "ok.d2", ranges[0].Path)
|
|
|
|
|
assert.Equal(t, 1, len(importRanges))
|
|
|
|
|
assert.Equal(t, 3, importRanges[0].Start.Line)
|
2024-10-19 15:21:32 +00:00
|
|
|
assert.Equal(t, 5, importRanges[0].Start.Column)
|
2024-10-19 05:56:00 +00:00
|
|
|
|
|
|
|
|
ranges, _, err = d2lsp.GetRefRanges("ok.d2", fs, nil, "hi")
|
|
|
|
|
assert.Success(t, err)
|
|
|
|
|
assert.Equal(t, 0, len(ranges))
|
2024-10-11 20:09:51 +00:00
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, _, err = d2lsp.GetRefRanges("ok.d2", fs, nil, "okay")
|
2024-10-11 20:09:51 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 1, len(ranges))
|
2024-10-11 20:09:51 +00:00
|
|
|
}
|
2024-10-12 00:42:23 +00:00
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
func TestGetRangesBoards(t *testing.T) {
|
2024-10-12 00:42:23 +00:00
|
|
|
fs := map[string]string{
|
|
|
|
|
"index.d2": `
|
|
|
|
|
hi
|
|
|
|
|
layers: {
|
|
|
|
|
x: {
|
|
|
|
|
hello
|
2024-10-30 01:08:22 +00:00
|
|
|
|
|
|
|
|
layers: {
|
|
|
|
|
y: {
|
|
|
|
|
qwer
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-12 00:42:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
}
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, _, err := d2lsp.GetRefRanges("index.d2", fs, []string{"x"}, "hello")
|
2024-10-12 00:42:23 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 1, len(ranges))
|
|
|
|
|
assert.Equal(t, 4, ranges[0].Start.Line)
|
2024-10-12 00:42:23 +00:00
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
ranges, _, err = d2lsp.GetRefRanges("index.d2", fs, []string{"x"}, "hi")
|
2024-10-12 00:42:23 +00:00
|
|
|
assert.Success(t, err)
|
2024-10-19 05:56:00 +00:00
|
|
|
assert.Equal(t, 0, len(ranges))
|
2024-10-12 00:42:23 +00:00
|
|
|
|
2024-10-30 01:08:22 +00:00
|
|
|
ranges, _, err = d2lsp.GetRefRanges("index.d2", fs, []string{"x", "y"}, "qwer")
|
|
|
|
|
assert.Success(t, err)
|
|
|
|
|
assert.Equal(t, 1, len(ranges))
|
|
|
|
|
|
2024-10-19 05:56:00 +00:00
|
|
|
_, _, err = d2lsp.GetRefRanges("index.d2", fs, []string{"y"}, "hello")
|
2024-10-12 00:42:23 +00:00
|
|
|
assert.Equal(t, `board "[y]" not found`, err.Error())
|
|
|
|
|
}
|
2024-11-13 05:38:21 +00:00
|
|
|
|
|
|
|
|
func TestGetBoardAtPosition(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
fs map[string]string
|
|
|
|
|
path string
|
|
|
|
|
position d2ast.Position
|
|
|
|
|
want []string
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "cursor in layer",
|
|
|
|
|
fs: map[string]string{
|
|
|
|
|
"index.d2": `x
|
|
|
|
|
layers: {
|
|
|
|
|
basic: {
|
|
|
|
|
x -> y
|
|
|
|
|
}
|
|
|
|
|
}`,
|
|
|
|
|
},
|
|
|
|
|
path: "index.d2",
|
|
|
|
|
position: d2ast.Position{Line: 3, Column: 4},
|
|
|
|
|
want: []string{"layers", "basic"},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "cursor in nested layer",
|
|
|
|
|
fs: map[string]string{
|
|
|
|
|
"index.d2": `
|
|
|
|
|
layers: {
|
|
|
|
|
outer: {
|
|
|
|
|
layers: {
|
|
|
|
|
inner: {
|
|
|
|
|
x -> y
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}`,
|
|
|
|
|
},
|
|
|
|
|
path: "index.d2",
|
|
|
|
|
position: d2ast.Position{Line: 5, Column: 4},
|
|
|
|
|
want: []string{"layers", "outer", "layers", "inner"},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "cursor in second sibling nested layer",
|
|
|
|
|
fs: map[string]string{
|
|
|
|
|
"index.d2": `
|
|
|
|
|
layers: {
|
|
|
|
|
outer: {
|
|
|
|
|
layers: {
|
|
|
|
|
first: {
|
|
|
|
|
a -> b
|
|
|
|
|
}
|
|
|
|
|
second: {
|
|
|
|
|
x -> y
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}`,
|
|
|
|
|
},
|
|
|
|
|
path: "index.d2",
|
|
|
|
|
position: d2ast.Position{Line: 8, Column: 4},
|
|
|
|
|
want: []string{"layers", "outer", "layers", "second"},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "cursor in root container",
|
|
|
|
|
fs: map[string]string{
|
|
|
|
|
"index.d2": `
|
|
|
|
|
wumbo: {
|
|
|
|
|
car
|
|
|
|
|
}`,
|
|
|
|
|
},
|
|
|
|
|
path: "index.d2",
|
|
|
|
|
position: d2ast.Position{Line: 2, Column: 4},
|
|
|
|
|
want: nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "cursor in layer container",
|
|
|
|
|
fs: map[string]string{
|
|
|
|
|
"index.d2": `
|
|
|
|
|
layers: {
|
|
|
|
|
x: {
|
|
|
|
|
wumbo: {
|
|
|
|
|
car
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}`,
|
|
|
|
|
},
|
|
|
|
|
path: "index.d2",
|
|
|
|
|
position: d2ast.Position{Line: 4, Column: 4},
|
|
|
|
|
want: []string{"layers", "x"},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "cursor in scenario",
|
|
|
|
|
fs: map[string]string{
|
|
|
|
|
"index.d2": `
|
|
|
|
|
scenarios: {
|
|
|
|
|
happy: {
|
|
|
|
|
x -> y
|
|
|
|
|
}
|
|
|
|
|
}`,
|
|
|
|
|
},
|
|
|
|
|
path: "index.d2",
|
|
|
|
|
position: d2ast.Position{Line: 3, Column: 4},
|
|
|
|
|
want: []string{"scenarios", "happy"},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "cursor in step",
|
|
|
|
|
fs: map[string]string{
|
|
|
|
|
"index.d2": `
|
|
|
|
|
steps: {
|
|
|
|
|
first: {
|
|
|
|
|
x -> y
|
|
|
|
|
}
|
|
|
|
|
}`,
|
|
|
|
|
},
|
|
|
|
|
path: "index.d2",
|
|
|
|
|
position: d2ast.Position{Line: 3, Column: 4},
|
|
|
|
|
want: []string{"steps", "first"},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "cursor outside any board",
|
|
|
|
|
fs: map[string]string{
|
|
|
|
|
"index.d2": `
|
|
|
|
|
x -> y
|
|
|
|
|
layers: {
|
|
|
|
|
basic: {
|
|
|
|
|
a -> b
|
|
|
|
|
}
|
|
|
|
|
}`,
|
|
|
|
|
},
|
|
|
|
|
path: "index.d2",
|
|
|
|
|
position: d2ast.Position{Line: 1, Column: 1},
|
|
|
|
|
want: nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "cursor in empty board",
|
|
|
|
|
fs: map[string]string{
|
|
|
|
|
"index.d2": `
|
|
|
|
|
layers: {
|
|
|
|
|
basic: {
|
|
|
|
|
}
|
|
|
|
|
}`,
|
|
|
|
|
},
|
|
|
|
|
path: "index.d2",
|
|
|
|
|
position: d2ast.Position{Line: 3, Column: 2},
|
|
|
|
|
want: []string{"layers", "basic"},
|
|
|
|
|
},
|
2024-11-13 18:15:28 +00:00
|
|
|
{
|
|
|
|
|
name: "cursor in between",
|
|
|
|
|
fs: map[string]string{
|
|
|
|
|
"index.d2": `
|
|
|
|
|
layers: {
|
|
|
|
|
basic: {
|
|
|
|
|
}
|
|
|
|
|
}`,
|
|
|
|
|
},
|
|
|
|
|
path: "index.d2",
|
|
|
|
|
position: d2ast.Position{Line: 2, Column: 2},
|
|
|
|
|
want: nil,
|
|
|
|
|
},
|
2024-11-13 05:38:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2024-11-13 05:55:17 +00:00
|
|
|
got, err := d2lsp.GetBoardAtPosition(tt.fs[tt.path], tt.position)
|
2024-11-13 05:38:21 +00:00
|
|
|
assert.Success(t, err)
|
|
|
|
|
if tt.want == nil {
|
|
|
|
|
assert.Equal(t, true, got == nil)
|
|
|
|
|
} else {
|
|
|
|
|
assert.Equal(t, len(tt.want), len(got))
|
2024-11-13 05:55:17 +00:00
|
|
|
assert.True(t, slices.Equal(tt.want, got))
|
2024-11-13 05:38:21 +00:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|