diff --git a/validator_instance.go b/validator_instance.go index 6fbd53ae..d230a324 100644 --- a/validator_instance.go +++ b/validator_instance.go @@ -414,7 +414,10 @@ func (v *Validate) StructPartialCtx(ctx context.Context, s interface{}, fields . if len(flds) > 0 { vd.misc = append(vd.misc[0:0], name...) - vd.misc = append(vd.misc, '.') + // Don't append empty name for unnamed structs + if len(vd.misc) != 0 { + vd.misc = append(vd.misc, '.') + } for _, s := range flds { diff --git a/validator_test.go b/validator_test.go index 76062a0d..982446d8 100644 --- a/validator_test.go +++ b/validator_test.go @@ -949,6 +949,38 @@ func TestStructPartial(t *testing.T) { NotEqual(t, errs, nil) AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "Test", "required") + // Test for unnamed struct + testStruct := &TestStruct{ + String: "test", + } + unnamedStruct := struct { + String string `validate:"required" json:"StringVal"` + }{String: "test"} + composedUnnamedStruct := struct{ *TestStruct }{&TestStruct{String: "test"}} + + errs = validate.StructPartial(testStruct, "String") + Equal(t, errs, nil) + + errs = validate.StructPartial(unnamedStruct, "String") + Equal(t, errs, nil) + + errs = validate.StructPartial(composedUnnamedStruct, "TestStruct.String") + Equal(t, errs, nil) + + testStruct.String = "" + errs = validate.StructPartial(testStruct, "String") + NotEqual(t, errs, nil) + AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "required") + + unnamedStruct.String = "" + errs = validate.StructPartial(unnamedStruct, "String") + NotEqual(t, errs, nil) + AssertError(t, errs, "String", "String", "String", "String", "required") + + composedUnnamedStruct.String = "" + errs = validate.StructPartial(composedUnnamedStruct, "TestStruct.String") + NotEqual(t, errs, nil) + AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "required") } func TestCrossStructLteFieldValidation(t *testing.T) {