github.com/medzin/terraform@v0.11.11/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 }