github.com/lamielle/terraform@v0.3.2-0.20141121070651-81f008ba53d5/config/interpolate_walk_test.go (about)

     1  package config
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/mitchellh/reflectwalk"
     8  )
     9  
    10  func TestInterpolationWalker_detect(t *testing.T) {
    11  	cases := []struct {
    12  		Input  interface{}
    13  		Result []Interpolation
    14  	}{
    15  		{
    16  			Input: map[string]interface{}{
    17  				"foo": "$${var.foo}",
    18  			},
    19  			Result: nil,
    20  		},
    21  
    22  		{
    23  			Input: map[string]interface{}{
    24  				"foo": "${var.foo}",
    25  			},
    26  			Result: []Interpolation{
    27  				&VariableInterpolation{
    28  					Variable: &UserVariable{
    29  						Name: "foo",
    30  						key:  "var.foo",
    31  					},
    32  				},
    33  			},
    34  		},
    35  
    36  		{
    37  			Input: map[string]interface{}{
    38  				"foo": "${aws_instance.foo.*.num}",
    39  			},
    40  			Result: []Interpolation{
    41  				&VariableInterpolation{
    42  					Variable: &ResourceVariable{
    43  						Type:  "aws_instance",
    44  						Name:  "foo",
    45  						Field: "num",
    46  
    47  						Multi: true,
    48  						Index: -1,
    49  
    50  						key: "aws_instance.foo.*.num",
    51  					},
    52  				},
    53  			},
    54  		},
    55  
    56  		{
    57  			Input: map[string]interface{}{
    58  				"foo": "${lookup(var.foo)}",
    59  			},
    60  			Result: []Interpolation{
    61  				&FunctionInterpolation{
    62  					Func: nil,
    63  					Args: []Interpolation{
    64  						&VariableInterpolation{
    65  							Variable: &UserVariable{
    66  								Name: "foo",
    67  								key:  "var.foo",
    68  							},
    69  						},
    70  					},
    71  				},
    72  			},
    73  		},
    74  
    75  		{
    76  			Input: map[string]interface{}{
    77  				"foo": `${file("test.txt")}`,
    78  			},
    79  			Result: []Interpolation{
    80  				&FunctionInterpolation{
    81  					Func: nil,
    82  					Args: []Interpolation{
    83  						&LiteralInterpolation{
    84  							Literal: "test.txt",
    85  						},
    86  					},
    87  				},
    88  			},
    89  		},
    90  
    91  		{
    92  			Input: map[string]interface{}{
    93  				"foo": `${file("foo/bar.txt")}`,
    94  			},
    95  			Result: []Interpolation{
    96  				&FunctionInterpolation{
    97  					Func: nil,
    98  					Args: []Interpolation{
    99  						&LiteralInterpolation{
   100  							Literal: "foo/bar.txt",
   101  						},
   102  					},
   103  				},
   104  			},
   105  		},
   106  
   107  		{
   108  			Input: map[string]interface{}{
   109  				"foo": `${join(",", foo.bar.*.id)}`,
   110  			},
   111  			Result: []Interpolation{
   112  				&FunctionInterpolation{
   113  					Func: nil,
   114  					Args: []Interpolation{
   115  						&LiteralInterpolation{
   116  							Literal: ",",
   117  						},
   118  						&VariableInterpolation{
   119  							Variable: &ResourceVariable{
   120  								Type:  "foo",
   121  								Name:  "bar",
   122  								Field: "id",
   123  								Multi: true,
   124  								Index: -1,
   125  								key:   "foo.bar.*.id",
   126  							},
   127  						},
   128  					},
   129  				},
   130  			},
   131  		},
   132  	}
   133  
   134  	for i, tc := range cases {
   135  		var actual []Interpolation
   136  
   137  		detectFn := func(i Interpolation) (string, error) {
   138  			actual = append(actual, i)
   139  			return "", nil
   140  		}
   141  
   142  		w := &interpolationWalker{F: detectFn}
   143  		if err := reflectwalk.Walk(tc.Input, w); err != nil {
   144  			t.Fatalf("err: %s", err)
   145  		}
   146  
   147  		for _, a := range actual {
   148  			// This is jank, but reflect.DeepEqual never has functions
   149  			// being the same.
   150  			if f, ok := a.(*FunctionInterpolation); ok {
   151  				f.Func = nil
   152  			}
   153  		}
   154  
   155  		if !reflect.DeepEqual(actual, tc.Result) {
   156  			t.Fatalf("%d: bad:\n\n%#v", i, actual)
   157  		}
   158  	}
   159  }
   160  
   161  func TestInterpolationWalker_replace(t *testing.T) {
   162  	cases := []struct {
   163  		Input  interface{}
   164  		Output interface{}
   165  		Value  string
   166  	}{
   167  		{
   168  			Input: map[string]interface{}{
   169  				"foo": "$${var.foo}",
   170  			},
   171  			Output: map[string]interface{}{
   172  				"foo": "$${var.foo}",
   173  			},
   174  			Value: "bar",
   175  		},
   176  
   177  		{
   178  			Input: map[string]interface{}{
   179  				"foo": "hello, ${var.foo}",
   180  			},
   181  			Output: map[string]interface{}{
   182  				"foo": "hello, bar",
   183  			},
   184  			Value: "bar",
   185  		},
   186  
   187  		{
   188  			Input: map[string]interface{}{
   189  				"foo": map[string]interface{}{
   190  					"${var.foo}": "bar",
   191  				},
   192  			},
   193  			Output: map[string]interface{}{
   194  				"foo": map[string]interface{}{
   195  					"bar": "bar",
   196  				},
   197  			},
   198  			Value: "bar",
   199  		},
   200  
   201  		{
   202  			Input: map[string]interface{}{
   203  				"foo": []interface{}{
   204  					"${var.foo}",
   205  					"bing",
   206  				},
   207  			},
   208  			Output: map[string]interface{}{
   209  				"foo": []interface{}{
   210  					"bar",
   211  					"baz",
   212  					"bing",
   213  				},
   214  			},
   215  			Value: "bar" + InterpSplitDelim + "baz",
   216  		},
   217  
   218  		{
   219  			Input: map[string]interface{}{
   220  				"foo": []interface{}{
   221  					"${var.foo}",
   222  					"bing",
   223  				},
   224  			},
   225  			Output: map[string]interface{}{},
   226  			Value:  UnknownVariableValue + InterpSplitDelim + "baz",
   227  		},
   228  	}
   229  
   230  	for i, tc := range cases {
   231  		fn := func(i Interpolation) (string, error) {
   232  			return tc.Value, nil
   233  		}
   234  
   235  		w := &interpolationWalker{F: fn, Replace: true}
   236  		if err := reflectwalk.Walk(tc.Input, w); err != nil {
   237  			t.Fatalf("err: %s", err)
   238  		}
   239  
   240  		if !reflect.DeepEqual(tc.Input, tc.Output) {
   241  			t.Fatalf("%d: bad:\n\n%#v", i, tc.Input)
   242  		}
   243  	}
   244  }