deps: Update GoDeps to reflect hashicorp/hil
This commit is contained in:
parent
4576eaa966
commit
0340ea7235
|
@ -75,8 +75,6 @@
|
|||
"github.com/hashicorp/terraform/communicator/ssh",
|
||||
"github.com/hashicorp/terraform/communicator/winrm",
|
||||
"github.com/hashicorp/terraform/config",
|
||||
"github.com/hashicorp/terraform/config/lang",
|
||||
"github.com/hashicorp/terraform/config/lang/ast",
|
||||
"github.com/hashicorp/terraform/config/module",
|
||||
"github.com/hashicorp/terraform/dag",
|
||||
"github.com/hashicorp/terraform/digraph",
|
||||
|
@ -499,6 +497,10 @@
|
|||
"ImportPath": "github.com/hashicorp/hcl",
|
||||
"Rev": "578dd9746824a54637686b51a41bad457a56bcef"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hil",
|
||||
"Rev": "075475a7408f16568f5cf79656dbcb053ac6196b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/logutils",
|
||||
"Rev": "0dc08b1671f34c4250ce212759ebd880f743d883"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
.DS_Store
|
|
@ -1,36 +0,0 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCallType(t *testing.T) {
|
||||
c := &Call{Func: "foo"}
|
||||
scope := &BasicScope{
|
||||
FuncMap: map[string]Function{
|
||||
"foo": Function{ReturnType: TypeString},
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := c.Type(scope)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if actual != TypeString {
|
||||
t.Fatalf("bad: %s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallType_invalid(t *testing.T) {
|
||||
c := &Call{Func: "bar"}
|
||||
scope := &BasicScope{
|
||||
FuncMap: map[string]Function{
|
||||
"foo": Function{ReturnType: TypeString},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := c.Type(scope)
|
||||
if err == nil {
|
||||
t.Fatal("should error")
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConcatType(t *testing.T) {
|
||||
c := &Concat{}
|
||||
actual, err := c.Type(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if actual != TypeString {
|
||||
t.Fatalf("bad: %s", actual)
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLiteralNodeType(t *testing.T) {
|
||||
c := &LiteralNode{Typex: TypeString}
|
||||
actual, err := c.Type(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if actual != TypeString {
|
||||
t.Fatalf("bad: %s", actual)
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBasicScope_impl(t *testing.T) {
|
||||
var _ Scope = new(BasicScope)
|
||||
}
|
||||
|
||||
func TestBasicScopeLookupFunc(t *testing.T) {
|
||||
scope := &BasicScope{
|
||||
FuncMap: map[string]Function{
|
||||
"foo": Function{},
|
||||
},
|
||||
}
|
||||
|
||||
if _, ok := scope.LookupFunc("bar"); ok {
|
||||
t.Fatal("should not find bar")
|
||||
}
|
||||
if _, ok := scope.LookupFunc("foo"); !ok {
|
||||
t.Fatal("should find foo")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBasicScopeLookupVar(t *testing.T) {
|
||||
scope := &BasicScope{
|
||||
VarMap: map[string]Variable{
|
||||
"foo": Variable{},
|
||||
},
|
||||
}
|
||||
|
||||
if _, ok := scope.LookupVar("bar"); ok {
|
||||
t.Fatal("should not find bar")
|
||||
}
|
||||
if _, ok := scope.LookupVar("foo"); !ok {
|
||||
t.Fatal("should find foo")
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStack(t *testing.T) {
|
||||
var s Stack
|
||||
if s.Len() != 0 {
|
||||
t.Fatalf("bad: %d", s.Len())
|
||||
}
|
||||
|
||||
n := &LiteralNode{Value: 42}
|
||||
s.Push(n)
|
||||
|
||||
if s.Len() != 1 {
|
||||
t.Fatalf("bad: %d", s.Len())
|
||||
}
|
||||
|
||||
actual := s.Pop()
|
||||
if !reflect.DeepEqual(actual, n) {
|
||||
t.Fatalf("bad: %#v", actual)
|
||||
}
|
||||
|
||||
if s.Len() != 0 {
|
||||
t.Fatalf("bad: %d", s.Len())
|
||||
}
|
||||
}
|
||||
|
||||
func TestStack_reset(t *testing.T) {
|
||||
var s Stack
|
||||
|
||||
n := &LiteralNode{Value: 42}
|
||||
s.Push(n)
|
||||
|
||||
if s.Len() != 1 {
|
||||
t.Fatalf("bad: %d", s.Len())
|
||||
}
|
||||
|
||||
s.Reset()
|
||||
|
||||
if s.Len() != 0 {
|
||||
t.Fatalf("bad: %d", s.Len())
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVariableAccessType(t *testing.T) {
|
||||
c := &VariableAccess{Name: "foo"}
|
||||
scope := &BasicScope{
|
||||
VarMap: map[string]Variable{
|
||||
"foo": Variable{Type: TypeString},
|
||||
},
|
||||
}
|
||||
|
||||
actual, err := c.Type(scope)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if actual != TypeString {
|
||||
t.Fatalf("bad: %s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVariableAccessType_invalid(t *testing.T) {
|
||||
c := &VariableAccess{Name: "bar"}
|
||||
scope := &BasicScope{
|
||||
VarMap: map[string]Variable{
|
||||
"foo": Variable{Type: TypeString},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := c.Type(scope)
|
||||
if err == nil {
|
||||
t.Fatal("should error")
|
||||
}
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
package hil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/hil/ast"
|
||||
)
|
||||
|
||||
func TestIdentifierCheck(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input string
|
||||
Scope ast.Scope
|
||||
Error bool
|
||||
}{
|
||||
{
|
||||
"foo",
|
||||
&ast.BasicScope{},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${bar} success",
|
||||
&ast.BasicScope{
|
||||
VarMap: map[string]ast.Variable{
|
||||
"bar": ast.Variable{
|
||||
Value: "baz",
|
||||
Type: ast.TypeString,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${bar}",
|
||||
&ast.BasicScope{},
|
||||
true,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${rand()} success",
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ReturnType: ast.TypeString,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${rand()}",
|
||||
&ast.BasicScope{},
|
||||
true,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${rand(42)} ",
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ReturnType: ast.TypeString,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${rand()} ",
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ReturnType: ast.TypeString,
|
||||
Variadic: true,
|
||||
VariadicType: ast.TypeInt,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${rand(42)} ",
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ReturnType: ast.TypeString,
|
||||
Variadic: true,
|
||||
VariadicType: ast.TypeInt,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${rand(\"foo\", 42)} ",
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ArgTypes: []ast.Type{ast.TypeString},
|
||||
ReturnType: ast.TypeString,
|
||||
Variadic: true,
|
||||
VariadicType: ast.TypeInt,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
node, err := Parse(tc.Input)
|
||||
if err != nil {
|
||||
t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
|
||||
}
|
||||
|
||||
visitor := &IdentifierCheck{Scope: tc.Scope}
|
||||
err = visitor.Visit(node)
|
||||
if err != nil != tc.Error {
|
||||
t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,265 +0,0 @@
|
|||
package hil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/hil/ast"
|
||||
)
|
||||
|
||||
func TestTypeCheck(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input string
|
||||
Scope ast.Scope
|
||||
Error bool
|
||||
}{
|
||||
{
|
||||
"foo",
|
||||
&ast.BasicScope{},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${bar}",
|
||||
&ast.BasicScope{
|
||||
VarMap: map[string]ast.Variable{
|
||||
"bar": ast.Variable{
|
||||
Value: "baz",
|
||||
Type: ast.TypeString,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${rand()}",
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ReturnType: ast.TypeString,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${rand("42")}`,
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ArgTypes: []ast.Type{ast.TypeString},
|
||||
ReturnType: ast.TypeString,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${rand(42)}`,
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ArgTypes: []ast.Type{ast.TypeString},
|
||||
ReturnType: ast.TypeString,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${rand()}`,
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ArgTypes: nil,
|
||||
ReturnType: ast.TypeString,
|
||||
Variadic: true,
|
||||
VariadicType: ast.TypeString,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${rand("42")}`,
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ArgTypes: nil,
|
||||
ReturnType: ast.TypeString,
|
||||
Variadic: true,
|
||||
VariadicType: ast.TypeString,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${rand("42", 42)}`,
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ArgTypes: nil,
|
||||
ReturnType: ast.TypeString,
|
||||
Variadic: true,
|
||||
VariadicType: ast.TypeString,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${bar}",
|
||||
&ast.BasicScope{
|
||||
VarMap: map[string]ast.Variable{
|
||||
"bar": ast.Variable{
|
||||
Value: 42,
|
||||
Type: ast.TypeInt,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${rand()}",
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ReturnType: ast.TypeInt,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return 42, nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
node, err := Parse(tc.Input)
|
||||
if err != nil {
|
||||
t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
|
||||
}
|
||||
|
||||
visitor := &TypeCheck{Scope: tc.Scope}
|
||||
err = visitor.Visit(node)
|
||||
if err != nil != tc.Error {
|
||||
t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypeCheck_implicit(t *testing.T) {
|
||||
implicitMap := map[ast.Type]map[ast.Type]string{
|
||||
ast.TypeInt: {
|
||||
ast.TypeString: "intToString",
|
||||
},
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
Input string
|
||||
Scope *ast.BasicScope
|
||||
Error bool
|
||||
}{
|
||||
{
|
||||
"foo ${bar}",
|
||||
&ast.BasicScope{
|
||||
VarMap: map[string]ast.Variable{
|
||||
"bar": ast.Variable{
|
||||
Value: 42,
|
||||
Type: ast.TypeInt,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${foo(42)}",
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"foo": ast.Function{
|
||||
ArgTypes: []ast.Type{ast.TypeString},
|
||||
ReturnType: ast.TypeString,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${foo("42", 42)}`,
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"foo": ast.Function{
|
||||
ArgTypes: []ast.Type{ast.TypeString},
|
||||
Variadic: true,
|
||||
VariadicType: ast.TypeString,
|
||||
ReturnType: ast.TypeString,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
node, err := Parse(tc.Input)
|
||||
if err != nil {
|
||||
t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
|
||||
}
|
||||
|
||||
// Modify the scope to add our conversion functions.
|
||||
if tc.Scope.FuncMap == nil {
|
||||
tc.Scope.FuncMap = make(map[string]ast.Function)
|
||||
}
|
||||
tc.Scope.FuncMap["intToString"] = ast.Function{
|
||||
ArgTypes: []ast.Type{ast.TypeInt},
|
||||
ReturnType: ast.TypeString,
|
||||
}
|
||||
|
||||
// Do the first pass...
|
||||
visitor := &TypeCheck{Scope: tc.Scope, Implicit: implicitMap}
|
||||
err = visitor.Visit(node)
|
||||
if err != nil != tc.Error {
|
||||
t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
|
||||
}
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// If we didn't error, then the next type check should not fail
|
||||
// WITHOUT implicits.
|
||||
visitor = &TypeCheck{Scope: tc.Scope}
|
||||
err = visitor.Visit(node)
|
||||
if err != nil {
|
||||
t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,273 +0,0 @@
|
|||
package hil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/hil/ast"
|
||||
)
|
||||
|
||||
func TestEval(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input string
|
||||
Scope *ast.BasicScope
|
||||
Error bool
|
||||
Result interface{}
|
||||
ResultType ast.Type
|
||||
}{
|
||||
{
|
||||
"foo",
|
||||
nil,
|
||||
false,
|
||||
"foo",
|
||||
ast.TypeString,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${bar}",
|
||||
&ast.BasicScope{
|
||||
VarMap: map[string]ast.Variable{
|
||||
"bar": ast.Variable{
|
||||
Value: "baz",
|
||||
Type: ast.TypeString,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
"foo baz",
|
||||
ast.TypeString,
|
||||
},
|
||||
|
||||
{
|
||||
"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,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${42%4}",
|
||||
nil,
|
||||
false,
|
||||
"foo 2",
|
||||
ast.TypeString,
|
||||
},
|
||||
|
||||
{
|
||||
"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,
|
||||
},
|
||||
|
||||
{
|
||||
"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,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${rand()}",
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
ReturnType: ast.TypeString,
|
||||
Callback: func([]interface{}) (interface{}, error) {
|
||||
return "42", nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
"foo 42",
|
||||
ast.TypeString,
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${rand("foo", "bar")}`,
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"rand": ast.Function{
|
||||
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}",
|
||||
&ast.BasicScope{
|
||||
VarMap: map[string]ast.Variable{
|
||||
"bar": ast.Variable{
|
||||
Value: 42,
|
||||
Type: ast.TypeInt,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
"foo 42",
|
||||
ast.TypeString,
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${foo("42")}`,
|
||||
&ast.BasicScope{
|
||||
FuncMap: map[string]ast.Function{
|
||||
"foo": ast.Function{
|
||||
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,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
node, err := Parse(tc.Input)
|
||||
if err != nil {
|
||||
t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
|
||||
}
|
||||
|
||||
out, outType, err := Eval(node, &EvalConfig{GlobalScope: tc.Scope})
|
||||
if err != nil != tc.Error {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
package hil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLex(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input string
|
||||
Output []int
|
||||
}{
|
||||
{
|
||||
"foo",
|
||||
[]int{STRING, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"foo$bar",
|
||||
[]int{STRING, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${bar}",
|
||||
[]int{STRING, PROGRAM_BRACKET_LEFT, IDENTIFIER, PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"foo $${bar}",
|
||||
[]int{STRING, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"foo $$$${bar}",
|
||||
[]int{STRING, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${\"bar\"}",
|
||||
[]int{STRING, PROGRAM_BRACKET_LEFT, STRING, PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"${bar(baz)}",
|
||||
[]int{PROGRAM_BRACKET_LEFT,
|
||||
IDENTIFIER, PAREN_LEFT, IDENTIFIER, PAREN_RIGHT,
|
||||
PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"${bar(baz, foo)}",
|
||||
[]int{PROGRAM_BRACKET_LEFT,
|
||||
IDENTIFIER, PAREN_LEFT,
|
||||
IDENTIFIER, COMMA, IDENTIFIER,
|
||||
PAREN_RIGHT,
|
||||
PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"${bar(42)}",
|
||||
[]int{PROGRAM_BRACKET_LEFT,
|
||||
IDENTIFIER, PAREN_LEFT, INTEGER, PAREN_RIGHT,
|
||||
PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"${bar(42+1)}",
|
||||
[]int{PROGRAM_BRACKET_LEFT,
|
||||
IDENTIFIER, PAREN_LEFT,
|
||||
INTEGER, ARITH_OP, INTEGER,
|
||||
PAREN_RIGHT,
|
||||
PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"${bar(3.14159)}",
|
||||
[]int{PROGRAM_BRACKET_LEFT,
|
||||
IDENTIFIER, PAREN_LEFT, FLOAT, PAREN_RIGHT,
|
||||
PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"${bar(inner(baz))}",
|
||||
[]int{PROGRAM_BRACKET_LEFT,
|
||||
IDENTIFIER, PAREN_LEFT,
|
||||
IDENTIFIER, PAREN_LEFT,
|
||||
IDENTIFIER,
|
||||
PAREN_RIGHT, PAREN_RIGHT,
|
||||
PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${foo.bar.baz}",
|
||||
[]int{STRING, PROGRAM_BRACKET_LEFT, IDENTIFIER, PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${foo.bar.*.baz}",
|
||||
[]int{STRING, PROGRAM_BRACKET_LEFT, IDENTIFIER, PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${foo(\"baz\")}",
|
||||
[]int{STRING, PROGRAM_BRACKET_LEFT,
|
||||
IDENTIFIER, PAREN_LEFT, STRING, PAREN_RIGHT,
|
||||
PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${"${var.foo}"}`,
|
||||
[]int{STRING, PROGRAM_BRACKET_LEFT,
|
||||
PROGRAM_BRACKET_LEFT, IDENTIFIER, PROGRAM_BRACKET_RIGHT,
|
||||
PROGRAM_BRACKET_RIGHT, lexEOF},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
l := &parserLex{Input: tc.Input}
|
||||
var actual []int
|
||||
for {
|
||||
token := l.Lex(new(parserSymType))
|
||||
actual = append(actual, token)
|
||||
|
||||
if token == lexEOF {
|
||||
break
|
||||
}
|
||||
|
||||
// Be careful against what are probably infinite loops
|
||||
if len(actual) > 100 {
|
||||
t.Fatalf("Input:%s\n\nExausted.", tc.Input)
|
||||
}
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(actual, tc.Output) {
|
||||
t.Fatalf(
|
||||
"Input: %s\n\nBad: %#v\n\nExpected: %#v",
|
||||
tc.Input, actual, tc.Output)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,363 +0,0 @@
|
|||
package hil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/hil/ast"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input string
|
||||
Error bool
|
||||
Result ast.Node
|
||||
}{
|
||||
{
|
||||
"",
|
||||
false,
|
||||
&ast.LiteralNode{
|
||||
Value: "",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"foo",
|
||||
false,
|
||||
&ast.LiteralNode{
|
||||
Value: "foo",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"$${var.foo}",
|
||||
false,
|
||||
&ast.LiteralNode{
|
||||
Value: "${var.foo}",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${var.bar}",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.VariableAccess{
|
||||
Name: "var.bar",
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${var.bar} baz",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.VariableAccess{
|
||||
Name: "var.bar",
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
&ast.LiteralNode{
|
||||
Value: " baz",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 15, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${\"bar\"}",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.LiteralNode{
|
||||
Value: "bar",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${func('baz')}`,
|
||||
true,
|
||||
nil,
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${42}",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.LiteralNode{
|
||||
Value: 42,
|
||||
Typex: ast.TypeInt,
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${3.14159}",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.LiteralNode{
|
||||
Value: 3.14159,
|
||||
Typex: ast.TypeFloat,
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${42+1}",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.Arithmetic{
|
||||
Op: ast.ArithmeticOpAdd,
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: 42,
|
||||
Typex: ast.TypeInt,
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
&ast.LiteralNode{
|
||||
Value: 1,
|
||||
Typex: ast.TypeInt,
|
||||
Posx: ast.Pos{Column: 10, Line: 1},
|
||||
},
|
||||
},
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"foo ${var.bar*1} baz",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.Arithmetic{
|
||||
Op: ast.ArithmeticOpMul,
|
||||
Exprs: []ast.Node{
|
||||
&ast.VariableAccess{
|
||||
Name: "var.bar",
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
&ast.LiteralNode{
|
||||
Value: 1,
|
||||
Typex: ast.TypeInt,
|
||||
Posx: ast.Pos{Column: 15, Line: 1},
|
||||
},
|
||||
},
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
&ast.LiteralNode{
|
||||
Value: " baz",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 17, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"${foo()}",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.Call{
|
||||
Func: "foo",
|
||||
Args: nil,
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"${foo(bar)}",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.Call{
|
||||
Func: "foo",
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
Args: []ast.Node{
|
||||
&ast.VariableAccess{
|
||||
Name: "bar",
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"${foo(bar, baz)}",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.Call{
|
||||
Func: "foo",
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
Args: []ast.Node{
|
||||
&ast.VariableAccess{
|
||||
Name: "bar",
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
&ast.VariableAccess{
|
||||
Name: "baz",
|
||||
Posx: ast.Pos{Column: 11, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
"${foo(bar(baz))}",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.Call{
|
||||
Func: "foo",
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
Args: []ast.Node{
|
||||
&ast.Call{
|
||||
Func: "bar",
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
Args: []ast.Node{
|
||||
&ast.VariableAccess{
|
||||
Name: "baz",
|
||||
Posx: ast.Pos{Column: 11, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${"bar ${baz}"}`,
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "bar ",
|
||||
Typex: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
&ast.VariableAccess{
|
||||
Name: "baz",
|
||||
Posx: ast.Pos{Column: 14, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${bar ${baz}}`,
|
||||
true,
|
||||
nil,
|
||||
},
|
||||
|
||||
{
|
||||
`foo ${${baz}}`,
|
||||
true,
|
||||
nil,
|
||||
},
|
||||
|
||||
{
|
||||
"${var",
|
||||
true,
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
actual, err := Parse(tc.Input)
|
||||
if err != nil != tc.Error {
|
||||
t.Fatalf("Error: %s\n\nInput: %s", err, tc.Input)
|
||||
}
|
||||
if !reflect.DeepEqual(actual, tc.Result) {
|
||||
t.Fatalf("Bad: %#v\n\nInput: %s", actual, tc.Input)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package hil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/hil/ast"
|
||||
)
|
||||
|
||||
func TestFixedValueTransform(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input ast.Node
|
||||
Output ast.Node
|
||||
}{
|
||||
{
|
||||
&ast.LiteralNode{Value: 42},
|
||||
&ast.LiteralNode{Value: 42},
|
||||
},
|
||||
|
||||
{
|
||||
&ast.VariableAccess{Name: "bar"},
|
||||
&ast.LiteralNode{Value: "foo"},
|
||||
},
|
||||
|
||||
{
|
||||
&ast.Concat{
|
||||
Exprs: []ast.Node{
|
||||
&ast.VariableAccess{Name: "bar"},
|
||||
&ast.LiteralNode{Value: 42},
|
||||
},
|
||||
},
|
||||
&ast.Concat{
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{Value: "foo"},
|
||||
&ast.LiteralNode{Value: 42},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
value := &ast.LiteralNode{Value: "foo"}
|
||||
for _, tc := range cases {
|
||||
actual := FixedValueTransform(tc.Input, value)
|
||||
if !reflect.DeepEqual(actual, tc.Output) {
|
||||
t.Fatalf("bad: %#v\n\nInput: %#v", actual, tc.Input)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,190 +0,0 @@
|
|||
package hil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInterpolationWalker_detect(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input interface{}
|
||||
Result []string
|
||||
}{
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": "$${var.foo}",
|
||||
},
|
||||
Result: []string{
|
||||
"Literal(TypeString, ${var.foo})",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": "${var.foo}",
|
||||
},
|
||||
Result: []string{
|
||||
"Variable(var.foo)",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": "${aws_instance.foo.*.num}",
|
||||
},
|
||||
Result: []string{
|
||||
"Variable(aws_instance.foo.*.num)",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": "${lookup(var.foo)}",
|
||||
},
|
||||
Result: []string{
|
||||
"Call(lookup, Variable(var.foo))",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": `${file("test.txt")}`,
|
||||
},
|
||||
Result: []string{
|
||||
"Call(file, Literal(TypeString, test.txt))",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": `${file("foo/bar.txt")}`,
|
||||
},
|
||||
Result: []string{
|
||||
"Call(file, Literal(TypeString, foo/bar.txt))",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": `${join(",", foo.bar.*.id)}`,
|
||||
},
|
||||
Result: []string{
|
||||
"Call(join, Literal(TypeString, ,), Variable(foo.bar.*.id))",
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": `${concat("localhost", ":8080")}`,
|
||||
},
|
||||
Result: []string{
|
||||
"Call(concat, Literal(TypeString, localhost), Literal(TypeString, :8080))",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
var actual []string
|
||||
detectFn := func(data *WalkData) error {
|
||||
actual = append(actual, fmt.Sprintf("%s", data.Root))
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := Walk(tc.Input, detectFn); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(actual, tc.Result) {
|
||||
t.Fatalf("%d: bad:\n\n%#v", i, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterpolationWalker_replace(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input interface{}
|
||||
Output interface{}
|
||||
Value string
|
||||
}{
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": "$${var.foo}",
|
||||
},
|
||||
Output: map[string]interface{}{
|
||||
"foo": "bar",
|
||||
},
|
||||
Value: "bar",
|
||||
},
|
||||
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": "hi, ${var.foo}",
|
||||
},
|
||||
Output: map[string]interface{}{
|
||||
"foo": "bar",
|
||||
},
|
||||
Value: "bar",
|
||||
},
|
||||
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": map[string]interface{}{
|
||||
"${var.foo}": "bar",
|
||||
},
|
||||
},
|
||||
Output: map[string]interface{}{
|
||||
"foo": map[string]interface{}{
|
||||
"bar": "bar",
|
||||
},
|
||||
},
|
||||
Value: "bar",
|
||||
},
|
||||
|
||||
/*
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": []interface{}{
|
||||
"${var.foo}",
|
||||
"bing",
|
||||
},
|
||||
},
|
||||
Output: map[string]interface{}{
|
||||
"foo": []interface{}{
|
||||
"bar",
|
||||
"baz",
|
||||
"bing",
|
||||
},
|
||||
},
|
||||
Value: NewStringList([]string{"bar", "baz"}).String(),
|
||||
},
|
||||
|
||||
{
|
||||
Input: map[string]interface{}{
|
||||
"foo": []interface{}{
|
||||
"${var.foo}",
|
||||
"bing",
|
||||
},
|
||||
},
|
||||
Output: map[string]interface{}{},
|
||||
Value: NewStringList([]string{UnknownVariableValue, "baz"}).String(),
|
||||
},
|
||||
*/
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
fn := func(data *WalkData) error {
|
||||
data.Replace = true
|
||||
data.ReplaceValue = tc.Value
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := Walk(tc.Input, fn); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(tc.Input, tc.Output) {
|
||||
t.Fatalf("%d: bad:\n\nexpected:%#v\ngot:%#v", i, tc.Output, tc.Input)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue