github.com/hashicorp/hcl/v2@v2.20.0/hcldec/variables_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package hcldec
     5  
     6  import (
     7  	"fmt"
     8  	"reflect"
     9  	"testing"
    10  
    11  	"github.com/hashicorp/hcl/v2"
    12  	"github.com/hashicorp/hcl/v2/hclsyntax"
    13  	"github.com/zclconf/go-cty/cty"
    14  )
    15  
    16  func TestVariables(t *testing.T) {
    17  	tests := []struct {
    18  		config string
    19  		spec   Spec
    20  		want   []hcl.Traversal
    21  	}{
    22  		{
    23  			``,
    24  			&ObjectSpec{},
    25  			nil,
    26  		},
    27  		{
    28  			"a = foo\n",
    29  			&ObjectSpec{},
    30  			nil, // "a" is not actually used, so "foo" is not required
    31  		},
    32  		{
    33  			"a = foo\n",
    34  			&AttrSpec{
    35  				Name: "a",
    36  			},
    37  			[]hcl.Traversal{
    38  				{
    39  					hcl.TraverseRoot{
    40  						Name: "foo",
    41  						SrcRange: hcl.Range{
    42  							Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
    43  							End:   hcl.Pos{Line: 1, Column: 8, Byte: 7},
    44  						},
    45  					},
    46  				},
    47  			},
    48  		},
    49  		{
    50  			"a = foo\nb = bar\n",
    51  			&DefaultSpec{
    52  				Primary: &AttrSpec{
    53  					Name: "a",
    54  				},
    55  				Default: &AttrSpec{
    56  					Name: "b",
    57  				},
    58  			},
    59  			[]hcl.Traversal{
    60  				{
    61  					hcl.TraverseRoot{
    62  						Name: "foo",
    63  						SrcRange: hcl.Range{
    64  							Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
    65  							End:   hcl.Pos{Line: 1, Column: 8, Byte: 7},
    66  						},
    67  					},
    68  				},
    69  				{
    70  					hcl.TraverseRoot{
    71  						Name: "bar",
    72  						SrcRange: hcl.Range{
    73  							Start: hcl.Pos{Line: 2, Column: 5, Byte: 12},
    74  							End:   hcl.Pos{Line: 2, Column: 8, Byte: 15},
    75  						},
    76  					},
    77  				},
    78  			},
    79  		},
    80  		{
    81  			"a = foo\n",
    82  			&ObjectSpec{
    83  				"a": &AttrSpec{
    84  					Name: "a",
    85  				},
    86  			},
    87  			[]hcl.Traversal{
    88  				{
    89  					hcl.TraverseRoot{
    90  						Name: "foo",
    91  						SrcRange: hcl.Range{
    92  							Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
    93  							End:   hcl.Pos{Line: 1, Column: 8, Byte: 7},
    94  						},
    95  					},
    96  				},
    97  			},
    98  		},
    99  		{
   100  			`
   101  b {
   102    a = foo
   103  }
   104  `,
   105  			&BlockSpec{
   106  				TypeName: "b",
   107  				Nested: &AttrSpec{
   108  					Name: "a",
   109  				},
   110  			},
   111  			[]hcl.Traversal{
   112  				{
   113  					hcl.TraverseRoot{
   114  						Name: "foo",
   115  						SrcRange: hcl.Range{
   116  							Start: hcl.Pos{Line: 3, Column: 7, Byte: 11},
   117  							End:   hcl.Pos{Line: 3, Column: 10, Byte: 14},
   118  						},
   119  					},
   120  				},
   121  			},
   122  		},
   123  		{
   124  			`
   125  b {
   126    a = foo
   127    b = bar
   128  }
   129  `,
   130  			&BlockAttrsSpec{
   131  				TypeName:    "b",
   132  				ElementType: cty.String,
   133  			},
   134  			[]hcl.Traversal{
   135  				{
   136  					hcl.TraverseRoot{
   137  						Name: "foo",
   138  						SrcRange: hcl.Range{
   139  							Start: hcl.Pos{Line: 3, Column: 7, Byte: 11},
   140  							End:   hcl.Pos{Line: 3, Column: 10, Byte: 14},
   141  						},
   142  					},
   143  				},
   144  				{
   145  					hcl.TraverseRoot{
   146  						Name: "bar",
   147  						SrcRange: hcl.Range{
   148  							Start: hcl.Pos{Line: 4, Column: 7, Byte: 21},
   149  							End:   hcl.Pos{Line: 4, Column: 10, Byte: 24},
   150  						},
   151  					},
   152  				},
   153  			},
   154  		},
   155  		{
   156  			`
   157  b {
   158    a = foo
   159  }
   160  b {
   161    a = bar
   162  }
   163  c {
   164    a = baz
   165  }
   166  `,
   167  			&BlockListSpec{
   168  				TypeName: "b",
   169  				Nested: &AttrSpec{
   170  					Name: "a",
   171  				},
   172  			},
   173  			[]hcl.Traversal{
   174  				{
   175  					hcl.TraverseRoot{
   176  						Name: "foo",
   177  						SrcRange: hcl.Range{
   178  							Start: hcl.Pos{Line: 3, Column: 7, Byte: 11},
   179  							End:   hcl.Pos{Line: 3, Column: 10, Byte: 14},
   180  						},
   181  					},
   182  				},
   183  				{
   184  					hcl.TraverseRoot{
   185  						Name: "bar",
   186  						SrcRange: hcl.Range{
   187  							Start: hcl.Pos{Line: 6, Column: 7, Byte: 27},
   188  							End:   hcl.Pos{Line: 6, Column: 10, Byte: 30},
   189  						},
   190  					},
   191  				},
   192  			},
   193  		},
   194  	}
   195  
   196  	for i, test := range tests {
   197  		t.Run(fmt.Sprintf("%02d-%s", i, test.config), func(t *testing.T) {
   198  			file, diags := hclsyntax.ParseConfig([]byte(test.config), "", hcl.Pos{Line: 1, Column: 1, Byte: 0})
   199  			if len(diags) != 0 {
   200  				t.Errorf("wrong number of diagnostics from ParseConfig %d; want %d", len(diags), 0)
   201  				for _, diag := range diags {
   202  					t.Logf(" - %s", diag.Error())
   203  				}
   204  			}
   205  			body := file.Body
   206  
   207  			got := Variables(body, test.spec)
   208  
   209  			if !reflect.DeepEqual(got, test.want) {
   210  				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.want)
   211  			}
   212  		})
   213  	}
   214  
   215  }