Implement unique=FieldName

pull/496/head
Shi Han NG 5 years ago
parent 556b9da3c0
commit d04a036fb5
No known key found for this signature in database
GPG Key ID: 3E9FA195E69C9A6D
  1. 18
      baked_in.go
  2. 43
      validator_test.go

@ -224,14 +224,28 @@ 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:
m := reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))
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), v)
m.SetMapIndex(field.Index(i).FieldByName(param), v)
}
return field.Len() == m.Len()
case reflect.Map:

@ -8160,6 +8160,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