d2ir: Add more import error tests
This commit is contained in:
parent
42706f8b64
commit
ad21f1fbea
2 changed files with 46 additions and 4 deletions
|
|
@ -3,6 +3,7 @@ package d2ir
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2ast"
|
"oss.terrastruct.com/d2/d2ast"
|
||||||
"oss.terrastruct.com/d2/d2parser"
|
"oss.terrastruct.com/d2/d2parser"
|
||||||
|
|
@ -15,9 +16,9 @@ func (c *compiler) pushImportStack(imp *d2ast.Import) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
newPath := imp.Path[0].Unbox().ScalarString()
|
newPath := imp.Path[0].Unbox().ScalarString()
|
||||||
for _, p := range c.importStack {
|
for i, p := range c.importStack {
|
||||||
if newPath == p {
|
if newPath == p {
|
||||||
c.errorf(imp, "detected cyclic import of %q", newPath)
|
c.errorf(imp, "detected cyclic import chain: %s", formatCyclicChain(c.importStack[i:]))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -30,6 +31,16 @@ func (c *compiler) popImportStack() {
|
||||||
c.importStack = c.importStack[:len(c.importStack)-1]
|
c.importStack = c.importStack[:len(c.importStack)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatCyclicChain(cyclicChain []string) string {
|
||||||
|
var b strings.Builder
|
||||||
|
for _, p := range cyclicChain {
|
||||||
|
b.WriteString(p)
|
||||||
|
b.WriteString(" -> ")
|
||||||
|
}
|
||||||
|
b.WriteString(cyclicChain[0])
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
// Returns either *Map or *Field.
|
// Returns either *Map or *Field.
|
||||||
func (c *compiler) _import(imp *d2ast.Import) (Node, bool) {
|
func (c *compiler) _import(imp *d2ast.Import) (Node, bool) {
|
||||||
ir, ok := c.__import(imp)
|
ir, ok := c.__import(imp)
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,9 @@ package d2ir_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2ir"
|
|
||||||
"oss.terrastruct.com/util-go/assert"
|
"oss.terrastruct.com/util-go/assert"
|
||||||
|
|
||||||
|
"oss.terrastruct.com/d2/d2ir"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testCompileImports(t *testing.T) {
|
func testCompileImports(t *testing.T) {
|
||||||
|
|
@ -89,7 +90,25 @@ label: meow`,
|
||||||
t.Run("errors", func(t *testing.T) {
|
t.Run("errors", func(t *testing.T) {
|
||||||
tca := []testCase{
|
tca := []testCase{
|
||||||
{
|
{
|
||||||
name: "parse_error",
|
name: "not_exist",
|
||||||
|
run: func(t testing.TB) {
|
||||||
|
_, err := compileFS(t, "index.d2", map[string]string{
|
||||||
|
"index.d2": "...@x.d2",
|
||||||
|
})
|
||||||
|
assert.ErrorString(t, err, `index.d2:1:1: failed to import "x.d2": open x.d2: no such file or directory`)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "absolute",
|
||||||
|
run: func(t testing.TB) {
|
||||||
|
_, err := compileFS(t, "index.d2", map[string]string{
|
||||||
|
"index.d2": "...@/x.d2",
|
||||||
|
})
|
||||||
|
assert.ErrorString(t, err, `index.d2:1:1: import paths must be relative`)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "parse",
|
||||||
run: func(t testing.TB) {
|
run: func(t testing.TB) {
|
||||||
_, err := compileFS(t, "index.d2", map[string]string{
|
_, err := compileFS(t, "index.d2", map[string]string{
|
||||||
"index.d2": "...@x.d2",
|
"index.d2": "...@x.d2",
|
||||||
|
|
@ -103,6 +122,18 @@ x.d2:1:6: connection missing destination
|
||||||
x.d2:1:7: connection missing source`)
|
x.d2:1:7: connection missing source`)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "cyclic",
|
||||||
|
run: func(t testing.TB) {
|
||||||
|
_, err := compileFS(t, "index.d2", map[string]string{
|
||||||
|
"index.d2": "...@x",
|
||||||
|
"x.d2": "...@y",
|
||||||
|
"y.d2": "...@q",
|
||||||
|
"q.d2": "...@x",
|
||||||
|
})
|
||||||
|
assert.ErrorString(t, err, `q.d2:1:1: detected cyclic import chain: x -> y -> q -> x`)
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
runa(t, tca)
|
runa(t, tca)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue