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  }