github.com/jzbruno/terraform@v0.10.3-0.20180104230435-18975d727047/config/interpolate_walk_test.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/hil/ast"
     9  	"github.com/mitchellh/reflectwalk"
    10  )
    11  
    12  func TestInterpolationWalker_detect(t *testing.T) {
    13  	cases := []struct {
    14  		Input  interface{}
    15  		Result []string
    16  	}{
    17  		{
    18  			Input: map[string]interface{}{
    19  				"foo": "$${var.foo}",
    20  			},
    21  			Result: []string{
    22  				"Literal(TypeString, ${var.foo})",
    23  			},
    24  		},
    25  
    26  		{
    27  			Input: map[string]interface{}{
    28  				"foo": "${var.foo}",
    29  			},
    30  			Result: []string{
    31  				"Variable(var.foo)",
    32  			},
    33  		},
    34  
    35  		{
    36  			Input: map[string]interface{}{
    37  				"foo": "${aws_instance.foo.*.num}",
    38  			},
    39  			Result: []string{
    40  				"Variable(aws_instance.foo.*.num)",
    41  			},
    42  		},
    43  
    44  		{
    45  			Input: map[string]interface{}{
    46  				"foo": "${lookup(var.foo)}",
    47  			},
    48  			Result: []string{
    49  				"Call(lookup, Variable(var.foo))",
    50  			},
    51  		},
    52  
    53  		{
    54  			Input: map[string]interface{}{
    55  				"foo": `${file("test.txt")}`,
    56  			},
    57  			Result: []string{
    58  				"Call(file, Literal(TypeString, test.txt))",
    59  			},
    60  		},
    61  
    62  		{
    63  			Input: map[string]interface{}{
    64  				"foo": `${file("foo/bar.txt")}`,
    65  			},
    66  			Result: []string{
    67  				"Call(file, Literal(TypeString, foo/bar.txt))",
    68  			},
    69  		},
    70  
    71  		{
    72  			Input: map[string]interface{}{
    73  				"foo": `${join(",", foo.bar.*.id)}`,
    74  			},
    75  			Result: []string{
    76  				"Call(join, Literal(TypeString, ,), Variable(foo.bar.*.id))",
    77  			},
    78  		},
    79  
    80  		{
    81  			Input: map[string]interface{}{
    82  				"foo": `${concat("localhost", ":8080")}`,
    83  			},
    84  			Result: []string{
    85  				"Call(concat, Literal(TypeString, localhost), Literal(TypeString, :8080))",
    86  			},
    87  		},
    88  	}
    89  
    90  	for i, tc := range cases {
    91  		var actual []string
    92  		detectFn := func(root ast.Node) (interface{}, error) {
    93  			actual = append(actual, fmt.Sprintf("%s", root))
    94  			return "", nil
    95  		}
    96  
    97  		w := &interpolationWalker{F: detectFn}
    98  		if err := reflectwalk.Walk(tc.Input, w); err != nil {
    99  			t.Fatalf("err: %s", err)
   100  		}
   101  
   102  		if !reflect.DeepEqual(actual, tc.Result) {
   103  			t.Fatalf("%d: bad:\n\n%#v", i, actual)
   104  		}
   105  	}
   106  }
   107  
   108  func TestInterpolationWalker_replace(t *testing.T) {
   109  	cases := []struct {
   110  		Input  interface{}
   111  		Output interface{}
   112  		Value  interface{}
   113  	}{
   114  		{
   115  			Input: map[string]interface{}{
   116  				"foo": "$${var.foo}",
   117  			},
   118  			Output: map[string]interface{}{
   119  				"foo": "bar",
   120  			},
   121  			Value: "bar",
   122  		},
   123  
   124  		{
   125  			Input: map[string]interface{}{
   126  				"foo": "hello, ${var.foo}",
   127  			},
   128  			Output: map[string]interface{}{
   129  				"foo": "bar",
   130  			},
   131  			Value: "bar",
   132  		},
   133  
   134  		{
   135  			Input: map[string]interface{}{
   136  				"foo": map[string]interface{}{
   137  					"${var.foo}": "bar",
   138  				},
   139  			},
   140  			Output: map[string]interface{}{
   141  				"foo": map[string]interface{}{
   142  					"bar": "bar",
   143  				},
   144  			},
   145  			Value: "bar",
   146  		},
   147  
   148  		{
   149  			Input: map[string]interface{}{
   150  				"foo": []interface{}{
   151  					"${var.foo}",
   152  					"bing",
   153  				},
   154  			},
   155  			Output: map[string]interface{}{
   156  				"foo": []interface{}{
   157  					"bar",
   158  					"baz",
   159  					"bing",
   160  				},
   161  			},
   162  			Value: []interface{}{"bar", "baz"},
   163  		},
   164  
   165  		{
   166  			Input: map[string]interface{}{
   167  				"foo": []interface{}{
   168  					"${var.foo}",
   169  					"bing",
   170  				},
   171  			},
   172  			Output: map[string]interface{}{
   173  				"foo": []interface{}{
   174  					UnknownVariableValue,
   175  					"baz",
   176  					"bing",
   177  				},
   178  			},
   179  			Value: []interface{}{UnknownVariableValue, "baz"},
   180  		},
   181  	}
   182  
   183  	for i, tc := range cases {
   184  		fn := func(ast.Node) (interface{}, error) {
   185  			return tc.Value, nil
   186  		}
   187  
   188  		t.Run(fmt.Sprintf("walk-%d", i), func(t *testing.T) {
   189  			w := &interpolationWalker{F: fn, Replace: true}
   190  			if err := reflectwalk.Walk(tc.Input, w); err != nil {
   191  				t.Fatalf("err: %s", err)
   192  			}
   193  
   194  			if !reflect.DeepEqual(tc.Input, tc.Output) {
   195  				t.Fatalf("%d: bad:\n\nexpected:%#v\ngot:%#v", i, tc.Output, tc.Input)
   196  			}
   197  		})
   198  	}
   199  }