kubeform.dev/terraform-backend-sdk@v0.0.0-20220310143633-45f07fe731c5/configs/configschema/path_test.go (about)

     1  package configschema
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/zclconf/go-cty/cty"
     7  )
     8  
     9  func TestAttributeByPath(t *testing.T) {
    10  	schema := &Block{
    11  		Attributes: map[string]*Attribute{
    12  			"a1": {Description: "a1"},
    13  			"a2": {Description: "a2"},
    14  			"a3": {
    15  				Description: "a3",
    16  				NestedType: &Object{
    17  					Nesting: NestingList,
    18  					Attributes: map[string]*Attribute{
    19  						"nt1": {Description: "nt1"},
    20  						"nt2": {
    21  							Description: "nt2",
    22  							NestedType: &Object{
    23  								Nesting: NestingSingle,
    24  								Attributes: map[string]*Attribute{
    25  									"deeply_nested": {Description: "deeply_nested"},
    26  								},
    27  							},
    28  						},
    29  					},
    30  				},
    31  			},
    32  		},
    33  		BlockTypes: map[string]*NestedBlock{
    34  			"b1": {
    35  				Nesting: NestingList,
    36  				Block: Block{
    37  					Attributes: map[string]*Attribute{
    38  						"a3": {Description: "a3"},
    39  						"a4": {Description: "a4"},
    40  					},
    41  					BlockTypes: map[string]*NestedBlock{
    42  						"b2": {
    43  							Nesting: NestingMap,
    44  							Block: Block{
    45  								Attributes: map[string]*Attribute{
    46  									"a5": {Description: "a5"},
    47  									"a6": {Description: "a6"},
    48  								},
    49  							},
    50  						},
    51  					},
    52  				},
    53  			},
    54  			"b3": {
    55  				Nesting: NestingMap,
    56  				Block: Block{
    57  					Attributes: map[string]*Attribute{
    58  						"a7": {Description: "a7"},
    59  						"a8": {Description: "a8"},
    60  					},
    61  					BlockTypes: map[string]*NestedBlock{
    62  						"b4": {
    63  							Nesting: NestingSet,
    64  							Block: Block{
    65  								Attributes: map[string]*Attribute{
    66  									"a9":  {Description: "a9"},
    67  									"a10": {Description: "a10"},
    68  								},
    69  							},
    70  						},
    71  					},
    72  				},
    73  			},
    74  		},
    75  	}
    76  
    77  	for _, tc := range []struct {
    78  		path            cty.Path
    79  		attrDescription string
    80  		exists          bool
    81  	}{
    82  		{
    83  			cty.GetAttrPath("a2"),
    84  			"a2",
    85  			true,
    86  		},
    87  		{
    88  			cty.GetAttrPath("a3").IndexInt(1).GetAttr("nt2"),
    89  			"nt2",
    90  			true,
    91  		},
    92  		{
    93  			cty.GetAttrPath("a3").IndexInt(1).GetAttr("b2").IndexString("foo").GetAttr("no"),
    94  			"missing",
    95  			false,
    96  		},
    97  		{
    98  			cty.GetAttrPath("b1"),
    99  			"block",
   100  			false,
   101  		},
   102  		{
   103  			cty.GetAttrPath("b1").IndexInt(1).GetAttr("a3"),
   104  			"a3",
   105  			true,
   106  		},
   107  		{
   108  			cty.GetAttrPath("b1").IndexInt(1).GetAttr("b2").IndexString("foo").GetAttr("a7"),
   109  			"missing",
   110  			false,
   111  		},
   112  		{
   113  			cty.GetAttrPath("b1").IndexInt(1).GetAttr("b2").IndexString("foo").GetAttr("a6"),
   114  			"a6",
   115  			true,
   116  		},
   117  		{
   118  			cty.GetAttrPath("b3").IndexString("foo").GetAttr("b2").IndexString("foo").GetAttr("a7"),
   119  			"missing_block",
   120  			false,
   121  		},
   122  		{
   123  			cty.GetAttrPath("b3").IndexString("foo").GetAttr("a7"),
   124  			"a7",
   125  			true,
   126  		},
   127  		{
   128  			// Index steps don't apply to the schema, so the set Index value doesn't matter.
   129  			cty.GetAttrPath("b3").IndexString("foo").GetAttr("b4").Index(cty.EmptyObjectVal).GetAttr("a9"),
   130  			"a9",
   131  			true,
   132  		},
   133  	} {
   134  		t.Run(tc.attrDescription, func(t *testing.T) {
   135  			attr := schema.AttributeByPath(tc.path)
   136  			if !tc.exists && attr == nil {
   137  				return
   138  			}
   139  
   140  			if attr == nil {
   141  				t.Fatalf("missing attribute from path %#v\n", tc.path)
   142  			}
   143  
   144  			if attr.Description != tc.attrDescription {
   145  				t.Fatalf("expected Attribute for %q, got %#v\n", tc.attrDescription, attr)
   146  			}
   147  		})
   148  	}
   149  }
   150  
   151  func TestObject_AttributeByPath(t *testing.T) {
   152  	obj := &Object{
   153  		Nesting: NestingList,
   154  		Attributes: map[string]*Attribute{
   155  			"a1": {Description: "a1"},
   156  			"a2": {
   157  				Description: "a2",
   158  				NestedType: &Object{
   159  					Nesting: NestingSingle,
   160  					Attributes: map[string]*Attribute{
   161  						"n1": {Description: "n1"},
   162  						"n2": {
   163  							Description: "n2",
   164  							NestedType: &Object{
   165  								Attributes: map[string]*Attribute{
   166  									"dn1": {Description: "dn1"},
   167  								},
   168  							},
   169  						},
   170  					},
   171  				},
   172  			},
   173  		},
   174  	}
   175  
   176  	tests := []struct {
   177  		path            cty.Path
   178  		attrDescription string
   179  		exists          bool
   180  	}{
   181  		{
   182  			cty.GetAttrPath("a2"),
   183  			"a2",
   184  			true,
   185  		},
   186  		{
   187  			cty.GetAttrPath("a3"),
   188  			"missing",
   189  			false,
   190  		},
   191  		{
   192  			cty.GetAttrPath("a2").IndexString("foo").GetAttr("n1"),
   193  			"n1",
   194  			true,
   195  		},
   196  		{
   197  			cty.GetAttrPath("a2").IndexString("foo").GetAttr("n2").IndexInt(11).GetAttr("dn1"),
   198  			"dn1",
   199  			true,
   200  		},
   201  		{
   202  			cty.GetAttrPath("a2").IndexString("foo").GetAttr("n2").IndexInt(11).GetAttr("dn1").IndexString("hello").GetAttr("nope"),
   203  			"missing_nested",
   204  			false,
   205  		},
   206  	}
   207  
   208  	for _, tc := range tests {
   209  		t.Run(tc.attrDescription, func(t *testing.T) {
   210  			attr := obj.AttributeByPath(tc.path)
   211  			if !tc.exists && attr == nil {
   212  				return
   213  			}
   214  
   215  			if !tc.exists && attr != nil {
   216  				t.Fatalf("found Attribute, expected nil from path %#v\n", tc.path)
   217  			}
   218  
   219  			if attr == nil {
   220  				t.Fatalf("missing attribute from path %#v\n", tc.path)
   221  			}
   222  
   223  			if attr.Description != tc.attrDescription {
   224  				t.Fatalf("expected Attribute for %q, got %#v\n", tc.attrDescription, attr)
   225  			}
   226  		})
   227  	}
   228  
   229  }