github.com/System-Glitch/goyave/v2@v2.10.3-0.20200819142921-51011e75d504/validation/validator_test.go (about)

     1  package validation
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/System-Glitch/goyave/v2/lang"
     8  	"github.com/stretchr/testify/suite"
     9  )
    10  
    11  type ValidatorTestSuite struct {
    12  	suite.Suite
    13  }
    14  
    15  func (suite *ValidatorTestSuite) SetupSuite() {
    16  	lang.LoadDefault()
    17  }
    18  
    19  func (suite *ValidatorTestSuite) TestParseRule() {
    20  	rule := parseRule("required")
    21  	suite.Equal("required", rule.Name)
    22  	suite.Equal(0, len(rule.Params))
    23  	suite.Equal(uint8(0), rule.ArrayDimension)
    24  
    25  	rule = parseRule("min:5")
    26  	suite.Equal("min", rule.Name)
    27  	suite.Equal(1, len(rule.Params))
    28  	suite.Equal("5", rule.Params[0])
    29  	suite.Equal(uint8(0), rule.ArrayDimension)
    30  
    31  	suite.Panics(func() {
    32  		parseRule("invalid,rule")
    33  	})
    34  
    35  	rule = parseRule(">min:3")
    36  	suite.Equal("min", rule.Name)
    37  	suite.Equal(1, len(rule.Params))
    38  	suite.Equal("3", rule.Params[0])
    39  	suite.Equal(uint8(1), rule.ArrayDimension)
    40  
    41  	rule = parseRule(">>max:5")
    42  	suite.Equal("max", rule.Name)
    43  	suite.Equal(1, len(rule.Params))
    44  	suite.Equal("5", rule.Params[0])
    45  	suite.Equal(uint8(2), rule.ArrayDimension)
    46  }
    47  
    48  func (suite *ValidatorTestSuite) TestGetMessage() {
    49  	suite.Equal("The :field is required.", getMessage([]*Rule{}, &Rule{Name: "required"}, reflect.ValueOf("test"), "en-US"))
    50  	suite.Equal("The :field must be at least :min.", getMessage([]*Rule{{Name: "numeric"}}, &Rule{Name: "min"}, reflect.ValueOf(42), "en-US"))
    51  	suite.Equal("The :field values must be at least :min.", getMessage([]*Rule{{Name: "numeric", ArrayDimension: 1}}, &Rule{Name: "min", ArrayDimension: 1}, reflect.ValueOf(42), "en-US"))
    52  
    53  	rules := []*Rule{
    54  		{Name: "array", Params: []string{"numeric"}},
    55  		{Name: "min", ArrayDimension: 1},
    56  	}
    57  	suite.Equal("The :field values must be at least :min.", getMessage(rules, rules[1], reflect.ValueOf(42), "en-US"))
    58  
    59  	// Test type fallback if no type rule is found
    60  	suite.Equal("The :field must be at least :min.", getMessage([]*Rule{}, &Rule{Name: "min"}, reflect.ValueOf(42), "en-US"))
    61  	suite.Equal("The :field must be at least :min characters.", getMessage([]*Rule{}, &Rule{Name: "min"}, reflect.ValueOf("test"), "en-US"))
    62  }
    63  
    64  func (suite *ValidatorTestSuite) TestAddRule() {
    65  	suite.Panics(func() {
    66  		AddRule("required", &RuleDefinition{
    67  			Function: func(field string, value interface{}, parameters []string, form map[string]interface{}) bool {
    68  				return false
    69  			},
    70  		})
    71  	})
    72  
    73  	AddRule("new_rule", &RuleDefinition{
    74  		Function: func(field string, value interface{}, parameters []string, form map[string]interface{}) bool {
    75  			return true
    76  		},
    77  	})
    78  	_, ok := validationRules["new_rule"]
    79  	suite.True(ok)
    80  }
    81  
    82  func (suite *ValidatorTestSuite) TestValidate() {
    83  	errors := Validate(nil, &Rules{}, false, "en-US")
    84  	suite.Equal(1, len(errors))
    85  	suite.Equal("Malformed request", errors["error"][0])
    86  
    87  	errors = Validate(nil, RuleSet{}, false, "en-US")
    88  	suite.Equal(1, len(errors))
    89  	suite.Equal("Malformed request", errors["error"][0])
    90  
    91  	errors = Validate(nil, &Rules{}, true, "en-US")
    92  	suite.Equal(1, len(errors))
    93  	suite.Equal("Malformed JSON", errors["error"][0])
    94  
    95  	errors = Validate(nil, RuleSet{}, true, "en-US")
    96  	suite.Equal(1, len(errors))
    97  	suite.Equal("Malformed JSON", errors["error"][0])
    98  
    99  	errors = Validate(map[string]interface{}{
   100  		"string": "hello world",
   101  		"number": 42,
   102  	}, RuleSet{
   103  		"string": {"required", "string"},
   104  		"number": {"required", "numeric", "min:10"},
   105  	}, true, "en-US")
   106  	suite.Equal(0, len(errors))
   107  
   108  	errors = Validate(map[string]interface{}{
   109  		"string": "hello world",
   110  		"number": 42,
   111  	}, &Rules{
   112  		Fields: FieldMap{
   113  			"string": {
   114  				Rules: []*Rule{
   115  					{Name: "required"},
   116  					{Name: "string"},
   117  				},
   118  			},
   119  			"number": {
   120  				Rules: []*Rule{
   121  					{Name: "required"},
   122  					{Name: "numeric"},
   123  					{Name: "min", Params: []string{"10"}},
   124  				},
   125  			},
   126  		},
   127  	}, true, "en-US")
   128  	suite.Equal(0, len(errors))
   129  
   130  	data := map[string]interface{}{
   131  		"nullField": nil,
   132  	}
   133  	errors = Validate(data, RuleSet{
   134  		"nullField": {"numeric"},
   135  	}, true, "en-US")
   136  	_, exists := data["nullField"]
   137  	suite.False(exists)
   138  	suite.Equal(0, len(errors))
   139  
   140  	data = map[string]interface{}{
   141  		"nullField": nil,
   142  	}
   143  	errors = Validate(data, RuleSet{
   144  		"nullField": {"required", "nullable", "numeric"},
   145  	}, true, "en-US")
   146  	val, exists := data["nullField"]
   147  	suite.True(exists)
   148  	suite.Nil(val)
   149  	suite.Equal(0, len(errors))
   150  
   151  	data = map[string]interface{}{
   152  		"nullField": "test",
   153  	}
   154  	errors = Validate(data, RuleSet{
   155  		"nullField": {"required", "nullable", "numeric"},
   156  	}, true, "en-US")
   157  	val, exists = data["nullField"]
   158  	suite.True(exists)
   159  	suite.Equal("test", val)
   160  	suite.Equal(1, len(errors))
   161  
   162  	errors = Validate(data, &Rules{
   163  		Fields: FieldMap{
   164  			"nullField": {
   165  				Rules: []*Rule{
   166  					{Name: "required"},
   167  					{Name: "nullable"},
   168  					{Name: "numeric"},
   169  				},
   170  			},
   171  		},
   172  	}, true, "en-US")
   173  	val, exists = data["nullField"]
   174  	suite.True(exists)
   175  	suite.Equal("test", val)
   176  	suite.Equal(1, len(errors))
   177  }
   178  
   179  func (suite *ValidatorTestSuite) TestValidateWithArray() {
   180  	data := map[string]interface{}{
   181  		"string": "hello",
   182  	}
   183  	errors := Validate(data, RuleSet{
   184  		"string": {"required", "array"},
   185  	}, false, "en-US")
   186  	suite.Equal("array", GetFieldType(data["string"]))
   187  	suite.Equal("hello", data["string"].([]string)[0])
   188  	suite.Equal(0, len(errors))
   189  
   190  	errors = Validate(data, &Rules{
   191  		Fields: FieldMap{
   192  			"string": {
   193  				Rules: []*Rule{
   194  					{Name: "required"},
   195  					{Name: "array"},
   196  				},
   197  			},
   198  		},
   199  	}, false, "en-US")
   200  	suite.Equal("array", GetFieldType(data["string"]))
   201  	suite.Equal("hello", data["string"].([]string)[0])
   202  	suite.Equal(0, len(errors))
   203  }
   204  
   205  func (suite *ValidatorTestSuite) TestValidateArrayValues() {
   206  	data := map[string]interface{}{
   207  		"string": []string{"hello", "world"},
   208  	}
   209  	errors := Validate(data, RuleSet{
   210  		"string": {"required", "array", ">min:3"},
   211  	}, false, "en-US")
   212  	suite.Len(errors, 0)
   213  
   214  	errors = Validate(data, &Rules{
   215  		Fields: FieldMap{
   216  			"string": {
   217  				Rules: []*Rule{
   218  					{Name: "required"},
   219  					{Name: "array"},
   220  					{Name: "min", Params: []string{"3"}, ArrayDimension: 1},
   221  				},
   222  			},
   223  		},
   224  	}, false, "en-US")
   225  	suite.Len(errors, 0)
   226  
   227  	data = map[string]interface{}{
   228  		"string": []string{"hi", ",", "there"},
   229  	}
   230  	errors = Validate(data, RuleSet{
   231  		"string": {"required", "array", ">min:3"},
   232  	}, false, "en-US")
   233  	suite.Len(errors, 1)
   234  
   235  	errors = Validate(data, &Rules{
   236  		Fields: FieldMap{
   237  			"string": {
   238  				Rules: []*Rule{
   239  					{Name: "required"},
   240  					{Name: "array"},
   241  					{Name: "min", Params: []string{"3"}, ArrayDimension: 1},
   242  				},
   243  			},
   244  		},
   245  	}, false, "en-US")
   246  	suite.Len(errors, 1)
   247  
   248  	data = map[string]interface{}{
   249  		"string": []string{"johndoe@example.org", "foobar@example.org"},
   250  	}
   251  	errors = Validate(data, RuleSet{
   252  		"string": {"required", "array:string", ">email"},
   253  	}, true, "en-US")
   254  	suite.Len(errors, 0)
   255  
   256  	errors = Validate(data, &Rules{
   257  		Fields: FieldMap{
   258  			"string": {
   259  				Rules: []*Rule{
   260  					{Name: "required"},
   261  					{Name: "array", Params: []string{"string"}},
   262  					{Name: "email", ArrayDimension: 1},
   263  				},
   264  			},
   265  		},
   266  	}, true, "en-US")
   267  	suite.Len(errors, 0)
   268  
   269  	// Cannot validate array values on non-array field string of type string
   270  	rule := &Rule{Name: "required", ArrayDimension: 1}
   271  	suite.False(validateRuleInArray(rule, "string", rule.ArrayDimension, map[string]interface{}{"string": "hi"}))
   272  
   273  	// Empty array
   274  	data = map[string]interface{}{
   275  		"string": []string{},
   276  	}
   277  	errors = Validate(data, RuleSet{
   278  		"string": {"array", ">uuid:5"},
   279  	}, true, "en-US")
   280  	suite.Len(errors, 0)
   281  
   282  	errors = Validate(data, &Rules{
   283  		Fields: FieldMap{
   284  			"string": {
   285  				Rules: []*Rule{
   286  					{Name: "array"},
   287  					{Name: "uuid", Params: []string{"5"}, ArrayDimension: 1},
   288  				},
   289  			},
   290  		},
   291  	}, true, "en-US")
   292  	suite.Len(errors, 0)
   293  }
   294  
   295  func (suite *ValidatorTestSuite) TestValidateTwoDimensionalArray() {
   296  	data := map[string]interface{}{
   297  		"values": [][]interface{}{{"0.5", 1.42}, {0.6, 7}},
   298  	}
   299  	errors := Validate(data, RuleSet{
   300  		"values": {"required", "array", ">array:numeric"},
   301  	}, false, "en-US")
   302  	suite.Len(errors, 0)
   303  
   304  	arr, ok := data["values"].([][]float64)
   305  	suite.True(ok)
   306  	if ok {
   307  		suite.Equal(2, len(arr))
   308  		suite.Equal(0.5, arr[0][0])
   309  		suite.Equal(1.42, arr[0][1])
   310  		suite.Equal(0.6, arr[1][0])
   311  		suite.Equal(7.0, arr[1][1])
   312  	}
   313  
   314  	data = map[string]interface{}{
   315  		"values": [][]interface{}{{"0.5", 1.42}, {0.6, 7}},
   316  	}
   317  	errors = Validate(data, &Rules{
   318  		Fields: FieldMap{
   319  			"values": {
   320  				Rules: []*Rule{
   321  					{Name: "required"},
   322  					{Name: "array"},
   323  					{Name: "array", Params: []string{"numeric"}, ArrayDimension: 1},
   324  				},
   325  			},
   326  		},
   327  	}, false, "en-US")
   328  	suite.Len(errors, 0)
   329  
   330  	arr, ok = data["values"].([][]float64)
   331  	suite.True(ok)
   332  	if ok {
   333  		suite.Equal(2, len(arr))
   334  		suite.Equal(0.5, arr[0][0])
   335  		suite.Equal(1.42, arr[0][1])
   336  		suite.Equal(0.6, arr[1][0])
   337  		suite.Equal(7.0, arr[1][1])
   338  	}
   339  
   340  	data = map[string]interface{}{
   341  		"values": [][]float64{{5, 8}, {0.6, 7}},
   342  	}
   343  	errors = Validate(data, RuleSet{
   344  		"values": {"required", "array", ">array:numeric", ">min:3"},
   345  	}, true, "en-US")
   346  	suite.Len(errors, 1)
   347  
   348  	_, ok = data["values"].([][]float64)
   349  	suite.True(ok)
   350  
   351  	data = map[string]interface{}{
   352  		"values": [][]float64{{5, 8}, {0.6, 7}},
   353  	}
   354  	errors = Validate(data, &Rules{
   355  		Fields: FieldMap{
   356  			"values": {
   357  				Rules: []*Rule{
   358  					{Name: "required"},
   359  					{Name: "array"},
   360  					{Name: "array", Params: []string{"numeric"}, ArrayDimension: 1},
   361  					{Name: "min", Params: []string{"3"}, ArrayDimension: 1},
   362  				},
   363  			},
   364  		},
   365  	}, true, "en-US")
   366  	suite.Len(errors, 1)
   367  
   368  	_, ok = data["values"].([][]float64)
   369  	suite.True(ok)
   370  
   371  	data = map[string]interface{}{
   372  		"values": [][]float64{{5, 8, 6}, {0.6, 7, 9}},
   373  	}
   374  	errors = Validate(data, RuleSet{
   375  		"values": {"required", "array", ">array:numeric", ">min:3"},
   376  	}, true, "en-US")
   377  	suite.Len(errors, 0)
   378  
   379  	data = map[string]interface{}{
   380  		"values": [][]float64{{5, 8, 6}, {0.6, 7, 9}},
   381  	}
   382  	errors = Validate(data, &Rules{
   383  		Fields: FieldMap{
   384  			"values": {
   385  				Rules: []*Rule{
   386  					{Name: "required"},
   387  					{Name: "array"},
   388  					{Name: "array", Params: []string{"numeric"}, ArrayDimension: 1},
   389  					{Name: "min", Params: []string{"3"}, ArrayDimension: 1},
   390  				},
   391  			},
   392  		},
   393  	}, true, "en-US")
   394  	suite.Len(errors, 0)
   395  
   396  	data = map[string]interface{}{
   397  		"values": [][]float64{{5, 8}, {3, 7}},
   398  	}
   399  	errors = Validate(data, RuleSet{
   400  		"values": {"required", "array", ">array:numeric", ">>min:3"},
   401  	}, true, "en-US")
   402  	suite.Len(errors, 0)
   403  
   404  	data = map[string]interface{}{
   405  		"values": [][]float64{{5, 8}, {3, 7}},
   406  	}
   407  	errors = Validate(data, &Rules{
   408  		Fields: FieldMap{
   409  			"values": {
   410  				Rules: []*Rule{
   411  					{Name: "required"},
   412  					{Name: "array"},
   413  					{Name: "array", Params: []string{"numeric"}, ArrayDimension: 1},
   414  					{Name: "min", Params: []string{"3"}, ArrayDimension: 2},
   415  				},
   416  			},
   417  		},
   418  	}, true, "en-US")
   419  	suite.Len(errors, 0)
   420  
   421  	data = map[string]interface{}{
   422  		"values": [][]float64{{5, 8}, {0.6, 7}},
   423  	}
   424  	errors = Validate(data, RuleSet{
   425  		"values": {"required", "array", ">array:numeric", ">>min:3"},
   426  	}, true, "en-US")
   427  	suite.Len(errors, 1)
   428  
   429  	data = map[string]interface{}{
   430  		"values": [][]float64{{5, 8}, {0.6, 7}},
   431  	}
   432  	errors = Validate(data, &Rules{
   433  		Fields: FieldMap{
   434  			"values": {
   435  				Rules: []*Rule{
   436  					{Name: "required"},
   437  					{Name: "array"},
   438  					{Name: "array", Params: []string{"numeric"}, ArrayDimension: 1},
   439  					{Name: "min", Params: []string{"3"}, ArrayDimension: 2},
   440  				},
   441  			},
   442  		},
   443  	}, true, "en-US")
   444  	suite.Len(errors, 1)
   445  }
   446  
   447  func (suite *ValidatorTestSuite) TestValidateNDimensionalArray() {
   448  	data := map[string]interface{}{
   449  		"values": [][][]interface{}{
   450  			{{"0.5", 1.42}, {0.6, 4, 3}},
   451  			{{"0.6", "1.43"}, {}, {2}},
   452  		},
   453  	}
   454  	errors := Validate(data, RuleSet{
   455  		"values": {"required", "array", ">array", ">>array:numeric", ">max:3", ">>>max:4"},
   456  	}, true, "en-US")
   457  	suite.Len(errors, 0)
   458  
   459  	arr, ok := data["values"].([][][]float64)
   460  	suite.True(ok)
   461  	if ok {
   462  		suite.Equal(2, len(arr))
   463  		suite.Equal(2, len(arr[0]))
   464  		suite.Equal(3, len(arr[1]))
   465  		suite.Equal(0.5, arr[0][0][0])
   466  		suite.Equal(1.42, arr[0][0][1])
   467  		suite.Equal(2.0, arr[1][2][0])
   468  	}
   469  
   470  	data = map[string]interface{}{
   471  		"values": [][][]interface{}{
   472  			{{"0.5", 1.42}, {0.6, 4, 3}},
   473  			{{"0.6", "1.43"}, {}, {2}},
   474  		},
   475  	}
   476  	errors = Validate(data, &Rules{
   477  		Fields: FieldMap{
   478  			"values": {
   479  				Rules: []*Rule{
   480  					{Name: "required"},
   481  					{Name: "array"},
   482  					{Name: "array", ArrayDimension: 1},
   483  					{Name: "array", Params: []string{"numeric"}, ArrayDimension: 2},
   484  					{Name: "max", Params: []string{"3"}, ArrayDimension: 1},
   485  					{Name: "max", Params: []string{"4"}, ArrayDimension: 3},
   486  				},
   487  			},
   488  		},
   489  	}, true, "en-US")
   490  	suite.Len(errors, 0)
   491  
   492  	arr, ok = data["values"].([][][]float64)
   493  	suite.True(ok)
   494  	if ok {
   495  		suite.Equal(2, len(arr))
   496  		suite.Equal(2, len(arr[0]))
   497  		suite.Equal(3, len(arr[1]))
   498  		suite.Equal(0.5, arr[0][0][0])
   499  		suite.Equal(1.42, arr[0][0][1])
   500  		suite.Equal(2.0, arr[1][2][0])
   501  	}
   502  
   503  	data = map[string]interface{}{
   504  		"values": [][][]interface{}{
   505  			{{"0.5", 1.42}, {0.6, 4, 3}},
   506  			{{"0.6", "1.43"}, {}, {2}, {4}},
   507  		},
   508  	}
   509  	errors = Validate(data, RuleSet{
   510  		"values": {"required", "array", ">array", ">>array:numeric", ">max:3", ">>>max:4"},
   511  	}, true, "en-US")
   512  	suite.Len(errors, 1)
   513  
   514  	data = map[string]interface{}{
   515  		"values": [][][]interface{}{
   516  			{{"0.5", 1.42}, {0.6, 4, 3}},
   517  			{{"0.6", "1.43"}, {}, {2}, {4}},
   518  		},
   519  	}
   520  	errors = Validate(data, &Rules{
   521  		Fields: FieldMap{
   522  			"values": {
   523  				Rules: []*Rule{
   524  					{Name: "required"},
   525  					{Name: "array"},
   526  					{Name: "array", ArrayDimension: 1},
   527  					{Name: "array", Params: []string{"numeric"}, ArrayDimension: 2},
   528  					{Name: "max", Params: []string{"3"}, ArrayDimension: 1},
   529  					{Name: "max", Params: []string{"4"}, ArrayDimension: 3},
   530  				},
   531  			},
   532  		},
   533  	}, true, "en-US")
   534  	suite.Len(errors, 1)
   535  
   536  	data = map[string]interface{}{
   537  		"values": [][][]interface{}{
   538  			{{"0.5", 1.42}, {0.6, 9, 3}},
   539  			{{"0.6", "1.43"}, {}, {2}},
   540  		},
   541  	}
   542  	errors = Validate(data, RuleSet{
   543  		"values": {"required", "array", ">array", ">>array:numeric", ">max:3", ">>>max:4"},
   544  	}, true, "en-US")
   545  	suite.Len(errors, 1)
   546  
   547  	data = map[string]interface{}{
   548  		"values": [][][]interface{}{
   549  			{{"0.5", 1.42}, {0.6, 9, 3}},
   550  			{{"0.6", "1.43"}, {}, {2}},
   551  		},
   552  	}
   553  	errors = Validate(data, &Rules{
   554  		Fields: FieldMap{
   555  			"values": {
   556  				Rules: []*Rule{
   557  					{Name: "required"},
   558  					{Name: "array"},
   559  					{Name: "array", ArrayDimension: 1},
   560  					{Name: "array", Params: []string{"numeric"}, ArrayDimension: 2},
   561  					{Name: "max", Params: []string{"3"}, ArrayDimension: 1},
   562  					{Name: "max", Params: []string{"4"}, ArrayDimension: 3},
   563  				},
   564  			},
   565  		},
   566  	}, true, "en-US")
   567  	suite.Len(errors, 1)
   568  }
   569  
   570  func (suite *ValidatorTestSuite) TestFieldCheck() {
   571  	suite.NotPanics(func() {
   572  		field := &Field{
   573  			Rules: []*Rule{
   574  				{Name: "required"},
   575  				{Name: "numeric"},
   576  			},
   577  		}
   578  
   579  		field.check()
   580  
   581  		suite.True(field.isRequired)
   582  		suite.False(field.isArray)
   583  		suite.False(field.isNullable)
   584  	})
   585  
   586  	suite.NotPanics(func() {
   587  		field := &Field{
   588  			Rules: []*Rule{
   589  				{Name: "nullable"},
   590  				{Name: "array"},
   591  			},
   592  		}
   593  
   594  		field.check()
   595  
   596  		suite.False(field.isRequired)
   597  		suite.True(field.isArray)
   598  		suite.True(field.isNullable)
   599  	})
   600  
   601  	suite.Panics(func() {
   602  		field := &Field{
   603  			Rules: []*Rule{
   604  				{Name: "required"},
   605  				{Name: "not a rule"},
   606  			},
   607  		}
   608  
   609  		field.check()
   610  	})
   611  }
   612  
   613  func (suite *ValidatorTestSuite) TestFieldCheckArrayProhibitedRules() {
   614  	prohibitedRules := []string{
   615  		"confirmed", "file", "mime", "image", "extension", "count",
   616  		"count_min", "count_max", "count_between",
   617  	}
   618  	for _, v := range prohibitedRules {
   619  		suite.Panics(func() {
   620  			field := &Field{
   621  				Rules: []*Rule{
   622  					{Name: v, ArrayDimension: 1},
   623  				},
   624  			}
   625  			field.check()
   626  		})
   627  	}
   628  }
   629  
   630  func (suite *ValidatorTestSuite) TestParseRuleSet() {
   631  	set := RuleSet{
   632  		"string": {"required", "array:string", ">min:3"},
   633  		"number": {"numeric"},
   634  	}
   635  
   636  	rules := set.parse()
   637  	suite.Len(rules.Fields, 2)
   638  	suite.Len(rules.Fields["string"].Rules, 3)
   639  	suite.Equal(&Rule{Name: "required", Params: []string{}, ArrayDimension: 0}, rules.Fields["string"].Rules[0])
   640  	suite.Equal(&Rule{Name: "array", Params: []string{"string"}, ArrayDimension: 0}, rules.Fields["string"].Rules[1])
   641  	suite.Equal(&Rule{Name: "min", Params: []string{"3"}, ArrayDimension: 1}, rules.Fields["string"].Rules[2])
   642  	suite.Len(rules.Fields["number"].Rules, 1)
   643  	suite.Equal(&Rule{Name: "numeric", Params: []string{}, ArrayDimension: 0}, rules.Fields["number"].Rules[0])
   644  
   645  	suite.Equal(rules, set.AsRules())
   646  
   647  	suite.True(rules.checked)
   648  	// Resulting Rules should be checked after parsing
   649  	suite.Panics(func() {
   650  		set := RuleSet{
   651  			"string": {"required", "not a rule", ">min:3"},
   652  		}
   653  		set.parse()
   654  	})
   655  }
   656  
   657  func (suite *ValidatorTestSuite) TestAsRules() {
   658  	rules := &Rules{
   659  		Fields: FieldMap{
   660  			"values": {
   661  				Rules: []*Rule{
   662  					{Name: "required"},
   663  					{Name: "array"},
   664  					{Name: "array", ArrayDimension: 1},
   665  					{Name: "array", Params: []string{"numeric"}, ArrayDimension: 2},
   666  					{Name: "max", Params: []string{"3"}, ArrayDimension: 1},
   667  					{Name: "max", Params: []string{"4"}, ArrayDimension: 3},
   668  				},
   669  			},
   670  		},
   671  	}
   672  	suite.Equal(rules, rules.AsRules())
   673  
   674  	suite.Panics(func() {
   675  		rules := &Rules{
   676  			Fields: FieldMap{
   677  				"values": {
   678  					Rules: []*Rule{
   679  						{Name: "not a rule"},
   680  					},
   681  				},
   682  			},
   683  		}
   684  		suite.False(rules.checked)
   685  		rules.AsRules()
   686  	})
   687  }
   688  
   689  func (suite *ValidatorTestSuite) TestRulesCheck() {
   690  	rules := &Rules{
   691  		Fields: FieldMap{
   692  			"values": {
   693  				Rules: []*Rule{
   694  					{Name: "required"},
   695  					{Name: "array"},
   696  					{Name: "array", ArrayDimension: 1},
   697  					{Name: "array", Params: []string{"numeric"}, ArrayDimension: 2},
   698  					{Name: "max", Params: []string{"3"}, ArrayDimension: 1},
   699  					{Name: "max", Params: []string{"4"}, ArrayDimension: 3},
   700  				},
   701  			},
   702  		},
   703  	}
   704  	suite.False(rules.checked)
   705  	rules.check()
   706  	suite.True(rules.checked)
   707  
   708  	// Check should not be executed multiple times
   709  	rules.Fields["values"].Rules[0].Name = "not a rule"
   710  	suite.NotPanics(func() {
   711  		rules.check()
   712  	})
   713  }
   714  
   715  func TestValidatorTestSuite(t *testing.T) {
   716  	suite.Run(t, new(ValidatorTestSuite))
   717  }