github.com/chalford/terraform@v0.3.7-0.20150113080010-a78c69a8c81f/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  			Input: map[string]interface{}{
   135  				"foo": `${concat("localhost", ":8080")}`,
   136  			},
   137  			Result: []Interpolation{
   138  				&FunctionInterpolation{
   139  					Func: nil,
   140  					Args: []Interpolation{
   141  						&LiteralInterpolation{
   142  							Literal: "localhost",
   143  						},
   144  						&LiteralInterpolation{
   145  							Literal: ":8080",
   146  						},
   147  					},
   148  				},
   149  			},
   150  		},
   151  	}
   152  
   153  	for i, tc := range cases {
   154  		var actual []Interpolation
   155  
   156  		detectFn := func(i Interpolation) (string, error) {
   157  			actual = append(actual, i)
   158  			return "", nil
   159  		}
   160  
   161  		w := &interpolationWalker{F: detectFn}
   162  		if err := reflectwalk.Walk(tc.Input, w); err != nil {
   163  			t.Fatalf("err: %s", err)
   164  		}
   165  
   166  		for _, a := range actual {
   167  			// This is jank, but reflect.DeepEqual never has functions
   168  			// being the same.
   169  			if f, ok := a.(*FunctionInterpolation); ok {
   170  				f.Func = nil
   171  			}
   172  		}
   173  
   174  		if !reflect.DeepEqual(actual, tc.Result) {
   175  			t.Fatalf("%d: bad:\n\n%#v", i, actual)
   176  		}
   177  	}
   178  }
   179  
   180  func TestInterpolationWalker_replace(t *testing.T) {
   181  	cases := []struct {
   182  		Input  interface{}
   183  		Output interface{}
   184  		Value  string
   185  	}{
   186  		{
   187  			Input: map[string]interface{}{
   188  				"foo": "$${var.foo}",
   189  			},
   190  			Output: map[string]interface{}{
   191  				"foo": "$${var.foo}",
   192  			},
   193  			Value: "bar",
   194  		},
   195  
   196  		{
   197  			Input: map[string]interface{}{
   198  				"foo": "hello, ${var.foo}",
   199  			},
   200  			Output: map[string]interface{}{
   201  				"foo": "hello, bar",
   202  			},
   203  			Value: "bar",
   204  		},
   205  
   206  		{
   207  			Input: map[string]interface{}{
   208  				"foo": map[string]interface{}{
   209  					"${var.foo}": "bar",
   210  				},
   211  			},
   212  			Output: map[string]interface{}{
   213  				"foo": map[string]interface{}{
   214  					"bar": "bar",
   215  				},
   216  			},
   217  			Value: "bar",
   218  		},
   219  
   220  		{
   221  			Input: map[string]interface{}{
   222  				"foo": []interface{}{
   223  					"${var.foo}",
   224  					"bing",
   225  				},
   226  			},
   227  			Output: map[string]interface{}{
   228  				"foo": []interface{}{
   229  					"bar",
   230  					"baz",
   231  					"bing",
   232  				},
   233  			},
   234  			Value: "bar" + InterpSplitDelim + "baz",
   235  		},
   236  
   237  		{
   238  			Input: map[string]interface{}{
   239  				"foo": []interface{}{
   240  					"${var.foo}",
   241  					"bing",
   242  				},
   243  			},
   244  			Output: map[string]interface{}{},
   245  			Value:  UnknownVariableValue + InterpSplitDelim + "baz",
   246  		},
   247  	}
   248  
   249  	for i, tc := range cases {
   250  		fn := func(i Interpolation) (string, error) {
   251  			return tc.Value, nil
   252  		}
   253  
   254  		w := &interpolationWalker{F: fn, Replace: true}
   255  		if err := reflectwalk.Walk(tc.Input, w); err != nil {
   256  			t.Fatalf("err: %s", err)
   257  		}
   258  
   259  		if !reflect.DeepEqual(tc.Input, tc.Output) {
   260  			t.Fatalf("%d: bad:\n\n%#v", i, tc.Input)
   261  		}
   262  	}
   263  }