core: Fix detection of empty list/map defaults
This commit changes config parsing from weak decoding lists and maps into []string and map[string]string respectively to decode into []interface{} and map[string]interface{} respectively. This is in order to take advantage of the work integrated in #7082 to defeat the backward compatibility features of the mapstructure library. Test coverage of loading empty variables and validating their default types against expectation.
This commit is contained in:
parent
3662bfa67a
commit
01cd596c60
|
@ -891,7 +891,8 @@ func (v *Variable) ValidateTypeAndDefault() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.inferTypeFromDefault() != v.Type() {
|
if v.inferTypeFromDefault() != v.Type() {
|
||||||
return fmt.Errorf("'%s' has a default value which is not of type '%s'", v.Name, v.DeclaredType)
|
return fmt.Errorf("'%s' has a default value which is not of type '%s' (got '%s')",
|
||||||
|
v.Name, v.DeclaredType, v.inferTypeFromDefault().Printable())
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -924,13 +925,13 @@ func (v *Variable) inferTypeFromDefault() VariableType {
|
||||||
return VariableTypeString
|
return VariableTypeString
|
||||||
}
|
}
|
||||||
|
|
||||||
var m map[string]string
|
var m map[string]interface{}
|
||||||
if err := hilmapstructure.WeakDecode(v.Default, &m); err == nil {
|
if err := hilmapstructure.WeakDecode(v.Default, &m); err == nil {
|
||||||
v.Default = m
|
v.Default = m
|
||||||
return VariableTypeMap
|
return VariableTypeMap
|
||||||
}
|
}
|
||||||
|
|
||||||
var l []string
|
var l []interface{}
|
||||||
if err := hilmapstructure.WeakDecode(v.Default, &l); err == nil {
|
if err := hilmapstructure.WeakDecode(v.Default, &l); err == nil {
|
||||||
v.Default = l
|
v.Default = l
|
||||||
return VariableTypeList
|
return VariableTypeList
|
||||||
|
|
|
@ -2,6 +2,7 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -85,6 +86,31 @@ func TestConfigCount_var(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfig_emptyCollections(t *testing.T) {
|
||||||
|
c := testConfig(t, "empty-collections")
|
||||||
|
if len(c.Variables) != 3 {
|
||||||
|
t.Fatalf("bad: expected 3 variables, got %d", len(c.Variables))
|
||||||
|
}
|
||||||
|
for _, variable := range c.Variables {
|
||||||
|
switch variable.Name {
|
||||||
|
case "empty_string":
|
||||||
|
if variable.Default != "" {
|
||||||
|
t.Fatalf("bad: wrong default %q for variable empty_string", variable.Default)
|
||||||
|
}
|
||||||
|
case "empty_map":
|
||||||
|
if !reflect.DeepEqual(variable.Default, map[string]interface{}{}) {
|
||||||
|
t.Fatalf("bad: wrong default %#v for variable empty_map", variable.Default)
|
||||||
|
}
|
||||||
|
case "empty_list":
|
||||||
|
if !reflect.DeepEqual(variable.Default, []interface{}{}) {
|
||||||
|
t.Fatalf("bad: wrong default %#v for variable empty_list", variable.Default)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
t.Fatalf("Unexpected variable: %s", variable.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestConfigValidate(t *testing.T) {
|
func TestConfigValidate(t *testing.T) {
|
||||||
c := testConfig(t, "validate-good")
|
c := testConfig(t, "validate-good")
|
||||||
if err := c.Validate(); err != nil {
|
if err := c.Validate(); err != nil {
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
variable "empty_string" {
|
||||||
|
default = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "empty_list" {
|
||||||
|
default = []
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "empty_map" {
|
||||||
|
default = {}
|
||||||
|
}
|
Loading…
Reference in New Issue