terraform/config/interpolate_funcs_test.go

206 lines
3.1 KiB
Go

package config
import (
"fmt"
"io/ioutil"
"os"
"reflect"
"testing"
"github.com/hashicorp/terraform/config/lang"
"github.com/hashicorp/terraform/config/lang/ast"
)
func TestInterpolateFuncConcat(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
{
`${concat("foo", "bar")}`,
"foobar",
false,
},
{
`${concat("foo")}`,
"foo",
false,
},
{
`${concat()}`,
nil,
true,
},
},
})
}
func TestInterpolateFuncFile(t *testing.T) {
tf, err := ioutil.TempFile("", "tf")
if err != nil {
t.Fatalf("err: %s", err)
}
path := tf.Name()
tf.Write([]byte("foo"))
tf.Close()
defer os.Remove(path)
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
{
fmt.Sprintf(`${file("%s")}`, path),
"foo",
false,
},
// Invalid path
{
`${file("/i/dont/exist")}`,
nil,
true,
},
// Too many args
{
`${file("foo", "bar")}`,
nil,
true,
},
},
})
}
func TestInterpolateFuncJoin(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
{
`${join(",")}`,
nil,
true,
},
{
`${join(",", "foo")}`,
"foo",
false,
},
/*
TODO
{
`${join(",", "foo", "bar")}`,
"foo,bar",
false,
},
*/
{
fmt.Sprintf(`${join(".", "%s")}`,
fmt.Sprintf(
"foo%sbar%sbaz",
InterpSplitDelim,
InterpSplitDelim)),
"foo.bar.baz",
false,
},
},
})
}
func TestInterpolateFuncLookup(t *testing.T) {
testFunction(t, testFunctionConfig{
Vars: map[string]lang.Variable{
"var.foo.bar": lang.Variable{
Value: "baz",
Type: ast.TypeString,
},
},
Cases: []testFunctionCase{
{
`${lookup("foo", "bar")}`,
"baz",
false,
},
// Invalid key
{
`${lookup("foo", "baz")}`,
nil,
true,
},
// Too many args
{
`${lookup("foo", "bar", "baz")}`,
nil,
true,
},
},
})
}
func TestInterpolateFuncElement(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
{
fmt.Sprintf(`${element("%s", "1")}`,
"foo"+InterpSplitDelim+"baz"),
"baz",
false,
},
{
`${element("foo", "0")}`,
"foo",
false,
},
// Invalid index should wrap vs. out-of-bounds
{
fmt.Sprintf(`${element("%s", "2")}`,
"foo"+InterpSplitDelim+"baz"),
"foo",
false,
},
// Too many args
{
fmt.Sprintf(`${element("%s", "0", "2")}`,
"foo"+InterpSplitDelim+"baz"),
nil,
true,
},
},
})
}
type testFunctionConfig struct {
Cases []testFunctionCase
Vars map[string]lang.Variable
}
type testFunctionCase struct {
Input string
Result interface{}
Error bool
}
func testFunction(t *testing.T, config testFunctionConfig) {
for i, tc := range config.Cases {
ast, err := lang.Parse(tc.Input)
if err != nil {
t.Fatalf("%d: err: %s", i, err)
}
engine := langEngine(config.Vars)
out, _, err := engine.Execute(ast)
if (err != nil) != tc.Error {
t.Fatalf("%d: err: %s", i, err)
}
if !reflect.DeepEqual(out, tc.Result) {
t.Fatalf("%d: bad: %#v", i, out)
}
}
}