d2ir: wip
This commit is contained in:
parent
4b50748dd0
commit
83ef53dc40
8 changed files with 139 additions and 87 deletions
|
|
@ -24,7 +24,10 @@ func (c *compiler) errorf(n d2ast.Node, f string, v ...interface{}) {
|
||||||
func Apply(dst *Map, ast *d2ast.Map) error {
|
func Apply(dst *Map, ast *d2ast.Map) error {
|
||||||
var c compiler
|
var c compiler
|
||||||
c.apply(dst, ast)
|
c.apply(dst, ast)
|
||||||
|
if !c.err.Empty() {
|
||||||
return c.err
|
return c.err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *compiler) apply(dst *Map, ast *d2ast.Map) {
|
func (c *compiler) apply(dst *Map, ast *d2ast.Map) {
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,17 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"oss.terrastruct.com/util-go/assert"
|
||||||
"oss.terrastruct.com/util-go/diff"
|
"oss.terrastruct.com/util-go/diff"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2ast"
|
"oss.terrastruct.com/d2/d2ast"
|
||||||
"oss.terrastruct.com/d2/d2ir"
|
"oss.terrastruct.com/d2/d2ir"
|
||||||
"oss.terrastruct.com/d2/d2parser"
|
"oss.terrastruct.com/d2/d2parser"
|
||||||
"oss.terrastruct.com/d2/internal/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
name string
|
name string
|
||||||
text string
|
run func(testing.TB, *d2ir.Map)
|
||||||
base *d2ir.Map
|
|
||||||
|
|
||||||
exp func(testing.TB, *d2ir.Map, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApply(t *testing.T) {
|
func TestApply(t *testing.T) {
|
||||||
|
|
@ -30,12 +27,13 @@ func TestApply(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testApplySimple(t *testing.T) {
|
func testApplySimple(t *testing.T) {
|
||||||
tcs := []testCase{
|
t.Parallel()
|
||||||
|
|
||||||
|
tca := []testCase{
|
||||||
{
|
{
|
||||||
name: "one",
|
name: "one",
|
||||||
text: `x`,
|
run: func(t testing.TB, m *d2ir.Map) {
|
||||||
|
err := parse(t, m, `x`)
|
||||||
exp: func(t testing.TB, m *d2ir.Map, err error) {
|
|
||||||
assert.Success(t, err)
|
assert.Success(t, err)
|
||||||
assertField(t, m, 1, 0, nil)
|
assertField(t, m, 1, 0, nil)
|
||||||
|
|
||||||
|
|
@ -44,9 +42,8 @@ func testApplySimple(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "nested",
|
name: "nested",
|
||||||
text: `x.y -> z.p`,
|
run: func(t testing.TB, m *d2ir.Map) {
|
||||||
|
err := parse(t, m, `x.y -> z.p`)
|
||||||
exp: func(t testing.TB, m *d2ir.Map, err error) {
|
|
||||||
assert.Success(t, err)
|
assert.Success(t, err)
|
||||||
assertField(t, m, 4, 1, nil)
|
assertField(t, m, 4, 1, nil)
|
||||||
|
|
||||||
|
|
@ -65,9 +62,8 @@ func testApplySimple(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "underscore_parent",
|
name: "underscore_parent",
|
||||||
text: `x._ -> z`,
|
run: func(t testing.TB, m *d2ir.Map) {
|
||||||
|
err := parse(t, m, `x._ -> z`)
|
||||||
exp: func(t testing.TB, m *d2ir.Map, err error) {
|
|
||||||
assert.Success(t, err)
|
assert.Success(t, err)
|
||||||
assertField(t, m, 2, 1, nil)
|
assertField(t, m, 2, 1, nil)
|
||||||
|
|
||||||
|
|
@ -83,63 +79,76 @@ func testApplySimple(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
runa(t, tcs)
|
runa(t, tca)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runa(t *testing.T, tcs []testCase) {
|
func runa(t *testing.T, tca []testCase) {
|
||||||
for _, tc := range tcs {
|
for _, tc := range tca {
|
||||||
tc := tc
|
tc := tc
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
m := &d2ir.Map{}
|
||||||
run(t, tc)
|
tc.run(t, m)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(t testing.TB, tc testCase) {
|
func parse(t testing.TB, dst *d2ir.Map, text string) error {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
d2Path := fmt.Sprintf("d2/testdata/d2ir/%v.d2", t.Name())
|
d2Path := fmt.Sprintf("d2/testdata/d2ir/%v.d2", t.Name())
|
||||||
ast, err := d2parser.Parse(d2Path, strings.NewReader(tc.text), nil)
|
ast, err := d2parser.Parse(d2Path, strings.NewReader(text), nil)
|
||||||
if err != nil {
|
assert.Success(t, err)
|
||||||
tc.exp(t, nil, err)
|
|
||||||
t.FailNow()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
dst := tc.base.Copy(nil).(*d2ir.Map)
|
|
||||||
err = d2ir.Apply(dst, ast)
|
err = d2ir.Apply(dst, ast)
|
||||||
tc.exp(t, dst, err)
|
|
||||||
|
|
||||||
err = diff.Testdata(filepath.Join("..", "testdata", "d2ir", t.Name()), dst)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tc.exp(t, nil, err)
|
return err
|
||||||
t.FailNow()
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = diff.TestdataJSON(filepath.Join("..", "testdata", "d2ir", t.Name()), dst)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertField(t testing.TB, n d2ir.Node, nfields, nedges int, primary interface{}, ida ...string) *d2ir.Field {
|
func assertField(t testing.TB, n d2ir.Node, nfields, nedges int, primary interface{}, ida ...string) *d2ir.Field {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
m := d2ir.NodeToMap(n)
|
var m *d2ir.Map
|
||||||
p := d2ir.NodeToPrimary(n)
|
p := &d2ir.Scalar{
|
||||||
|
Value: &d2ast.Null{},
|
||||||
|
}
|
||||||
|
switch n := n.(type) {
|
||||||
|
case *d2ir.Field:
|
||||||
|
mm, ok := n.Composite.(*d2ir.Map)
|
||||||
|
if ok {
|
||||||
|
m = mm
|
||||||
|
} else {
|
||||||
|
t.Fatalf("unexpected d2ir.Field.Composite %T", n.Composite)
|
||||||
|
}
|
||||||
|
p = n.Primary
|
||||||
|
case *d2ir.Map:
|
||||||
|
m = n
|
||||||
|
p.Value = &d2ast.Null{}
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected d2ir.Node %T", n)
|
||||||
|
}
|
||||||
|
|
||||||
var f *d2ir.Field
|
var f *d2ir.Field
|
||||||
|
var ok bool
|
||||||
if len(ida) > 0 {
|
if len(ida) > 0 {
|
||||||
f = m.Get(ida)
|
f, ok = m.Get(ida)
|
||||||
if f == nil {
|
if !ok {
|
||||||
t.Fatalf("expected field %#v in map %#v but not found", ida, m)
|
t.Fatalf("expected field %v in map %s", ida, m)
|
||||||
}
|
}
|
||||||
p = f.Primary
|
p = f.Primary
|
||||||
m = d2ir.NodeToMap(f)
|
if f_m, ok := f.Composite.(*d2ir.Map); ok {
|
||||||
|
m = f_m
|
||||||
|
} else {
|
||||||
|
m = &d2ir.Map{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.FieldCount() != nfields {
|
assert.Equal(t, nfields, m.FieldCount())
|
||||||
t.Fatalf("expected %d fields but got %d", nfields, m.FieldCount())
|
assert.Equal(t, nedges, m.EdgeCount())
|
||||||
}
|
|
||||||
if m.EdgeCount() != nedges {
|
|
||||||
t.Fatalf("expected %d edges but got %d", nedges, m.EdgeCount())
|
|
||||||
}
|
|
||||||
if !p.Equal(makeScalar(primary)) {
|
if !p.Equal(makeScalar(primary)) {
|
||||||
t.Fatalf("expected primary %#v but %#v", primary, p)
|
t.Fatalf("expected primary %#v but %#v", primary, p)
|
||||||
}
|
}
|
||||||
|
|
@ -150,19 +159,27 @@ func assertField(t testing.TB, n d2ir.Node, nfields, nedges int, primary interfa
|
||||||
func assertEdge(t testing.TB, n d2ir.Node, nfields int, primary interface{}, eid *d2ir.EdgeID) *d2ir.Edge {
|
func assertEdge(t testing.TB, n d2ir.Node, nfields int, primary interface{}, eid *d2ir.EdgeID) *d2ir.Edge {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
m := d2ir.NodeToMap(n)
|
var m *d2ir.Map
|
||||||
|
switch n := n.(type) {
|
||||||
e := m.GetEdge(eid)
|
case *d2ir.Field:
|
||||||
if e == nil {
|
mm, ok := n.Composite.(*d2ir.Map)
|
||||||
t.Fatalf("expected edge %#v in map %#v but not found", eid, m)
|
if ok {
|
||||||
|
m = mm
|
||||||
|
} else {
|
||||||
|
t.Fatalf("unexpected d2ir.Field.Composite %T", n.Composite)
|
||||||
|
}
|
||||||
|
case *d2ir.Map:
|
||||||
|
m = n
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected d2ir.Node %T", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Map.FieldCount() != nfields {
|
e, ok := m.GetEdge(eid)
|
||||||
t.Fatalf("expected %d fields but got %d", nfields, e.Map.FieldCount())
|
if !ok {
|
||||||
}
|
t.Fatalf("expected edge %v in map %s but not found", eid, m)
|
||||||
if e.Map.EdgeCount() != 0 {
|
|
||||||
t.Fatalf("expected %d edges but got %d", 0, e.Map.EdgeCount())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, nfields, e.Map.FieldCount())
|
||||||
if !e.Primary.Equal(makeScalar(primary)) {
|
if !e.Primary.Equal(makeScalar(primary)) {
|
||||||
t.Fatalf("expected primary %#v but %#v", primary, e.Primary)
|
t.Fatalf("expected primary %#v but %#v", primary, e.Primary)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
34
d2ir/d2ir.go
34
d2ir/d2ir.go
|
|
@ -1,6 +1,8 @@
|
||||||
package d2ir
|
package d2ir
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2ast"
|
"oss.terrastruct.com/d2/d2ast"
|
||||||
|
|
@ -51,6 +53,7 @@ func (n *Edge) node() {}
|
||||||
func (n *Array) node() {}
|
func (n *Array) node() {}
|
||||||
func (n *Map) node() {}
|
func (n *Map) node() {}
|
||||||
|
|
||||||
|
func (n *Scalar) Parent() Parent { return n.parent }
|
||||||
func (n *Field) Parent() Parent { return n.parent }
|
func (n *Field) Parent() Parent { return n.parent }
|
||||||
func (n *Edge) Parent() Parent { return n.parent }
|
func (n *Edge) Parent() Parent { return n.parent }
|
||||||
func (n *Array) Parent() Parent { return n.parent }
|
func (n *Array) Parent() Parent { return n.parent }
|
||||||
|
|
@ -77,6 +80,17 @@ func (s *Scalar) Copy(newp Parent) Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Scalar) Equal(s2 *Scalar) bool {
|
func (s *Scalar) Equal(s2 *Scalar) bool {
|
||||||
|
if s == nil {
|
||||||
|
if s2 == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
_, ok := s2.Value.(*d2ast.Null)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
if s2 == nil {
|
||||||
|
_, ok := s.Value.(*d2ast.Null)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
return s.Value.ScalarString() == s2.Value.ScalarString() && s.Value.Type() == s2.Value.Type()
|
return s.Value.ScalarString() == s2.Value.ScalarString() && s.Value.Type() == s2.Value.Type()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,10 +127,10 @@ type Field struct {
|
||||||
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
Primary *Scalar `json:"primary"`
|
Primary *Scalar `json:"primary,omitempty"`
|
||||||
Composite Composite `json:"composite"`
|
Composite Composite `json:"composite,omitempty"`
|
||||||
|
|
||||||
Refs []KeyReference `json:"refs"`
|
Refs []KeyReference `json:"refs,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Field) Copy(newp Parent) Node {
|
func (f *Field) Copy(newp Parent) Node {
|
||||||
|
|
@ -203,10 +217,10 @@ type Edge struct {
|
||||||
|
|
||||||
ID *EdgeID `json:"edge_id"`
|
ID *EdgeID `json:"edge_id"`
|
||||||
|
|
||||||
Primary *Scalar `json:"primary"`
|
Primary *Scalar `json:"primary,omitempty"`
|
||||||
Map *Map `json:"map"`
|
Map *Map `json:"map,omitempty"`
|
||||||
|
|
||||||
Refs []EdgeReference `json:"refs"`
|
Refs []EdgeReference `json:"refs,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Edge) Copy(newp Parent) Node {
|
func (e *Edge) Copy(newp Parent) Node {
|
||||||
|
|
@ -384,3 +398,11 @@ func (m *Map) GetEdge(eid *EdgeID) (*Edge, bool) {
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Map) String() string {
|
||||||
|
b, err := json.Marshal(m)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("d2ir: failed to marshal d2ir.Map: %v", err))
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,10 @@ package d2ir_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"oss.terrastruct.com/util-go/assert"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2ast"
|
"oss.terrastruct.com/d2/d2ast"
|
||||||
"oss.terrastruct.com/d2/d2ir"
|
"oss.terrastruct.com/d2/d2ir"
|
||||||
"oss.terrastruct.com/d2/internal/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCopy(t *testing.T) {
|
func TestCopy(t *testing.T) {
|
||||||
|
|
@ -13,14 +14,11 @@ func TestCopy(t *testing.T) {
|
||||||
|
|
||||||
const scalStr = `Those who claim the dead never return to life haven't ever been around.`
|
const scalStr = `Those who claim the dead never return to life haven't ever been around.`
|
||||||
s := &d2ir.Scalar{
|
s := &d2ir.Scalar{
|
||||||
parent: nil,
|
|
||||||
Value: d2ast.FlatUnquotedString(scalStr),
|
Value: d2ast.FlatUnquotedString(scalStr),
|
||||||
}
|
}
|
||||||
a := &d2ir.Array{
|
a := &d2ir.Array{
|
||||||
Parent: nil,
|
|
||||||
Values: []d2ir.Value{
|
Values: []d2ir.Value{
|
||||||
&d2ir.Scalar{
|
&d2ir.Scalar{
|
||||||
parent: nil,
|
|
||||||
Value: &d2ast.Boolean{
|
Value: &d2ast.Boolean{
|
||||||
Value: true,
|
Value: true,
|
||||||
},
|
},
|
||||||
|
|
@ -28,7 +26,6 @@ func TestCopy(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
m2 := &d2ir.Map{
|
m2 := &d2ir.Map{
|
||||||
Parent: nil,
|
|
||||||
Fields: []*d2ir.Field{
|
Fields: []*d2ir.Field{
|
||||||
{Primary: s},
|
{Primary: s},
|
||||||
},
|
},
|
||||||
|
|
@ -36,20 +33,17 @@ func TestCopy(t *testing.T) {
|
||||||
|
|
||||||
const keyStr = `Absence makes the heart grow frantic.`
|
const keyStr = `Absence makes the heart grow frantic.`
|
||||||
f := &d2ir.Field{
|
f := &d2ir.Field{
|
||||||
Parent: nil,
|
|
||||||
Name: keyStr,
|
Name: keyStr,
|
||||||
|
|
||||||
Primary: s,
|
Primary: s,
|
||||||
Composite: a,
|
Composite: a,
|
||||||
}
|
}
|
||||||
e := &d2ir.Edge{
|
e := &d2ir.Edge{
|
||||||
Parent: nil,
|
|
||||||
|
|
||||||
Primary: s,
|
Primary: s,
|
||||||
Map: m2,
|
Map: m2,
|
||||||
}
|
}
|
||||||
m := &d2ir.Map{
|
m := &d2ir.Map{
|
||||||
Parent: nil,
|
|
||||||
|
|
||||||
Fields: []*d2ir.Field{f},
|
Fields: []*d2ir.Field{f},
|
||||||
Edges: []*d2ir.Edge{e},
|
Edges: []*d2ir.Edge{e},
|
||||||
|
|
@ -58,20 +52,20 @@ func TestCopy(t *testing.T) {
|
||||||
m = m.Copy(nil).(*d2ir.Map)
|
m = m.Copy(nil).(*d2ir.Map)
|
||||||
f.Name = `Many a wife thinks her husband is the world's greatest lover.`
|
f.Name = `Many a wife thinks her husband is the world's greatest lover.`
|
||||||
|
|
||||||
assert.Equal(t, m, m.Fields[0].Parent)
|
assert.Equal(t, m, m.Fields[0].Parent())
|
||||||
assert.Equal(t, keyStr, m.Fields[0].Name)
|
assert.Equal(t, keyStr, m.Fields[0].Name)
|
||||||
assert.Equal(t, m.Fields[0], m.Fields[0].Primary.parent)
|
assert.Equal(t, m.Fields[0], m.Fields[0].Primary.Parent())
|
||||||
assert.Equal(t, m.Fields[0], m.Fields[0].Composite.(*d2ir.Array).Parent)
|
assert.Equal(t, m.Fields[0], m.Fields[0].Composite.(*d2ir.Array).Parent())
|
||||||
|
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
m.Fields[0].Composite,
|
m.Fields[0].Composite,
|
||||||
m.Fields[0].Composite.(*d2ir.Array).Values[0].(*d2ir.Scalar).parent,
|
m.Fields[0].Composite.(*d2ir.Array).Values[0].(*d2ir.Scalar).Parent(),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert.Equal(t, m, m.Edges[0].Parent)
|
assert.Equal(t, m, m.Edges[0].Parent())
|
||||||
assert.Equal(t, m.Edges[0], m.Edges[0].Primary.parent)
|
assert.Equal(t, m.Edges[0], m.Edges[0].Primary.Parent())
|
||||||
assert.Equal(t, m.Edges[0], m.Edges[0].Map.Parent)
|
assert.Equal(t, m.Edges[0], m.Edges[0].Map.Parent())
|
||||||
|
|
||||||
assert.Equal(t, m.Edges[0].Map, m.Edges[0].Map.Fields[0].Parent)
|
assert.Equal(t, m.Edges[0].Map, m.Edges[0].Map.Fields[0].Parent())
|
||||||
assert.Equal(t, m.Edges[0].Map.Fields[0], m.Edges[0].Map.Fields[0].Primary.parent)
|
assert.Equal(t, m.Edges[0].Map.Fields[0], m.Edges[0].Map.Fields[0].Primary.Parent())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ func Parse(path string, r io.RuneReader, opts *ParseOptions) (*d2ast.Map, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
m := p.parseMap(true)
|
m := p.parseMap(true)
|
||||||
if !p.err.empty() {
|
if !p.err.Empty() {
|
||||||
return m, p.err
|
return m, p.err
|
||||||
}
|
}
|
||||||
return m, nil
|
return m, nil
|
||||||
|
|
@ -57,7 +57,7 @@ func ParseKey(key string) (*d2ast.KeyPath, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
k := p.parseKey()
|
k := p.parseKey()
|
||||||
if !p.err.empty() {
|
if !p.err.Empty() {
|
||||||
return nil, fmt.Errorf("failed to parse key %q: %w", key, p.err)
|
return nil, fmt.Errorf("failed to parse key %q: %w", key, p.err)
|
||||||
}
|
}
|
||||||
if k == nil {
|
if k == nil {
|
||||||
|
|
@ -72,7 +72,7 @@ func ParseMapKey(mapKey string) (*d2ast.Key, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mk := p.parseMapKey()
|
mk := p.parseMapKey()
|
||||||
if !p.err.empty() {
|
if !p.err.Empty() {
|
||||||
return nil, fmt.Errorf("failed to parse map key %q: %w", mapKey, p.err)
|
return nil, fmt.Errorf("failed to parse map key %q: %w", mapKey, p.err)
|
||||||
}
|
}
|
||||||
if mk == nil {
|
if mk == nil {
|
||||||
|
|
@ -87,7 +87,7 @@ func ParseValue(value string) (d2ast.Value, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
v := p.parseValue()
|
v := p.parseValue()
|
||||||
if !p.err.empty() {
|
if !p.err.Empty() {
|
||||||
return nil, fmt.Errorf("failed to parse value %q: %w", value, p.err)
|
return nil, fmt.Errorf("failed to parse value %q: %w", value, p.err)
|
||||||
}
|
}
|
||||||
if v.Unbox() == nil {
|
if v.Unbox() == nil {
|
||||||
|
|
@ -130,7 +130,7 @@ type ParseError struct {
|
||||||
Errors []d2ast.Error `json:"errs"`
|
Errors []d2ast.Error `json:"errs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pe ParseError) empty() bool {
|
func (pe ParseError) Empty() bool {
|
||||||
return pe.IOError == nil && len(pe.Errors) == 0
|
return pe.IOError == nil && len(pe.Errors) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
4
testdata/d2ir/TestApply/simple/nested.exp.json
generated
vendored
Normal file
4
testdata/d2ir/TestApply/simple/nested.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"fields": null,
|
||||||
|
"edges": null
|
||||||
|
}
|
||||||
8
testdata/d2ir/TestApply/simple/one.exp.json
generated
vendored
Normal file
8
testdata/d2ir/TestApply/simple/one.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edges": null
|
||||||
|
}
|
||||||
4
testdata/d2ir/TestApply/simple/underscore_parent.exp.json
generated
vendored
Normal file
4
testdata/d2ir/TestApply/simple/underscore_parent.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"fields": null,
|
||||||
|
"edges": null
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue