github.com/wangyougui/gf/v2@v2.6.5/util/gvalid/gvalid_z_unit_feature_custom_rule_test.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/wangyougui/gf. 6 7 package gvalid_test 8 9 import ( 10 "context" 11 "errors" 12 "testing" 13 14 "github.com/wangyougui/gf/v2/errors/gerror" 15 "github.com/wangyougui/gf/v2/frame/g" 16 "github.com/wangyougui/gf/v2/test/gtest" 17 "github.com/wangyougui/gf/v2/util/guid" 18 "github.com/wangyougui/gf/v2/util/gvalid" 19 ) 20 21 func Test_CustomRule1(t *testing.T) { 22 rule := "custom" 23 gvalid.RegisterRule( 24 rule, 25 func(ctx context.Context, in gvalid.RuleFuncInput) error { 26 pass := in.Value.String() 27 if len(pass) != 6 { 28 return errors.New(in.Message) 29 } 30 m := in.Data.Map() 31 if m["data"] != pass { 32 return errors.New(in.Message) 33 } 34 return nil 35 }, 36 ) 37 38 gtest.C(t, func(t *gtest.T) { 39 err := g.Validator().Data("123456").Rules(rule).Messages("custom message").Run(ctx) 40 t.Assert(err.String(), "custom message") 41 err = g.Validator().Data("123456").Assoc(g.Map{"data": "123456"}).Rules(rule).Messages("custom message").Run(ctx) 42 t.AssertNil(err) 43 }) 44 // Error with struct validation. 45 gtest.C(t, func(t *gtest.T) { 46 type T struct { 47 Value string `v:"uid@custom#自定义错误"` 48 Data string `p:"data"` 49 } 50 st := &T{ 51 Value: "123", 52 Data: "123456", 53 } 54 err := g.Validator().Data(st).Run(ctx) 55 t.Assert(err.String(), "自定义错误") 56 }) 57 // No error with struct validation. 58 gtest.C(t, func(t *gtest.T) { 59 type T struct { 60 Value string `v:"uid@custom#自定义错误"` 61 Data string `p:"data"` 62 } 63 st := &T{ 64 Value: "123456", 65 Data: "123456", 66 } 67 err := g.Validator().Data(st).Run(ctx) 68 t.AssertNil(err) 69 }) 70 } 71 72 func Test_CustomRule2(t *testing.T) { 73 rule := "required-map" 74 gvalid.RegisterRule(rule, func(ctx context.Context, in gvalid.RuleFuncInput) error { 75 m := in.Value.Map() 76 if len(m) == 0 { 77 return errors.New(in.Message) 78 } 79 return nil 80 }) 81 // Check. 82 gtest.C(t, func(t *gtest.T) { 83 errStr := "data map should not be empty" 84 t.Assert(g.Validator().Data(g.Map{}).Messages(errStr).Rules(rule).Run(ctx), errStr) 85 t.Assert(g.Validator().Data(g.Map{"k": "v"}).Rules(rule).Messages(errStr).Run(ctx), nil) 86 }) 87 // Error with struct validation. 88 gtest.C(t, func(t *gtest.T) { 89 type T struct { 90 Value map[string]string `v:"uid@required-map#自定义错误"` 91 Data string `p:"data"` 92 } 93 st := &T{ 94 Value: map[string]string{}, 95 Data: "123456", 96 } 97 err := g.Validator().Data(st).Run(ctx) 98 t.Assert(err.String(), "自定义错误") 99 }) 100 // No error with struct validation. 101 gtest.C(t, func(t *gtest.T) { 102 type T struct { 103 Value map[string]string `v:"uid@required-map#自定义错误"` 104 Data string `p:"data"` 105 } 106 st := &T{ 107 Value: map[string]string{"k": "v"}, 108 Data: "123456", 109 } 110 err := g.Validator().Data(st).Run(ctx) 111 t.AssertNil(err) 112 }) 113 } 114 115 func Test_CustomRule_AllowEmpty(t *testing.T) { 116 rule := "allow-empty-str" 117 gvalid.RegisterRule(rule, func(ctx context.Context, in gvalid.RuleFuncInput) error { 118 s := in.Value.String() 119 if len(s) == 0 || s == "gf" { 120 return nil 121 } 122 return errors.New(in.Message) 123 }) 124 // Check. 125 gtest.C(t, func(t *gtest.T) { 126 errStr := "error" 127 t.Assert(g.Validator().Data("").Rules(rule).Messages(errStr).Run(ctx), "") 128 t.Assert(g.Validator().Data("gf").Rules(rule).Messages(errStr).Run(ctx), "") 129 t.Assert(g.Validator().Data("gf2").Rules(rule).Messages(errStr).Run(ctx), errStr) 130 }) 131 // Error with struct validation. 132 gtest.C(t, func(t *gtest.T) { 133 type T struct { 134 Value string `v:"uid@allow-empty-str#自定义错误"` 135 Data string `p:"data"` 136 } 137 st := &T{ 138 Value: "", 139 Data: "123456", 140 } 141 err := g.Validator().Data(st).Run(ctx) 142 t.AssertNil(err) 143 }) 144 // No error with struct validation. 145 gtest.C(t, func(t *gtest.T) { 146 type T struct { 147 Value string `v:"uid@allow-empty-str#自定义错误"` 148 Data string `p:"data"` 149 } 150 st := &T{ 151 Value: "john", 152 Data: "123456", 153 } 154 err := g.Validator().Data(st).Run(ctx) 155 t.Assert(err.String(), "自定义错误") 156 }) 157 } 158 159 func TestValidator_RuleFunc(t *testing.T) { 160 ruleName := "custom_1" 161 ruleFunc := func(ctx context.Context, in gvalid.RuleFuncInput) error { 162 pass := in.Value.String() 163 if len(pass) != 6 { 164 return errors.New(in.Message) 165 } 166 if m := in.Data.Map(); m["data"] != pass { 167 return errors.New(in.Message) 168 } 169 return nil 170 } 171 gtest.C(t, func(t *gtest.T) { 172 err := g.Validator().Rules(ruleName). 173 Messages("custom message"). 174 RuleFunc(ruleName, ruleFunc). 175 Data("123456"). 176 Run(ctx) 177 t.Assert(err.String(), "custom message") 178 err = g.Validator(). 179 Rules(ruleName). 180 Messages("custom message"). 181 Data("123456").Assoc(g.Map{"data": "123456"}). 182 RuleFunc(ruleName, ruleFunc). 183 Run(ctx) 184 t.AssertNil(err) 185 }) 186 // Error with struct validation. 187 gtest.C(t, func(t *gtest.T) { 188 type T struct { 189 Value string `v:"uid@custom_1#自定义错误"` 190 Data string `p:"data"` 191 } 192 st := &T{ 193 Value: "123", 194 Data: "123456", 195 } 196 err := g.Validator().RuleFunc(ruleName, ruleFunc).Data(st).Run(ctx) 197 t.Assert(err.String(), "自定义错误") 198 }) 199 // No error with struct validation. 200 gtest.C(t, func(t *gtest.T) { 201 type T struct { 202 Value string `v:"uid@custom_1#自定义错误"` 203 Data string `p:"data"` 204 } 205 st := &T{ 206 Value: "123456", 207 Data: "123456", 208 } 209 err := g.Validator().RuleFunc(ruleName, ruleFunc).Data(st).Run(ctx) 210 t.AssertNil(err) 211 }) 212 } 213 214 func TestValidator_RuleFuncMap(t *testing.T) { 215 ruleName := "custom_1" 216 ruleFunc := func(ctx context.Context, in gvalid.RuleFuncInput) error { 217 pass := in.Value.String() 218 if len(pass) != 6 { 219 return errors.New(in.Message) 220 } 221 if m := in.Data.Map(); m["data"] != pass { 222 return errors.New(in.Message) 223 } 224 return nil 225 } 226 gtest.C(t, func(t *gtest.T) { 227 err := g.Validator(). 228 Rules(ruleName). 229 Messages("custom message"). 230 RuleFuncMap(map[string]gvalid.RuleFunc{ 231 ruleName: ruleFunc, 232 }).Data("123456").Run(ctx) 233 t.Assert(err.String(), "custom message") 234 err = g.Validator(). 235 Rules(ruleName). 236 Messages("custom message"). 237 Data("123456").Assoc(g.Map{"data": "123456"}). 238 RuleFuncMap(map[string]gvalid.RuleFunc{ 239 ruleName: ruleFunc, 240 }).Run(ctx) 241 t.AssertNil(err) 242 }) 243 // Error with struct validation. 244 gtest.C(t, func(t *gtest.T) { 245 type T struct { 246 Value string `v:"uid@custom_1#自定义错误"` 247 Data string `p:"data"` 248 } 249 st := &T{ 250 Value: "123", 251 Data: "123456", 252 } 253 err := g.Validator(). 254 RuleFuncMap(map[string]gvalid.RuleFunc{ 255 ruleName: ruleFunc, 256 }).Data(st).Run(ctx) 257 t.Assert(err.String(), "自定义错误") 258 }) 259 // No error with struct validation. 260 gtest.C(t, func(t *gtest.T) { 261 type T struct { 262 Value string `v:"uid@custom_1#自定义错误"` 263 Data string `p:"data"` 264 } 265 st := &T{ 266 Value: "123456", 267 Data: "123456", 268 } 269 err := g.Validator(). 270 RuleFuncMap(map[string]gvalid.RuleFunc{ 271 ruleName: ruleFunc, 272 }).Data(st).Run(ctx) 273 t.AssertNil(err) 274 }) 275 } 276 277 func Test_CustomRule_Overwrite(t *testing.T) { 278 gtest.C(t, func(t *gtest.T) { 279 var rule = "custom-" + guid.S() 280 gvalid.RegisterRule(rule, func(ctx context.Context, in gvalid.RuleFuncInput) error { 281 return gerror.New("1") 282 }) 283 t.Assert(g.Validator().Rules(rule).Data(1).Run(ctx), "1") 284 gvalid.RegisterRule(rule, func(ctx context.Context, in gvalid.RuleFuncInput) error { 285 return gerror.New("2") 286 }) 287 t.Assert(g.Validator().Rules(rule).Data(1).Run(ctx), "2") 288 }) 289 g.Dump(gvalid.GetRegisteredRuleMap()) 290 } 291 292 func Test_Issue2499(t *testing.T) { 293 ruleName := "required" 294 ruleFunc := func(ctx context.Context, in gvalid.RuleFuncInput) error { 295 return errors.New(in.Message) 296 } 297 gtest.C(t, func(t *gtest.T) { 298 type T struct { 299 Value string `v:"uid@required"` 300 Data string `p:"data"` 301 } 302 st := &T{ 303 Value: "", 304 Data: "123456", 305 } 306 err := g.Validator(). 307 RuleFuncMap(map[string]gvalid.RuleFunc{ 308 ruleName: ruleFunc, 309 }).Data(st).Run(ctx) 310 t.Assert(err.String(), `The uid field is required`) 311 }) 312 }