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 }