hcl/zcl/zclsyntax/expression_test.go

189 lines
3.6 KiB
Go
Raw Normal View History

package zclsyntax
import (
"testing"
"github.com/apparentlymart/go-cty/cty"
"github.com/apparentlymart/go-cty/cty/function"
"github.com/apparentlymart/go-cty/cty/function/stdlib"
"github.com/apparentlymart/go-zcl/zcl"
)
func TestFunctionCallExprValue(t *testing.T) {
funcs := map[string]function.Function{
"length": stdlib.StrlenFunc,
"jsondecode": stdlib.JSONDecodeFunc,
}
tests := map[string]struct {
expr *FunctionCallExpr
ctx *zcl.EvalContext
want cty.Value
diagCount int
}{
"valid call with no conversions": {
&FunctionCallExpr{
Name: "length",
Args: []Expression{
&LiteralValueExpr{
Val: cty.StringVal("hello"),
},
},
},
&zcl.EvalContext{
Functions: funcs,
},
cty.NumberIntVal(5),
0,
},
"valid call with arg conversion": {
&FunctionCallExpr{
Name: "length",
Args: []Expression{
&LiteralValueExpr{
Val: cty.BoolVal(true),
},
},
},
&zcl.EvalContext{
Functions: funcs,
},
cty.NumberIntVal(4), // length of string "true"
0,
},
"valid call with unknown arg": {
&FunctionCallExpr{
Name: "length",
Args: []Expression{
&LiteralValueExpr{
Val: cty.UnknownVal(cty.String),
},
},
},
&zcl.EvalContext{
Functions: funcs,
},
cty.UnknownVal(cty.Number),
0,
},
"valid call with unknown arg needing conversion": {
&FunctionCallExpr{
Name: "length",
Args: []Expression{
&LiteralValueExpr{
Val: cty.UnknownVal(cty.Bool),
},
},
},
&zcl.EvalContext{
Functions: funcs,
},
cty.UnknownVal(cty.Number),
0,
},
"valid call with dynamic arg": {
&FunctionCallExpr{
Name: "length",
Args: []Expression{
&LiteralValueExpr{
Val: cty.DynamicVal,
},
},
},
&zcl.EvalContext{
Functions: funcs,
},
cty.UnknownVal(cty.Number),
0,
},
"invalid arg type": {
&FunctionCallExpr{
Name: "length",
Args: []Expression{
&LiteralValueExpr{
Val: cty.ListVal([]cty.Value{cty.StringVal("hello")}),
},
},
},
&zcl.EvalContext{
Functions: funcs,
},
cty.DynamicVal,
1,
},
"function with dynamic return type": {
&FunctionCallExpr{
Name: "jsondecode",
Args: []Expression{
&LiteralValueExpr{
Val: cty.StringVal(`"hello"`),
},
},
},
&zcl.EvalContext{
Functions: funcs,
},
cty.StringVal("hello"),
0,
},
"function with dynamic return type unknown arg": {
&FunctionCallExpr{
Name: "jsondecode",
Args: []Expression{
&LiteralValueExpr{
Val: cty.UnknownVal(cty.String),
},
},
},
&zcl.EvalContext{
Functions: funcs,
},
cty.DynamicVal, // type depends on arg value
0,
},
"error in function": {
&FunctionCallExpr{
Name: "jsondecode",
Args: []Expression{
&LiteralValueExpr{
Val: cty.StringVal("invalid-json"),
},
},
},
&zcl.EvalContext{
Functions: funcs,
},
cty.DynamicVal,
1, // JSON parse error
},
"unknown function": {
&FunctionCallExpr{
Name: "lenth",
Args: []Expression{},
},
&zcl.EvalContext{
Functions: funcs,
},
cty.DynamicVal,
1,
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
got, diags := test.expr.Value(test.ctx)
if len(diags) != test.diagCount {
t.Errorf("wrong number of diagnostics %d; want %d", len(diags), test.diagCount)
for _, diag := range diags {
t.Logf(" - %s", diag.Error())
}
}
if !got.RawEquals(test.want) {
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.want)
}
})
}
}