github.com/opentofu/opentofu@v1.7.1/internal/lang/funcs/render_template_test.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package funcs
     7  
     8  import (
     9  	"testing"
    10  
    11  	"github.com/hashicorp/hcl/v2"
    12  	"github.com/opentofu/opentofu/internal/lang/marks"
    13  	"github.com/zclconf/go-cty/cty"
    14  	"github.com/zclconf/go-cty/cty/function"
    15  )
    16  
    17  func TestRenderTemplate(t *testing.T) {
    18  	tests := map[string]struct {
    19  		Expr hcl.Expression
    20  		Vars cty.Value
    21  		Want cty.Value
    22  		Err  string
    23  	}{
    24  		"String interpolation with variable": {
    25  			hcl.StaticExpr(cty.StringVal("Hello, ${name}!"), hcl.Range{}),
    26  			cty.MapVal(map[string]cty.Value{
    27  				"name": cty.StringVal("Jodie"),
    28  			}),
    29  			cty.StringVal("Hello, ${name}!"),
    30  			``,
    31  		},
    32  		"Looping through list": {
    33  			hcl.StaticExpr(cty.StringVal("Items: %{ for x in list ~} ${x} %{ endfor ~}"), hcl.Range{}),
    34  			cty.ObjectVal(map[string]cty.Value{
    35  				"list": cty.ListVal([]cty.Value{
    36  					cty.StringVal("a"),
    37  					cty.StringVal("b"),
    38  					cty.StringVal("c"),
    39  				}),
    40  			}),
    41  			cty.StringVal("Items: %{ for x in list ~} ${x} %{ endfor ~}"),
    42  			``,
    43  		},
    44  		"Looping through map": {
    45  			hcl.StaticExpr(cty.StringVal("%{ for key, value in list ~} ${key}:${value} %{ endfor ~}"), hcl.Range{}),
    46  			cty.ObjectVal(map[string]cty.Value{
    47  				"list": cty.ObjectVal(map[string]cty.Value{
    48  					"item1": cty.StringVal("a"),
    49  					"item2": cty.StringVal("b"),
    50  					"item3": cty.StringVal("c"),
    51  				}),
    52  			}),
    53  			cty.StringVal("%{ for key, value in list ~} ${key}:${value} %{ endfor ~}"),
    54  			``,
    55  		},
    56  		"Invalid template variable name": {
    57  			hcl.StaticExpr(cty.StringVal("Hello, ${1}!"), hcl.Range{}),
    58  			cty.MapVal(map[string]cty.Value{
    59  				"1": cty.StringVal("Jodie"),
    60  			}),
    61  			cty.NilVal,
    62  			`invalid template variable name "1": must start with a letter, followed by zero or more letters, digits, and underscores`,
    63  		},
    64  		"Interpolation of a boolean value": {
    65  			hcl.StaticExpr(cty.StringVal("${val}"), hcl.Range{}),
    66  			cty.ObjectVal(map[string]cty.Value{
    67  				"val": cty.True,
    68  			}),
    69  			cty.StringVal("${val}"),
    70  			``,
    71  		},
    72  		"Sensitive string template": {
    73  			hcl.StaticExpr(cty.StringVal("My password is 1234").Mark(marks.Sensitive), hcl.Range{}),
    74  			cty.EmptyObjectVal,
    75  			cty.StringVal("My password is 1234").Mark(marks.Sensitive),
    76  			``,
    77  		},
    78  		"Sensitive template variable": {
    79  			hcl.StaticExpr(cty.StringVal("My password is ${pass}"), hcl.Range{}),
    80  			cty.ObjectVal(map[string]cty.Value{
    81  				"pass": cty.StringVal("secret").Mark(marks.Sensitive),
    82  			}),
    83  			cty.StringVal("My password is ${pass}"),
    84  			``,
    85  		},
    86  	}
    87  
    88  	for name, test := range tests {
    89  		t.Run(name, func(t *testing.T) {
    90  
    91  			got, err := renderTemplate(test.Expr, test.Vars, map[string]function.Function{})
    92  
    93  			if err != nil {
    94  				if test.Err == "" {
    95  					t.Fatalf("unexpected error: %s", err)
    96  				} else {
    97  					if got, want := err.Error(), test.Err; got != want {
    98  						t.Errorf("wrong error\ngot:  %s\nwant: %s", got, want)
    99  					}
   100  				}
   101  			} else if test.Err != "" {
   102  				t.Fatal("succeeded; want error")
   103  			} else {
   104  				if !got.RawEquals(test.Want) {
   105  					t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
   106  				}
   107  			}
   108  		})
   109  	}
   110  }