package validate import ( "reflect" "testing" ) func TestAddRule(t *testing.T) { type s struct { A string `validate:"custom"` } AddRule(`custom`, nil, Kinds{ reflect.String: func(rv reflect.Value, _ interface{}) bool { return rv.String() == `custom` }, }) var pass = s{`custom`} var fail = s{`somethingelse`} check(t, pass, 0) check(t, fail, 1) } func TestRuleRequired(t *testing.T) { type s struct { A *string `validate:"required"` B []int `validate:"required"` C []int `validate:"required"` D string `validate:"required"` E int `validate:"required"` F uint `validate:"required"` G float64 `validate:"required"` H interface{} `validate:"required"` I map[int]int `validate:"required"` } str := `` var pass = s{&str, make([]int, 1), make([]int, 1), ` `, -1, 1, 0.01, ``, map[int]int{0: 1}} var fail = s{nil, nil, make([]int, 0), ``, 0, 0, 0.000, nil, nil} check(t, pass, 0) check(t, fail, 9) } func TestRulePrefixSuffix(t *testing.T) { type s struct { A string `validate:"prefix=#"` B string `validate:"suffix=@"` } var pass = s{`#a`, `a@`} var fail = s{`a#`, `@a`} check(t, pass, 0) check(t, fail, 2) } func TestRuleContains(t *testing.T) { type s struct { A string `validate:"contains=%"` } var pass1 = s{`a%`} var pass2 = s{`%a`} var pass3 = s{`%`} var pass4 = s{`a%a`} var fail = s{`aa`} check(t, pass1, 0) check(t, pass2, 0) check(t, pass3, 0) check(t, pass4, 0) check(t, fail, 1) } func TestRuleRegexp(t *testing.T) { type s struct { A string `validate:"regexp=^[0-9]$"` } var pass1 = s{`0`} var pass2 = s{`7`} var fail1 = s{`A`} var fail2 = s{`11`} check(t, pass1, 0) check(t, pass2, 0) check(t, fail1, 1) check(t, fail2, 1) } func TestRuleEqGtLt(t *testing.T) { type s struct { A int `validate:"eq=3"` B float64 `validate:"gt=1e5"` C uint `validate:"lt=1"` } var pass = s{3, 100001, 0} var fail1 = s{2, 1e5, 1} var fail2 = s{4, 9999, 2} check(t, pass, 0) check(t, fail1, 3) check(t, fail2, 3) } func TestLenMinMax(t *testing.T) { type s struct { A string `validate:"len=3"` B []int `validate:"min=2"` C map[int]string `validate:"max=1"` } var pass = s{`abc`, []int{1, 2}, nil} var fail1 = s{`ab`, []int{1}, map[int]string{1: `a`, 2: `b`}} var fail2 = s{`abcd`, nil, nil} check(t, pass, 0) check(t, fail1, 3) check(t, fail2, 2) } func check(t *testing.T, c interface{}, errCount int) { t.Helper() errs := Validate(c) if len(errs) != errCount { t.Errorf(`Case %T(%v) should get %d errors, but got %v`, c, c, errCount, errs) } }