2021-01-12 00:11:37 +01:00
|
|
|
package configschema
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/zclconf/go-cty/cty"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestAttributeByPath(t *testing.T) {
|
|
|
|
schema := &Block{
|
|
|
|
Attributes: map[string]*Attribute{
|
|
|
|
"a1": {Description: "a1"},
|
|
|
|
"a2": {Description: "a2"},
|
2021-07-22 15:45:33 +02:00
|
|
|
"a3": {
|
|
|
|
Description: "a3",
|
|
|
|
NestedType: &Object{
|
|
|
|
Nesting: NestingList,
|
|
|
|
Attributes: map[string]*Attribute{
|
|
|
|
"nt1": {Description: "nt1"},
|
|
|
|
"nt2": {
|
|
|
|
Description: "nt2",
|
|
|
|
NestedType: &Object{
|
|
|
|
Nesting: NestingSingle,
|
|
|
|
Attributes: map[string]*Attribute{
|
|
|
|
"deeply_nested": {Description: "deeply_nested"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2021-01-12 00:11:37 +01:00
|
|
|
},
|
|
|
|
BlockTypes: map[string]*NestedBlock{
|
|
|
|
"b1": {
|
|
|
|
Nesting: NestingList,
|
|
|
|
Block: Block{
|
|
|
|
Attributes: map[string]*Attribute{
|
|
|
|
"a3": {Description: "a3"},
|
|
|
|
"a4": {Description: "a4"},
|
|
|
|
},
|
|
|
|
BlockTypes: map[string]*NestedBlock{
|
|
|
|
"b2": {
|
|
|
|
Nesting: NestingMap,
|
|
|
|
Block: Block{
|
|
|
|
Attributes: map[string]*Attribute{
|
|
|
|
"a5": {Description: "a5"},
|
|
|
|
"a6": {Description: "a6"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"b3": {
|
|
|
|
Nesting: NestingMap,
|
|
|
|
Block: Block{
|
|
|
|
Attributes: map[string]*Attribute{
|
|
|
|
"a7": {Description: "a7"},
|
|
|
|
"a8": {Description: "a8"},
|
|
|
|
},
|
|
|
|
BlockTypes: map[string]*NestedBlock{
|
|
|
|
"b4": {
|
|
|
|
Nesting: NestingSet,
|
|
|
|
Block: Block{
|
|
|
|
Attributes: map[string]*Attribute{
|
|
|
|
"a9": {Description: "a9"},
|
|
|
|
"a10": {Description: "a10"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range []struct {
|
|
|
|
path cty.Path
|
|
|
|
attrDescription string
|
|
|
|
exists bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("a2"),
|
|
|
|
"a2",
|
|
|
|
true,
|
|
|
|
},
|
2021-07-22 15:45:33 +02:00
|
|
|
{
|
|
|
|
cty.GetAttrPath("a3").IndexInt(1).GetAttr("nt2"),
|
|
|
|
"nt2",
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("a3").IndexInt(1).GetAttr("b2").IndexString("foo").GetAttr("no"),
|
|
|
|
"missing",
|
|
|
|
false,
|
|
|
|
},
|
2021-01-12 00:11:37 +01:00
|
|
|
{
|
|
|
|
cty.GetAttrPath("b1"),
|
|
|
|
"block",
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("b1").IndexInt(1).GetAttr("a3"),
|
|
|
|
"a3",
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("b1").IndexInt(1).GetAttr("b2").IndexString("foo").GetAttr("a7"),
|
|
|
|
"missing",
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("b1").IndexInt(1).GetAttr("b2").IndexString("foo").GetAttr("a6"),
|
|
|
|
"a6",
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("b3").IndexString("foo").GetAttr("b2").IndexString("foo").GetAttr("a7"),
|
|
|
|
"missing_block",
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("b3").IndexString("foo").GetAttr("a7"),
|
|
|
|
"a7",
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// Index steps don't apply to the schema, so the set Index value doesn't matter.
|
|
|
|
cty.GetAttrPath("b3").IndexString("foo").GetAttr("b4").Index(cty.EmptyObjectVal).GetAttr("a9"),
|
|
|
|
"a9",
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
} {
|
|
|
|
t.Run(tc.attrDescription, func(t *testing.T) {
|
|
|
|
attr := schema.AttributeByPath(tc.path)
|
|
|
|
if !tc.exists && attr == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if attr == nil {
|
|
|
|
t.Fatalf("missing attribute from path %#v\n", tc.path)
|
|
|
|
}
|
|
|
|
|
|
|
|
if attr.Description != tc.attrDescription {
|
|
|
|
t.Fatalf("expected Attribute for %q, got %#v\n", tc.attrDescription, attr)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2021-07-22 15:45:33 +02:00
|
|
|
|
|
|
|
func TestObject_AttributeByPath(t *testing.T) {
|
|
|
|
obj := &Object{
|
|
|
|
Nesting: NestingList,
|
|
|
|
Attributes: map[string]*Attribute{
|
|
|
|
"a1": {Description: "a1"},
|
|
|
|
"a2": {
|
|
|
|
Description: "a2",
|
|
|
|
NestedType: &Object{
|
|
|
|
Nesting: NestingSingle,
|
|
|
|
Attributes: map[string]*Attribute{
|
|
|
|
"n1": {Description: "n1"},
|
|
|
|
"n2": {
|
|
|
|
Description: "n2",
|
|
|
|
NestedType: &Object{
|
|
|
|
Attributes: map[string]*Attribute{
|
|
|
|
"dn1": {Description: "dn1"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
path cty.Path
|
|
|
|
attrDescription string
|
|
|
|
exists bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("a2"),
|
|
|
|
"a2",
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("a3"),
|
|
|
|
"missing",
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("a2").IndexString("foo").GetAttr("n1"),
|
|
|
|
"n1",
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("a2").IndexString("foo").GetAttr("n2").IndexInt(11).GetAttr("dn1"),
|
|
|
|
"dn1",
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
cty.GetAttrPath("a2").IndexString("foo").GetAttr("n2").IndexInt(11).GetAttr("dn1").IndexString("hello").GetAttr("nope"),
|
|
|
|
"missing_nested",
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range tests {
|
|
|
|
t.Run(tc.attrDescription, func(t *testing.T) {
|
|
|
|
attr := obj.AttributeByPath(tc.path)
|
|
|
|
if !tc.exists && attr == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if !tc.exists && attr != nil {
|
|
|
|
t.Fatalf("found Attribute, expected nil from path %#v\n", tc.path)
|
|
|
|
}
|
|
|
|
|
|
|
|
if attr == nil {
|
|
|
|
t.Fatalf("missing attribute from path %#v\n", tc.path)
|
|
|
|
}
|
|
|
|
|
|
|
|
if attr.Description != tc.attrDescription {
|
|
|
|
t.Fatalf("expected Attribute for %q, got %#v\n", tc.attrDescription, attr)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|