helper/validation: Add All() and IntInSlice() SchemaValidateFunc
`All()` combines the outputs of multiple `SchemaValidateFunc`, to reduce the usage of custom validation functions that implement standard validation functions. Example provider usage: ```go ValidateFunc: validation.All( StringLenBetween(5, 42), StringMatch(regexp.MustCompile(`[a-zA-Z0-9]+`), "value must be alphanumeric"), ), ``` `IntInSlice()` is the `int` equivalent of `StringInSlice()` Example provider usage: ```go ValidateFunc: validation.IntInSlice([]int{30, 60, 120}) ``` Output from unit testing: ``` $ make test TEST=./helper/validation ==> Checking that code complies with gofmt requirements... go generate ./... 2018/10/17 14:16:03 Generated command/internal_plugin_list.go go list ./helper/validation | xargs -t -n4 go test -timeout=2m -parallel=4 go test -timeout=2m -parallel=4 github.com/hashicorp/terraform/helper/validation ok github.com/hashicorp/terraform/helper/validation 1.106s ```
This commit is contained in:
parent
9143cb5b49
commit
17ac9a5756
|
@ -13,6 +13,21 @@ import (
|
||||||
"github.com/hashicorp/terraform/helper/structure"
|
"github.com/hashicorp/terraform/helper/structure"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// All returns a SchemaValidateFunc which tests if the provided value
|
||||||
|
// passes all provided SchemaValidateFunc
|
||||||
|
func All(validators ...schema.SchemaValidateFunc) schema.SchemaValidateFunc {
|
||||||
|
return func(i interface{}, k string) ([]string, []error) {
|
||||||
|
var allErrors []error
|
||||||
|
var allWarnings []string
|
||||||
|
for _, validator := range validators {
|
||||||
|
validatorWarnings, validatorErrors := validator(i, k)
|
||||||
|
allWarnings = append(allWarnings, validatorWarnings...)
|
||||||
|
allErrors = append(allErrors, validatorErrors...)
|
||||||
|
}
|
||||||
|
return allWarnings, allErrors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// IntBetween returns a SchemaValidateFunc which tests if the provided value
|
// IntBetween returns a SchemaValidateFunc which tests if the provided value
|
||||||
// is of type int and is between min and max (inclusive)
|
// is of type int and is between min and max (inclusive)
|
||||||
func IntBetween(min, max int) schema.SchemaValidateFunc {
|
func IntBetween(min, max int) schema.SchemaValidateFunc {
|
||||||
|
@ -70,6 +85,27 @@ func IntAtMost(max int) schema.SchemaValidateFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IntInSlice returns a SchemaValidateFunc which tests if the provided value
|
||||||
|
// is of type int and matches the value of an element in the valid slice
|
||||||
|
func IntInSlice(valid []int) schema.SchemaValidateFunc {
|
||||||
|
return func(i interface{}, k string) (s []string, es []error) {
|
||||||
|
v, ok := i.(int)
|
||||||
|
if !ok {
|
||||||
|
es = append(es, fmt.Errorf("expected type of %s to be an integer", k))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, validInt := range valid {
|
||||||
|
if v == validInt {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
es = append(es, fmt.Errorf("expected %s to be one of %v, got %d", k, valid, v))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// StringInSlice returns a SchemaValidateFunc which tests if the provided value
|
// StringInSlice returns a SchemaValidateFunc which tests if the provided value
|
||||||
// is of type string and matches the value of an element in the valid slice
|
// is of type string and matches the value of an element in the valid slice
|
||||||
// will test with in lower case if ignoreCase is true
|
// will test with in lower case if ignoreCase is true
|
||||||
|
|
|
@ -13,6 +13,34 @@ type testCase struct {
|
||||||
expectedErr *regexp.Regexp
|
expectedErr *regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidationAll(t *testing.T) {
|
||||||
|
runTestCases(t, []testCase{
|
||||||
|
{
|
||||||
|
val: "valid",
|
||||||
|
f: All(
|
||||||
|
StringLenBetween(5, 42),
|
||||||
|
StringMatch(regexp.MustCompile(`[a-zA-Z0-9]+`), "value must be alphanumeric"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
val: "foo",
|
||||||
|
f: All(
|
||||||
|
StringLenBetween(5, 42),
|
||||||
|
StringMatch(regexp.MustCompile(`[a-zA-Z0-9]+`), "value must be alphanumeric"),
|
||||||
|
),
|
||||||
|
expectedErr: regexp.MustCompile("expected length of [\\w]+ to be in the range \\(5 - 42\\), got foo"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
val: "!!!!!",
|
||||||
|
f: All(
|
||||||
|
StringLenBetween(5, 42),
|
||||||
|
StringMatch(regexp.MustCompile(`[a-zA-Z0-9]+`), "value must be alphanumeric"),
|
||||||
|
),
|
||||||
|
expectedErr: regexp.MustCompile("value must be alphanumeric"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestValidationIntBetween(t *testing.T) {
|
func TestValidationIntBetween(t *testing.T) {
|
||||||
runTestCases(t, []testCase{
|
runTestCases(t, []testCase{
|
||||||
{
|
{
|
||||||
|
@ -82,6 +110,25 @@ func TestValidationIntAtMost(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidationIntInSlice(t *testing.T) {
|
||||||
|
runTestCases(t, []testCase{
|
||||||
|
{
|
||||||
|
val: 42,
|
||||||
|
f: IntInSlice([]int{1, 42}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
val: 42,
|
||||||
|
f: IntInSlice([]int{10, 20}),
|
||||||
|
expectedErr: regexp.MustCompile("expected [\\w]+ to be one of \\[10 20\\], got 42"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
val: "InvalidValue",
|
||||||
|
f: IntInSlice([]int{10, 20}),
|
||||||
|
expectedErr: regexp.MustCompile("expected type of [\\w]+ to be an integer"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestValidationStringInSlice(t *testing.T) {
|
func TestValidationStringInSlice(t *testing.T) {
|
||||||
runTestCases(t, []testCase{
|
runTestCases(t, []testCase{
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue