github.com/opentofu/opentofu@v1.7.1/internal/gohcl/schema_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package gohcl
     5  
     6  import (
     7  	"fmt"
     8  	"reflect"
     9  	"testing"
    10  
    11  	"github.com/davecgh/go-spew/spew"
    12  	"github.com/hashicorp/hcl/v2"
    13  )
    14  
    15  func TestImpliedBodySchema(t *testing.T) {
    16  	tests := []struct {
    17  		val         interface{}
    18  		wantSchema  *hcl.BodySchema
    19  		wantPartial bool
    20  	}{
    21  		{
    22  			struct{}{},
    23  			&hcl.BodySchema{},
    24  			false,
    25  		},
    26  		{
    27  			struct {
    28  				Ignored bool
    29  			}{},
    30  			&hcl.BodySchema{},
    31  			false,
    32  		},
    33  		{
    34  			struct {
    35  				Attr1 bool `hcl:"attr1"`
    36  				Attr2 bool `hcl:"attr2"`
    37  			}{},
    38  			&hcl.BodySchema{
    39  				Attributes: []hcl.AttributeSchema{
    40  					{
    41  						Name:     "attr1",
    42  						Required: true,
    43  					},
    44  					{
    45  						Name:     "attr2",
    46  						Required: true,
    47  					},
    48  				},
    49  			},
    50  			false,
    51  		},
    52  		{
    53  			struct {
    54  				Attr *bool `hcl:"attr,attr"`
    55  			}{},
    56  			&hcl.BodySchema{
    57  				Attributes: []hcl.AttributeSchema{
    58  					{
    59  						Name:     "attr",
    60  						Required: false,
    61  					},
    62  				},
    63  			},
    64  			false,
    65  		},
    66  		{
    67  			struct {
    68  				Thing struct{} `hcl:"thing,block"`
    69  			}{},
    70  			&hcl.BodySchema{
    71  				Blocks: []hcl.BlockHeaderSchema{
    72  					{
    73  						Type: "thing",
    74  					},
    75  				},
    76  			},
    77  			false,
    78  		},
    79  		{
    80  			struct {
    81  				Thing struct {
    82  					Type string `hcl:"type,label"`
    83  					Name string `hcl:"name,label"`
    84  				} `hcl:"thing,block"`
    85  			}{},
    86  			&hcl.BodySchema{
    87  				Blocks: []hcl.BlockHeaderSchema{
    88  					{
    89  						Type:       "thing",
    90  						LabelNames: []string{"type", "name"},
    91  					},
    92  				},
    93  			},
    94  			false,
    95  		},
    96  		{
    97  			struct {
    98  				Thing []struct {
    99  					Type string `hcl:"type,label"`
   100  					Name string `hcl:"name,label"`
   101  				} `hcl:"thing,block"`
   102  			}{},
   103  			&hcl.BodySchema{
   104  				Blocks: []hcl.BlockHeaderSchema{
   105  					{
   106  						Type:       "thing",
   107  						LabelNames: []string{"type", "name"},
   108  					},
   109  				},
   110  			},
   111  			false,
   112  		},
   113  		{
   114  			struct {
   115  				Thing *struct {
   116  					Type string `hcl:"type,label"`
   117  					Name string `hcl:"name,label"`
   118  				} `hcl:"thing,block"`
   119  			}{},
   120  			&hcl.BodySchema{
   121  				Blocks: []hcl.BlockHeaderSchema{
   122  					{
   123  						Type:       "thing",
   124  						LabelNames: []string{"type", "name"},
   125  					},
   126  				},
   127  			},
   128  			false,
   129  		},
   130  		{
   131  			struct {
   132  				Thing struct {
   133  					Name      string `hcl:"name,label"`
   134  					Something string `hcl:"something"`
   135  				} `hcl:"thing,block"`
   136  			}{},
   137  			&hcl.BodySchema{
   138  				Blocks: []hcl.BlockHeaderSchema{
   139  					{
   140  						Type:       "thing",
   141  						LabelNames: []string{"name"},
   142  					},
   143  				},
   144  			},
   145  			false,
   146  		},
   147  		{
   148  			struct {
   149  				Doodad string `hcl:"doodad"`
   150  				Thing  struct {
   151  					Name string `hcl:"name,label"`
   152  				} `hcl:"thing,block"`
   153  			}{},
   154  			&hcl.BodySchema{
   155  				Attributes: []hcl.AttributeSchema{
   156  					{
   157  						Name:     "doodad",
   158  						Required: true,
   159  					},
   160  				},
   161  				Blocks: []hcl.BlockHeaderSchema{
   162  					{
   163  						Type:       "thing",
   164  						LabelNames: []string{"name"},
   165  					},
   166  				},
   167  			},
   168  			false,
   169  		},
   170  		{
   171  			struct {
   172  				Doodad string `hcl:"doodad"`
   173  				Config string `hcl:",remain"`
   174  			}{},
   175  			&hcl.BodySchema{
   176  				Attributes: []hcl.AttributeSchema{
   177  					{
   178  						Name:     "doodad",
   179  						Required: true,
   180  					},
   181  				},
   182  			},
   183  			true,
   184  		},
   185  		{
   186  			struct {
   187  				Expr hcl.Expression `hcl:"expr"`
   188  			}{},
   189  			&hcl.BodySchema{
   190  				Attributes: []hcl.AttributeSchema{
   191  					{
   192  						Name:     "expr",
   193  						Required: false,
   194  					},
   195  				},
   196  			},
   197  			false,
   198  		},
   199  		{
   200  			struct {
   201  				Meh string `hcl:"meh,optional"`
   202  			}{},
   203  			&hcl.BodySchema{
   204  				Attributes: []hcl.AttributeSchema{
   205  					{
   206  						Name:     "meh",
   207  						Required: false,
   208  					},
   209  				},
   210  			},
   211  			false,
   212  		},
   213  	}
   214  
   215  	for _, test := range tests {
   216  		t.Run(fmt.Sprintf("%#v", test.val), func(t *testing.T) {
   217  			schema, partial := ImpliedBodySchema(test.val)
   218  			if !reflect.DeepEqual(schema, test.wantSchema) {
   219  				t.Errorf(
   220  					"wrong schema\ngot:  %s\nwant: %s",
   221  					spew.Sdump(schema), spew.Sdump(test.wantSchema),
   222  				)
   223  			}
   224  
   225  			if partial != test.wantPartial {
   226  				t.Errorf(
   227  					"wrong partial flag\ngot:  %#v\nwant: %#v",
   228  					partial, test.wantPartial,
   229  				)
   230  			}
   231  		})
   232  	}
   233  }