2021-01-17 21:46:25 +08:00
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
2020-08-21 00:00:00 +08:00
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gvalid_test
import (
2021-05-13 20:56:52 +08:00
"context"
2020-09-21 23:51:30 +08:00
"errors"
2020-08-21 00:00:00 +08:00
"fmt"
2021-11-30 23:48:26 +08:00
"github.com/gogf/gf/v2/i18n/gi18n"
2021-11-13 23:30:31 +08:00
"math"
"reflect"
2021-10-11 21:41:56 +08:00
"github.com/gogf/gf/v2/container/gvar"
"github.com/gogf/gf/v2/frame/g"
2021-10-29 22:37:38 +08:00
"github.com/gogf/gf/v2/os/gctx"
2021-10-11 21:41:56 +08:00
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/gvalid"
2020-08-21 00:00:00 +08:00
)
2021-11-30 23:48:26 +08:00
func ExampleNew ( ) {
validator := gvalid . New ( )
if err := validator . Data ( 16 ) . Rules ( "min:18" ) . Run ( context . Background ( ) ) ; err != nil {
fmt . Print ( err )
}
// Output:
// The value `16` must be equal or greater than 18
}
func ExampleValidator_Run ( ) {
// check value mode
if err := g . Validator ( ) . Data ( 16 ) . Rules ( "min:18" ) . Run ( context . Background ( ) ) ; err != nil {
fmt . Println ( "check value err:" , err )
}
// check map mode
data := map [ string ] interface { } {
"passport" : "" ,
"password" : "123456" ,
"password2" : "1234567" ,
}
rules := map [ string ] string {
"passport" : "required|length:6,16" ,
"password" : "required|length:6,16|same:password2" ,
"password2" : "required|length:6,16" ,
}
if err := g . Validator ( ) . Data ( data ) . Rules ( rules ) . Run ( context . Background ( ) ) ; err != nil {
fmt . Println ( "check map err:" , err )
}
// check struct mode
type Params struct {
Page int ` v:"required|min:1" `
Size int ` v:"required|between:1,100" `
ProjectId string ` v:"between:1,10000" `
}
rules = map [ string ] string {
"Page" : "required|min:1" ,
"Size" : "required|between:1,100" ,
"ProjectId" : "between:1,10000" ,
}
obj := & Params {
Page : 0 ,
Size : 101 ,
}
2021-12-04 14:35:33 +08:00
if err := g . Validator ( ) . Data ( obj ) . Run ( context . Background ( ) ) ; err != nil {
2021-11-30 23:48:26 +08:00
fmt . Println ( "check struct err:" , err )
}
2021-12-04 14:35:33 +08:00
// May Output:
2021-11-30 23:48:26 +08:00
// check value err: The value `16` must be equal or greater than 18
// 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
// check struct err: The Page value `0` must be equal or greater than 1; The Size value `101` must be between 1 and 100
}
func ExampleValidator_Clone ( ) {
if err := g . Validator ( ) . Data ( 16 ) . Rules ( "min:18" ) . Run ( context . Background ( ) ) ; err != nil {
fmt . Println ( err )
}
if err := g . Validator ( ) . Clone ( ) . Data ( 20 ) . Run ( context . Background ( ) ) ; err != nil {
fmt . Println ( err )
} else {
fmt . Println ( "Check Success!" )
}
// Output:
// The value `16` must be equal or greater than 18
// Check Success!
}
func ExampleValidator_I18n ( ) {
var (
i18nManager = gi18n . New ( )
ctxCn = gi18n . WithLanguage ( context . Background ( ) , "cn" )
validator = gvalid . New ( )
)
validator = validator . Data ( 16 ) . Rules ( "min:18" )
if err := validator . Run ( context . Background ( ) ) ; err != nil {
fmt . Println ( err )
}
if err := validator . I18n ( i18nManager ) . Run ( ctxCn ) ; err != nil {
fmt . Println ( err )
}
// Output:
// The value `16` must be equal or greater than 18
// 字段值`16`字段最小值应当为18
}
func ExampleValidator_Bail ( ) {
type BizReq struct {
2021-12-01 23:16:16 +08:00
Account string ` v:"required|length:6,16|same:QQ" `
2021-11-30 23:48:26 +08:00
QQ string
Password string ` v:"required|same:Password2" `
Password2 string ` v:"required" `
}
var (
ctx = context . Background ( )
req = BizReq {
Account : "gf" ,
QQ : "123456" ,
Password : "goframe.org" ,
Password2 : "goframe.org" ,
}
)
2021-12-01 23:16:16 +08:00
if err := g . Validator ( ) . Bail ( ) . Data ( req ) . Run ( ctx ) ; err != nil {
fmt . Println ( "Use Bail Error:" , err )
}
2021-11-30 23:48:26 +08:00
if err := g . Validator ( ) . Data ( req ) . Run ( ctx ) ; err != nil {
2021-12-01 23:16:16 +08:00
fmt . Println ( "Not Use Bail Error:" , err )
2021-11-30 23:48:26 +08:00
}
// output:
2021-12-01 23:16:16 +08:00
// Use Bail Error: The Account value `gf` length must be between 6 and 16
// 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
2021-11-30 23:48:26 +08:00
}
func ExampleValidator_Ci ( ) {
2021-12-01 23:16:16 +08:00
type BizReq struct {
Account string ` v:"required" `
Password string ` v:"required|same:Password2" `
Password2 string ` v:"required" `
}
var (
ctx = context . Background ( )
req = BizReq {
Account : "gf" ,
Password : "Goframe.org" , // Diff from Password2, but because of "ci", rule check passed
Password2 : "goframe.org" ,
}
)
if err := g . Validator ( ) . Data ( req ) . Run ( ctx ) ; err != nil {
fmt . Println ( "Not Use CI Error:" , err )
}
if err := g . Validator ( ) . Ci ( ) . Data ( req ) . Run ( ctx ) ; err == nil {
fmt . Println ( "Use CI Passed!" )
}
// output:
// Not Use CI Error: The Password value `Goframe.org` must be the same as field Password2
// Use CI Passed!
2021-11-30 23:48:26 +08:00
}
func ExampleValidator_Data ( ) {
2021-12-01 23:16:16 +08:00
type BizReq struct {
Password1 string ` v:"password" `
Password2 string ` v:"password" `
}
var (
ctx = context . Background ( )
req = BizReq {
Password1 : "goframe" ,
Password2 : "gofra" , // error length between 6 and 18
}
)
if err := g . Validator ( ) . Data ( req ) . Run ( ctx ) ; err != nil {
fmt . Print ( err )
}
2021-11-30 23:48:26 +08:00
2021-12-01 23:16:16 +08:00
// Output:
// The Password2 value `gofra` is not a valid password format
2021-11-30 23:48:26 +08:00
}
func ExampleValidator_Assoc ( ) {
2021-12-01 23:16:16 +08:00
type User struct {
Name string ` v:"required" `
Type int ` v:"required" `
}
data := g . Map {
"name" : "john" ,
}
user := User { }
if err := gconv . Scan ( data , & user ) ; err != nil {
panic ( err )
}
if err := g . Validator ( ) . Data ( user ) . Assoc ( data ) . Run ( context . Background ( ) ) ; err != nil {
fmt . Print ( err )
}
// Output:
// The Type field is required
2021-11-30 23:48:26 +08:00
}
func ExampleValidator_Rules ( ) {
2021-12-01 23:16:16 +08:00
if err := g . Validator ( ) . Data ( 16 ) . Rules ( "min:18" ) . Run ( context . Background ( ) ) ; err != nil {
fmt . Println ( err )
2021-11-30 23:48:26 +08:00
}
// Output:
2021-12-01 23:16:16 +08:00
// The value `16` must be equal or greater than 18
2021-11-30 23:48:26 +08:00
}
func ExampleValidator_Messages ( ) {
2021-12-04 14:35:33 +08:00
if err := g . Validator ( ) . Data ( 16 ) . Rules ( "min:18" ) . Messages ( "Can not regist, Age is less then 18!" ) . Run ( context . Background ( ) ) ; err != nil {
2021-12-01 23:16:16 +08:00
fmt . Println ( err )
}
2021-11-30 23:48:26 +08:00
2021-12-01 23:16:16 +08:00
// Output:
2021-12-04 14:35:33 +08:00
// Can not regist, Age is less then 18!
2021-11-30 23:48:26 +08:00
}
func ExampleValidator_RuleFunc ( ) {
2021-12-04 14:35:33 +08:00
var (
ctx = context . Background ( )
lenErrRuleName = "LenErr"
passErrRuleName = "PassErr"
lenErrRuleFunc = func ( ctx context . Context , in gvalid . RuleFuncInput ) error {
pass := in . Value . String ( )
if len ( pass ) != 6 {
return errors . New ( in . Message )
}
return nil
}
passErrRuleFunc = func ( ctx context . Context , in gvalid . RuleFuncInput ) error {
pass := in . Value . String ( )
if m := in . Data . Map ( ) ; m [ "data" ] != pass {
return errors . New ( in . Message )
}
return nil
}
)
type LenErrStruct struct {
Value string ` v:"uid@LenErr#Value Length Error!" `
Data string ` p:"data" `
}
st := & LenErrStruct {
Value : "123" ,
Data : "123456" ,
}
// single error sample
if err := g . Validator ( ) . RuleFunc ( lenErrRuleName , lenErrRuleFunc ) . Data ( st ) . Run ( ctx ) ; err != nil {
fmt . Println ( err )
}
type MultiErrorStruct struct {
Value string ` v:"uid@LenErr|PassErr#Value Length Error!|Pass is not Same!" `
Data string ` p:"data" `
}
multi := & MultiErrorStruct {
Value : "123" ,
Data : "123456" ,
}
// multi error sample
if err := g . Validator ( ) . RuleFunc ( lenErrRuleName , lenErrRuleFunc ) . RuleFunc ( passErrRuleName , passErrRuleFunc ) . Data ( multi ) . Run ( ctx ) ; err != nil {
fmt . Println ( err )
}
2021-11-30 23:48:26 +08:00
2021-12-04 14:35:33 +08:00
// Output:
// Value Length Error!
// Value Length Error!; Pass is not Same!
2021-11-30 23:48:26 +08:00
}
func ExampleValidator_RuleFuncMap ( ) {
2021-12-04 14:35:33 +08:00
var (
ctx = context . Background ( )
lenErrRuleName = "LenErr"
passErrRuleName = "PassErr"
lenErrRuleFunc = func ( ctx context . Context , in gvalid . RuleFuncInput ) error {
pass := in . Value . String ( )
if len ( pass ) != 6 {
return errors . New ( in . Message )
}
return nil
}
passErrRuleFunc = func ( ctx context . Context , in gvalid . RuleFuncInput ) error {
pass := in . Value . String ( )
if m := in . Data . Map ( ) ; m [ "data" ] != pass {
return errors . New ( in . Message )
}
return nil
}
ruleMap = map [ string ] gvalid . RuleFunc {
lenErrRuleName : lenErrRuleFunc ,
passErrRuleName : passErrRuleFunc ,
}
)
2021-11-30 23:48:26 +08:00
2021-12-04 14:35:33 +08:00
type MultiErrorStruct struct {
Value string ` v:"uid@LenErr|PassErr#Value Length Error!|Pass is not Same!" `
Data string ` p:"data" `
}
multi := & MultiErrorStruct {
Value : "123" ,
Data : "123456" ,
}
if err := g . Validator ( ) . RuleFuncMap ( ruleMap ) . Data ( multi ) . Run ( ctx ) ; err != nil {
fmt . Println ( err )
}
// Output:
// Value Length Error!; Pass is not Same!
2021-11-30 23:48:26 +08:00
}
2020-08-21 00:00:00 +08:00
func ExampleCheckMap ( ) {
params := map [ string ] interface { } {
"passport" : "" ,
"password" : "123456" ,
"password2" : "1234567" ,
}
rules := [ ] string {
2021-11-14 21:00:34 +08:00
"passport@required|length:6,16#账号不能为空|账号长度应当在{min}到{max}之间" ,
"password@required|length:6,16|same{password}2#密码不能为空|密码长度应当在{min}到{max}之间|两次密码输入不相等" ,
2020-08-21 00:00:00 +08:00
"password2@required|length:6,16#" ,
}
2021-11-22 22:43:09 +08:00
if e := g . Validator ( ) . Data ( params ) . Rules ( rules ) . Run ( gctx . New ( ) ) ; e != nil {
2020-08-21 00:00:00 +08:00
fmt . Println ( e . Map ( ) )
fmt . Println ( e . FirstItem ( ) )
2021-11-09 17:50:14 +08:00
fmt . Println ( e . FirstError ( ) )
2020-08-21 00:00:00 +08:00
}
// May Output:
// map[required:账号不能为空 length:账号长度应当在6到16之间]
// passport map[required:账号不能为空 length:账号长度应当在6到16之间]
// 账号不能为空
}
func ExampleCheckMap2 ( ) {
params := map [ string ] interface { } {
"passport" : "" ,
"password" : "123456" ,
"password2" : "1234567" ,
}
rules := [ ] string {
2021-11-14 21:00:34 +08:00
"passport@length:6,16#账号不能为空|账号长度应当在{min}到{max}之间" ,
"password@required|length:6,16|same:password2#密码不能为空|密码长度应当在{min}到{max}之间|两次密码输入不相等" ,
2020-08-21 00:00:00 +08:00
"password2@required|length:6,16#" ,
}
2021-11-22 22:43:09 +08:00
if e := g . Validator ( ) . Data ( params ) . Rules ( rules ) . Run ( gctx . New ( ) ) ; e != nil {
2020-08-21 00:00:00 +08:00
fmt . Println ( e . Map ( ) )
fmt . Println ( e . FirstItem ( ) )
2021-11-09 17:50:14 +08:00
fmt . Println ( e . FirstError ( ) )
2020-08-21 00:00:00 +08:00
}
// Output:
// map[same:两次密码输入不相等]
// password map[same:两次密码输入不相等]
// 两次密码输入不相等
}
// Empty string attribute.
func ExampleCheckStruct ( ) {
type Params struct {
Page int ` v:"required|min:1 # page is required" `
Size int ` v:"required|between:1,100 # size is required" `
2021-11-14 21:00:34 +08:00
ProjectId string ` v:"between:1,10000 # project id must between { min}, { max}" `
2020-08-21 00:00:00 +08:00
}
obj := & Params {
Page : 1 ,
Size : 10 ,
}
2021-11-22 22:43:09 +08:00
err := g . Validator ( ) . Data ( obj ) . Rules ( nil ) . Run ( gctx . New ( ) )
2020-09-22 08:45:22 +08:00
fmt . Println ( err == nil )
2020-08-21 00:00:00 +08:00
// Output:
2020-09-22 08:45:22 +08:00
// true
2020-08-21 00:00:00 +08:00
}
// Empty pointer attribute.
func ExampleCheckStruct2 ( ) {
type Params struct {
Page int ` v:"required|min:1 # page is required" `
Size int ` v:"required|between:1,100 # size is required" `
2021-11-14 21:00:34 +08:00
ProjectId * gvar . Var ` v:"between:1,10000 # project id must between { min}, { max}" `
2020-08-21 00:00:00 +08:00
}
obj := & Params {
Page : 1 ,
Size : 10 ,
}
2021-11-22 22:43:09 +08:00
err := g . Validator ( ) . Data ( obj ) . Rules ( nil ) . Run ( gctx . New ( ) )
2020-09-22 08:45:22 +08:00
fmt . Println ( err == nil )
2020-08-21 00:00:00 +08:00
// Output:
2020-09-22 08:45:22 +08:00
// true
2020-08-21 00:00:00 +08:00
}
// Empty integer attribute.
func ExampleCheckStruct3 ( ) {
type Params struct {
Page int ` v:"required|min:1 # page is required" `
Size int ` v:"required|between:1,100 # size is required" `
2021-11-14 21:00:34 +08:00
ProjectId int ` v:"between:1,10000 # project id must between { min}, { max}" `
2020-08-21 00:00:00 +08:00
}
obj := & Params {
Page : 1 ,
Size : 10 ,
}
2021-11-22 22:43:09 +08:00
err := g . Validator ( ) . Data ( obj ) . Rules ( nil ) . Run ( gctx . New ( ) )
2020-08-21 00:00:00 +08:00
fmt . Println ( err )
// Output:
// project id must between 1, 10000
}
2020-09-21 23:51:30 +08:00
func ExampleRegisterRule ( ) {
2021-05-29 11:30:34 +08:00
type User struct {
Id int
Name string ` v:"required|unique-name # 请输入用户名称|用户名称已被占用" `
Pass string ` v:"required|length:6,18" `
}
user := & User {
Id : 1 ,
Name : "john" ,
Pass : "123456" ,
}
2020-09-21 23:51:30 +08:00
rule := "unique-name"
2021-11-09 14:31:16 +08:00
gvalid . RegisterRule ( rule , func ( ctx context . Context , in gvalid . RuleFuncInput ) error {
2020-09-21 23:51:30 +08:00
var (
2021-11-09 14:31:16 +08:00
id = in . Data . Val ( ) . ( * User ) . Id
name = gconv . String ( in . Value )
2020-09-21 23:51:30 +08:00
)
2021-05-29 11:30:34 +08:00
n , err := g . Model ( "user" ) . Where ( "id != ? and name = ?" , id , name ) . Count ( )
2020-09-21 23:51:30 +08:00
if err != nil {
return err
}
if n > 0 {
2021-11-09 14:31:16 +08:00
return errors . New ( in . Message )
2020-09-21 23:51:30 +08:00
}
return nil
} )
2021-11-22 22:43:09 +08:00
err := g . Validator ( ) . Data ( user ) . Rules ( nil ) . Run ( gctx . New ( ) )
2020-09-21 23:51:30 +08:00
fmt . Println ( err . Error ( ) )
2020-09-22 08:45:22 +08:00
// May Output:
2020-09-21 23:51:30 +08:00
// 用户名称已被占用
}
2020-09-22 08:45:22 +08:00
func ExampleRegisterRule_OverwriteRequired ( ) {
rule := "required"
2021-11-09 14:31:16 +08:00
gvalid . RegisterRule ( rule , func ( ctx context . Context , in gvalid . RuleFuncInput ) error {
reflectValue := reflect . ValueOf ( in . Value . Val ( ) )
2020-09-22 08:45:22 +08:00
if reflectValue . Kind ( ) == reflect . Ptr {
reflectValue = reflectValue . Elem ( )
}
isEmpty := false
switch reflectValue . Kind ( ) {
case reflect . Bool :
isEmpty = ! reflectValue . Bool ( )
case reflect . Int , reflect . Int8 , reflect . Int16 , reflect . Int32 , reflect . Int64 :
isEmpty = reflectValue . Int ( ) == 0
case reflect . Uint , reflect . Uint8 , reflect . Uint16 , reflect . Uint32 , reflect . Uint64 , reflect . Uintptr :
isEmpty = reflectValue . Uint ( ) == 0
case reflect . Float32 , reflect . Float64 :
isEmpty = math . Float64bits ( reflectValue . Float ( ) ) == 0
case reflect . Complex64 , reflect . Complex128 :
c := reflectValue . Complex ( )
isEmpty = math . Float64bits ( real ( c ) ) == 0 && math . Float64bits ( imag ( c ) ) == 0
case reflect . String , reflect . Map , reflect . Array , reflect . Slice :
isEmpty = reflectValue . Len ( ) == 0
}
if isEmpty {
2021-11-09 14:31:16 +08:00
return errors . New ( in . Message )
2020-09-22 08:45:22 +08:00
}
return nil
} )
2021-11-22 22:43:09 +08:00
fmt . Println ( g . Validator ( ) . Data ( "" ) . Rules ( "required" ) . Messages ( "It's required" ) . Run ( gctx . New ( ) ) )
fmt . Println ( g . Validator ( ) . Data ( 0 ) . Rules ( "required" ) . Messages ( "It's required" ) . Run ( gctx . New ( ) ) )
fmt . Println ( g . Validator ( ) . Data ( false ) . Rules ( "required" ) . Messages ( "It's required" ) . Run ( gctx . New ( ) ) )
2020-09-22 08:45:22 +08:00
gvalid . DeleteRule ( rule )
fmt . Println ( "rule deleted" )
2021-11-22 22:43:09 +08:00
fmt . Println ( g . Validator ( ) . Data ( "" ) . Rules ( "required" ) . Messages ( "It's required" ) . Run ( gctx . New ( ) ) )
fmt . Println ( g . Validator ( ) . Data ( 0 ) . Rules ( "required" ) . Messages ( "It's required" ) . Run ( gctx . New ( ) ) )
fmt . Println ( g . Validator ( ) . Data ( false ) . Rules ( "required" ) . Messages ( "It's required" ) . Run ( gctx . New ( ) ) )
2020-09-22 08:45:22 +08:00
// Output:
// It's required
// It's required
// It's required
// rule deleted
// It's required
2021-10-21 19:25:39 +08:00
// <nil>
// <nil>
2020-09-22 08:45:22 +08:00
}
2021-05-19 22:33:50 +08:00
func ExampleValidator_CheckValue ( ) {
2021-10-11 21:34:19 +08:00
err := g . Validator ( ) . Rules ( "min:18" ) .
Messages ( "未成年人不允许注册哟" ) .
2021-11-22 22:43:09 +08:00
Data ( 16 ) . Run ( gctx . New ( ) )
2021-05-19 22:33:50 +08:00
fmt . Println ( err . String ( ) )
// Output:
// 未成年人不允许注册哟
}
func ExampleValidator_CheckMap ( ) {
params := map [ string ] interface { } {
"passport" : "" ,
"password" : "123456" ,
"password2" : "1234567" ,
}
rules := map [ string ] string {
"passport" : "required|length:6,16" ,
"password" : "required|length:6,16|same:password2" ,
"password2" : "required|length:6,16" ,
}
messages := map [ string ] interface { } {
2021-11-14 21:00:34 +08:00
"passport" : "账号不能为空|账号长度应当在{min}到{max}之间" ,
2021-05-19 22:33:50 +08:00
"password" : map [ string ] string {
"required" : "密码不能为空" ,
"same" : "两次密码输入不相等" ,
} ,
}
2021-10-11 21:34:19 +08:00
err := g . Validator ( ) .
Messages ( messages ) .
Rules ( rules ) .
2021-11-22 22:43:09 +08:00
Data ( params ) . Run ( gctx . New ( ) )
2021-05-19 22:33:50 +08:00
if err != nil {
g . Dump ( err . Maps ( ) )
}
// May Output:
2021-11-13 23:30:31 +08:00
// {
2021-05-19 22:33:50 +08:00
// "passport": {
// "length": "账号长度应当在6到16之间",
// "required": "账号不能为空"
2021-11-13 23:30:31 +08:00
// },
2021-05-19 22:33:50 +08:00
// "password": {
// "same": "两次密码输入不相等"
2021-11-13 23:30:31 +08:00
// }
// }
2021-05-19 22:33:50 +08:00
}
func ExampleValidator_CheckStruct ( ) {
type User struct {
Name string ` v:"required#请输入用户姓名" `
Type int ` v:"required#请选择用户类型" `
}
data := g . Map {
"name" : "john" ,
}
user := User { }
if err := gconv . Scan ( data , & user ) ; err != nil {
panic ( err )
}
2021-11-23 10:42:43 +08:00
err := g . Validator ( ) . Data ( user ) . Assoc ( data ) . Run ( gctx . New ( ) )
2021-05-19 22:33:50 +08:00
if err != nil {
fmt . Println ( err . Items ( ) )
}
// Output:
// [map[Type:map[required:请选择用户类型]]]
}