github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/config/lang/eval_test.go (about) 1 package lang 2 3 import ( 4 "reflect" 5 "strconv" 6 "testing" 7 8 "github.com/hashicorp/terraform/config/lang/ast" 9 ) 10 11 func TestEval(t *testing.T) { 12 cases := []struct { 13 Input string 14 Scope *ast.BasicScope 15 Error bool 16 Result interface{} 17 ResultType ast.Type 18 }{ 19 { 20 "foo", 21 nil, 22 false, 23 "foo", 24 ast.TypeString, 25 }, 26 27 { 28 "foo ${bar}", 29 &ast.BasicScope{ 30 VarMap: map[string]ast.Variable{ 31 "bar": ast.Variable{ 32 Value: "baz", 33 Type: ast.TypeString, 34 }, 35 }, 36 }, 37 false, 38 "foo baz", 39 ast.TypeString, 40 }, 41 42 { 43 "foo ${42+1}", 44 nil, 45 false, 46 "foo 43", 47 ast.TypeString, 48 }, 49 50 { 51 "foo ${42-1}", 52 nil, 53 false, 54 "foo 41", 55 ast.TypeString, 56 }, 57 58 { 59 "foo ${42*2}", 60 nil, 61 false, 62 "foo 84", 63 ast.TypeString, 64 }, 65 66 { 67 "foo ${42/2}", 68 nil, 69 false, 70 "foo 21", 71 ast.TypeString, 72 }, 73 74 { 75 "foo ${42%4}", 76 nil, 77 false, 78 "foo 2", 79 ast.TypeString, 80 }, 81 82 { 83 "foo ${42.0+1.0}", 84 nil, 85 false, 86 "foo 43", 87 ast.TypeString, 88 }, 89 90 { 91 "foo ${42.0+1}", 92 nil, 93 false, 94 "foo 43", 95 ast.TypeString, 96 }, 97 98 { 99 "foo ${42+1.0}", 100 nil, 101 false, 102 "foo 43", 103 ast.TypeString, 104 }, 105 106 { 107 "foo ${42+2*2}", 108 nil, 109 false, 110 "foo 88", 111 ast.TypeString, 112 }, 113 114 { 115 "foo ${42+(2*2)}", 116 nil, 117 false, 118 "foo 46", 119 ast.TypeString, 120 }, 121 122 { 123 "foo ${bar+1}", 124 &ast.BasicScope{ 125 VarMap: map[string]ast.Variable{ 126 "bar": ast.Variable{ 127 Value: 41, 128 Type: ast.TypeInt, 129 }, 130 }, 131 }, 132 false, 133 "foo 42", 134 ast.TypeString, 135 }, 136 137 { 138 "foo ${bar+1}", 139 &ast.BasicScope{ 140 VarMap: map[string]ast.Variable{ 141 "bar": ast.Variable{ 142 Value: "41", 143 Type: ast.TypeString, 144 }, 145 }, 146 }, 147 false, 148 "foo 42", 149 ast.TypeString, 150 }, 151 152 { 153 "foo ${bar+baz}", 154 &ast.BasicScope{ 155 VarMap: map[string]ast.Variable{ 156 "bar": ast.Variable{ 157 Value: "41", 158 Type: ast.TypeString, 159 }, 160 "baz": ast.Variable{ 161 Value: "1", 162 Type: ast.TypeString, 163 }, 164 }, 165 }, 166 false, 167 "foo 42", 168 ast.TypeString, 169 }, 170 171 { 172 "foo ${rand()}", 173 &ast.BasicScope{ 174 FuncMap: map[string]ast.Function{ 175 "rand": ast.Function{ 176 ReturnType: ast.TypeString, 177 Callback: func([]interface{}) (interface{}, error) { 178 return "42", nil 179 }, 180 }, 181 }, 182 }, 183 false, 184 "foo 42", 185 ast.TypeString, 186 }, 187 188 { 189 `foo ${rand("foo", "bar")}`, 190 &ast.BasicScope{ 191 FuncMap: map[string]ast.Function{ 192 "rand": ast.Function{ 193 ReturnType: ast.TypeString, 194 Variadic: true, 195 VariadicType: ast.TypeString, 196 Callback: func(args []interface{}) (interface{}, error) { 197 var result string 198 for _, a := range args { 199 result += a.(string) 200 } 201 return result, nil 202 }, 203 }, 204 }, 205 }, 206 false, 207 "foo foobar", 208 ast.TypeString, 209 }, 210 211 // Testing implicit type conversions 212 213 { 214 "foo ${bar}", 215 &ast.BasicScope{ 216 VarMap: map[string]ast.Variable{ 217 "bar": ast.Variable{ 218 Value: 42, 219 Type: ast.TypeInt, 220 }, 221 }, 222 }, 223 false, 224 "foo 42", 225 ast.TypeString, 226 }, 227 228 { 229 `foo ${foo("42")}`, 230 &ast.BasicScope{ 231 FuncMap: map[string]ast.Function{ 232 "foo": ast.Function{ 233 ArgTypes: []ast.Type{ast.TypeInt}, 234 ReturnType: ast.TypeString, 235 Callback: func(args []interface{}) (interface{}, error) { 236 return strconv.FormatInt(int64(args[0].(int)), 10), nil 237 }, 238 }, 239 }, 240 }, 241 false, 242 "foo 42", 243 ast.TypeString, 244 }, 245 246 // Multiline 247 { 248 "foo ${42+\n1.0}", 249 nil, 250 false, 251 "foo 43", 252 ast.TypeString, 253 }, 254 255 { 256 "foo ${-46}", 257 nil, 258 false, 259 "foo -46", 260 ast.TypeString, 261 }, 262 263 { 264 "foo ${-46 + 5}", 265 nil, 266 false, 267 "foo -41", 268 ast.TypeString, 269 }, 270 271 { 272 "foo ${46 + -5}", 273 nil, 274 false, 275 "foo 41", 276 ast.TypeString, 277 }, 278 279 { 280 "foo ${-bar}", 281 &ast.BasicScope{ 282 VarMap: map[string]ast.Variable{ 283 "bar": ast.Variable{ 284 Value: 41, 285 Type: ast.TypeInt, 286 }, 287 }, 288 }, 289 false, 290 "foo -41", 291 ast.TypeString, 292 }, 293 294 { 295 "foo ${5 + -bar}", 296 &ast.BasicScope{ 297 VarMap: map[string]ast.Variable{ 298 "bar": ast.Variable{ 299 Value: 41, 300 Type: ast.TypeInt, 301 }, 302 }, 303 }, 304 false, 305 "foo -36", 306 ast.TypeString, 307 }, 308 } 309 310 for _, tc := range cases { 311 node, err := Parse(tc.Input) 312 if err != nil { 313 t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input) 314 } 315 316 out, outType, err := Eval(node, &EvalConfig{GlobalScope: tc.Scope}) 317 if err != nil != tc.Error { 318 t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input) 319 } 320 if outType != tc.ResultType { 321 t.Fatalf("Bad: %s\n\nInput: %s", outType, tc.Input) 322 } 323 if !reflect.DeepEqual(out, tc.Result) { 324 t.Fatalf("Bad: %#v\n\nInput: %s", out, tc.Input) 325 } 326 } 327 }