github.com/franklinhu/terraform@v0.6.9-0.20151202232446-81f7fb1e6f9e/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 for _, tc := range cases { 257 node, err := Parse(tc.Input) 258 if err != nil { 259 t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input) 260 } 261 262 out, outType, err := Eval(node, &EvalConfig{GlobalScope: tc.Scope}) 263 if err != nil != tc.Error { 264 t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input) 265 } 266 if outType != tc.ResultType { 267 t.Fatalf("Bad: %s\n\nInput: %s", outType, tc.Input) 268 } 269 if !reflect.DeepEqual(out, tc.Result) { 270 t.Fatalf("Bad: %#v\n\nInput: %s", out, tc.Input) 271 } 272 } 273 }