terraform/config/interpolate_funcs_test.go

310 lines
4.6 KiB
Go
Raw Normal View History

2014-07-21 22:12:43 +02:00
package config
import (
2014-10-10 06:22:35 +02:00
"fmt"
"io/ioutil"
"os"
"reflect"
2014-07-21 22:12:43 +02:00
"testing"
2014-08-19 22:14:45 +02:00
"github.com/hashicorp/terraform/config/lang"
2015-01-14 19:40:43 +01:00
"github.com/hashicorp/terraform/config/lang/ast"
)
2014-08-19 22:14:45 +02:00
2015-01-13 21:47:54 +01:00
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)
2015-01-13 21:06:04 +01:00
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
{
fmt.Sprintf(`${file("%s")}`, path),
"foo",
false,
},
2015-01-13 21:06:04 +01:00
// Invalid path
{
`${file("/i/dont/exist")}`,
nil,
true,
},
2015-01-13 21:06:04 +01:00
// Too many args
{
`${file("foo", "bar")}`,
nil,
true,
},
},
})
}
2014-07-23 03:35:53 +02:00
2015-03-02 19:26:06 +01:00
func TestInterpolateFuncFormat(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
{
`${format("hello")}`,
"hello",
false,
},
{
`${format("hello %s", "world")}`,
"hello world",
false,
},
{
`${format("hello %d", 42)}`,
"hello 42",
false,
},
{
`${format("hello %05d", 42)}`,
"hello 00042",
false,
},
{
`${format("hello %05d", 12345)}`,
"hello 12345",
false,
},
},
})
}
2014-10-10 06:22:35 +02:00
func TestInterpolateFuncJoin(t *testing.T) {
2015-01-13 21:06:04 +01:00
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
{
`${join(",")}`,
nil,
true,
},
2014-10-10 06:22:35 +02:00
2015-01-13 21:06:04 +01:00
{
`${join(",", "foo")}`,
"foo",
false,
},
/*
TODO
{
`${join(",", "foo", "bar")}`,
"foo,bar",
false,
},
*/
2014-10-10 06:22:35 +02:00
{
2015-01-13 21:06:04 +01:00
fmt.Sprintf(`${join(".", "%s")}`,
fmt.Sprintf(
"foo%sbar%sbaz",
InterpSplitDelim,
InterpSplitDelim)),
"foo.bar.baz",
false,
},
2014-10-10 06:22:35 +02:00
},
})
2014-10-10 06:22:35 +02:00
}
2015-03-02 18:37:40 +01:00
func TestInterpolateFuncReplace(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
// Regular search and replace
{
`${replace("hello", "hel", "bel")}`,
"bello",
false,
},
// Search string doesn't match
{
`${replace("hello", "nope", "bel")}`,
"hello",
false,
},
// Regular expression
{
`${replace("hello", "/l/", "L")}`,
"heLLo",
false,
},
{
`${replace("helo", "/(l)/", "$1$1")}`,
"hello",
false,
},
2015-03-02 18:44:45 +01:00
// Bad regexp
{
`${replace("helo", "/(l/", "$1$1")}`,
nil,
true,
},
2015-03-02 18:37:40 +01:00
},
})
}
2015-01-28 22:59:16 +01:00
func TestInterpolateFuncSplit(t *testing.T) {
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
{
`${split(",")}`,
nil,
true,
},
{
`${split(",", "foo")}`,
"foo",
false,
},
{
`${split(".", "foo.bar.baz")}`,
fmt.Sprintf(
"foo%sbar%sbaz",
InterpSplitDelim,
InterpSplitDelim),
false,
},
},
})
}
2014-07-21 22:12:43 +02:00
func TestInterpolateFuncLookup(t *testing.T) {
2015-01-13 21:06:04 +01:00
testFunction(t, testFunctionConfig{
2015-01-15 07:01:42 +01:00
Vars: map[string]ast.Variable{
"var.foo.bar": ast.Variable{
2015-01-14 19:40:43 +01:00
Value: "baz",
Type: ast.TypeString,
},
},
2015-01-13 21:06:04 +01:00
Cases: []testFunctionCase{
{
`${lookup("foo", "bar")}`,
"baz",
false,
2014-07-21 22:12:43 +02:00
},
2015-01-13 21:06:04 +01:00
// Invalid key
{
`${lookup("foo", "baz")}`,
nil,
true,
2014-07-21 22:12:43 +02:00
},
2015-01-13 21:06:04 +01:00
// Too many args
{
`${lookup("foo", "bar", "baz")}`,
nil,
true,
2014-07-21 22:12:43 +02:00
},
},
2015-01-13 21:06:04 +01:00
})
2014-07-21 22:12:43 +02:00
}
func TestInterpolateFuncElement(t *testing.T) {
2015-01-13 21:06:04 +01:00
testFunction(t, testFunctionConfig{
Cases: []testFunctionCase{
{
fmt.Sprintf(`${element("%s", "1")}`,
"foo"+InterpSplitDelim+"baz"),
"baz",
false,
},
2015-01-13 21:06:04 +01:00
{
`${element("foo", "0")}`,
"foo",
false,
},
2015-01-13 21:06:04 +01:00
// Invalid index should wrap vs. out-of-bounds
{
fmt.Sprintf(`${element("%s", "2")}`,
"foo"+InterpSplitDelim+"baz"),
"foo",
false,
},
2015-01-13 21:06:04 +01:00
// Too many args
{
fmt.Sprintf(`${element("%s", "0", "2")}`,
"foo"+InterpSplitDelim+"baz"),
nil,
true,
},
},
})
}
2015-01-13 21:06:04 +01:00
type testFunctionConfig struct {
Cases []testFunctionCase
2015-01-15 07:01:42 +01:00
Vars map[string]ast.Variable
2015-01-13 21:06:04 +01:00
}
type testFunctionCase struct {
Input string
Result interface{}
Error bool
}
2015-01-13 21:06:04 +01:00
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)
}
2015-01-15 07:01:42 +01:00
out, _, err := lang.Eval(ast, langEvalConfig(config.Vars))
if (err != nil) != tc.Error {
t.Fatalf("%d: err: %s", i, err)
}
if !reflect.DeepEqual(out, tc.Result) {
2015-03-02 18:37:40 +01:00
t.Fatalf(
"%d: bad output for input: %s\n\nOutput: %#v",
i, tc.Input, out)
}
}
}