lang/funcs: `matchkeys` - unify type for keys and searchset

Added higher-level test for matchkeys to exercise mixing
types in searchset. This had to be in the functions tests so the HCL
auto conversion from tuple to list would occur.
pull/21576/head
Kristin Laemmert 7 years ago
parent f2a14d7c18
commit 30a924e162

@ -800,6 +800,8 @@ var MatchkeysFunc = function.New(&function.Spec{
},
},
Type: func(args []cty.Value) (cty.Type, error) {
// Verify that args[1] (keys) and args[2] (searchset) are of the same
// (or unifiable) type
argTypes := make([]cty.Type, 2)
for i := 0; i < 2; i++ {
argTypes[i] = args[i+1].Type()
@ -807,9 +809,10 @@ var MatchkeysFunc = function.New(&function.Spec{
ty, _ := convert.UnifyUnsafe(argTypes)
if ty == cty.NilType {
return cty.NilType, errors.New("lists must be of the same type")
return cty.NilType, errors.New("keys and searchset must be of the same type")
}
// the return type is based on args[0] (values)
return args[0].Type(), nil
},
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
@ -822,10 +825,18 @@ var MatchkeysFunc = function.New(&function.Spec{
}
output := make([]cty.Value, 0)
values := args[0]
keys := args[1]
searchset := args[2]
// Keys and searchset must be the same type.
// We can skip error checking here because we've already verified that
// they can be unified in the Type function
argTypes := make([]cty.Type, 2)
for i := 0; i < 2; i++ {
argTypes[i] = args[i+1].Type()
}
ty, _ := convert.UnifyUnsafe(argTypes)
keys, _ := convert.Convert(args[1], ty)
searchset, _ := convert.Convert(args[2], ty)
// if searchset is empty, return an empty list.
if searchset.LengthInt() == 0 {

@ -1896,6 +1896,37 @@ func TestMatchkeys(t *testing.T) {
cty.ListValEmpty(cty.String),
false,
},
{ // complex values: values is a different type from keys and searchset
cty.ListVal([]cty.Value{
cty.MapVal(map[string]cty.Value{
"foo": cty.StringVal("bar"),
}),
cty.MapVal(map[string]cty.Value{
"foo": cty.StringVal("baz"),
}),
cty.MapVal(map[string]cty.Value{
"foo": cty.StringVal("beep"),
}),
}),
cty.ListVal([]cty.Value{
cty.StringVal("a"),
cty.StringVal("b"),
cty.StringVal("c"),
}),
cty.ListVal([]cty.Value{
cty.StringVal("a"),
cty.StringVal("c"),
}),
cty.ListVal([]cty.Value{
cty.MapVal(map[string]cty.Value{
"foo": cty.StringVal("bar"),
}),
cty.MapVal(map[string]cty.Value{
"foo": cty.StringVal("beep"),
}),
}),
false,
},
// errors
{ // different types
cty.ListVal([]cty.Value{

@ -459,6 +459,13 @@ func TestFunctions(t *testing.T) {
cty.StringVal("a"),
}),
},
{ // mixing types in searchset
`matchkeys(["a", "b", "c"], [1, 2, 3], [1, "3"])`,
cty.ListVal([]cty.Value{
cty.StringVal("a"),
cty.StringVal("c"),
}),
},
},
"max": {

Loading…
Cancel
Save