helper/validation: Add NoZeroValues
This adds NoZeroValues, a small SchemaValidateFunc that checks that a defined value is not a zero value. It's useful for situations where you want to keep someone from explicitly entering a zero value (ie: literally "0", or an empty string) on a required field, and want to catch it in the validation stage, versus during apply using GetOk.
This commit is contained in:
parent
f846beecbc
commit
edb8e8904c
|
@ -3,6 +3,7 @@ package validation
|
|||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
|
@ -105,6 +106,24 @@ func StringLenBetween(min, max int) schema.SchemaValidateFunc {
|
|||
}
|
||||
}
|
||||
|
||||
// NoZeroValues is a SchemaValidateFunc which tests if the provided value is
|
||||
// not a zero value. It's useful in situations where you want to catch
|
||||
// explicit zero values on things like required fields during validation.
|
||||
func NoZeroValues(i interface{}, k string) (s []string, es []error) {
|
||||
if reflect.ValueOf(i).Interface() == reflect.Zero(reflect.TypeOf(i)).Interface() {
|
||||
switch reflect.TypeOf(i).Kind() {
|
||||
case reflect.String:
|
||||
es = append(es, fmt.Errorf("%s must not be empty", k))
|
||||
case reflect.Int, reflect.Float64:
|
||||
es = append(es, fmt.Errorf("%s must not be zero", k))
|
||||
default:
|
||||
// this validator should only ever be applied to TypeString, TypeInt and TypeFloat
|
||||
panic(fmt.Errorf("can't use NoZeroValues with %T attribute %s", i, k))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// CIDRNetwork returns a SchemaValidateFunc which tests if the provided value
|
||||
// is of type string, is in valid CIDR network notation, and has significant bits between min and max (inclusive)
|
||||
func CIDRNetwork(min, max int) schema.SchemaValidateFunc {
|
||||
|
|
|
@ -199,6 +199,38 @@ func TestValidateListUniqueStrings(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestValidationNoZeroValues(t *testing.T) {
|
||||
runTestCases(t, []testCase{
|
||||
{
|
||||
val: "foo",
|
||||
f: NoZeroValues,
|
||||
},
|
||||
{
|
||||
val: 1,
|
||||
f: NoZeroValues,
|
||||
},
|
||||
{
|
||||
val: float64(1),
|
||||
f: NoZeroValues,
|
||||
},
|
||||
{
|
||||
val: "",
|
||||
f: NoZeroValues,
|
||||
expectedErr: regexp.MustCompile("must not be empty"),
|
||||
},
|
||||
{
|
||||
val: 0,
|
||||
f: NoZeroValues,
|
||||
expectedErr: regexp.MustCompile("must not be zero"),
|
||||
},
|
||||
{
|
||||
val: float64(0),
|
||||
f: NoZeroValues,
|
||||
expectedErr: regexp.MustCompile("must not be zero"),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func runTestCases(t *testing.T, cases []testCase) {
|
||||
matchErr := func(errs []error, r *regexp.Regexp) bool {
|
||||
// err must match one provided
|
||||
|
|
Loading…
Reference in New Issue