terraform/config/lang/eval_test.go

274 lines
4.0 KiB
Go
Raw Normal View History

2015-01-12 00:26:54 +01:00
package lang
import (
"reflect"
2015-01-14 21:02:26 +01:00
"strconv"
2015-01-12 00:26:54 +01:00
"testing"
"github.com/hashicorp/terraform/config/lang/ast"
)
2015-01-15 06:48:20 +01:00
func TestEval(t *testing.T) {
2015-01-12 00:26:54 +01:00
cases := []struct {
Input string
2015-01-15 05:58:46 +01:00
Scope *ast.BasicScope
2015-01-12 00:26:54 +01:00
Error bool
Result interface{}
ResultType ast.Type
}{
{
"foo",
2015-01-12 18:57:16 +01:00
nil,
2015-01-12 00:26:54 +01:00
false,
"foo",
ast.TypeString,
},
{
"foo ${bar}",
2015-01-15 05:58:46 +01:00
&ast.BasicScope{
VarMap: map[string]ast.Variable{
"bar": ast.Variable{
2015-01-12 00:26:54 +01:00
Value: "baz",
Type: ast.TypeString,
},
},
},
false,
"foo baz",
ast.TypeString,
},
2015-01-12 00:33:24 +01:00
{
"foo ${42+1}",
nil,
false,
"foo 43",
ast.TypeString,
},
{
"foo ${42-1}",
nil,
false,
"foo 41",
ast.TypeString,
},
{
"foo ${42*2}",
nil,
false,
"foo 84",
ast.TypeString,
},
{
"foo ${42/2}",
nil,
false,
"foo 21",
ast.TypeString,
},
2015-02-27 00:17:37 +01:00
{
"foo ${42%4}",
nil,
false,
"foo 2",
ast.TypeString,
},
2015-02-26 23:26:14 +01:00
{
"foo ${42.0+1.0}",
nil,
false,
"foo 43",
ast.TypeString,
},
{
"foo ${42.0+1}",
nil,
false,
"foo 43",
ast.TypeString,
},
{
"foo ${42+1.0}",
nil,
false,
"foo 43",
ast.TypeString,
},
{
"foo ${42+2*2}",
nil,
false,
"foo 88",
ast.TypeString,
},
{
"foo ${42+(2*2)}",
nil,
false,
"foo 46",
ast.TypeString,
},
2015-02-26 23:34:45 +01:00
{
"foo ${bar+1}",
&ast.BasicScope{
VarMap: map[string]ast.Variable{
"bar": ast.Variable{
Value: 41,
Type: ast.TypeInt,
},
},
},
false,
"foo 42",
ast.TypeString,
},
{
"foo ${bar+1}",
&ast.BasicScope{
VarMap: map[string]ast.Variable{
"bar": ast.Variable{
Value: "41",
Type: ast.TypeString,
},
},
},
false,
"foo 42",
ast.TypeString,
},
{
"foo ${bar+baz}",
&ast.BasicScope{
VarMap: map[string]ast.Variable{
"bar": ast.Variable{
Value: "41",
Type: ast.TypeString,
},
"baz": ast.Variable{
Value: "1",
Type: ast.TypeString,
},
},
},
false,
"foo 42",
ast.TypeString,
2015-02-26 23:34:45 +01:00
},
2015-01-12 00:33:24 +01:00
{
"foo ${rand()}",
2015-01-15 05:58:46 +01:00
&ast.BasicScope{
FuncMap: map[string]ast.Function{
"rand": ast.Function{
2015-01-12 00:33:24 +01:00
ReturnType: ast.TypeString,
Callback: func([]interface{}) (interface{}, error) {
return "42", nil
},
},
},
},
false,
"foo 42",
ast.TypeString,
},
2015-01-13 21:40:47 +01:00
{
`foo ${rand("foo", "bar")}`,
2015-01-15 05:58:46 +01:00
&ast.BasicScope{
FuncMap: map[string]ast.Function{
"rand": ast.Function{
2015-01-13 21:40:47 +01:00
ReturnType: ast.TypeString,
Variadic: true,
VariadicType: ast.TypeString,
Callback: func(args []interface{}) (interface{}, error) {
var result string
for _, a := range args {
result += a.(string)
}
return result, nil
},
},
},
},
false,
"foo foobar",
ast.TypeString,
},
// Testing implicit type conversions
{
"foo ${bar}",
2015-01-15 05:58:46 +01:00
&ast.BasicScope{
VarMap: map[string]ast.Variable{
"bar": ast.Variable{
Value: 42,
Type: ast.TypeInt,
},
},
},
false,
"foo 42",
ast.TypeString,
},
2015-01-14 21:02:26 +01:00
{
`foo ${foo("42")}`,
2015-01-15 05:58:46 +01:00
&ast.BasicScope{
FuncMap: map[string]ast.Function{
"foo": ast.Function{
2015-01-14 21:02:26 +01:00
ArgTypes: []ast.Type{ast.TypeInt},
ReturnType: ast.TypeString,
Callback: func(args []interface{}) (interface{}, error) {
return strconv.FormatInt(int64(args[0].(int)), 10), nil
},
},
},
},
false,
"foo 42",
ast.TypeString,
},
// Multiline
{
"foo ${42+\n1.0}",
nil,
false,
"foo 43",
ast.TypeString,
},
2015-01-12 00:26:54 +01:00
}
for _, tc := range cases {
node, err := Parse(tc.Input)
if err != nil {
t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
}
2015-01-15 06:48:20 +01:00
out, outType, err := Eval(node, &EvalConfig{GlobalScope: tc.Scope})
2015-10-08 14:48:04 +02:00
if err != nil != tc.Error {
2015-01-12 00:26:54 +01:00
t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
}
if outType != tc.ResultType {
t.Fatalf("Bad: %s\n\nInput: %s", outType, tc.Input)
}
if !reflect.DeepEqual(out, tc.Result) {
t.Fatalf("Bad: %#v\n\nInput: %s", out, tc.Input)
}
}
}