github.com/wangyougui/gf/v2@v2.6.5/util/gvalid/gvalid_z_example_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  	"fmt"
    13  
    14  	"github.com/wangyougui/gf/v2/container/gvar"
    15  	"github.com/wangyougui/gf/v2/frame/g"
    16  	"github.com/wangyougui/gf/v2/i18n/gi18n"
    17  	"github.com/wangyougui/gf/v2/os/gctx"
    18  	"github.com/wangyougui/gf/v2/test/gtest"
    19  	"github.com/wangyougui/gf/v2/util/gconv"
    20  	"github.com/wangyougui/gf/v2/util/gvalid"
    21  )
    22  
    23  func ExampleNew() {
    24  	if err := g.Validator().Data(16).Rules("min:18").Run(context.Background()); err != nil {
    25  		fmt.Println(err)
    26  	}
    27  
    28  	// Output:
    29  	// The value `16` must be equal or greater than 18
    30  }
    31  
    32  func ExampleValidator_Run() {
    33  	// check value mode
    34  	if err := g.Validator().Data(16).Rules("min:18").Run(context.Background()); err != nil {
    35  		fmt.Println("check value err:", err)
    36  	}
    37  	// check map mode
    38  	data := map[string]interface{}{
    39  		"passport":  "",
    40  		"password":  "123456",
    41  		"password2": "1234567",
    42  	}
    43  	rules := map[string]string{
    44  		"passport":  "required|length:6,16",
    45  		"password":  "required|length:6,16|same:password2",
    46  		"password2": "required|length:6,16",
    47  	}
    48  	if err := g.Validator().Data(data).Rules(rules).Run(context.Background()); err != nil {
    49  		fmt.Println("check map err:", err)
    50  	}
    51  	// check struct mode
    52  	type Params struct {
    53  		Page      int    `v:"required|min:1"`
    54  		Size      int    `v:"required|between:1,100"`
    55  		ProjectId string `v:"between:1,10000"`
    56  	}
    57  	rules = map[string]string{
    58  		"Page":      "required|min:1",
    59  		"Size":      "required|between:1,100",
    60  		"ProjectId": "between:1,10000",
    61  	}
    62  	obj := &Params{
    63  		Page: 0,
    64  		Size: 101,
    65  	}
    66  	if err := g.Validator().Data(obj).Run(context.Background()); err != nil {
    67  		fmt.Println("check struct err:", err)
    68  	}
    69  
    70  	// May Output:
    71  	// check value err: The value `16` must be equal or greater than 18
    72  	// check map err: The passport field is required; The passport value `` length must be between 6 and 16; The password value `123456` must be the same as field password2
    73  	// check struct err: The Page value `0` must be equal or greater than 1; The Size value `101` must be between 1 and 100
    74  }
    75  
    76  func ExampleValidator_Clone() {
    77  	if err := g.Validator().Data(16).Rules("min:18").Run(context.Background()); err != nil {
    78  		fmt.Println(err)
    79  	}
    80  
    81  	if err := g.Validator().Clone().Data(20).Run(context.Background()); err != nil {
    82  		fmt.Println(err)
    83  	} else {
    84  		fmt.Println("Check Success!")
    85  	}
    86  
    87  	// Output:
    88  	// The value `16` must be equal or greater than 18
    89  	// Check Success!
    90  }
    91  
    92  func ExampleValidator_I18n() {
    93  	var (
    94  		i18nManager = gi18n.New(gi18n.Options{Path: gtest.DataPath("i18n")})
    95  		ctxCn       = gi18n.WithLanguage(context.Background(), "cn")
    96  		validator   = gvalid.New()
    97  	)
    98  
    99  	validator = validator.Data(16).Rules("min:18")
   100  
   101  	if err := validator.Run(context.Background()); err != nil {
   102  		fmt.Println(err)
   103  	}
   104  
   105  	if err := validator.I18n(i18nManager).Run(ctxCn); err != nil {
   106  		fmt.Println(err)
   107  	}
   108  
   109  	// Output:
   110  	// The value `16` must be equal or greater than 18
   111  	// 字段值`16`字段最小值应当为18
   112  }
   113  
   114  func ExampleValidator_Bail() {
   115  	type BizReq struct {
   116  		Account   string `v:"required|length:6,16|same:QQ"`
   117  		QQ        string
   118  		Password  string `v:"required|same:Password2"`
   119  		Password2 string `v:"required"`
   120  	}
   121  	var (
   122  		ctx = context.Background()
   123  		req = BizReq{
   124  			Account:   "gf",
   125  			QQ:        "123456",
   126  			Password:  "goframe.org",
   127  			Password2: "goframe.org",
   128  		}
   129  	)
   130  
   131  	if err := g.Validator().Bail().Data(req).Run(ctx); err != nil {
   132  		fmt.Println("Use Bail Error:", err)
   133  	}
   134  
   135  	if err := g.Validator().Data(req).Run(ctx); err != nil {
   136  		fmt.Println("Not Use Bail Error:", err)
   137  	}
   138  
   139  	// output:
   140  	// Use Bail Error: The Account value `gf` length must be between 6 and 16
   141  	// Not Use Bail Error: The Account value `gf` length must be between 6 and 16; The Account value `gf` must be the same as field QQ value `123456`
   142  }
   143  
   144  func ExampleValidator_Ci() {
   145  	type BizReq struct {
   146  		Account   string `v:"required"`
   147  		Password  string `v:"required|same:Password2"`
   148  		Password2 string `v:"required"`
   149  	}
   150  	var (
   151  		ctx = context.Background()
   152  		req = BizReq{
   153  			Account:   "gf",
   154  			Password:  "Goframe.org", // Diff from Password2, but because of "ci", rule check passed
   155  			Password2: "goframe.org",
   156  		}
   157  	)
   158  
   159  	if err := g.Validator().Data(req).Run(ctx); err != nil {
   160  		fmt.Println("Not Use CI Error:", err)
   161  	}
   162  
   163  	if err := g.Validator().Ci().Data(req).Run(ctx); err == nil {
   164  		fmt.Println("Use CI Passed!")
   165  	}
   166  
   167  	// output:
   168  	// Not Use CI Error: The Password value `Goframe.org` must be the same as field Password2 value `goframe.org`
   169  	// Use CI Passed!
   170  }
   171  
   172  func ExampleValidator_Data() {
   173  	type BizReq struct {
   174  		Password1 string `v:"password"`
   175  		Password2 string `v:"password"`
   176  	}
   177  
   178  	var (
   179  		ctx = context.Background()
   180  		req = BizReq{
   181  			Password1: "goframe",
   182  			Password2: "gofra", // error length between 6 and 18
   183  		}
   184  	)
   185  	if err := g.Validator().Data(req).Run(ctx); err != nil {
   186  		fmt.Print(err)
   187  	}
   188  
   189  	// Output:
   190  	// The Password2 value `gofra` is not a valid password format
   191  }
   192  
   193  func ExampleValidator_Data_Value() {
   194  	err := g.Validator().Rules("min:18").
   195  		Messages("未成年人不允许注册哟").
   196  		Data(16).Run(gctx.New())
   197  	fmt.Println(err.String())
   198  
   199  	// Output:
   200  	// 未成年人不允许注册哟
   201  }
   202  
   203  func ExampleValidator_Data_Map1() {
   204  	params := map[string]interface{}{
   205  		"passport":  "",
   206  		"password":  "123456",
   207  		"password2": "1234567",
   208  	}
   209  	rules := []string{
   210  		"passport@required|length:6,16#账号不能为空|账号长度应当在{min}到{max}之间",
   211  		"password@required|length:6,16|same{password}2#密码不能为空|密码长度应当在{min}到{max}之间|两次密码输入不相等",
   212  		"password2@required|length:6,16#",
   213  	}
   214  	if e := g.Validator().Data(params).Rules(rules).Run(gctx.New()); e != nil {
   215  		fmt.Println(e.Map())
   216  		fmt.Println(e.FirstItem())
   217  		fmt.Println(e.FirstError())
   218  	}
   219  	// May Output:
   220  	// map[required:账号不能为空 length:账号长度应当在6到16之间]
   221  	// passport map[required:账号不能为空 length:账号长度应当在6到16之间]
   222  	// 账号不能为空
   223  }
   224  
   225  func ExampleValidator_Data_Map2() {
   226  	params := map[string]interface{}{
   227  		"passport":  "",
   228  		"password":  "123456",
   229  		"password2": "1234567",
   230  	}
   231  	rules := []string{
   232  		"passport@length:6,16#账号不能为空|账号长度应当在{min}到{max}之间",
   233  		"password@required|length:6,16|same:password2#密码不能为空|密码长度应当在{min}到{max}之间|两次密码输入不相等",
   234  		"password2@required|length:6,16#",
   235  	}
   236  	if e := g.Validator().Data(params).Rules(rules).Run(gctx.New()); e != nil {
   237  		fmt.Println(e.Map())
   238  		fmt.Println(e.FirstItem())
   239  		fmt.Println(e.FirstError())
   240  	}
   241  	// Output:
   242  	// map[same:两次密码输入不相等]
   243  	// password map[same:两次密码输入不相等]
   244  	// 两次密码输入不相等
   245  }
   246  
   247  func ExampleValidator_Data_Map3() {
   248  	params := map[string]interface{}{
   249  		"passport":  "",
   250  		"password":  "123456",
   251  		"password2": "1234567",
   252  	}
   253  	rules := map[string]string{
   254  		"passport":  "required|length:6,16",
   255  		"password":  "required|length:6,16|same:password2",
   256  		"password2": "required|length:6,16",
   257  	}
   258  	messages := map[string]interface{}{
   259  		"passport": "账号不能为空|账号长度应当在{min}到{max}之间",
   260  		"password": map[string]string{
   261  			"required": "密码不能为空",
   262  			"same":     "两次密码输入不相等",
   263  		},
   264  	}
   265  	err := g.Validator().
   266  		Messages(messages).
   267  		Rules(rules).
   268  		Data(params).Run(gctx.New())
   269  	if err != nil {
   270  		g.Dump(err.Maps())
   271  	}
   272  
   273  	// May Output:
   274  	// {
   275  	//	"passport": {
   276  	//	"length": "账号长度应当在6到16之间",
   277  	//		"required": "账号不能为空"
   278  	// },
   279  	//	"password": {
   280  	//	"same": "两次密码输入不相等"
   281  	// }
   282  	// }
   283  }
   284  
   285  // Empty string attribute.
   286  func ExampleValidator_Data_Struct1() {
   287  	type Params struct {
   288  		Page      int    `v:"required|min:1         # page is required"`
   289  		Size      int    `v:"required|between:1,100 # size is required"`
   290  		ProjectId string `v:"between:1,10000        # project id must between {min}, {max}"`
   291  	}
   292  	obj := &Params{
   293  		Page: 1,
   294  		Size: 10,
   295  	}
   296  	err := g.Validator().Data(obj).Run(gctx.New())
   297  	fmt.Println(err == nil)
   298  	// Output:
   299  	// true
   300  }
   301  
   302  // Empty pointer attribute.
   303  func ExampleValidator_Data_Struct2() {
   304  	type Params struct {
   305  		Page      int       `v:"required|min:1         # page is required"`
   306  		Size      int       `v:"required|between:1,100 # size is required"`
   307  		ProjectId *gvar.Var `v:"between:1,10000        # project id must between {min}, {max}"`
   308  	}
   309  	obj := &Params{
   310  		Page: 1,
   311  		Size: 10,
   312  	}
   313  	err := g.Validator().Data(obj).Run(gctx.New())
   314  	fmt.Println(err == nil)
   315  	// Output:
   316  	// true
   317  }
   318  
   319  // Empty integer attribute.
   320  func ExampleValidator_Data_Struct3() {
   321  	type Params struct {
   322  		Page      int `v:"required|min:1         # page is required"`
   323  		Size      int `v:"required|between:1,100 # size is required"`
   324  		ProjectId int `v:"between:1,10000        # project id must between {min}, {max}"`
   325  	}
   326  	obj := &Params{
   327  		Page: 1,
   328  		Size: 10,
   329  	}
   330  	err := g.Validator().Data(obj).Run(gctx.New())
   331  	fmt.Println(err)
   332  	// Output:
   333  	// project id must between 1, 10000
   334  }
   335  
   336  func ExampleValidator_Data_Struct4() {
   337  	type User struct {
   338  		Name string `v:"required#请输入用户姓名"`
   339  		Type int    `v:"required#请选择用户类型"`
   340  	}
   341  	data := g.Map{
   342  		"name": "john",
   343  	}
   344  	user := User{}
   345  	if err := gconv.Scan(data, &user); err != nil {
   346  		panic(err)
   347  	}
   348  	err := g.Validator().Data(user).Assoc(data).Run(gctx.New())
   349  	if err != nil {
   350  		fmt.Println(err.Items())
   351  	}
   352  
   353  	// Output:
   354  	// [map[Type:map[required:请选择用户类型]]]
   355  }
   356  
   357  func ExampleValidator_Assoc() {
   358  	type User struct {
   359  		Name string `v:"required"`
   360  		Type int    `v:"required"`
   361  	}
   362  	data := g.Map{
   363  		"name": "john",
   364  	}
   365  	user := User{}
   366  
   367  	if err := gconv.Scan(data, &user); err != nil {
   368  		panic(err)
   369  	}
   370  
   371  	if err := g.Validator().Data(user).Assoc(data).Run(context.Background()); err != nil {
   372  		fmt.Print(err)
   373  	}
   374  
   375  	// Output:
   376  	// The Type field is required
   377  }
   378  
   379  func ExampleValidator_Rules() {
   380  	if err := g.Validator().Data(16).Rules("min:18").Run(context.Background()); err != nil {
   381  		fmt.Println(err)
   382  	}
   383  
   384  	// Output:
   385  	// The value `16` must be equal or greater than 18
   386  }
   387  
   388  func ExampleValidator_Messages() {
   389  	if err := g.Validator().Data(16).Rules("min:18").Messages("Can not regist, Age is less then 18!").Run(context.Background()); err != nil {
   390  		fmt.Println(err)
   391  	}
   392  
   393  	// Output:
   394  	// Can not regist, Age is less then 18!
   395  }
   396  
   397  func ExampleValidator_RuleFunc() {
   398  	var (
   399  		ctx             = context.Background()
   400  		lenErrRuleName  = "LenErr"
   401  		passErrRuleName = "PassErr"
   402  		lenErrRuleFunc  = func(ctx context.Context, in gvalid.RuleFuncInput) error {
   403  			pass := in.Value.String()
   404  			if len(pass) != 6 {
   405  				return errors.New(in.Message)
   406  			}
   407  			return nil
   408  		}
   409  		passErrRuleFunc = func(ctx context.Context, in gvalid.RuleFuncInput) error {
   410  			pass := in.Value.String()
   411  			if m := in.Data.Map(); m["data"] != pass {
   412  				return errors.New(in.Message)
   413  			}
   414  			return nil
   415  		}
   416  	)
   417  
   418  	type LenErrStruct struct {
   419  		Value string `v:"uid@LenErr#Value Length Error!"`
   420  		Data  string `p:"data"`
   421  	}
   422  
   423  	st := &LenErrStruct{
   424  		Value: "123",
   425  		Data:  "123456",
   426  	}
   427  	// single error sample
   428  	if err := g.Validator().RuleFunc(lenErrRuleName, lenErrRuleFunc).Data(st).Run(ctx); err != nil {
   429  		fmt.Println(err)
   430  	}
   431  
   432  	type MultiErrorStruct struct {
   433  		Value string `v:"uid@LenErr|PassErr#Value Length Error!|Pass is not Same!"`
   434  		Data  string `p:"data"`
   435  	}
   436  
   437  	multi := &MultiErrorStruct{
   438  		Value: "123",
   439  		Data:  "123456",
   440  	}
   441  	// multi error sample
   442  	if err := g.Validator().RuleFunc(lenErrRuleName, lenErrRuleFunc).RuleFunc(passErrRuleName, passErrRuleFunc).Data(multi).Run(ctx); err != nil {
   443  		fmt.Println(err)
   444  	}
   445  
   446  	// Output:
   447  	// Value Length Error!
   448  	// Value Length Error!; Pass is not Same!
   449  }
   450  
   451  func ExampleValidator_RuleFuncMap() {
   452  	var (
   453  		ctx             = context.Background()
   454  		lenErrRuleName  = "LenErr"
   455  		passErrRuleName = "PassErr"
   456  		lenErrRuleFunc  = func(ctx context.Context, in gvalid.RuleFuncInput) error {
   457  			pass := in.Value.String()
   458  			if len(pass) != 6 {
   459  				return errors.New(in.Message)
   460  			}
   461  			return nil
   462  		}
   463  		passErrRuleFunc = func(ctx context.Context, in gvalid.RuleFuncInput) error {
   464  			pass := in.Value.String()
   465  			if m := in.Data.Map(); m["data"] != pass {
   466  				return errors.New(in.Message)
   467  			}
   468  			return nil
   469  		}
   470  		ruleMap = map[string]gvalid.RuleFunc{
   471  			lenErrRuleName:  lenErrRuleFunc,
   472  			passErrRuleName: passErrRuleFunc,
   473  		}
   474  	)
   475  
   476  	type MultiErrorStruct struct {
   477  		Value string `v:"uid@LenErr|PassErr#Value Length Error!|Pass is not Same!"`
   478  		Data  string `p:"data"`
   479  	}
   480  
   481  	multi := &MultiErrorStruct{
   482  		Value: "123",
   483  		Data:  "123456",
   484  	}
   485  
   486  	if err := g.Validator().RuleFuncMap(ruleMap).Data(multi).Run(ctx); err != nil {
   487  		fmt.Println(err)
   488  	}
   489  
   490  	// Output:
   491  	// Value Length Error!; Pass is not Same!
   492  }
   493  
   494  func ExampleValidator_RegisterRule() {
   495  	type User struct {
   496  		Id   int
   497  		Name string `v:"required|unique-name # 请输入用户名称|用户名称已被占用"`
   498  		Pass string `v:"required|length:6,18"`
   499  	}
   500  	user := &User{
   501  		Id:   1,
   502  		Name: "john",
   503  		Pass: "123456",
   504  	}
   505  
   506  	rule := "unique-name"
   507  	gvalid.RegisterRule(rule, func(ctx context.Context, in gvalid.RuleFuncInput) error {
   508  		var (
   509  			id   = in.Data.Val().(*User).Id
   510  			name = gconv.String(in.Value)
   511  		)
   512  		n, err := g.Model("user").Where("id != ? and name = ?", id, name).Count()
   513  		if err != nil {
   514  			return err
   515  		}
   516  		if n > 0 {
   517  			return errors.New(in.Message)
   518  		}
   519  		return nil
   520  	})
   521  	err := g.Validator().Data(user).Run(gctx.New())
   522  	fmt.Println(err.Error())
   523  	// May Output:
   524  	// 用户名称已被占用
   525  }