| 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"}, |
| "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"}, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| 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, |
| }, |
| { |
| cty.GetAttrPath("a3").IndexInt(1).GetAttr("nt2"), |
| "nt2", |
| true, |
| }, |
| { |
| cty.GetAttrPath("a3").IndexInt(1).GetAttr("b2").IndexString("foo").GetAttr("no"), |
| "missing", |
| false, |
| }, |
| { |
| 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) |
| } |
| }) |
| } |
| } |
| |
| 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) |
| } |
| }) |
| } |
| |
| } |