package validate import ( "testing" ) func TestOptionalMultiple(t *testing.T) { type s struct { A string `validate:"optional,eq=a"` B int `validate:"gt=3,lt=20"` } pass1 := s{``, 4} pass2 := s{`a`, 19} fail := s{`b`, 3} check(t, pass1, 0) check(t, pass2, 0) check(t, fail, 2) } func TestNesting(t *testing.T) { type sa struct { AA string `validate:"required"` } type sb struct { BA int `validate:"gt=10"` } type s struct { A []sa `validate:"required"` B sb } pass := s{[]sa{{`abc`}}, sb{12}} fail1 := s{nil, sb{12}} fail2 := s{[]sa{{``}}, sb{12}} fail3 := s{[]sa{{``}}, sb{9}} check(t, pass, 0) check(t, fail1, 1) check(t, fail2, 1) check(t, fail3, 2) } func TestValidationErrorField(t *testing.T) { type sc struct { D int `validate:"eq=1"` } type sb struct { C []sc } type sa struct { B sb } type s struct { A sa } errs := Validate(s{ A: sa{ B: sb{ C: []sc{ {D: 0}, {D: 1}, {D: 2}, }, }, }, }) if errs[0].Field.String() != `A.B.C[0].D` || errs[1].Field.String() != `A.B.C[2].D` { t.Fatal(`Expected errors to be A.B.C[0].D and A.B.C[2].D; got`, errs[0].Field, `and`, errs[1].Field) } } func TestNot(t *testing.T) { type s struct { A string `validate:"!len=3"` B int `validate:"!eq=3"` } pass1 := s{`ab`, 2} pass2 := s{`abcd`, 4} fail := s{`abc`, 3} check(t, pass1, 0) check(t, pass2, 0) check(t, fail, 2) errs := Validate(fail) if errs[0].Check != `!len` || errs[1].Check != `!eq` { t.Errorf(`Checknames missing !, got "%s" and "%s"`, errs[0].Check, errs[1].Check) } } func TestPtr(t *testing.T) { type s struct { A *int `validate:"eq=3"` B *int `validate:"optional,eq=3"` } two := 2 three := 3 pass1 := s{&three, &three} pass2 := s{&three, nil} fail1 := s{&two, &two} fail2 := s{nil, nil} check(t, pass1, 0) check(t, pass2, 0) check(t, fail1, 2) check(t, fail2, 1) } type val struct { Int int Valid bool } func (v val) ValidateValue() interface{} { if !v.Valid { return (*int)(nil) } return &v.Int } func TestValidateValuer(t *testing.T) { type s struct { A val `validate:"required,lt=2"` B val `validate:"optional,eq=3"` } pass1 := s{val{Valid: true}, val{}} pass2 := s{val{Valid: true}, val{Int: 3, Valid: true}} fail1 := s{} fail2 := s{val{Int: 2, Valid: true}, val{}} fail3 := s{val{Valid: true}, val{Int: 2, Valid: true}} check(t, pass1, 0) check(t, pass2, 0) check(t, fail1, 1) check(t, fail2, 1) check(t, fail3, 1) }