Implement unique=FieldName

pull/560/head
Shi Han NG 5 years ago committed by Dean Karn
parent 1effcb06a7
commit 8f604265e0
  1. 14
      baked_in.go
  2. 43
      validator_test.go

@ -228,16 +228,30 @@ func isOneOf(fl FieldLevel) bool {
func isUnique(fl FieldLevel) bool {
field := fl.Field()
param := fl.Param()
v := reflect.ValueOf(struct{}{})
switch field.Kind() {
case reflect.Slice, reflect.Array:
if param == "" {
m := reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))
for i := 0; i < field.Len(); i++ {
m.SetMapIndex(field.Index(i), v)
}
return field.Len() == m.Len()
}
sf, ok := field.Type().Elem().FieldByName(param)
if !ok {
panic(fmt.Sprintf("Bad field name %s", param))
}
m := reflect.MakeMap(reflect.MapOf(sf.Type, v.Type()))
for i := 0; i < field.Len(); i++ {
m.SetMapIndex(field.Index(i).FieldByName(param), v)
}
return field.Len() == m.Len()
case reflect.Map:
m := reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))

@ -8185,6 +8185,49 @@ func TestUniqueValidation(t *testing.T) {
PanicMatches(t, func() { _ = validate.Var(1.0, "unique") }, "Bad field type float64")
}
func TestUniqueValidationStructSlice(t *testing.T) {
testStructs := []struct {
A string
B string
}{
{A: "one", B: "two"},
{A: "one", B: "three"},
}
tests := []struct {
target interface{}
param string
expected bool
}{
{testStructs, "unique", true},
{testStructs, "unique=A", false},
{testStructs, "unique=B", true},
}
validate := New()
for i, test := range tests {
errs := validate.Var(test.target, test.param)
if test.expected {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d unique failed Error: %v", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d unique failed Error: %v", i, errs)
} else {
val := getError(errs, "", "")
if val.Tag() != "unique" {
t.Fatalf("Index: %d unique failed Error: %v", i, errs)
}
}
}
}
PanicMatches(t, func() { validate.Var(testStructs, "unique=C") }, "Bad field name C")
}
func TestHTMLValidation(t *testing.T) {
tests := []struct {
param string

Loading…
Cancel
Save