git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/validate/validator_test.go (about)

     1  package validate
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  )
     9  
    10  func init() {
    11  	CustomTypeTagMap.Set("customFalseValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool {
    12  		return false
    13  	}))
    14  	CustomTypeTagMap.Set("customTrueValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool {
    15  		return true
    16  	}))
    17  }
    18  
    19  func TestIsAlpha(t *testing.T) {
    20  	t.Parallel()
    21  
    22  	var tests = []struct {
    23  		param    string
    24  		expected bool
    25  	}{
    26  		{"\n", false},
    27  		{"\r", false},
    28  		{"Ⅸ", false},
    29  		{"", true},
    30  		{"   fooo   ", false},
    31  		{"abc!!!", false},
    32  		{"abc1", false},
    33  		{"abc〩", false},
    34  		{"abc", true},
    35  		{"소주", false},
    36  		{"ABC", true},
    37  		{"FoObAr", true},
    38  		{"소aBC", false},
    39  		{"소", false},
    40  		{"달기&Co.", false},
    41  		{"〩Hours", false},
    42  		{"\ufff0", false},
    43  		{"\u0070", true},  //UTF-8(ASCII): p
    44  		{"\u0026", false}, //UTF-8(ASCII): &
    45  		{"\u0030", false}, //UTF-8(ASCII): 0
    46  		{"123", false},
    47  		{"0123", false},
    48  		{"-00123", false},
    49  		{"0", false},
    50  		{"-0", false},
    51  		{"123.123", false},
    52  		{" ", false},
    53  		{".", false},
    54  		{"-1¾", false},
    55  		{"1¾", false},
    56  		{"〥〩", false},
    57  		{"모자", false},
    58  		{"ix", true},
    59  		{"۳۵۶۰", false},
    60  		{"1--", false},
    61  		{"1-1", false},
    62  		{"-", false},
    63  		{"--", false},
    64  		{"1++", false},
    65  		{"1+1", false},
    66  		{"+", false},
    67  		{"++", false},
    68  		{"+1", false},
    69  	}
    70  	for _, test := range tests {
    71  		actual := IsAlpha(test.param)
    72  		if actual != test.expected {
    73  			t.Errorf("Expected IsAlpha(%q) to be %v, got %v", test.param, test.expected, actual)
    74  		}
    75  	}
    76  }
    77  
    78  func TestIsUTFLetter(t *testing.T) {
    79  	t.Parallel()
    80  
    81  	var tests = []struct {
    82  		param    string
    83  		expected bool
    84  	}{
    85  		{"\n", false},
    86  		{"\r", false},
    87  		{"Ⅸ", false},
    88  		{"", true},
    89  		{"   fooo   ", false},
    90  		{"abc!!!", false},
    91  		{"abc1", false},
    92  		{"abc〩", false},
    93  		{"", true},
    94  		{"abc", true},
    95  		{"소주", true},
    96  		{"ABC", true},
    97  		{"FoObAr", true},
    98  		{"소aBC", true},
    99  		{"소", true},
   100  		{"달기&Co.", false},
   101  		{"〩Hours", false},
   102  		{"\ufff0", false},
   103  		{"\u0070", true},  //UTF-8(ASCII): p
   104  		{"\u0026", false}, //UTF-8(ASCII): &
   105  		{"\u0030", false}, //UTF-8(ASCII): 0
   106  		{"123", false},
   107  		{"0123", false},
   108  		{"-00123", false},
   109  		{"0", false},
   110  		{"-0", false},
   111  		{"123.123", false},
   112  		{" ", false},
   113  		{".", false},
   114  		{"-1¾", false},
   115  		{"1¾", false},
   116  		{"〥〩", false},
   117  		{"모자", true},
   118  		{"ix", true},
   119  		{"۳۵۶۰", false},
   120  		{"1--", false},
   121  		{"1-1", false},
   122  		{"-", false},
   123  		{"--", false},
   124  		{"1++", false},
   125  		{"1+1", false},
   126  		{"+", false},
   127  		{"++", false},
   128  		{"+1", false},
   129  	}
   130  	for _, test := range tests {
   131  		actual := IsUTFLetter(test.param)
   132  		if actual != test.expected {
   133  			t.Errorf("Expected IsUTFLetter(%q) to be %v, got %v", test.param, test.expected, actual)
   134  		}
   135  	}
   136  }
   137  
   138  func TestIsAlphanumeric(t *testing.T) {
   139  	t.Parallel()
   140  
   141  	var tests = []struct {
   142  		param    string
   143  		expected bool
   144  	}{
   145  		{"\n", false},
   146  		{"\r", false},
   147  		{"Ⅸ", false},
   148  		{"", true},
   149  		{"   fooo   ", false},
   150  		{"abc!!!", false},
   151  		{"abc123", true},
   152  		{"ABC111", true},
   153  		{"abc1", true},
   154  		{"abc〩", false},
   155  		{"abc", true},
   156  		{"소주", false},
   157  		{"ABC", true},
   158  		{"FoObAr", true},
   159  		{"소aBC", false},
   160  		{"소", false},
   161  		{"달기&Co.", false},
   162  		{"〩Hours", false},
   163  		{"\ufff0", false},
   164  		{"\u0070", true},  //UTF-8(ASCII): p
   165  		{"\u0026", false}, //UTF-8(ASCII): &
   166  		{"\u0030", true},  //UTF-8(ASCII): 0
   167  		{"123", true},
   168  		{"0123", true},
   169  		{"-00123", false},
   170  		{"0", true},
   171  		{"-0", false},
   172  		{"123.123", false},
   173  		{" ", false},
   174  		{".", false},
   175  		{"-1¾", false},
   176  		{"1¾", false},
   177  		{"〥〩", false},
   178  		{"모자", false},
   179  		{"ix", true},
   180  		{"۳۵۶۰", false},
   181  		{"1--", false},
   182  		{"1-1", false},
   183  		{"-", false},
   184  		{"--", false},
   185  		{"1++", false},
   186  		{"1+1", false},
   187  		{"+", false},
   188  		{"++", false},
   189  		{"+1", false},
   190  	}
   191  	for _, test := range tests {
   192  		actual := IsAlphanumeric(test.param)
   193  		if actual != test.expected {
   194  			t.Errorf("Expected IsAlphanumeric(%q) to be %v, got %v", test.param, test.expected, actual)
   195  		}
   196  	}
   197  }
   198  
   199  func TestIsUTFLetterNumeric(t *testing.T) {
   200  	t.Parallel()
   201  
   202  	var tests = []struct {
   203  		param    string
   204  		expected bool
   205  	}{
   206  		{"\n", false},
   207  		{"\r", false},
   208  		{"Ⅸ", true},
   209  		{"", true},
   210  		{"   fooo   ", false},
   211  		{"abc!!!", false},
   212  		{"abc1", true},
   213  		{"abc〩", true},
   214  		{"abc", true},
   215  		{"소주", true},
   216  		{"ABC", true},
   217  		{"FoObAr", true},
   218  		{"소aBC", true},
   219  		{"소", true},
   220  		{"달기&Co.", false},
   221  		{"〩Hours", true},
   222  		{"\ufff0", false},
   223  		{"\u0070", true},  //UTF-8(ASCII): p
   224  		{"\u0026", false}, //UTF-8(ASCII): &
   225  		{"\u0030", true},  //UTF-8(ASCII): 0
   226  		{"123", true},
   227  		{"0123", true},
   228  		{"-00123", false},
   229  		{"0", true},
   230  		{"-0", false},
   231  		{"123.123", false},
   232  		{" ", false},
   233  		{".", false},
   234  		{"-1¾", false},
   235  		{"1¾", true},
   236  		{"〥〩", true},
   237  		{"모자", true},
   238  		{"ix", true},
   239  		{"۳۵۶۰", true},
   240  		{"1--", false},
   241  		{"1-1", false},
   242  		{"-", false},
   243  		{"--", false},
   244  		{"1++", false},
   245  		{"1+1", false},
   246  		{"+", false},
   247  		{"++", false},
   248  		{"+1", false},
   249  	}
   250  	for _, test := range tests {
   251  		actual := IsUTFLetterNumeric(test.param)
   252  		if actual != test.expected {
   253  			t.Errorf("Expected IsUTFLetterNumeric(%q) to be %v, got %v", test.param, test.expected, actual)
   254  		}
   255  	}
   256  }
   257  
   258  func TestIsNumeric(t *testing.T) {
   259  	t.Parallel()
   260  
   261  	var tests = []struct {
   262  		param    string
   263  		expected bool
   264  	}{
   265  		{"\n", false},
   266  		{"\r", false},
   267  		{"Ⅸ", false},
   268  		{"", true},
   269  		{"   fooo   ", false},
   270  		{"abc!!!", false},
   271  		{"abc1", false},
   272  		{"abc〩", false},
   273  		{"abc", false},
   274  		{"소주", false},
   275  		{"ABC", false},
   276  		{"FoObAr", false},
   277  		{"소aBC", false},
   278  		{"소", false},
   279  		{"달기&Co.", false},
   280  		{"〩Hours", false},
   281  		{"\ufff0", false},
   282  		{"\u0070", false}, //UTF-8(ASCII): p
   283  		{"\u0026", false}, //UTF-8(ASCII): &
   284  		{"\u0030", true},  //UTF-8(ASCII): 0
   285  		{"123", true},
   286  		{"0123", true},
   287  		{"-00123", false},
   288  		{"+00123", false},
   289  		{"0", true},
   290  		{"-0", false},
   291  		{"123.123", false},
   292  		{" ", false},
   293  		{".", false},
   294  		{"12𐅪3", false},
   295  		{"-1¾", false},
   296  		{"1¾", false},
   297  		{"〥〩", false},
   298  		{"모자", false},
   299  		{"ix", false},
   300  		{"۳۵۶۰", false},
   301  		{"1--", false},
   302  		{"1-1", false},
   303  		{"-", false},
   304  		{"--", false},
   305  		{"1++", false},
   306  		{"1+1", false},
   307  		{"+", false},
   308  		{"++", false},
   309  		{"+1", false},
   310  	}
   311  	for _, test := range tests {
   312  		actual := IsNumeric(test.param)
   313  		if actual != test.expected {
   314  			t.Errorf("Expected IsNumeric(%q) to be %v, got %v", test.param, test.expected, actual)
   315  		}
   316  	}
   317  }
   318  
   319  func TestIsUTFNumeric(t *testing.T) {
   320  	t.Parallel()
   321  
   322  	var tests = []struct {
   323  		param    string
   324  		expected bool
   325  	}{
   326  		{"\n", false},
   327  		{"\r", false},
   328  		{"Ⅸ", true},
   329  		{"", true},
   330  		{"   fooo   ", false},
   331  		{"abc!!!", false},
   332  		{"abc1", false},
   333  		{"abc〩", false},
   334  		{"abc", false},
   335  		{"소주", false},
   336  		{"ABC", false},
   337  		{"FoObAr", false},
   338  		{"소aBC", false},
   339  		{"소", false},
   340  		{"달기&Co.", false},
   341  		{"〩Hours", false},
   342  		{"\ufff0", false},
   343  		{"\u0070", false}, //UTF-8(ASCII): p
   344  		{"\u0026", false}, //UTF-8(ASCII): &
   345  		{"\u0030", true},  //UTF-8(ASCII): 0
   346  		{"123", true},
   347  		{"0123", true},
   348  		{"-00123", true},
   349  		{"0", true},
   350  		{"-0", true},
   351  		{"--0", false},
   352  		{"-0-", false},
   353  		{"123.123", false},
   354  		{" ", false},
   355  		{".", false},
   356  		{"12𐅪3", true},
   357  		{"-1¾", true},
   358  		{"1¾", true},
   359  		{"〥〩", true},
   360  		{"모자", false},
   361  		{"ix", false},
   362  		{"۳۵۶۰", true},
   363  		{"1++", false},
   364  		{"1+1", false},
   365  		{"+", false},
   366  		{"++", false},
   367  		{"+1", true},
   368  	}
   369  	for _, test := range tests {
   370  		actual := IsUTFNumeric(test.param)
   371  		if actual != test.expected {
   372  			t.Errorf("Expected IsUTFNumeric(%q) to be %v, got %v", test.param, test.expected, actual)
   373  		}
   374  	}
   375  }
   376  
   377  func TestIsUTFDigit(t *testing.T) {
   378  	t.Parallel()
   379  
   380  	var tests = []struct {
   381  		param    string
   382  		expected bool
   383  	}{
   384  
   385  		{"\n", false},
   386  		{"\r", false},
   387  		{"Ⅸ", false},
   388  		{"", true},
   389  		{"   fooo   ", false},
   390  		{"abc!!!", false},
   391  		{"abc1", false},
   392  		{"abc〩", false},
   393  		{"abc", false},
   394  		{"소주", false},
   395  		{"ABC", false},
   396  		{"FoObAr", false},
   397  		{"소aBC", false},
   398  		{"소", false},
   399  		{"달기&Co.", false},
   400  		{"〩Hours", false},
   401  		{"\ufff0", false},
   402  		{"\u0070", false}, //UTF-8(ASCII): p
   403  		{"\u0026", false}, //UTF-8(ASCII): &
   404  		{"\u0030", true},  //UTF-8(ASCII): 0
   405  		{"123", true},
   406  		{"0123", true},
   407  		{"-00123", true},
   408  		{"0", true},
   409  		{"-0", true},
   410  		{"--0", false},
   411  		{"-0-", false},
   412  		{"123.123", false},
   413  		{" ", false},
   414  		{".", false},
   415  		{"12𐅪3", false},
   416  		{"1483920", true},
   417  		{"", true},
   418  		{"۳۵۶۰", true},
   419  		{"-29", true},
   420  		{"-1¾", false},
   421  		{"1¾", false},
   422  		{"〥〩", false},
   423  		{"모자", false},
   424  		{"ix", false},
   425  		{"۳۵۶۰", true},
   426  		{"1++", false},
   427  		{"1+1", false},
   428  		{"+", false},
   429  		{"++", false},
   430  		{"+1", true},
   431  	}
   432  	for _, test := range tests {
   433  		actual := IsUTFDigit(test.param)
   434  		if actual != test.expected {
   435  			t.Errorf("Expected IsUTFDigit(%q) to be %v, got %v", test.param, test.expected, actual)
   436  		}
   437  	}
   438  }
   439  
   440  func TestIsLowerCase(t *testing.T) {
   441  	t.Parallel()
   442  
   443  	var tests = []struct {
   444  		param    string
   445  		expected bool
   446  	}{
   447  		{"", true},
   448  		{"abc123", true},
   449  		{"abc", true},
   450  		{"a b c", true},
   451  		{"abcß", true},
   452  		{"abcẞ", false},
   453  		{"ABCẞ", false},
   454  		{"tr竪s 端ber", true},
   455  		{"fooBar", false},
   456  		{"123ABC", false},
   457  		{"ABC123", false},
   458  		{"ABC", false},
   459  		{"S T R", false},
   460  		{"fooBar", false},
   461  		{"abacaba123", true},
   462  	}
   463  	for _, test := range tests {
   464  		actual := IsLowerCase(test.param)
   465  		if actual != test.expected {
   466  			t.Errorf("Expected IsLowerCase(%q) to be %v, got %v", test.param, test.expected, actual)
   467  		}
   468  	}
   469  }
   470  
   471  func TestIsUpperCase(t *testing.T) {
   472  	t.Parallel()
   473  
   474  	var tests = []struct {
   475  		param    string
   476  		expected bool
   477  	}{
   478  		{"", true},
   479  		{"abc123", false},
   480  		{"abc", false},
   481  		{"a b c", false},
   482  		{"abcß", false},
   483  		{"abcẞ", false},
   484  		{"ABCẞ", true},
   485  		{"tr竪s 端ber", false},
   486  		{"fooBar", false},
   487  		{"123ABC", true},
   488  		{"ABC123", true},
   489  		{"ABC", true},
   490  		{"S T R", true},
   491  		{"fooBar", false},
   492  		{"abacaba123", false},
   493  	}
   494  	for _, test := range tests {
   495  		actual := IsUpperCase(test.param)
   496  		if actual != test.expected {
   497  			t.Errorf("Expected IsUpperCase(%q) to be %v, got %v", test.param, test.expected, actual)
   498  		}
   499  	}
   500  }
   501  
   502  func TestHasLowerCase(t *testing.T) {
   503  	t.Parallel()
   504  
   505  	var tests = []struct {
   506  		param    string
   507  		expected bool
   508  	}{
   509  		{"", true},
   510  		{"abc123", true},
   511  		{"abc", true},
   512  		{"a b c", true},
   513  		{"abcß", true},
   514  		{"abcẞ", true},
   515  		{"ABCẞ", false},
   516  		{"tr竪s 端ber", true},
   517  		{"fooBar", true},
   518  		{"123ABC", false},
   519  		{"ABC123", false},
   520  		{"ABC", false},
   521  		{"S T R", false},
   522  		{"fooBar", true},
   523  		{"abacaba123", true},
   524  		{"FÒÔBÀŘ", false},
   525  		{"fòôbàř", true},
   526  		{"fÒÔBÀŘ", true},
   527  	}
   528  	for _, test := range tests {
   529  		actual := HasLowerCase(test.param)
   530  		if actual != test.expected {
   531  			t.Errorf("Expected HasLowerCase(%q) to be %v, got %v", test.param, test.expected, actual)
   532  		}
   533  	}
   534  }
   535  
   536  func TestHasUpperCase(t *testing.T) {
   537  	t.Parallel()
   538  
   539  	var tests = []struct {
   540  		param    string
   541  		expected bool
   542  	}{
   543  		{"", true},
   544  		{"abc123", false},
   545  		{"abc", false},
   546  		{"a b c", false},
   547  		{"abcß", false},
   548  		{"abcẞ", false},
   549  		{"ABCẞ", true},
   550  		{"tr竪s 端ber", false},
   551  		{"fooBar", true},
   552  		{"123ABC", true},
   553  		{"ABC123", true},
   554  		{"ABC", true},
   555  		{"S T R", true},
   556  		{"fooBar", true},
   557  		{"abacaba123", false},
   558  		{"FÒÔBÀŘ", true},
   559  		{"fòôbàř", false},
   560  		{"Fòôbàř", true},
   561  	}
   562  	for _, test := range tests {
   563  		actual := HasUpperCase(test.param)
   564  		if actual != test.expected {
   565  			t.Errorf("Expected HasUpperCase(%q) to be %v, got %v", test.param, test.expected, actual)
   566  		}
   567  	}
   568  }
   569  
   570  func TestIsInt(t *testing.T) {
   571  	t.Parallel()
   572  
   573  	var tests = []struct {
   574  		param    string
   575  		expected bool
   576  	}{
   577  		{"-2147483648", true},          //Signed 32 Bit Min Int
   578  		{"2147483647", true},           //Signed 32 Bit Max Int
   579  		{"-2147483649", true},          //Signed 32 Bit Min Int - 1
   580  		{"2147483648", true},           //Signed 32 Bit Max Int + 1
   581  		{"4294967295", true},           //Unsigned 32 Bit Max Int
   582  		{"4294967296", true},           //Unsigned 32 Bit Max Int + 1
   583  		{"-9223372036854775808", true}, //Signed 64 Bit Min Int
   584  		{"9223372036854775807", true},  //Signed 64 Bit Max Int
   585  		{"-9223372036854775809", true}, //Signed 64 Bit Min Int - 1
   586  		{"9223372036854775808", true},  //Signed 64 Bit Max Int + 1
   587  		{"18446744073709551615", true}, //Unsigned 64 Bit Max Int
   588  		{"18446744073709551616", true}, //Unsigned 64 Bit Max Int + 1
   589  		{"", true},
   590  		{"123", true},
   591  		{"0", true},
   592  		{"-0", true},
   593  		{"+0", true},
   594  		{"01", false},
   595  		{"123.123", false},
   596  		{" ", false},
   597  		{"000", false},
   598  	}
   599  	for _, test := range tests {
   600  		actual := IsInt(test.param)
   601  		if actual != test.expected {
   602  			t.Errorf("Expected IsInt(%q) to be %v, got %v", test.param, test.expected, actual)
   603  		}
   604  	}
   605  }
   606  
   607  func TestIsHash(t *testing.T) {
   608  	t.Parallel()
   609  
   610  	var tests = []struct {
   611  		param    string
   612  		algo     string
   613  		expected bool
   614  	}{
   615  		{"3ca25ae354e192b26879f651a51d92aa8a34d8d3", "sha1", true},
   616  		{"3ca25ae354e192b26879f651a51d34d8d3", "sha1", false},
   617  		{"3ca25ae354e192b26879f651a51d92aa8a34d8d3", "Tiger160", true},
   618  		{"3ca25ae354e192b26879f651a51d34d8d3", "ripemd160", false},
   619  		{"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898c", "sha256", true},
   620  		{"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898casfdsafsadfsdf", "sha256", false},
   621  		{"bf547c3fc5841a377eb1519c2890344dbab15c40ae4150b4b34443d2212e5b04aa9d58865bf03d8ae27840fef430b891", "sha384", true},
   622  		{"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898casfdsafsadfsdf", "sha384", false},
   623  		{"45bc5fa8cb45ee408c04b6269e9f1e1c17090c5ce26ffeeda2af097735b29953ce547e40ff3ad0d120e5361cc5f9cee35ea91ecd4077f3f589b4d439168f91b9", "sha512", true},
   624  		{"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898casfdsafsadfsdf", "sha512", false},
   625  		{"46fc0125a148788a3ac1d649566fc04eb84a746f1a6e4fa7", "tiger192", true},
   626  		{"46fc0125a148788a3ac1d649566fc04eb84a746f1a6$$%@^", "TIGER192", false},
   627  		{"46fc0125a148788a3ac1d649566fc04eb84a746f1a6$$%@^", "SOMEHASH", false},
   628  		{"b87f88c72702fff1748e58b87e9141a42c0dbedc29a78cb0d4a5cd81", "sha3-224", true},
   629  		{"b87f88c72702fff1748e58b87e9141a42c0dbedc29a78cb0d4a5cd81g", "sha3-224", false},
   630  		{"3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f392", "sha3-256", true},
   631  		{"3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f392g", "sha3-256", false},
   632  		{"720aea11019ef06440fbf05d87aa24680a2153df3907b23631e7177ce620fa1330ff07c0fddee54699a4c3ee0ee9d887", "sha3-384", true},
   633  		{"720aea11019ef06440fbf05d87aa24680a2153df3907b23631e7177ce620fa1330ff07c0fddee54699a4c3ee0ee9d88", "sha3-384", false},
   634  		{"75d527c368f2efe848ecf6b073a36767800805e9eef2b1857d5f984f036eb6df891d75f72d9b154518c1cd58835286d1da9a38deba3de98b5a53e5ed78a84976", "sha3-512", true},
   635  		{"75d527c368f2efe848ecf6b073a36767800805e9eef2b1857d5f984f036eb6df891d75f72d9b154518c1cd58835286d1da9a38deba3de98b5a53e5ed78a8497", "sha3-512", false},
   636  	}
   637  	for _, test := range tests {
   638  		actual := IsHash(test.param, test.algo)
   639  		if actual != test.expected {
   640  			t.Errorf("Expected IsHash(%q, %q) to be %v, got %v", test.param, test.algo, test.expected, actual)
   641  		}
   642  	}
   643  }
   644  
   645  func TestIsSHA3224(t *testing.T) {
   646  	t.Parallel()
   647  
   648  	var tests = []struct {
   649  		param    string
   650  		expected bool
   651  	}{
   652  		{"b87f88c72702fff1748e58b87e9141a42c0dbedc29a78cb0d4a5cd81", true},
   653  		{"b87f88c72702fff1748e58b87e9141a42c0dbedc29a78cb0d4a5cd81g", false},
   654  	}
   655  	for _, test := range tests {
   656  		actual := IsSHA3224(test.param)
   657  		if actual != test.expected {
   658  			t.Errorf("Expected IsSHA3224(%q) to be %v, got %v", test.param, test.expected, actual)
   659  		}
   660  	}
   661  }
   662  
   663  func TestIsSHA3256(t *testing.T) {
   664  	t.Parallel()
   665  
   666  	var tests = []struct {
   667  		param    string
   668  		expected bool
   669  	}{
   670  		{"3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f392", true},
   671  		{"3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f39", false},
   672  	}
   673  	for _, test := range tests {
   674  		actual := IsSHA3256(test.param)
   675  		if actual != test.expected {
   676  			t.Errorf("Expected IsSHA3256(%q) to be %v, got %v", test.param, test.expected, actual)
   677  		}
   678  	}
   679  }
   680  
   681  func TestIsSHA3384(t *testing.T) {
   682  	t.Parallel()
   683  
   684  	var tests = []struct {
   685  		param    string
   686  		expected bool
   687  	}{
   688  		{"720aea11019ef06440fbf05d87aa24680a2153df3907b23631e7177ce620fa1330ff07c0fddee54699a4c3ee0ee9d887", true},
   689  		{"720aea11019ef06440fbf05d87aa24680a2153df3907b23631e7177ce620fa1330ff07c0fddee54699a4c3ee0ee9d88", false},
   690  	}
   691  	for _, test := range tests {
   692  		actual := IsSHA3384(test.param)
   693  		if actual != test.expected {
   694  			t.Errorf("Expected IsSHA3384(%q) to be %v, got %v", test.param, test.expected, actual)
   695  		}
   696  	}
   697  }
   698  
   699  func TestIsSHA3512(t *testing.T) {
   700  	t.Parallel()
   701  
   702  	var tests = []struct {
   703  		param    string
   704  		expected bool
   705  	}{
   706  		{"75d527c368f2efe848ecf6b073a36767800805e9eef2b1857d5f984f036eb6df891d75f72d9b154518c1cd58835286d1da9a38deba3de98b5a53e5ed78a84976", true},
   707  		{"75d527c368f2efe848ecf6b073a36767800805e9eef2b1857d5f984f036eb6df891d75f72d9b154518c1cd58835286d1da9a38deba3de98b5a53e5ed78a8497", false},
   708  	}
   709  	for _, test := range tests {
   710  		actual := IsSHA3512(test.param)
   711  		if actual != test.expected {
   712  			t.Errorf("Expected IsSHA3512(%q) to be %v, got %v", test.param, test.expected, actual)
   713  		}
   714  	}
   715  }
   716  
   717  func TestIsExistingEmail(t *testing.T) {
   718  	t.Parallel()
   719  
   720  	var tests = []struct {
   721  		param    string
   722  		expected bool
   723  	}{
   724  		{"", false},
   725  		{"foo@bar.com", true},
   726  		{"foo@bar.com.au", true},
   727  		{"foo+bar@bar.com", true},
   728  		{"foo@bar.coffee..coffee", false},
   729  		{"invalidemail@", false},
   730  		{"invalid.com", false},
   731  		{"@invalid.com", false},
   732  		{"NathAn.daVIeS@DomaIn.cOM", true},
   733  		{"NATHAN.DAVIES@DOMAIN.CO.UK", true},
   734  		{"prasun.joshi@localhost", true},
   735  		{"[prasun.joshi]@DomaIn.cOM", false},
   736  		{"sizeofuserismorethansixtyfour0123sizeofuserismorethansixtyfour0123@DOMAIN.CO.UK", false},
   737  		{"nosuchdomain@bar.nosuchdomainsuffix", false},
   738  	}
   739  	for _, test := range tests {
   740  		actual := IsExistingEmail(test.param)
   741  		if actual != test.expected {
   742  			t.Errorf("Expected IsExistingEmail(%q) to be %v, got %v", test.param, test.expected, actual)
   743  		}
   744  	}
   745  }
   746  
   747  func TestIsEmail(t *testing.T) {
   748  	t.Parallel()
   749  
   750  	var tests = []struct {
   751  		param    string
   752  		expected bool
   753  	}{
   754  		{"", false},
   755  		{"foo@bar.com", true},
   756  		{"x@x.x", true},
   757  		{"foo@bar.com.au", true},
   758  		{"foo+bar@bar.com", true},
   759  		{"foo@bar.coffee", true},
   760  		{"foo@bar.coffee..coffee", false},
   761  		{"foo@bar.bar.coffee", true},
   762  		{"foo@bar.中文网", true},
   763  		{"invalidemail@", false},
   764  		{"invalid.com", false},
   765  		{"@invalid.com", false},
   766  		{"test|123@m端ller.com", true},
   767  		{"hans@m端ller.com", true},
   768  		{"hans.m端ller@test.com", true},
   769  		{"NathAn.daVIeS@DomaIn.cOM", true},
   770  		{"NATHAN.DAVIES@DOMAIN.CO.UK", true},
   771  	}
   772  	for _, test := range tests {
   773  		actual := IsEmail(test.param)
   774  		if actual != test.expected {
   775  			t.Errorf("Expected IsEmail(%q) to be %v, got %v", test.param, test.expected, actual)
   776  		}
   777  	}
   778  }
   779  
   780  func TestIsURL(t *testing.T) {
   781  	t.Parallel()
   782  
   783  	var tests = []struct {
   784  		param    string
   785  		expected bool
   786  	}{
   787  		{"", false},
   788  		{"http://foo.bar#com", true},
   789  		{"http://foobar.com", true},
   790  		{"https://foobar.com", true},
   791  		{"foobar.com", true},
   792  		{"http://foobar.coffee/", true},
   793  		{"http://foobar.中文网/", true},
   794  		{"http://foobar.org/", true},
   795  		{"http://foobar.ORG", true},
   796  		{"http://foobar.org:8080/", true},
   797  		{"ftp://foobar.ru/", true},
   798  		{"ftp.foo.bar", true},
   799  		{"http://user:pass@www.foobar.com/", true},
   800  		{"http://user:pass@www.foobar.com/path/file", true},
   801  		{"http://127.0.0.1/", true},
   802  		{"http://duckduckgo.com/?q=%2F", true},
   803  		{"http://localhost:3000/", true},
   804  		{"http://foobar.com/?foo=bar#baz=qux", true},
   805  		{"http://foobar.com?foo=bar", true},
   806  		{"http://www.xn--froschgrn-x9a.net/", true},
   807  		{"http://foobar.com/a-", true},
   808  		{"http://foobar.پاکستان/", true},
   809  		{"http://foobar.c_o_m", false},
   810  		{"http://_foobar.com", false},
   811  		{"http://foo_bar.com", true},
   812  		{"http://user:pass@foo_bar_bar.bar_foo.com", true},
   813  		{"", false},
   814  		{"xyz://foobar.com", false},
   815  		// {"invalid.", false}, is it false like "localhost."?
   816  		{".com", false},
   817  		{"rtmp://foobar.com", false},
   818  		{"http://localhost:3000/", true},
   819  		{"http://foobar.com#baz=qux", true},
   820  		{"http://foobar.com/t$-_.+!*\\'(),", true},
   821  		{"http://www.foobar.com/~foobar", true},
   822  		{"http://www.-foobar.com/", false},
   823  		{"http://www.foo---bar.com/", false},
   824  		{"http://r6---snnvoxuioq6.googlevideo.com", true},
   825  		{"mailto:someone@example.com", true},
   826  		{"irc://irc.server.org/channel", false},
   827  		{"irc://#channel@network", true},
   828  		{"/abs/test/dir", false},
   829  		{"./rel/test/dir", false},
   830  		{"http://foo^bar.org", false},
   831  		{"http://foo&*bar.org", false},
   832  		{"http://foo&bar.org", false},
   833  		{"http://foo bar.org", false},
   834  		{"http://foo.bar.org", true},
   835  		{"http://www.foo.bar.org", true},
   836  		{"http://www.foo.co.uk", true},
   837  		{"foo", false},
   838  		{"http://.foo.com", false},
   839  		{"http://,foo.com", false},
   840  		{",foo.com", false},
   841  		{"http://myservice.:9093/", true},
   842  		// according to issues #62 #66
   843  		{"https://pbs.twimg.com/profile_images/560826135676588032/j8fWrmYY_normal.jpeg", true},
   844  		// according to #125
   845  		{"http://prometheus-alertmanager.service.q:9093", true},
   846  		{"aio1_alertmanager_container-63376c45:9093", true},
   847  		{"https://www.logn-123-123.url.with.sigle.letter.d:12345/url/path/foo?bar=zzz#user", true},
   848  		{"http://me.example.com", true},
   849  		{"http://www.me.example.com", true},
   850  		{"https://farm6.static.flickr.com", true},
   851  		{"https://zh.wikipedia.org/wiki/Wikipedia:%E9%A6%96%E9%A1%B5", true},
   852  		{"google", false},
   853  		// According to #87
   854  		{"http://hyphenated-host-name.example.co.in", true},
   855  		{"http://cant-end-with-hyphen-.example.com", false},
   856  		{"http://-cant-start-with-hyphen.example.com", false},
   857  		{"http://www.domain-can-have-dashes.com", true},
   858  		{"http://m.abcd.com/test.html", true},
   859  		{"http://m.abcd.com/a/b/c/d/test.html?args=a&b=c", true},
   860  		{"http://[::1]:9093", true},
   861  		{"http://[::1]:909388", false},
   862  		{"1200::AB00:1234::2552:7777:1313", false},
   863  		{"http://[2001:db8:a0b:12f0::1]/index.html", true},
   864  		{"http://[1200:0000:AB00:1234:0000:2552:7777:1313]", true},
   865  		{"http://user:pass@[::1]:9093/a/b/c/?a=v#abc", true},
   866  		{"https://127.0.0.1/a/b/c?a=v&c=11d", true},
   867  		{"https://foo_bar.example.com", true},
   868  		{"http://foo_bar.example.com", true},
   869  		{"http://foo_bar_fizz_buzz.example.com", true},
   870  		{"http://_cant_start_with_underescore", false},
   871  		{"http://cant_end_with_underescore_", false},
   872  		{"foo_bar.example.com", true},
   873  		{"foo_bar_fizz_buzz.example.com", true},
   874  		{"http://hello_world.example.com", true},
   875  		// According to #212
   876  		{"foo_bar-fizz-buzz:1313", true},
   877  		{"foo_bar-fizz-buzz:13:13", false},
   878  		{"foo_bar-fizz-buzz://1313", false},
   879  	}
   880  	for _, test := range tests {
   881  		actual := IsURL(test.param)
   882  		if actual != test.expected {
   883  			t.Errorf("Expected IsURL(%q) to be %v, got %v", test.param, test.expected, actual)
   884  		}
   885  	}
   886  }
   887  
   888  func TestIsRequestURL(t *testing.T) {
   889  	t.Parallel()
   890  
   891  	var tests = []struct {
   892  		param    string
   893  		expected bool
   894  	}{
   895  		{"", false},
   896  		{"http://foo.bar/#com", true},
   897  		{"http://foobar.com", true},
   898  		{"https://foobar.com", true},
   899  		{"foobar.com", false},
   900  		{"http://foobar.coffee/", true},
   901  		{"http://foobar.中文网/", true},
   902  		{"http://foobar.org/", true},
   903  		{"http://foobar.org:8080/", true},
   904  		{"ftp://foobar.ru/", true},
   905  		{"http://user:pass@www.foobar.com/", true},
   906  		{"http://127.0.0.1/", true},
   907  		{"http://duckduckgo.com/?q=%2F", true},
   908  		{"http://localhost:3000/", true},
   909  		{"http://foobar.com/?foo=bar#baz=qux", true},
   910  		{"http://foobar.com?foo=bar", true},
   911  		{"http://www.xn--froschgrn-x9a.net/", true},
   912  		{"", false},
   913  		{"xyz://foobar.com", true},
   914  		{"invalid.", false},
   915  		{".com", false},
   916  		{"rtmp://foobar.com", true},
   917  		{"http://www.foo_bar.com/", true},
   918  		{"http://localhost:3000/", true},
   919  		{"http://foobar.com/#baz=qux", true},
   920  		{"http://foobar.com/t$-_.+!*\\'(),", true},
   921  		{"http://www.foobar.com/~foobar", true},
   922  		{"http://www.-foobar.com/", true},
   923  		{"http://www.foo---bar.com/", true},
   924  		{"mailto:someone@example.com", true},
   925  		{"irc://irc.server.org/channel", true},
   926  		{"/abs/test/dir", false},
   927  		{"./rel/test/dir", false},
   928  	}
   929  	for _, test := range tests {
   930  		actual := IsRequestURL(test.param)
   931  		if actual != test.expected {
   932  			t.Errorf("Expected IsRequestURL(%q) to be %v, got %v", test.param, test.expected, actual)
   933  		}
   934  	}
   935  }
   936  
   937  func TestIsRequestURI(t *testing.T) {
   938  	t.Parallel()
   939  
   940  	var tests = []struct {
   941  		param    string
   942  		expected bool
   943  	}{
   944  		{"", false},
   945  		{"http://foo.bar/#com", true},
   946  		{"http://foobar.com", true},
   947  		{"https://foobar.com", true},
   948  		{"foobar.com", false},
   949  		{"http://foobar.coffee/", true},
   950  		{"http://foobar.中文网/", true},
   951  		{"http://foobar.org/", true},
   952  		{"http://foobar.org:8080/", true},
   953  		{"ftp://foobar.ru/", true},
   954  		{"http://user:pass@www.foobar.com/", true},
   955  		{"http://127.0.0.1/", true},
   956  		{"http://duckduckgo.com/?q=%2F", true},
   957  		{"http://localhost:3000/", true},
   958  		{"http://foobar.com/?foo=bar#baz=qux", true},
   959  		{"http://foobar.com?foo=bar", true},
   960  		{"http://www.xn--froschgrn-x9a.net/", true},
   961  		{"xyz://foobar.com", true},
   962  		{"invalid.", false},
   963  		{".com", false},
   964  		{"rtmp://foobar.com", true},
   965  		{"http://www.foo_bar.com/", true},
   966  		{"http://localhost:3000/", true},
   967  		{"http://foobar.com/#baz=qux", true},
   968  		{"http://foobar.com/t$-_.+!*\\'(),", true},
   969  		{"http://www.foobar.com/~foobar", true},
   970  		{"http://www.-foobar.com/", true},
   971  		{"http://www.foo---bar.com/", true},
   972  		{"mailto:someone@example.com", true},
   973  		{"irc://irc.server.org/channel", true},
   974  		{"/abs/test/dir", true},
   975  		{"./rel/test/dir", false},
   976  	}
   977  	for _, test := range tests {
   978  		actual := IsRequestURI(test.param)
   979  		if actual != test.expected {
   980  			t.Errorf("Expected IsRequestURI(%q) to be %v, got %v", test.param, test.expected, actual)
   981  		}
   982  	}
   983  }
   984  
   985  func TestIsFloat(t *testing.T) {
   986  	t.Parallel()
   987  
   988  	var tests = []struct {
   989  		param    string
   990  		expected bool
   991  	}{
   992  		{"", false},
   993  		{"  ", false},
   994  		{"-.123", false},
   995  		{"abacaba", false},
   996  		{"1f", false},
   997  		{"-1f", false},
   998  		{"+1f", false},
   999  		{"123", true},
  1000  		{"123.", true},
  1001  		{"123.123", true},
  1002  		{"-123.123", true},
  1003  		{"+123.123", true},
  1004  		{"0.123", true},
  1005  		{"-0.123", true},
  1006  		{"+0.123", true},
  1007  		{".0", true},
  1008  		{"01.123", true},
  1009  		{"-0.22250738585072011e-307", true},
  1010  		{"+0.22250738585072011e-307", true},
  1011  	}
  1012  	for _, test := range tests {
  1013  		actual := IsFloat(test.param)
  1014  		if actual != test.expected {
  1015  			t.Errorf("Expected IsFloat(%q) to be %v, got %v", test.param, test.expected, actual)
  1016  		}
  1017  	}
  1018  }
  1019  
  1020  func TestIsHexadecimal(t *testing.T) {
  1021  	t.Parallel()
  1022  
  1023  	var tests = []struct {
  1024  		param    string
  1025  		expected bool
  1026  	}{
  1027  		{"abcdefg", false},
  1028  		{"", false},
  1029  		{"..", false},
  1030  		{"deadBEEF", true},
  1031  		{"ff0044", true},
  1032  	}
  1033  	for _, test := range tests {
  1034  		actual := IsHexadecimal(test.param)
  1035  		if actual != test.expected {
  1036  			t.Errorf("Expected IsHexadecimal(%q) to be %v, got %v", test.param, test.expected, actual)
  1037  		}
  1038  	}
  1039  }
  1040  
  1041  func TestIsHexcolor(t *testing.T) {
  1042  	t.Parallel()
  1043  
  1044  	var tests = []struct {
  1045  		param    string
  1046  		expected bool
  1047  	}{
  1048  		{"", false},
  1049  		{"#ff", false},
  1050  		{"fff0", false},
  1051  		{"#ff12FG", false},
  1052  		{"CCccCC", true},
  1053  		{"fff", true},
  1054  		{"#f00", true},
  1055  	}
  1056  	for _, test := range tests {
  1057  		actual := IsHexcolor(test.param)
  1058  		if actual != test.expected {
  1059  			t.Errorf("Expected IsHexcolor(%q) to be %v, got %v", test.param, test.expected, actual)
  1060  		}
  1061  	}
  1062  }
  1063  
  1064  func TestIsRGBcolor(t *testing.T) {
  1065  	t.Parallel()
  1066  
  1067  	var tests = []struct {
  1068  		param    string
  1069  		expected bool
  1070  	}{
  1071  		{"", false},
  1072  		{"rgb(0,31,255)", true},
  1073  		{"rgb(1,349,275)", false},
  1074  		{"rgb(01,31,255)", false},
  1075  		{"rgb(0.6,31,255)", false},
  1076  		{"rgba(0,31,255)", false},
  1077  		{"rgb(0,  31, 255)", true},
  1078  	}
  1079  	for _, test := range tests {
  1080  		actual := IsRGBcolor(test.param)
  1081  		if actual != test.expected {
  1082  			t.Errorf("Expected IsRGBcolor(%q) to be %v, got %v", test.param, test.expected, actual)
  1083  		}
  1084  	}
  1085  }
  1086  
  1087  func TestIsNull(t *testing.T) {
  1088  	t.Parallel()
  1089  
  1090  	var tests = []struct {
  1091  		param    string
  1092  		expected bool
  1093  	}{
  1094  		{"abacaba", false},
  1095  		{"", true},
  1096  	}
  1097  	for _, test := range tests {
  1098  		actual := IsNull(test.param)
  1099  		if actual != test.expected {
  1100  			t.Errorf("Expected IsNull(%q) to be %v, got %v", test.param, test.expected, actual)
  1101  		}
  1102  	}
  1103  }
  1104  
  1105  func TestIsNotNull(t *testing.T) {
  1106  	t.Parallel()
  1107  
  1108  	var tests = []struct {
  1109  		param    string
  1110  		expected bool
  1111  	}{
  1112  		{"abacaba", true},
  1113  		{"", false},
  1114  	}
  1115  	for _, test := range tests {
  1116  		actual := IsNotNull(test.param)
  1117  		if actual != test.expected {
  1118  			t.Errorf("Expected IsNull(%q) to be %v, got %v", test.param, test.expected, actual)
  1119  		}
  1120  	}
  1121  }
  1122  
  1123  func TestIsIMEI(t *testing.T) {
  1124  	tests := []struct {
  1125  		param    string
  1126  		expected bool
  1127  	}{
  1128  		{"990000862471854", true},
  1129  		{"351756051523999", true},
  1130  		{"9900008624718541", false},
  1131  		{"1", false},
  1132  	}
  1133  	for _, test := range tests {
  1134  		actual := IsIMEI(test.param)
  1135  		if actual != test.expected {
  1136  			t.Errorf("Expected IsIMEI(%q) to be %v, got %v", test.param, test.expected, actual)
  1137  		}
  1138  	}
  1139  }
  1140  
  1141  func TestHasWhitespaceOnly(t *testing.T) {
  1142  	t.Parallel()
  1143  
  1144  	var tests = []struct {
  1145  		param    string
  1146  		expected bool
  1147  	}{
  1148  		{"abacaba", false},
  1149  		{"", false},
  1150  		{"    ", true},
  1151  		{"  \r\n  ", true},
  1152  		{"\014\012\011\013\015", true},
  1153  		{"\014\012\011\013 abc  \015", false},
  1154  		{"\f\n\t\v\r\f", true},
  1155  		{"x\n\t\t\t\t", false},
  1156  		{"\f\n\t  \n\n\n   \v\r\f", true},
  1157  	}
  1158  	for _, test := range tests {
  1159  		actual := HasWhitespaceOnly(test.param)
  1160  		if actual != test.expected {
  1161  			t.Errorf("Expected HasWhitespaceOnly(%q) to be %v, got %v", test.param, test.expected, actual)
  1162  		}
  1163  	}
  1164  }
  1165  
  1166  func TestHasWhitespace(t *testing.T) {
  1167  	t.Parallel()
  1168  
  1169  	var tests = []struct {
  1170  		param    string
  1171  		expected bool
  1172  	}{
  1173  		{"abacaba", false},
  1174  		{"", false},
  1175  		{"    ", true},
  1176  		{"  \r\n  ", true},
  1177  		{"\014\012\011\013\015", true},
  1178  		{"\014\012\011\013 abc  \015", true},
  1179  		{"\f\n\t\v\r\f", true},
  1180  		{"x\n\t\t\t\t", true},
  1181  		{"\f\n\t  \n\n\n   \v\r\f", true},
  1182  	}
  1183  	for _, test := range tests {
  1184  		actual := HasWhitespace(test.param)
  1185  		if actual != test.expected {
  1186  			t.Errorf("Expected HasWhitespace(%q) to be %v, got %v", test.param, test.expected, actual)
  1187  		}
  1188  	}
  1189  }
  1190  
  1191  func TestIsDivisibleBy(t *testing.T) {
  1192  	t.Parallel()
  1193  
  1194  	var tests = []struct {
  1195  		param1   string
  1196  		param2   string
  1197  		expected bool
  1198  	}{
  1199  		{"4", "2", true},
  1200  		{"100", "10", true},
  1201  		{"", "1", true},
  1202  		{"123", "foo", false},
  1203  		{"123", "0", false},
  1204  	}
  1205  	for _, test := range tests {
  1206  		actual := IsDivisibleBy(test.param1, test.param2)
  1207  		if actual != test.expected {
  1208  			t.Errorf("Expected IsDivisibleBy(%q, %q) to be %v, got %v", test.param1, test.param2, test.expected, actual)
  1209  		}
  1210  	}
  1211  }
  1212  
  1213  // This small example illustrate how to work with IsDivisibleBy function.
  1214  func ExampleIsDivisibleBy() {
  1215  	println("1024 is divisible by 64: ", IsDivisibleBy("1024", "64"))
  1216  }
  1217  
  1218  func TestIsByteLength(t *testing.T) {
  1219  	t.Parallel()
  1220  
  1221  	var tests = []struct {
  1222  		param1   string
  1223  		param2   int
  1224  		param3   int
  1225  		expected bool
  1226  	}{
  1227  		{"abacaba", 100, -1, false},
  1228  		{"abacaba", 1, 3, false},
  1229  		{"abacaba", 1, 7, true},
  1230  		{"abacaba", 0, 8, true},
  1231  		{"\ufff0", 1, 1, false},
  1232  	}
  1233  	for _, test := range tests {
  1234  		actual := IsByteLength(test.param1, test.param2, test.param3)
  1235  		if actual != test.expected {
  1236  			t.Errorf("Expected IsByteLength(%q, %q, %q) to be %v, got %v", test.param1, test.param2, test.param3, test.expected, actual)
  1237  		}
  1238  	}
  1239  }
  1240  
  1241  func TestIsJSON(t *testing.T) {
  1242  	t.Parallel()
  1243  
  1244  	var tests = []struct {
  1245  		param    string
  1246  		expected bool
  1247  	}{
  1248  		{"", false},
  1249  		{"145", true},
  1250  		{"asdf", false},
  1251  		{"123:f00", false},
  1252  		{"{\"Name\":\"Alice\",\"Body\":\"Hello\",\"Time\":1294706395881547000}", true},
  1253  		{"{}", true},
  1254  		{"{\"Key\":{\"Key\":{\"Key\":123}}}", true},
  1255  		{"[]", true},
  1256  		{"null", true},
  1257  	}
  1258  	for _, test := range tests {
  1259  		actual := IsJSON(test.param)
  1260  		if actual != test.expected {
  1261  			t.Errorf("Expected IsJSON(%q) to be %v, got %v", test.param, test.expected, actual)
  1262  		}
  1263  	}
  1264  }
  1265  
  1266  func TestIsMultibyte(t *testing.T) {
  1267  	t.Parallel()
  1268  
  1269  	var tests = []struct {
  1270  		param    string
  1271  		expected bool
  1272  	}{
  1273  		{"abc", false},
  1274  		{"123", false},
  1275  		{"<>@;.-=", false},
  1276  		{"ひらがな・カタカナ、.漢字", true},
  1277  		{"あいうえお foobar", true},
  1278  		{"test@example.com", true},
  1279  		{"test@example.com", true},
  1280  		{"1234abcDExyz", true},
  1281  		{"カタカナ", true},
  1282  		{"", true},
  1283  	}
  1284  	for _, test := range tests {
  1285  		actual := IsMultibyte(test.param)
  1286  		if actual != test.expected {
  1287  			t.Errorf("Expected IsMultibyte(%q) to be %v, got %v", test.param, test.expected, actual)
  1288  		}
  1289  	}
  1290  }
  1291  
  1292  func TestIsASCII(t *testing.T) {
  1293  	t.Parallel()
  1294  
  1295  	var tests = []struct {
  1296  		param    string
  1297  		expected bool
  1298  	}{
  1299  		{"", true},
  1300  		{"foobar", false},
  1301  		{"xyz098", false},
  1302  		{"123456", false},
  1303  		{"カタカナ", false},
  1304  		{"foobar", true},
  1305  		{"0987654321", true},
  1306  		{"test@example.com", true},
  1307  		{"1234abcDEF", true},
  1308  		{"", true},
  1309  	}
  1310  	for _, test := range tests {
  1311  		actual := IsASCII(test.param)
  1312  		if actual != test.expected {
  1313  			t.Errorf("Expected IsASCII(%q) to be %v, got %v", test.param, test.expected, actual)
  1314  		}
  1315  	}
  1316  }
  1317  
  1318  func TestIsPrintableASCII(t *testing.T) {
  1319  	t.Parallel()
  1320  
  1321  	var tests = []struct {
  1322  		param    string
  1323  		expected bool
  1324  	}{
  1325  		{"", true},
  1326  		{"foobar", false},
  1327  		{"xyz098", false},
  1328  		{"123456", false},
  1329  		{"カタカナ", false},
  1330  		{"foobar", true},
  1331  		{"0987654321", true},
  1332  		{"test@example.com", true},
  1333  		{"1234abcDEF", true},
  1334  		{"newline\n", false},
  1335  		{"\x19test\x7F", false},
  1336  	}
  1337  	for _, test := range tests {
  1338  		actual := IsPrintableASCII(test.param)
  1339  		if actual != test.expected {
  1340  			t.Errorf("Expected IsPrintableASCII(%q) to be %v, got %v", test.param, test.expected, actual)
  1341  		}
  1342  	}
  1343  }
  1344  
  1345  func TestIsFullWidth(t *testing.T) {
  1346  	t.Parallel()
  1347  
  1348  	var tests = []struct {
  1349  		param    string
  1350  		expected bool
  1351  	}{
  1352  		{"", true},
  1353  		{"abc", false},
  1354  		{"abc123", false},
  1355  		{"!\"#$%&()<>/+=-_? ~^|.,@`{}[]", false},
  1356  		{"ひらがな・カタカナ、.漢字", true},
  1357  		{"3ー0 a@com", true},
  1358  		{"Fカタカナ゙ᆲ", true},
  1359  		{"Good=Parts", true},
  1360  		{"", true},
  1361  	}
  1362  	for _, test := range tests {
  1363  		actual := IsFullWidth(test.param)
  1364  		if actual != test.expected {
  1365  			t.Errorf("Expected IsFullWidth(%q) to be %v, got %v", test.param, test.expected, actual)
  1366  		}
  1367  	}
  1368  }
  1369  
  1370  func TestIsHalfWidth(t *testing.T) {
  1371  	t.Parallel()
  1372  
  1373  	var tests = []struct {
  1374  		param    string
  1375  		expected bool
  1376  	}{
  1377  		{"", true},
  1378  		{"あいうえお", false},
  1379  		{"0011", false},
  1380  		{"!\"#$%&()<>/+=-_? ~^|.,@`{}[]", true},
  1381  		{"l-btn_02--active", true},
  1382  		{"abc123い", true},
  1383  		{"カタカナ゙ᆲ←", true},
  1384  		{"", true},
  1385  	}
  1386  	for _, test := range tests {
  1387  		actual := IsHalfWidth(test.param)
  1388  		if actual != test.expected {
  1389  			t.Errorf("Expected IsHalfWidth(%q) to be %v, got %v", test.param, test.expected, actual)
  1390  		}
  1391  	}
  1392  }
  1393  
  1394  func TestIsVariableWidth(t *testing.T) {
  1395  	t.Parallel()
  1396  
  1397  	var tests = []struct {
  1398  		param    string
  1399  		expected bool
  1400  	}{
  1401  		{"", true},
  1402  		{"ひらがなカタカナ漢字ABCDE", true},
  1403  		{"3ー0123", true},
  1404  		{"Fカタカナ゙ᆲ", true},
  1405  		{"", true},
  1406  		{"Good=Parts", true},
  1407  		{"abc", false},
  1408  		{"abc123", false},
  1409  		{"!\"#$%&()<>/+=-_? ~^|.,@`{}[]", false},
  1410  		{"ひらがな・カタカナ、.漢字", false},
  1411  		{"123456", false},
  1412  		{"カタカナ゙ᆲ", false},
  1413  	}
  1414  	for _, test := range tests {
  1415  		actual := IsVariableWidth(test.param)
  1416  		if actual != test.expected {
  1417  			t.Errorf("Expected IsVariableWidth(%q) to be %v, got %v", test.param, test.expected, actual)
  1418  		}
  1419  	}
  1420  }
  1421  
  1422  func TestIsUUID(t *testing.T) {
  1423  	t.Parallel()
  1424  
  1425  	// Tests without version
  1426  	var tests = []struct {
  1427  		param    string
  1428  		expected bool
  1429  	}{
  1430  		{"", false},
  1431  		{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  1432  		{"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
  1433  		{"a987fbc94bed3078cf079141ba07c9f3", false},
  1434  		{"934859", false},
  1435  		{"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false},
  1436  		{"aaaaaaaa-1111-1111-aaag-111111111111", false},
  1437  		{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
  1438  	}
  1439  	for _, test := range tests {
  1440  		actual := IsUUID(test.param)
  1441  		if actual != test.expected {
  1442  			t.Errorf("Expected IsUUID(%q) to be %v, got %v", test.param, test.expected, actual)
  1443  		}
  1444  	}
  1445  
  1446  	// UUID ver. 3
  1447  	tests = []struct {
  1448  		param    string
  1449  		expected bool
  1450  	}{
  1451  		{"", false},
  1452  		{"412452646", false},
  1453  		{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  1454  		{"a987fbc9-4bed-4078-8f07-9141ba07c9f3", false},
  1455  		{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
  1456  	}
  1457  	for _, test := range tests {
  1458  		actual := IsUUIDv3(test.param)
  1459  		if actual != test.expected {
  1460  			t.Errorf("Expected IsUUIDv3(%q) to be %v, got %v", test.param, test.expected, actual)
  1461  		}
  1462  	}
  1463  
  1464  	// UUID ver. 4
  1465  	tests = []struct {
  1466  		param    string
  1467  		expected bool
  1468  	}{
  1469  		{"", false},
  1470  		{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  1471  		{"a987fbc9-4bed-5078-af07-9141ba07c9f3", false},
  1472  		{"934859", false},
  1473  		{"57b73598-8764-4ad0-a76a-679bb6640eb1", true},
  1474  		{"625e63f3-58f5-40b7-83a1-a72ad31acffb", true},
  1475  	}
  1476  	for _, test := range tests {
  1477  		actual := IsUUIDv4(test.param)
  1478  		if actual != test.expected {
  1479  			t.Errorf("Expected IsUUIDv4(%q) to be %v, got %v", test.param, test.expected, actual)
  1480  		}
  1481  	}
  1482  
  1483  	// UUID ver. 5
  1484  	tests = []struct {
  1485  		param    string
  1486  		expected bool
  1487  	}{
  1488  
  1489  		{"", false},
  1490  		{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  1491  		{"9c858901-8a57-4791-81fe-4c455b099bc9", false},
  1492  		{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  1493  		{"987fbc97-4bed-5078-af07-9141ba07c9f3", true},
  1494  		{"987fbc97-4bed-5078-9f07-9141ba07c9f3", true},
  1495  	}
  1496  	for _, test := range tests {
  1497  		actual := IsUUIDv5(test.param)
  1498  		if actual != test.expected {
  1499  			t.Errorf("Expected IsUUIDv5(%q) to be %v, got %v", test.param, test.expected, actual)
  1500  		}
  1501  	}
  1502  }
  1503  
  1504  func TestIsULID(t *testing.T) {
  1505  	t.Parallel()
  1506  
  1507  	var tests = []struct {
  1508  		param    string
  1509  		expected bool
  1510  	}{
  1511  		{"", false},
  1512  		{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  1513  		{"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
  1514  		{"a987fbc94bed3078cf079141ba07c9f3", false},
  1515  		{"934859", false},
  1516  		{"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false},
  1517  		{"aaaaaaaa-1111-1111-aaag-111111111111", false},
  1518  		{"0000000000zzzzzzzzzzzzzzzz", true},
  1519  		{"0123456789zzzzzzzzzzzzzzzz", true},
  1520  		{"0123456789abcdefghjkmnpqrs", true},
  1521  		{"7zzzzzzzzzaaaaaaaaaaaaaaaa", true},
  1522  		{"7zanmkqfpyaaaaaaaaaaaaaaaa", true},
  1523  		{"7zanmkqfpyaaaaaaaaaaAAAAAA", true},
  1524  		{"8000000000zzzzzzzzzzzzzzzz", false},
  1525  		{"8000000001zzzzzzzzzzzzzzzz", false},
  1526  		{"8123456789zzzzzzzzzzzzzzzz", false},
  1527  		{"8123456789zzzzzzzzzzzzzzzL", false},
  1528  		{"8123456789zzzzzzzzzzzzzzzO", false},
  1529  		{"8123456789zzzzzzzzzzzzzzzu", false},
  1530  		{"8123456789zzzzzzzzzzzzzzzI", false},
  1531  	}
  1532  	for _, test := range tests {
  1533  		tc := test
  1534  		t.Run(fmt.Sprintf("%26.26s", tc.param), func(t *testing.T) {
  1535  			actual := IsULID(tc.param)
  1536  			if actual != tc.expected {
  1537  				t.Errorf("Expected IsULID(%q) to be %v, got %v", tc.param, tc.expected, actual)
  1538  			}
  1539  		})
  1540  	}
  1541  }
  1542  
  1543  func TestIsCreditCard(t *testing.T) {
  1544  	t.Parallel()
  1545  	tests := []struct {
  1546  		name   string
  1547  		number string
  1548  		want   bool
  1549  	}{
  1550  		{"empty", "", false},
  1551  		{"not numbers", "credit card", false},
  1552  		{"invalid luhn algorithm", "4220855426213389", false},
  1553  
  1554  		{"visa", "4220855426222389", true},
  1555  		{"visa spaces", "4220 8554 2622 2389", true},
  1556  		{"visa dashes", "4220-8554-2622-2389", true},
  1557  		{"mastercard", "5139288802098206", true},
  1558  		{"american express", "374953669708156", true},
  1559  		{"discover", "6011464355444102", true},
  1560  		{"jcb", "3548209662790989", true},
  1561  
  1562  		// below should be valid, do they respect international standards?
  1563  		// is our validator logic not correct?
  1564  		{"diners club international", "30190239451016", false},
  1565  		{"rupay", "6521674451993089", false},
  1566  		{"mir", "2204151414444676", false},
  1567  		{"china unionPay", "624356436327468104", false},
  1568  	}
  1569  	for _, tt := range tests {
  1570  		t.Run(tt.name, func(t *testing.T) {
  1571  			if got := IsCreditCard(tt.number); got != tt.want {
  1572  				t.Errorf("IsCreditCard(%v) = %v, want %v", tt.number, got, tt.want)
  1573  			}
  1574  		})
  1575  	}
  1576  }
  1577  
  1578  func TestIsISBN(t *testing.T) {
  1579  	t.Parallel()
  1580  
  1581  	// Without version
  1582  	var tests = []struct {
  1583  		param    string
  1584  		expected bool
  1585  	}{
  1586  		{"", false},
  1587  		{"foo", false},
  1588  		{"3836221195", true},
  1589  		{"1-61729-085-8", true},
  1590  		{"3 423 21412 0", true},
  1591  		{"3 401 01319 X", true},
  1592  		{"9784873113685", true},
  1593  		{"978-4-87311-368-5", true},
  1594  		{"978 3401013190", true},
  1595  		{"978-3-8362-2119-1", true},
  1596  	}
  1597  	for _, test := range tests {
  1598  		actual := IsISBN(test.param, -1)
  1599  		if actual != test.expected {
  1600  			t.Errorf("Expected IsISBN(%q, -1) to be %v, got %v", test.param, test.expected, actual)
  1601  		}
  1602  	}
  1603  
  1604  	// ISBN 10
  1605  	tests = []struct {
  1606  		param    string
  1607  		expected bool
  1608  	}{
  1609  		{"", false},
  1610  		{"foo", false},
  1611  		{"3423214121", false},
  1612  		{"978-3836221191", false},
  1613  		{"3-423-21412-1", false},
  1614  		{"3 423 21412 1", false},
  1615  		{"3836221195", true},
  1616  		{"1-61729-085-8", true},
  1617  		{"3 423 21412 0", true},
  1618  		{"3 401 01319 X", true},
  1619  	}
  1620  	for _, test := range tests {
  1621  		actual := IsISBN10(test.param)
  1622  		if actual != test.expected {
  1623  			t.Errorf("Expected IsISBN10(%q) to be %v, got %v", test.param, test.expected, actual)
  1624  		}
  1625  	}
  1626  
  1627  	// ISBN 13
  1628  	tests = []struct {
  1629  		param    string
  1630  		expected bool
  1631  	}{
  1632  		{"", false},
  1633  		{"foo", false},
  1634  		{"3-8362-2119-5", false},
  1635  		{"01234567890ab", false},
  1636  		{"978 3 8362 2119 0", false},
  1637  		{"9784873113685", true},
  1638  		{"978-4-87311-368-5", true},
  1639  		{"978 3401013190", true},
  1640  		{"978-3-8362-2119-1", true},
  1641  	}
  1642  	for _, test := range tests {
  1643  		actual := IsISBN13(test.param)
  1644  		if actual != test.expected {
  1645  			t.Errorf("Expected IsISBN13(%q) to be %v, got %v", test.param, test.expected, actual)
  1646  		}
  1647  	}
  1648  }
  1649  
  1650  func TestIsDataURI(t *testing.T) {
  1651  	t.Parallel()
  1652  
  1653  	var tests = []struct {
  1654  		param    string
  1655  		expected bool
  1656  	}{
  1657  		{"data:image/png;base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true},
  1658  		{"data:text/plain;base64,Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true},
  1659  		{"image/gif;base64,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false},
  1660  		{"data:image/gif;base64,MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" +
  1661  			"UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" +
  1662  			"rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" +
  1663  			"FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" +
  1664  			"QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" +
  1665  			"Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true},
  1666  		{"data:image/png;base64,12345", false},
  1667  		{"", false},
  1668  		{"data:text,:;base85,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false},
  1669  	}
  1670  	for _, test := range tests {
  1671  		actual := IsDataURI(test.param)
  1672  		if actual != test.expected {
  1673  			t.Errorf("Expected IsDataURI(%q) to be %v, got %v", test.param, test.expected, actual)
  1674  		}
  1675  	}
  1676  }
  1677  
  1678  func TestIsMagnetURI(t *testing.T) {
  1679  	t.Parallel()
  1680  
  1681  	var tests = []struct {
  1682  		param    string
  1683  		expected bool
  1684  	}{
  1685  		{"magnet:?xt=urn:btih:06E2A9683BF4DA92C73A661AC56F0ECC9C63C5B4&dn=helloword2000&tr=udp://helloworld:1337/announce", true},
  1686  		{"magnet:?xt=urn:btih:3E30322D5BFC7444B7B1D8DD42404B75D0531DFB&dn=world&tr=udp://world.com:1337", true},
  1687  		{"magnet:?xt=urn:btih:4ODKSDJBVMSDSNJVBCBFYFBKNRU875DW8D97DWC6&dn=helloworld&tr=udp://helloworld.com:1337", true},
  1688  		{"magnet:?xt=urn:btih:1GSHJVBDVDVJFYEHKFHEFIO8573898434JBFEGHD&dn=foo&tr=udp://foo.com:1337", true},
  1689  		{"magnet:?xt=urn:btih:MCJDCYUFHEUD6E2752T7UJNEKHSUGEJFGTFHVBJS&dn=bar&tr=udp://bar.com:1337", true},
  1690  		{"magnet:?xt=urn:btih:LAKDHWDHEBFRFVUFJENBYYTEUY837562JH2GEFYH&dn=foobar&tr=udp://foobar.com:1337", true},
  1691  		{"magnet:?xt=urn:btih:MKCJBHCBJDCU725TGEB3Y6RE8EJ2U267UNJFGUID&dn=test&tr=udp://test.com:1337", true},
  1692  		{"magnet:?xt=urn:btih:UHWY2892JNEJ2GTEYOMDNU67E8ICGICYE92JDUGH&dn=baz&tr=udp://baz.com:1337", true},
  1693  		{"magnet:?xt=urn:btih:HS263FG8U3GFIDHWD7829BYFCIXB78XIHG7CWCUG&dn=foz&tr=udp://foz.com:1337", true},
  1694  		{"", false},
  1695  		{":?xt=urn:btih:06E2A9683BF4DA92C73A661AC56F0ECC9C63C5B4&dn=helloword2000&tr=udp://helloworld:1337/announce", false},
  1696  		{"magnett:?xt=urn:btih:3E30322D5BFC7444B7B1D8DD42404B75D0531DFB&dn=world&tr=udp://world.com:1337", false},
  1697  		{"xt=urn:btih:4ODKSDJBVMSDSNJVBCBFYFBKNRU875DW8D97DWC6&dn=helloworld&tr=udp://helloworld.com:1337", false},
  1698  		{"magneta:?xt=urn:btih:1GSHJVBDVDVJFYEHKFHEFIO8573898434JBFEGHD&dn=foo&tr=udp://foo.com:1337", false},
  1699  		{"magnet:?xt=uarn:btih:MCJDCYUFHEUD6E2752T7UJNEKHSUGEJFGTFHVBJS&dn=bar&tr=udp://bar.com:1337", false},
  1700  		{"magnet:?xt=urn:btihz&dn=foobar&tr=udp://foobar.com:1337", false},
  1701  		{"magnet:?xat=urn:btih:MKCJBHCBJDCU725TGEB3Y6RE8EJ2U267UNJFGUID&dn=test&tr=udp://test.com:1337", false},
  1702  		{"magnet::?xt=urn:btih:UHWY2892JNEJ2GTEYOMDNU67E8ICGICYE92JDUGH&dn=baz&tr=udp://baz.com:1337", false},
  1703  		{"magnet:?xt:btih:HS263FG8U3GFIDHWD7829BYFCIXB78XIHG7CWCUG&dn=foz&tr=udp://foz.com:1337", false},
  1704  	}
  1705  	for _, test := range tests {
  1706  		actual := IsMagnetURI(test.param)
  1707  		if actual != test.expected {
  1708  			t.Errorf("Expected IsMagnetURI(%q) to be %v, got %v", test.param, test.expected, actual)
  1709  		}
  1710  	}
  1711  }
  1712  
  1713  func TestIsBase64(t *testing.T) {
  1714  	t.Parallel()
  1715  
  1716  	var tests = []struct {
  1717  		param    string
  1718  		expected bool
  1719  	}{
  1720  		{"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true},
  1721  		{"Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true},
  1722  		{"U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", true},
  1723  		{"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" +
  1724  			"UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" +
  1725  			"rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" +
  1726  			"FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" +
  1727  			"QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" +
  1728  			"Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true},
  1729  		{"12345", false},
  1730  		{"", false},
  1731  		{"Vml2YW11cyBmZXJtZtesting123", false},
  1732  	}
  1733  	for _, test := range tests {
  1734  		actual := IsBase64(test.param)
  1735  		if actual != test.expected {
  1736  			t.Errorf("Expected IsBase64(%q) to be %v, got %v", test.param, test.expected, actual)
  1737  		}
  1738  	}
  1739  }
  1740  
  1741  func TestIsISO3166Alpha2(t *testing.T) {
  1742  	t.Parallel()
  1743  
  1744  	var tests = []struct {
  1745  		param    string
  1746  		expected bool
  1747  	}{
  1748  		{"", false},
  1749  		{"ABCD", false},
  1750  		{"A", false},
  1751  		{"AC", false},
  1752  		{"AP", false},
  1753  		{"GER", false},
  1754  		{"NU", true},
  1755  		{"DE", true},
  1756  		{"JP", true},
  1757  		{"JPN", false},
  1758  		{"ZWE", false},
  1759  		{"GER", false},
  1760  		{"DEU", false},
  1761  	}
  1762  	for _, test := range tests {
  1763  		actual := IsISO3166Alpha2(test.param)
  1764  		if actual != test.expected {
  1765  			t.Errorf("Expected IsISO3166Alpha2(%q) to be %v, got %v", test.param, test.expected, actual)
  1766  		}
  1767  	}
  1768  }
  1769  
  1770  func TestIsISO3166Alpha3(t *testing.T) {
  1771  	t.Parallel()
  1772  
  1773  	var tests = []struct {
  1774  		param    string
  1775  		expected bool
  1776  	}{
  1777  		{"", false},
  1778  		{"ABCD", false},
  1779  		{"A", false},
  1780  		{"AC", false},
  1781  		{"AP", false},
  1782  		{"NU", false},
  1783  		{"DE", false},
  1784  		{"JP", false},
  1785  		{"ZWE", true},
  1786  		{"JPN", true},
  1787  		{"GER", false},
  1788  		{"DEU", true},
  1789  	}
  1790  	for _, test := range tests {
  1791  		actual := IsISO3166Alpha3(test.param)
  1792  		if actual != test.expected {
  1793  			t.Errorf("Expected IsISO3166Alpha3(%q) to be %v, got %v", test.param, test.expected, actual)
  1794  		}
  1795  	}
  1796  }
  1797  
  1798  func TestIsISO693Alpha2(t *testing.T) {
  1799  	t.Parallel()
  1800  
  1801  	var tests = []struct {
  1802  		param    string
  1803  		expected bool
  1804  	}{
  1805  		{"", false},
  1806  		{"abcd", false},
  1807  		{"a", false},
  1808  		{"ac", false},
  1809  		{"ap", false},
  1810  		{"de", true},
  1811  		{"DE", false},
  1812  		{"mk", true},
  1813  		{"mac", false},
  1814  		{"sw", true},
  1815  		{"SW", false},
  1816  		{"ger", false},
  1817  		{"deu", false},
  1818  	}
  1819  	for _, test := range tests {
  1820  		actual := IsISO693Alpha2(test.param)
  1821  		if actual != test.expected {
  1822  			t.Errorf("Expected IsISO693Alpha2(%q) to be %v, got %v", test.param, test.expected, actual)
  1823  		}
  1824  	}
  1825  }
  1826  
  1827  func TestIsISO693Alpha3b(t *testing.T) {
  1828  	t.Parallel()
  1829  
  1830  	var tests = []struct {
  1831  		param    string
  1832  		expected bool
  1833  	}{
  1834  		{"", false},
  1835  		{"abcd", false},
  1836  		{"a", false},
  1837  		{"ac", false},
  1838  		{"ap", false},
  1839  		{"de", false},
  1840  		{"DE", false},
  1841  		{"mkd", false},
  1842  		{"mac", true},
  1843  		{"sw", false},
  1844  		{"SW", false},
  1845  		{"ger", true},
  1846  		{"deu", false},
  1847  	}
  1848  	for _, test := range tests {
  1849  		actual := IsISO693Alpha3b(test.param)
  1850  		if actual != test.expected {
  1851  			t.Errorf("Expected IsISO693Alpha3b(%q) to be %v, got %v", test.param, test.expected, actual)
  1852  		}
  1853  	}
  1854  }
  1855  
  1856  func TestIsIP(t *testing.T) {
  1857  	t.Parallel()
  1858  
  1859  	// Without version
  1860  	var tests = []struct {
  1861  		param    string
  1862  		expected bool
  1863  	}{
  1864  		{"", false},
  1865  		{"127.0.0.1", true},
  1866  		{"0.0.0.0", true},
  1867  		{"255.255.255.255", true},
  1868  		{"1.2.3.4", true},
  1869  		{"::1", true},
  1870  		{"2001:db8:0000:1:1:1:1:1", true},
  1871  		{"300.0.0.0", false},
  1872  	}
  1873  	for _, test := range tests {
  1874  		actual := IsIP(test.param)
  1875  		if actual != test.expected {
  1876  			t.Errorf("Expected IsIP(%q) to be %v, got %v", test.param, test.expected, actual)
  1877  		}
  1878  	}
  1879  
  1880  	// IPv4
  1881  	tests = []struct {
  1882  		param    string
  1883  		expected bool
  1884  	}{
  1885  		{"", false},
  1886  		{"127.0.0.1", true},
  1887  		{"0.0.0.0", true},
  1888  		{"255.255.255.255", true},
  1889  		{"1.2.3.4", true},
  1890  		{"::1", false},
  1891  		{"2001:db8:0000:1:1:1:1:1", false},
  1892  		{"300.0.0.0", false},
  1893  	}
  1894  	for _, test := range tests {
  1895  		actual := IsIPv4(test.param)
  1896  		if actual != test.expected {
  1897  			t.Errorf("Expected IsIPv4(%q) to be %v, got %v", test.param, test.expected, actual)
  1898  		}
  1899  	}
  1900  
  1901  	// IPv6
  1902  	tests = []struct {
  1903  		param    string
  1904  		expected bool
  1905  	}{
  1906  		{"", false},
  1907  		{"127.0.0.1", false},
  1908  		{"0.0.0.0", false},
  1909  		{"255.255.255.255", false},
  1910  		{"1.2.3.4", false},
  1911  		{"::1", true},
  1912  		{"2001:db8:0000:1:1:1:1:1", true},
  1913  		{"300.0.0.0", false},
  1914  	}
  1915  	for _, test := range tests {
  1916  		actual := IsIPv6(test.param)
  1917  		if actual != test.expected {
  1918  			t.Errorf("Expected IsIPv6(%q) to be %v, got %v", test.param, test.expected, actual)
  1919  		}
  1920  	}
  1921  }
  1922  
  1923  func TestIsPort(t *testing.T) {
  1924  	t.Parallel()
  1925  
  1926  	var tests = []struct {
  1927  		param    string
  1928  		expected bool
  1929  	}{
  1930  		{"1", true},
  1931  		{"65535", true},
  1932  		{"0", false},
  1933  		{"65536", false},
  1934  		{"65538", false},
  1935  	}
  1936  
  1937  	for _, test := range tests {
  1938  		actual := IsPort(test.param)
  1939  		if actual != test.expected {
  1940  			t.Errorf("Expected IsPort(%q) to be %v, got %v", test.param, test.expected, actual)
  1941  		}
  1942  	}
  1943  }
  1944  
  1945  func TestIsDNSName(t *testing.T) {
  1946  	t.Parallel()
  1947  
  1948  	var tests = []struct {
  1949  		param    string
  1950  		expected bool
  1951  	}{
  1952  		{"localhost", true},
  1953  		{"a.bc", true},
  1954  		{"a.b.", true},
  1955  		{"a.b..", false},
  1956  		{"localhost.local", true},
  1957  		{"localhost.localdomain.intern", true},
  1958  		{"l.local.intern", true},
  1959  		{"ru.link.n.svpncloud.com", true},
  1960  		{"-localhost", false},
  1961  		{"localhost.-localdomain", false},
  1962  		{"localhost.localdomain.-int", false},
  1963  		{"_localhost", true},
  1964  		{"localhost._localdomain", true},
  1965  		{"localhost.localdomain._int", true},
  1966  		{"lÖcalhost", false},
  1967  		{"localhost.lÖcaldomain", false},
  1968  		{"localhost.localdomain.üntern", false},
  1969  		{"__", true},
  1970  		{"localhost/", false},
  1971  		{"127.0.0.1", false},
  1972  		{"[::1]", false},
  1973  		{"50.50.50.50", false},
  1974  		{"localhost.localdomain.intern:65535", false},
  1975  		{"漢字汉字", false},
  1976  		{"www.jubfvq1v3p38i51622y0dvmdk1mymowjyeu26gbtw9andgynj1gg8z3msb1kl5z6906k846pj3sulm4kiyk82ln5teqj9nsht59opr0cs5ssltx78lfyvml19lfq1wp4usbl0o36cmiykch1vywbttcus1p9yu0669h8fj4ll7a6bmop505908s1m83q2ec2qr9nbvql2589adma3xsq2o38os2z3dmfh2tth4is4ixyfasasasefqwe4t2ub2fz1rme.de", false},
  1977  	}
  1978  
  1979  	for _, test := range tests {
  1980  		actual := IsDNSName(test.param)
  1981  		if actual != test.expected {
  1982  			t.Errorf("Expected IsDNS(%q) to be %v, got %v", test.param, test.expected, actual)
  1983  		}
  1984  	}
  1985  }
  1986  
  1987  func TestIsHost(t *testing.T) {
  1988  	t.Parallel()
  1989  	var tests = []struct {
  1990  		param    string
  1991  		expected bool
  1992  	}{
  1993  		{"localhost", true},
  1994  		{"localhost.localdomain", true},
  1995  		{"2001:db8:0000:1:1:1:1:1", true},
  1996  		{"::1", true},
  1997  		{"play.golang.org", true},
  1998  		{"localhost.localdomain.intern:65535", false},
  1999  		{"-[::1]", false},
  2000  		{"-localhost", false},
  2001  		{".localhost", false},
  2002  	}
  2003  	for _, test := range tests {
  2004  		actual := IsHost(test.param)
  2005  		if actual != test.expected {
  2006  			t.Errorf("Expected IsHost(%q) to be %v, got %v", test.param, test.expected, actual)
  2007  		}
  2008  	}
  2009  
  2010  }
  2011  
  2012  func TestIsDialString(t *testing.T) {
  2013  	t.Parallel()
  2014  
  2015  	var tests = []struct {
  2016  		param    string
  2017  		expected bool
  2018  	}{
  2019  		{"localhost.local:1", true},
  2020  		{"localhost.localdomain:9090", true},
  2021  		{"localhost.localdomain.intern:65535", true},
  2022  		{"127.0.0.1:30000", true},
  2023  		{"[::1]:80", true},
  2024  		{"[1200::AB00:1234::2552:7777:1313]:22", false},
  2025  		{"-localhost:1", false},
  2026  		{"localhost.-localdomain:9090", false},
  2027  		{"localhost.localdomain.-int:65535", false},
  2028  		{"localhost.loc:100000", false},
  2029  		{"漢字汉字:2", false},
  2030  		{"www.jubfvq1v3p38i51622y0dvmdk1mymowjyeu26gbtw9andgynj1gg8z3msb1kl5z6906k846pj3sulm4kiyk82ln5teqj9nsht59opr0cs5ssltx78lfyvml19lfq1wp4usbl0o36cmiykch1vywbttcus1p9yu0669h8fj4ll7a6bmop505908s1m83q2ec2qr9nbvql2589adma3xsq2o38os2z3dmfh2tth4is4ixyfasasasefqwe4t2ub2fz1rme.de:20000", false},
  2031  	}
  2032  
  2033  	for _, test := range tests {
  2034  		actual := IsDialString(test.param)
  2035  		if actual != test.expected {
  2036  			t.Errorf("Expected IsDialString(%q) to be %v, got %v", test.param, test.expected, actual)
  2037  		}
  2038  	}
  2039  }
  2040  
  2041  func TestIsMAC(t *testing.T) {
  2042  	t.Parallel()
  2043  
  2044  	var tests = []struct {
  2045  		param    string
  2046  		expected bool
  2047  	}{
  2048  		{"3D:F2:C9:A6:B3:4F", true},
  2049  		{"3D-F2-C9-A6-B3:4F", false},
  2050  		{"123", false},
  2051  		{"", false},
  2052  		{"abacaba", false},
  2053  	}
  2054  	for _, test := range tests {
  2055  		actual := IsMAC(test.param)
  2056  		if actual != test.expected {
  2057  			t.Errorf("Expected IsMAC(%q) to be %v, got %v", test.param, test.expected, actual)
  2058  		}
  2059  	}
  2060  }
  2061  
  2062  func TestFilePath(t *testing.T) {
  2063  	t.Parallel()
  2064  
  2065  	var tests = []struct {
  2066  		param    string
  2067  		expected bool
  2068  		osType   int
  2069  	}{
  2070  		{"c:\\" + strings.Repeat("a", 32767), true, Win}, //See http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
  2071  		{"c:\\" + strings.Repeat("a", 32768), false, Win},
  2072  		{"c:\\path\\file (x86)\bar", true, Win},
  2073  		{"c:\\path\\file", true, Win},
  2074  		{"c:\\path\\file:exe", false, Unknown},
  2075  		{"C:\\", true, Win},
  2076  		{"c:\\path\\file\\", true, Win},
  2077  		{"c:/path/file/", false, Unknown},
  2078  		{"/path/file/", true, Unix},
  2079  		{"/path/file:SAMPLE/", true, Unix},
  2080  		{"/path/file:/.txt", true, Unix},
  2081  		{"/path", true, Unix},
  2082  		{"/path/__bc/file.txt", true, Unix},
  2083  		{"/path/a--ac/file.txt", true, Unix},
  2084  		{"/_path/file.txt", true, Unix},
  2085  		{"/path/__bc/file.txt", true, Unix},
  2086  		{"/path/a--ac/file.txt", true, Unix},
  2087  		{"/__path/--file.txt", true, Unix},
  2088  		{"/path/a bc", true, Unix},
  2089  	}
  2090  	for _, test := range tests {
  2091  		actual, osType := IsFilePath(test.param)
  2092  		if actual != test.expected || osType != test.osType {
  2093  			t.Errorf("Expected IsFilePath(%q) to be %v, got %v", test.param, test.expected, actual)
  2094  		}
  2095  	}
  2096  }
  2097  
  2098  func TestIsWinFilePath(t *testing.T) {
  2099  	t.Parallel()
  2100  
  2101  	var tests = []struct {
  2102  		param    string
  2103  		expected bool
  2104  	}{
  2105  		{"c:\\" + strings.Repeat("a", 32767), true}, //See http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
  2106  		{"c:\\" + strings.Repeat("a", 32768), false},
  2107  		{"c:\\path\\file (x86)\\bar", true},
  2108  		{"c:\\path\\file", true},
  2109  		{"c:\\path\\file:exe", false},
  2110  		{"C:\\", true},
  2111  		{"c:\\path\\file\\", true},
  2112  		{"..\\path\\file\\", true},
  2113  		{"c:/path/file/", false},
  2114  		{"a bc", true},
  2115  		{"abc.jd", true},
  2116  		{"abc.jd:$#%# dsd", false},
  2117  	}
  2118  	for _, test := range tests {
  2119  		actual := IsWinFilePath(test.param)
  2120  		if actual != test.expected {
  2121  			t.Errorf("Expected IsWinFilePath(%q) to be %v, got %v", test.param, test.expected, actual)
  2122  		}
  2123  	}
  2124  }
  2125  
  2126  func TestIsUnixFilePath(t *testing.T) {
  2127  	t.Parallel()
  2128  
  2129  	var tests = []struct {
  2130  		param    string
  2131  		expected bool
  2132  	}{
  2133  		{"c:/path/file/", true},    //relative path
  2134  		{"../path/file/", true},    //relative path
  2135  		{"../../path/file/", true}, //relative path
  2136  		{"./path/file/", true},     //relative path
  2137  		{"./file.dghdg", true},     //relative path
  2138  		{"/path/file/", true},
  2139  		{"/path/file:SAMPLE/", true},
  2140  		{"/path/file:/.txt", true},
  2141  		{"/path", true},
  2142  		{"/path/__bc/file.txt", true},
  2143  		{"/path/a--ac/file.txt", true},
  2144  		{"/_path/file.txt", true},
  2145  		{"/path/__bc/file.txt", true},
  2146  		{"/path/a--ac/file.txt", true},
  2147  		{"/__path/--file.txt", true},
  2148  		{"/path/a bc", true},
  2149  		{"a bc", true},
  2150  		{"abc.jd", true},
  2151  		{"abc.jd:$#%# dsd", true},
  2152  	}
  2153  	for _, test := range tests {
  2154  		actual := IsUnixFilePath(test.param)
  2155  		if actual != test.expected {
  2156  			t.Errorf("Expected IsUnixFilePath(%q) to be %v, got %v", test.param, test.expected, actual)
  2157  		}
  2158  	}
  2159  }
  2160  
  2161  func TestIsLatitude(t *testing.T) {
  2162  	t.Parallel()
  2163  
  2164  	var tests = []struct {
  2165  		param    string
  2166  		expected bool
  2167  	}{
  2168  		{"", false},
  2169  		{"-90.000", true},
  2170  		{"+90", true},
  2171  		{"47.1231231", true},
  2172  		{"+99.9", false},
  2173  		{"108", false},
  2174  	}
  2175  	for _, test := range tests {
  2176  		actual := IsLatitude(test.param)
  2177  		if actual != test.expected {
  2178  			t.Errorf("Expected IsLatitude(%q) to be %v, got %v", test.param, test.expected, actual)
  2179  		}
  2180  	}
  2181  }
  2182  
  2183  func TestIsLongitude(t *testing.T) {
  2184  	t.Parallel()
  2185  
  2186  	var tests = []struct {
  2187  		param    string
  2188  		expected bool
  2189  	}{
  2190  		{"", false},
  2191  		{"-180.000", true},
  2192  		{"180.1", false},
  2193  		{"+73.234", true},
  2194  		{"+382.3811", false},
  2195  		{"23.11111111", true},
  2196  	}
  2197  	for _, test := range tests {
  2198  		actual := IsLongitude(test.param)
  2199  		if actual != test.expected {
  2200  			t.Errorf("Expected IsLongitude(%q) to be %v, got %v", test.param, test.expected, actual)
  2201  		}
  2202  	}
  2203  }
  2204  
  2205  func TestIsSSN(t *testing.T) {
  2206  	t.Parallel()
  2207  
  2208  	var tests = []struct {
  2209  		param    string
  2210  		expected bool
  2211  	}{
  2212  		{"", false},
  2213  		{"00-90-8787", false},
  2214  		{"66690-76", false},
  2215  		{"191 60 2869", true},
  2216  		{"191-60-2869", true},
  2217  	}
  2218  	for _, test := range tests {
  2219  		actual := IsSSN(test.param)
  2220  		if actual != test.expected {
  2221  			t.Errorf("Expected IsSSN(%q) to be %v, got %v", test.param, test.expected, actual)
  2222  		}
  2223  	}
  2224  }
  2225  
  2226  func TestIsMongoID(t *testing.T) {
  2227  	t.Parallel()
  2228  
  2229  	var tests = []struct {
  2230  		param    string
  2231  		expected bool
  2232  	}{
  2233  		{"507f1f77bcf86cd799439011", true},
  2234  		{"507f1f77bcf86cd7994390", false},
  2235  		{"507f1f77bcf86cd79943901z", false},
  2236  		{"507f1f77bcf86cd799439011 ", false},
  2237  		{"", false},
  2238  	}
  2239  	for _, test := range tests {
  2240  		actual := IsMongoID(test.param)
  2241  		if actual != test.expected {
  2242  			t.Errorf("Expected IsMongoID(%q) to be %v, got %v", test.param, test.expected, actual)
  2243  		}
  2244  	}
  2245  }
  2246  
  2247  func TestIsSemver(t *testing.T) {
  2248  	t.Parallel()
  2249  	var tests = []struct {
  2250  		param    string
  2251  		expected bool
  2252  	}{
  2253  		{"v1.0.0", true},
  2254  		{"1.0.0", true},
  2255  		{"1.1.01", false},
  2256  		{"1.01.0", false},
  2257  		{"01.1.0", false},
  2258  		{"v1.1.01", false},
  2259  		{"v1.01.0", false},
  2260  		{"v01.1.0", false},
  2261  		{"1.0.0-alpha", true},
  2262  		{"1.0.0-alpha.1", true},
  2263  		{"1.0.0-0.3.7", true},
  2264  		{"1.0.0-0.03.7", false},
  2265  		{"1.0.0-00.3.7", false},
  2266  		{"1.0.0-x.7.z.92", true},
  2267  		{"1.0.0-alpha+001", true},
  2268  		{"1.0.0+20130313144700", true},
  2269  		{"1.0.0-beta+exp.sha.5114f85", true},
  2270  		{"1.0.0-beta+exp.sha.05114f85", true},
  2271  		{"1.0.0-+beta", false},
  2272  		{"1.0.0-b+-9+eta", false},
  2273  		{"v+1.8.0-b+-9+eta", false},
  2274  	}
  2275  	for _, test := range tests {
  2276  		actual := IsSemver(test.param)
  2277  		if actual != test.expected {
  2278  			t.Errorf("Expected IsSemver(%q) to be %v, got %v", test.param, test.expected, actual)
  2279  		}
  2280  	}
  2281  }
  2282  
  2283  func TestIsTime(t *testing.T) {
  2284  	t.Parallel()
  2285  	var tests = []struct {
  2286  		param    string
  2287  		format   string
  2288  		expected bool
  2289  	}{
  2290  		{"2016-12-31 11:00", time.RFC3339, false},
  2291  		{"2016-12-31 11:00:00", time.RFC3339, false},
  2292  		{"2016-12-31T11:00", time.RFC3339, false},
  2293  		{"2016-12-31T11:00:00", time.RFC3339, false},
  2294  		{"2016-12-31T11:00:00Z", time.RFC3339, true},
  2295  		{"2016-12-31T11:00:00+01:00", time.RFC3339, true},
  2296  		{"2016-12-31T11:00:00-01:00", time.RFC3339, true},
  2297  		{"2016-12-31T11:00:00.05Z", time.RFC3339, true},
  2298  		{"2016-12-31T11:00:00.05-01:00", time.RFC3339, true},
  2299  		{"2016-12-31T11:00:00.05+01:00", time.RFC3339, true},
  2300  		{"2016-12-31T11:00:00", rfc3339WithoutZone, true},
  2301  		{"2016-12-31T11:00:00Z", rfc3339WithoutZone, false},
  2302  		{"2016-12-31T11:00:00+01:00", rfc3339WithoutZone, false},
  2303  		{"2016-12-31T11:00:00-01:00", rfc3339WithoutZone, false},
  2304  		{"2016-12-31T11:00:00.05Z", rfc3339WithoutZone, false},
  2305  		{"2016-12-31T11:00:00.05-01:00", rfc3339WithoutZone, false},
  2306  		{"2016-12-31T11:00:00.05+01:00", rfc3339WithoutZone, false},
  2307  	}
  2308  	for _, test := range tests {
  2309  		actual := IsTime(test.param, test.format)
  2310  		if actual != test.expected {
  2311  			t.Errorf("Expected IsTime(%q, time.RFC3339) to be %v, got %v", test.param, test.expected, actual)
  2312  		}
  2313  	}
  2314  }
  2315  
  2316  func TestIsRFC3339(t *testing.T) {
  2317  	t.Parallel()
  2318  	var tests = []struct {
  2319  		param    string
  2320  		expected bool
  2321  	}{
  2322  		{"2016-12-31 11:00", false},
  2323  		{"2016-12-31 11:00:00", false},
  2324  		{"2016-12-31T11:00", false},
  2325  		{"2016-12-31T11:00:00", false},
  2326  		{"2016-12-31T11:00:00Z", true},
  2327  		{"2016-12-31T11:00:00+01:00", true},
  2328  		{"2016-12-31T11:00:00-01:00", true},
  2329  		{"2016-12-31T11:00:00.05Z", true},
  2330  		{"2016-12-31T11:00:00.05-01:00", true},
  2331  		{"2016-12-31T11:00:00.05+01:00", true},
  2332  	}
  2333  	for _, test := range tests {
  2334  		actual := IsRFC3339(test.param)
  2335  		if actual != test.expected {
  2336  			t.Errorf("Expected IsRFC3339(%q) to be %v, got %v", test.param, test.expected, actual)
  2337  		}
  2338  	}
  2339  }
  2340  
  2341  func TestIsISO4217(t *testing.T) {
  2342  	t.Parallel()
  2343  
  2344  	var tests = []struct {
  2345  		param    string
  2346  		expected bool
  2347  	}{
  2348  		{"", false},
  2349  		{"ABCD", false},
  2350  		{"A", false},
  2351  		{"ZZZ", false},
  2352  		{"usd", false},
  2353  		{"USD", true},
  2354  	}
  2355  	for _, test := range tests {
  2356  		actual := IsISO4217(test.param)
  2357  		if actual != test.expected {
  2358  			t.Errorf("Expected IsISO4217(%q) to be %v, got %v", test.param, test.expected, actual)
  2359  		}
  2360  	}
  2361  }
  2362  
  2363  func TestByteLength(t *testing.T) {
  2364  	t.Parallel()
  2365  
  2366  	var tests = []struct {
  2367  		value    string
  2368  		min      string
  2369  		max      string
  2370  		expected bool
  2371  	}{
  2372  		{"123456", "0", "100", true},
  2373  		{"1239999", "0", "0", false},
  2374  		{"1239asdfasf99", "100", "200", false},
  2375  		{"1239999asdff29", "10", "30", true},
  2376  		{"你", "0", "1", false},
  2377  	}
  2378  	for _, test := range tests {
  2379  		actual := ByteLength(test.value, test.min, test.max)
  2380  		if actual != test.expected {
  2381  			t.Errorf("Expected ByteLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual)
  2382  		}
  2383  	}
  2384  }
  2385  
  2386  func TestRuneLength(t *testing.T) {
  2387  	t.Parallel()
  2388  
  2389  	var tests = []struct {
  2390  		value    string
  2391  		min      string
  2392  		max      string
  2393  		expected bool
  2394  	}{
  2395  		{"123456", "0", "100", true},
  2396  		{"1239999", "0", "0", false},
  2397  		{"1239asdfasf99", "100", "200", false},
  2398  		{"1239999asdff29", "10", "30", true},
  2399  		{"你", "0", "1", true},
  2400  	}
  2401  	for _, test := range tests {
  2402  		actual := RuneLength(test.value, test.min, test.max)
  2403  		if actual != test.expected {
  2404  			t.Errorf("Expected RuneLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual)
  2405  		}
  2406  	}
  2407  }
  2408  
  2409  func TestStringLength(t *testing.T) {
  2410  	t.Parallel()
  2411  
  2412  	var tests = []struct {
  2413  		value    string
  2414  		min      string
  2415  		max      string
  2416  		expected bool
  2417  	}{
  2418  		{"123456", "0", "100", true},
  2419  		{"1239999", "0", "0", false},
  2420  		{"1239asdfasf99", "100", "200", false},
  2421  		{"1239999asdff29", "10", "30", true},
  2422  		{"あいうえお", "0", "5", true},
  2423  		{"あいうえおか", "0", "5", false},
  2424  		{"あいうえお", "0", "0", false},
  2425  		{"あいうえ", "5", "10", false},
  2426  	}
  2427  	for _, test := range tests {
  2428  		actual := StringLength(test.value, test.min, test.max)
  2429  		if actual != test.expected {
  2430  			t.Errorf("Expected StringLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual)
  2431  		}
  2432  	}
  2433  }
  2434  
  2435  func TestIsIn(t *testing.T) {
  2436  	t.Parallel()
  2437  
  2438  	var tests = []struct {
  2439  		value    string
  2440  		params   []string
  2441  		expected bool
  2442  	}{
  2443  		{"PRESENT", []string{"PRESENT"}, true},
  2444  		{"PRESENT", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, true},
  2445  		{"PRÉSENTE", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, true},
  2446  		{"PRESENT", []string{}, false},
  2447  		{"PRESENT", nil, false},
  2448  		{"ABSENT", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, false},
  2449  		{"", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, false},
  2450  	}
  2451  	for _, test := range tests {
  2452  		actual := IsIn(test.value, test.params...)
  2453  		if actual != test.expected {
  2454  			t.Errorf("Expected IsIn(%s, %v) to be %v, got %v", test.value, test.params, test.expected, actual)
  2455  		}
  2456  	}
  2457  }
  2458  
  2459  type Address struct {
  2460  	Street string `valid:"-"`
  2461  	Zip    string `json:"zip" valid:"numeric,required"`
  2462  }
  2463  
  2464  type User struct {
  2465  	Name     string `valid:"required"`
  2466  	Email    string `valid:"required,email"`
  2467  	Password string `valid:"required"`
  2468  	Age      int    `valid:"required,numeric,@#\u0000"`
  2469  	Home     *Address
  2470  	Work     []Address
  2471  }
  2472  
  2473  type UserValid struct {
  2474  	Name     string `valid:"required"`
  2475  	Email    string `valid:"required,email"`
  2476  	Password string `valid:"required"`
  2477  	Age      int    `valid:"required"`
  2478  	Home     *Address
  2479  	Work     []Address `valid:"required"`
  2480  }
  2481  
  2482  type PrivateStruct struct {
  2483  	privateField string `valid:"required,alpha,d_k"`
  2484  	NonZero      int
  2485  	ListInt      []int
  2486  	ListString   []string `valid:"alpha"`
  2487  	Work         [2]Address
  2488  	Home         Address
  2489  	Map          map[string]Address
  2490  }
  2491  
  2492  type NegationStruct struct {
  2493  	NotInt string `valid:"!int"`
  2494  	Int    string `valid:"int"`
  2495  }
  2496  
  2497  type LengthStruct struct {
  2498  	Length string `valid:"length(10|20)"`
  2499  }
  2500  
  2501  type StringLengthStruct struct {
  2502  	Length string `valid:"stringlength(10|20)"`
  2503  }
  2504  
  2505  type StringMatchesStruct struct {
  2506  	StringMatches string `valid:"matches(^[0-9]{3}$)"`
  2507  }
  2508  
  2509  // TODO: this testcase should be fixed
  2510  // type StringMatchesComplexStruct struct {
  2511  // 	StringMatches string `valid:"matches(^\\$\\([\"']\\w+[\"']\\)$)"`
  2512  // }
  2513  
  2514  type IsInStruct struct {
  2515  	IsIn string `valid:"in(PRESENT|PRÉSENTE|NOTABSENT)"`
  2516  }
  2517  
  2518  type Post struct {
  2519  	Title    string `valid:"alpha,required"`
  2520  	Message  string `valid:"ascii"`
  2521  	AuthorIP string `valid:"ipv4"`
  2522  }
  2523  
  2524  type MissingValidationDeclarationStruct struct {
  2525  	Name  string ``
  2526  	Email string `valid:"required,email"`
  2527  }
  2528  
  2529  type FieldRequiredByDefault struct {
  2530  	Email string `valid:"email"`
  2531  }
  2532  
  2533  type MultipleFieldsRequiredByDefault struct {
  2534  	Url   string `valid:"url"`
  2535  	Email string `valid:"email"`
  2536  }
  2537  
  2538  type FieldsRequiredByDefaultButExemptStruct struct {
  2539  	Name  string `valid:"-"`
  2540  	Email string `valid:"email"`
  2541  }
  2542  
  2543  type FieldsRequiredByDefaultButExemptOrOptionalStruct struct {
  2544  	Name  string `valid:"-"`
  2545  	Email string `valid:"optional,email"`
  2546  }
  2547  
  2548  type MessageWithSeveralFieldsStruct struct {
  2549  	Title string `valid:"length(1|10)"`
  2550  	Body  string `valid:"length(1|10)"`
  2551  }
  2552  
  2553  func TestValidateMissingValidationDeclarationStruct(t *testing.T) {
  2554  	var tests = []struct {
  2555  		param    MissingValidationDeclarationStruct
  2556  		expected bool
  2557  	}{
  2558  		{MissingValidationDeclarationStruct{}, false},
  2559  		{MissingValidationDeclarationStruct{Name: "TEST", Email: "test@example.com"}, false},
  2560  	}
  2561  	SetFieldsRequiredByDefault(true)
  2562  	for _, test := range tests {
  2563  		actual, err := ValidateStruct(test.param)
  2564  		if actual != test.expected {
  2565  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2566  			if err != nil {
  2567  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2568  			}
  2569  		}
  2570  	}
  2571  	SetFieldsRequiredByDefault(false)
  2572  }
  2573  
  2574  func TestFieldRequiredByDefault(t *testing.T) {
  2575  	var tests = []struct {
  2576  		param    FieldRequiredByDefault
  2577  		expected bool
  2578  	}{
  2579  		{FieldRequiredByDefault{}, false},
  2580  	}
  2581  	SetFieldsRequiredByDefault(true)
  2582  	for _, test := range tests {
  2583  		actual, err := ValidateStruct(test.param)
  2584  		if actual != test.expected {
  2585  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2586  			if err != nil {
  2587  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2588  			}
  2589  		}
  2590  	}
  2591  	SetFieldsRequiredByDefault(false)
  2592  }
  2593  
  2594  func TestMultipleFieldsRequiredByDefault(t *testing.T) {
  2595  	var tests = []struct {
  2596  		param    MultipleFieldsRequiredByDefault
  2597  		expected bool
  2598  	}{
  2599  		{MultipleFieldsRequiredByDefault{}, false},
  2600  	}
  2601  	SetFieldsRequiredByDefault(true)
  2602  	for _, test := range tests {
  2603  		actual, err := ValidateStruct(test.param)
  2604  		if actual != test.expected {
  2605  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2606  			if err != nil {
  2607  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2608  			}
  2609  		}
  2610  	}
  2611  	SetFieldsRequiredByDefault(false)
  2612  }
  2613  
  2614  func TestFieldsRequiredByDefaultButExemptStruct(t *testing.T) {
  2615  	var tests = []struct {
  2616  		param    FieldsRequiredByDefaultButExemptStruct
  2617  		expected bool
  2618  	}{
  2619  		{FieldsRequiredByDefaultButExemptStruct{}, false},
  2620  		{FieldsRequiredByDefaultButExemptStruct{Name: "TEST"}, false},
  2621  		{FieldsRequiredByDefaultButExemptStruct{Email: ""}, false},
  2622  		{FieldsRequiredByDefaultButExemptStruct{Email: "test@example.com"}, true},
  2623  	}
  2624  	SetFieldsRequiredByDefault(true)
  2625  	for _, test := range tests {
  2626  		actual, err := ValidateStruct(test.param)
  2627  		if actual != test.expected {
  2628  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2629  			if err != nil {
  2630  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2631  			}
  2632  		}
  2633  	}
  2634  	SetFieldsRequiredByDefault(false)
  2635  }
  2636  
  2637  func TestFieldsRequiredByDefaultButExemptOrOptionalStruct(t *testing.T) {
  2638  	var tests = []struct {
  2639  		param    FieldsRequiredByDefaultButExemptOrOptionalStruct
  2640  		expected bool
  2641  	}{
  2642  		{FieldsRequiredByDefaultButExemptOrOptionalStruct{}, true},
  2643  		{FieldsRequiredByDefaultButExemptOrOptionalStruct{Name: "TEST"}, true},
  2644  		{FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: ""}, true},
  2645  		{FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: "test@example.com"}, true},
  2646  		{FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: "test@example"}, false},
  2647  	}
  2648  	SetFieldsRequiredByDefault(true)
  2649  	for _, test := range tests {
  2650  		actual, err := ValidateStruct(test.param)
  2651  		if actual != test.expected {
  2652  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2653  			if err != nil {
  2654  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2655  			}
  2656  		}
  2657  	}
  2658  	SetFieldsRequiredByDefault(false)
  2659  }
  2660  
  2661  func TestInvalidValidator(t *testing.T) {
  2662  	type InvalidStruct struct {
  2663  		Field int `valid:"someInvalidValidator"`
  2664  	}
  2665  
  2666  	invalidStruct := InvalidStruct{1}
  2667  	if valid, err := ValidateStruct(&invalidStruct); valid || err == nil ||
  2668  		err.Error() != `Field: The following validator is invalid or can't be applied to the field: "someInvalidValidator"` {
  2669  		t.Errorf("Got an unexpected result for struct with invalid validator: %t %s", valid, err)
  2670  	}
  2671  }
  2672  
  2673  func TestCustomValidator(t *testing.T) {
  2674  	type ValidStruct struct {
  2675  		Field int `valid:"customTrueValidator"`
  2676  	}
  2677  
  2678  	type InvalidStruct struct {
  2679  		Field int `valid:"customFalseValidator~Value: %s Custom validator error: %s"`
  2680  	}
  2681  
  2682  	type StructWithCustomAndBuiltinValidator struct {
  2683  		Field int `valid:"customTrueValidator,required"`
  2684  	}
  2685  
  2686  	if valid, err := ValidateStruct(&ValidStruct{Field: 1}); !valid || err != nil {
  2687  		t.Errorf("Got an unexpected result for struct with custom always true validator: %t %s", valid, err)
  2688  	}
  2689  
  2690  	if valid, err := ValidateStruct(&InvalidStruct{Field: 1}); valid || err == nil || err.Error() != "Value: 1 Custom validator error: customFalseValidator" {
  2691  		fmt.Println(err)
  2692  		t.Errorf("Got an unexpected result for struct with custom always false validator: %t %s", valid, err)
  2693  	}
  2694  
  2695  	mixedStruct := StructWithCustomAndBuiltinValidator{}
  2696  	if valid, err := ValidateStruct(&mixedStruct); valid || err == nil || err.Error() != "Field: non zero value required" {
  2697  		t.Errorf("Got an unexpected result for invalid struct with custom and built-in validators: %t %s", valid, err)
  2698  	}
  2699  
  2700  	mixedStruct.Field = 1
  2701  	if valid, err := ValidateStruct(&mixedStruct); !valid || err != nil {
  2702  		t.Errorf("Got an unexpected result for valid struct with custom and built-in validators: %t %s", valid, err)
  2703  	}
  2704  }
  2705  
  2706  type CustomByteArray [6]byte
  2707  
  2708  type StructWithCustomByteArray struct {
  2709  	ID              CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"`
  2710  	Email           string          `valid:"email"`
  2711  	CustomMinLength int             `valid:"-"`
  2712  }
  2713  
  2714  func TestStructWithCustomByteArray(t *testing.T) {
  2715  	t.Parallel()
  2716  
  2717  	// add our custom byte array validator that fails when the byte array is pristine (all zeroes)
  2718  	CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool {
  2719  		switch v := o.(type) {
  2720  		case StructWithCustomByteArray:
  2721  			if len(v.Email) > 0 {
  2722  				if v.Email != "test@example.com" {
  2723  					t.Errorf("v.Email should have been 'test@example.com' but was '%s'", v.Email)
  2724  				}
  2725  			}
  2726  		default:
  2727  			t.Errorf("Context object passed to custom validator should have been a StructWithCustomByteArray but was %T (%+v)", o, o)
  2728  		}
  2729  
  2730  		switch v := i.(type) {
  2731  		case CustomByteArray:
  2732  			for _, e := range v { // checks if v is empty, i.e. all zeroes
  2733  				if e != 0 {
  2734  					return true
  2735  				}
  2736  			}
  2737  		}
  2738  		return false
  2739  	}))
  2740  	CustomTypeTagMap.Set("customMinLengthValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool {
  2741  		switch v := o.(type) {
  2742  		case StructWithCustomByteArray:
  2743  			return len(v.ID) >= v.CustomMinLength
  2744  		}
  2745  		return false
  2746  	}))
  2747  	testCustomByteArray := CustomByteArray{'1', '2', '3', '4', '5', '6'}
  2748  	var tests = []struct {
  2749  		param    StructWithCustomByteArray
  2750  		expected bool
  2751  	}{
  2752  		{StructWithCustomByteArray{}, false},
  2753  		{StructWithCustomByteArray{Email: "test@example.com"}, false},
  2754  		{StructWithCustomByteArray{ID: testCustomByteArray, Email: "test@example.com"}, true},
  2755  		{StructWithCustomByteArray{ID: testCustomByteArray, Email: "test@example.com", CustomMinLength: 7}, false},
  2756  	}
  2757  	SetFieldsRequiredByDefault(true)
  2758  	for _, test := range tests {
  2759  		actual, err := ValidateStruct(test.param)
  2760  		if actual != test.expected {
  2761  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2762  			if err != nil {
  2763  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2764  			}
  2765  		}
  2766  	}
  2767  	SetFieldsRequiredByDefault(false)
  2768  }
  2769  
  2770  func TestValidateNegationStruct(t *testing.T) {
  2771  	var tests = []struct {
  2772  		param    NegationStruct
  2773  		expected bool
  2774  	}{
  2775  		{NegationStruct{"a1", "11"}, true},
  2776  		{NegationStruct{"email@email.email", "11"}, true},
  2777  		{NegationStruct{"123456----", "11"}, true},
  2778  		{NegationStruct{"::1", "11"}, true},
  2779  		{NegationStruct{"123.123", "11"}, true},
  2780  		{NegationStruct{"a1", "a1"}, false},
  2781  		{NegationStruct{"11", "a1"}, false},
  2782  		{NegationStruct{"11", "11"}, false},
  2783  	}
  2784  	for _, test := range tests {
  2785  		actual, err := ValidateStruct(test.param)
  2786  		if actual != test.expected {
  2787  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2788  			if err != nil {
  2789  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2790  			}
  2791  		}
  2792  	}
  2793  }
  2794  
  2795  func TestLengthStruct(t *testing.T) {
  2796  	var tests = []struct {
  2797  		param    interface{}
  2798  		expected bool
  2799  	}{
  2800  		{LengthStruct{"11111"}, false},
  2801  		{LengthStruct{"11111111111111111110000000000000000"}, false},
  2802  		{LengthStruct{"11dfffdf0099"}, true},
  2803  	}
  2804  
  2805  	for _, test := range tests {
  2806  		actual, err := ValidateStruct(test.param)
  2807  		if actual != test.expected {
  2808  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2809  			if err != nil {
  2810  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2811  			}
  2812  		}
  2813  	}
  2814  }
  2815  
  2816  func TestStringLengthStruct(t *testing.T) {
  2817  	var tests = []struct {
  2818  		param    interface{}
  2819  		expected bool
  2820  	}{
  2821  		{StringLengthStruct{"11111"}, false},
  2822  		{StringLengthStruct{"11111111111111111110000000000000000"}, false},
  2823  		{StringLengthStruct{"11dfffdf0099"}, true},
  2824  		{StringLengthStruct{"あいうえお"}, false},
  2825  		{StringLengthStruct{"あいうえおかきくけこ"}, true},
  2826  		{StringLengthStruct{"あいうえおかきくけこさしすせそたちつてと"}, true},
  2827  		{StringLengthStruct{"あいうえおかきくけこさしすせそたちつてとな"}, false},
  2828  	}
  2829  
  2830  	for _, test := range tests {
  2831  		actual, err := ValidateStruct(test.param)
  2832  		if actual != test.expected {
  2833  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2834  			if err != nil {
  2835  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2836  			}
  2837  		}
  2838  	}
  2839  }
  2840  
  2841  func TestStringMatchesStruct(t *testing.T) {
  2842  	var tests = []struct {
  2843  		param    interface{}
  2844  		expected bool
  2845  	}{
  2846  		{StringMatchesStruct{"123"}, true},
  2847  		{StringMatchesStruct{"123456"}, false},
  2848  		{StringMatchesStruct{"123abcd"}, false},
  2849  	}
  2850  
  2851  	for _, test := range tests {
  2852  		actual, err := ValidateStruct(test.param)
  2853  		if actual != test.expected {
  2854  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2855  			if err != nil {
  2856  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2857  			}
  2858  		}
  2859  	}
  2860  }
  2861  
  2862  func TestIsInStruct(t *testing.T) {
  2863  	var tests = []struct {
  2864  		param    interface{}
  2865  		expected bool
  2866  	}{
  2867  		{IsInStruct{"PRESENT"}, true},
  2868  		{IsInStruct{""}, true},
  2869  		{IsInStruct{" "}, false},
  2870  		{IsInStruct{"ABSENT"}, false},
  2871  	}
  2872  
  2873  	for _, test := range tests {
  2874  		actual, err := ValidateStruct(test.param)
  2875  		if actual != test.expected {
  2876  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2877  			if err != nil {
  2878  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2879  			}
  2880  		}
  2881  	}
  2882  }
  2883  
  2884  func TestRequiredIsInStruct(t *testing.T) {
  2885  	type RequiredIsInStruct struct {
  2886  		IsIn string `valid:"in(PRESENT|PRÉSENTE|NOTABSENT),required"`
  2887  	}
  2888  
  2889  	var tests = []struct {
  2890  		param    interface{}
  2891  		expected bool
  2892  	}{
  2893  		{RequiredIsInStruct{"PRESENT"}, true},
  2894  		{RequiredIsInStruct{""}, false},
  2895  		{RequiredIsInStruct{" "}, false},
  2896  		{RequiredIsInStruct{"ABSENT"}, false},
  2897  	}
  2898  
  2899  	for _, test := range tests {
  2900  		actual, err := ValidateStruct(test.param)
  2901  		if actual != test.expected {
  2902  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2903  			if err != nil {
  2904  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2905  			}
  2906  		}
  2907  	}
  2908  }
  2909  
  2910  func TestEmptyRequiredIsInStruct(t *testing.T) {
  2911  	type EmptyRequiredIsInStruct struct {
  2912  		IsIn string `valid:"in(),required"`
  2913  	}
  2914  
  2915  	var tests = []struct {
  2916  		param    interface{}
  2917  		expected bool
  2918  	}{
  2919  		{EmptyRequiredIsInStruct{"PRESENT"}, false},
  2920  		{EmptyRequiredIsInStruct{""}, false},
  2921  		{EmptyRequiredIsInStruct{" "}, false},
  2922  		{EmptyRequiredIsInStruct{"ABSENT"}, false},
  2923  	}
  2924  
  2925  	for _, test := range tests {
  2926  		actual, err := ValidateStruct(test.param)
  2927  		if actual != test.expected {
  2928  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2929  			if err != nil {
  2930  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  2931  			}
  2932  		}
  2933  	}
  2934  }
  2935  
  2936  func TestEmptyStringPtr(t *testing.T) {
  2937  	type EmptyIsInStruct struct {
  2938  		IsIn *string `valid:"length(3|5),required"`
  2939  	}
  2940  
  2941  	var empty = ""
  2942  	var valid = "123"
  2943  	var invalid = "123456"
  2944  
  2945  	var tests = []struct {
  2946  		param       interface{}
  2947  		expected    bool
  2948  		expectedErr string
  2949  	}{
  2950  		{EmptyIsInStruct{&empty}, false, "IsIn: non zero value required"},
  2951  		{EmptyIsInStruct{nil}, true, ""},
  2952  		{EmptyIsInStruct{&valid}, true, ""},
  2953  		{EmptyIsInStruct{&invalid}, false, "IsIn: 123456 does not validate as length(3|5)"},
  2954  	}
  2955  
  2956  	SetNilPtrAllowedByRequired(true)
  2957  	for _, test := range tests {
  2958  		actual, err := ValidateStruct(test.param)
  2959  
  2960  		if actual != test.expected {
  2961  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  2962  		}
  2963  		if err != nil {
  2964  			if err.Error() != test.expectedErr {
  2965  				t.Errorf("Got Error on ValidateStruct(%q). Expected: %s Actual: %s", test.param, test.expectedErr, err)
  2966  			}
  2967  		} else if test.expectedErr != "" {
  2968  			t.Errorf("Expected error on ValidateStruct(%q).", test.param)
  2969  		}
  2970  	}
  2971  	SetNilPtrAllowedByRequired(false)
  2972  }
  2973  
  2974  func TestNestedStruct(t *testing.T) {
  2975  	type EvenMoreNestedStruct struct {
  2976  		Bar string `valid:"length(3|5)"`
  2977  	}
  2978  	type NestedStruct struct {
  2979  		Foo                 string `valid:"length(3|5),required"`
  2980  		EvenMoreNested      EvenMoreNestedStruct
  2981  		SliceEvenMoreNested []EvenMoreNestedStruct
  2982  		MapEvenMoreNested   map[string]EvenMoreNestedStruct
  2983  	}
  2984  	type OuterStruct struct {
  2985  		Nested NestedStruct
  2986  	}
  2987  
  2988  	var tests = []struct {
  2989  		param       interface{}
  2990  		expected    bool
  2991  		expectedErr string
  2992  	}{
  2993  		{OuterStruct{
  2994  			Nested: NestedStruct{
  2995  				Foo: "",
  2996  			},
  2997  		}, false, "Nested.Foo: non zero value required"},
  2998  		{OuterStruct{
  2999  			Nested: NestedStruct{
  3000  				Foo: "123",
  3001  			},
  3002  		}, true, ""},
  3003  		{OuterStruct{
  3004  			Nested: NestedStruct{
  3005  				Foo: "123456",
  3006  			},
  3007  		}, false, "Nested.Foo: 123456 does not validate as length(3|5)"},
  3008  		{OuterStruct{
  3009  			Nested: NestedStruct{
  3010  				Foo: "123",
  3011  				EvenMoreNested: EvenMoreNestedStruct{
  3012  					Bar: "123456",
  3013  				},
  3014  			},
  3015  		}, false, "Nested.EvenMoreNested.Bar: 123456 does not validate as length(3|5)"},
  3016  		{OuterStruct{
  3017  			Nested: NestedStruct{
  3018  				Foo: "123",
  3019  				SliceEvenMoreNested: []EvenMoreNestedStruct{
  3020  					{
  3021  						Bar: "123456",
  3022  					},
  3023  				},
  3024  			},
  3025  		}, false, "Nested.SliceEvenMoreNested.0.Bar: 123456 does not validate as length(3|5)"},
  3026  		{OuterStruct{
  3027  			Nested: NestedStruct{
  3028  				Foo: "123",
  3029  				MapEvenMoreNested: map[string]EvenMoreNestedStruct{
  3030  					"Foo": {
  3031  						Bar: "123456",
  3032  					},
  3033  				},
  3034  			},
  3035  		}, false, "Nested.MapEvenMoreNested.Foo.Bar: 123456 does not validate as length(3|5)"},
  3036  	}
  3037  
  3038  	for _, test := range tests {
  3039  		actual, err := ValidateStruct(test.param)
  3040  
  3041  		if actual != test.expected {
  3042  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  3043  		}
  3044  		if err != nil {
  3045  			if err.Error() != test.expectedErr {
  3046  				t.Errorf("Got Error on ValidateStruct(%q). Expected: %s Actual: %s", test.param, test.expectedErr, err)
  3047  			}
  3048  		} else if test.expectedErr != "" {
  3049  			t.Errorf("Expected error on ValidateStruct(%q).", test.param)
  3050  		}
  3051  	}
  3052  }
  3053  
  3054  func TestFunkyIsInStruct(t *testing.T) {
  3055  	type FunkyIsInStruct struct {
  3056  		IsIn string `valid:"in(PRESENT|| |PRÉSENTE|NOTABSENT)"`
  3057  	}
  3058  
  3059  	var tests = []struct {
  3060  		param    interface{}
  3061  		expected bool
  3062  	}{
  3063  		{FunkyIsInStruct{"PRESENT"}, true},
  3064  		{FunkyIsInStruct{""}, true},
  3065  		{FunkyIsInStruct{" "}, true},
  3066  		{FunkyIsInStruct{"ABSENT"}, false},
  3067  	}
  3068  
  3069  	for _, test := range tests {
  3070  		actual, err := ValidateStruct(test.param)
  3071  		if actual != test.expected {
  3072  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  3073  			if err != nil {
  3074  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  3075  			}
  3076  		}
  3077  	}
  3078  }
  3079  
  3080  // TODO: test case broken
  3081  // func TestStringMatchesComplexStruct(t *testing.T) {
  3082  // 	var tests = []struct {
  3083  // 		param    interface{}
  3084  // 		expected bool
  3085  // 	}{
  3086  // 		{StringMatchesComplexStruct{"$()"}, false},
  3087  // 		{StringMatchesComplexStruct{"$('AZERTY')"}, true},
  3088  // 		{StringMatchesComplexStruct{`$("AZERTY")`}, true},
  3089  // 		{StringMatchesComplexStruct{`$("")`}, false},
  3090  // 		{StringMatchesComplexStruct{"AZERTY"}, false},
  3091  // 		{StringMatchesComplexStruct{"$AZERTY"}, false},
  3092  // 	}
  3093  
  3094  // 	for _, test := range tests {
  3095  // 		actual, err := ValidateStruct(test.param)
  3096  // 		if actual != test.expected {
  3097  // 			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  3098  // 			if err != nil {
  3099  // 				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  3100  // 			}
  3101  // 		}
  3102  // 	}
  3103  // }
  3104  
  3105  func TestValidateStruct(t *testing.T) {
  3106  
  3107  	var tests = []struct {
  3108  		param    interface{}
  3109  		expected bool
  3110  	}{
  3111  		{User{"John", "john@yahoo.com", "123G#678", 20, &Address{"Street", "ABC456D89"}, []Address{{"Street", "123456"}, {"Street", "123456"}}}, false},
  3112  		{User{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false},
  3113  		{User{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false},
  3114  		{UserValid{"John", "john@yahoo.com", "123G#678", 20, &Address{"Street", "123456"}, []Address{{"Street", "123456"}, {"Street", "123456"}}}, true},
  3115  		{UserValid{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{}}, false},
  3116  		{UserValid{"John", "john@yahoo.com", "12345678", 20, &Address{"Street", "123456xxx"}, []Address{{"Street", "123456"}, {"Street", "123456"}}}, false},
  3117  		{UserValid{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false},
  3118  		{UserValid{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false},
  3119  		{nil, true},
  3120  		{User{"John", "john@yahoo.com", "123G#678", 0, &Address{"Street", "123456"}, []Address{}}, false},
  3121  		{"im not a struct", false},
  3122  	}
  3123  	for _, test := range tests {
  3124  		actual, err := ValidateStruct(test.param)
  3125  		if actual != test.expected {
  3126  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  3127  			if err != nil {
  3128  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  3129  			}
  3130  		}
  3131  	}
  3132  
  3133  	TagMap["d_k"] = Validator(func(str string) bool {
  3134  		return str == "d_k"
  3135  	})
  3136  	result, err := ValidateStruct(PrivateStruct{"d_k", 0, []int{1, 2}, []string{"hi", "super"}, [2]Address{{"Street", "123456"},
  3137  		{"Street", "123456"}}, Address{"Street", "123456"}, map[string]Address{"address": {"Street", "123456"}}})
  3138  	if !result {
  3139  		t.Log("Case ", 6, ": expected ", true, " when result is ", result)
  3140  		t.Error(err)
  3141  		t.FailNow()
  3142  	}
  3143  }
  3144  
  3145  type testByteArray [8]byte
  3146  type testByteMap map[byte]byte
  3147  type testByteSlice []byte
  3148  type testStringStringMap map[string]string
  3149  type testStringIntMap map[string]int
  3150  
  3151  func TestRequired(t *testing.T) {
  3152  
  3153  	testString := "foobar"
  3154  	testEmptyString := ""
  3155  	var tests = []struct {
  3156  		param    interface{}
  3157  		expected bool
  3158  	}{
  3159  		{
  3160  			struct {
  3161  				Pointer *string `valid:"required"`
  3162  			}{},
  3163  			false,
  3164  		},
  3165  		{
  3166  			struct {
  3167  				Pointer *string `valid:"required"`
  3168  			}{
  3169  				Pointer: &testEmptyString,
  3170  			},
  3171  			false,
  3172  		},
  3173  		{
  3174  			struct {
  3175  				Pointer *string `valid:"required"`
  3176  			}{
  3177  				Pointer: &testString,
  3178  			},
  3179  			true,
  3180  		},
  3181  		{
  3182  			struct {
  3183  				Addr Address `valid:"required"`
  3184  			}{},
  3185  			false,
  3186  		},
  3187  		{
  3188  			struct {
  3189  				Addr Address `valid:"required"`
  3190  			}{
  3191  				Addr: Address{"", "123"},
  3192  			},
  3193  			true,
  3194  		},
  3195  		{
  3196  			struct {
  3197  				Pointer *Address `valid:"required"`
  3198  			}{},
  3199  			false,
  3200  		},
  3201  		{
  3202  			struct {
  3203  				Pointer *Address `valid:"required"`
  3204  			}{
  3205  				Pointer: &Address{"", "123"},
  3206  			},
  3207  			true,
  3208  		},
  3209  		{
  3210  			struct {
  3211  				TestByteArray testByteArray `valid:"required"`
  3212  			}{},
  3213  			false,
  3214  		},
  3215  		{
  3216  			struct {
  3217  				TestByteArray testByteArray `valid:"required"`
  3218  			}{
  3219  				testByteArray{},
  3220  			},
  3221  			false,
  3222  		},
  3223  		{
  3224  			struct {
  3225  				TestByteArray testByteArray `valid:"required"`
  3226  			}{
  3227  				testByteArray{'1', '2', '3', '4', '5', '6', '7', 'A'},
  3228  			},
  3229  			true,
  3230  		},
  3231  		{
  3232  			struct {
  3233  				TestByteMap testByteMap `valid:"required"`
  3234  			}{},
  3235  			false,
  3236  		},
  3237  		{
  3238  			struct {
  3239  				TestByteSlice testByteSlice `valid:"required"`
  3240  			}{},
  3241  			false,
  3242  		},
  3243  		{
  3244  			struct {
  3245  				TestStringStringMap testStringStringMap `valid:"required"`
  3246  			}{
  3247  				testStringStringMap{"test": "test"},
  3248  			},
  3249  			true,
  3250  		},
  3251  		{
  3252  			struct {
  3253  				TestIntMap testStringIntMap `valid:"required"`
  3254  			}{
  3255  				testStringIntMap{"test": 42},
  3256  			},
  3257  			true,
  3258  		},
  3259  	}
  3260  	for _, test := range tests {
  3261  		actual, err := ValidateStruct(test.param)
  3262  		if actual != test.expected {
  3263  			t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
  3264  			if err != nil {
  3265  				t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
  3266  			}
  3267  		}
  3268  	}
  3269  }
  3270  
  3271  func TestErrorByField(t *testing.T) {
  3272  	t.Parallel()
  3273  
  3274  	var tests = []struct {
  3275  		param    string
  3276  		expected string
  3277  	}{
  3278  		{"message", ""},
  3279  		{"Message", ""},
  3280  		{"title", ""},
  3281  		{"Title", "My123 does not validate as alpha"},
  3282  		{"AuthorIP", "123 does not validate as ipv4"},
  3283  	}
  3284  	post := &Post{"My123", "duck13126", "123"}
  3285  	_, err := ValidateStruct(post)
  3286  
  3287  	for _, test := range tests {
  3288  		actual := ErrorByField(err, test.param)
  3289  		if actual != test.expected {
  3290  			t.Errorf("Expected ErrorByField(%q) to be %v, got %v", test.param, test.expected, actual)
  3291  		}
  3292  	}
  3293  }
  3294  
  3295  func TestErrorsByField(t *testing.T) {
  3296  	t.Parallel()
  3297  
  3298  	var tests = []struct {
  3299  		param    string
  3300  		expected string
  3301  	}{
  3302  		{"Title", "My123 does not validate as alpha"},
  3303  		{"AuthorIP", "123 does not validate as ipv4"},
  3304  	}
  3305  	post := &Post{Title: "My123", Message: "duck13126", AuthorIP: "123"}
  3306  	_, err := ValidateStruct(post)
  3307  	errs := ErrorsByField(err)
  3308  	if len(errs) != 2 {
  3309  		t.Errorf("There should only be 2 errors but got %v", len(errs))
  3310  	}
  3311  
  3312  	for _, test := range tests {
  3313  		if actual, ok := errs[test.param]; !ok || actual != test.expected {
  3314  			t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual)
  3315  		}
  3316  	}
  3317  
  3318  	tests = []struct {
  3319  		param    string
  3320  		expected string
  3321  	}{
  3322  		{"Title", ";:;message;:; does not validate as length(1|10)"},
  3323  		{"Body", ";:;message;:; does not validate as length(1|10)"},
  3324  	}
  3325  
  3326  	message := &MessageWithSeveralFieldsStruct{Title: ";:;message;:;", Body: ";:;message;:;"}
  3327  	_, err = ValidateStruct(message)
  3328  	errs = ErrorsByField(err)
  3329  	if len(errs) != 2 {
  3330  		t.Errorf("There should only be 2 errors but got %v", len(errs))
  3331  	}
  3332  
  3333  	for _, test := range tests {
  3334  		if actual, ok := errs[test.param]; !ok || actual != test.expected {
  3335  			t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual)
  3336  		}
  3337  	}
  3338  
  3339  	tests = []struct {
  3340  		param    string
  3341  		expected string
  3342  	}{
  3343  		{"CustomField", "An error occurred"},
  3344  	}
  3345  
  3346  	err = Error{"CustomField", fmt.Errorf("An error occurred"), false, "hello", []string{}}
  3347  	errs = ErrorsByField(err)
  3348  
  3349  	if len(errs) != 1 {
  3350  		t.Errorf("There should only be 1 errors but got %v", len(errs))
  3351  	}
  3352  
  3353  	for _, test := range tests {
  3354  		if actual, ok := errs[test.param]; !ok || actual != test.expected {
  3355  			t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual)
  3356  		}
  3357  	}
  3358  
  3359  	type StructWithCustomValidation struct {
  3360  		Email string `valid:"email"`
  3361  		ID    string `valid:"falseValidation"`
  3362  	}
  3363  
  3364  	CustomTypeTagMap.Set("falseValidation", CustomTypeValidator(func(i interface{}, o interface{}) bool {
  3365  		return false
  3366  	}))
  3367  
  3368  	tests = []struct {
  3369  		param    string
  3370  		expected string
  3371  	}{
  3372  		{"Email", "My123 does not validate as email"},
  3373  		{"ID", "duck13126 does not validate as falseValidation"},
  3374  	}
  3375  	s := &StructWithCustomValidation{Email: "My123", ID: "duck13126"}
  3376  	_, err = ValidateStruct(s)
  3377  	errs = ErrorsByField(err)
  3378  	if len(errs) != 2 {
  3379  		t.Errorf("There should only be 2 errors but got %v", len(errs))
  3380  	}
  3381  
  3382  	for _, test := range tests {
  3383  		if actual, ok := errs[test.param]; !ok || actual != test.expected {
  3384  			t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual)
  3385  		}
  3386  	}
  3387  }
  3388  
  3389  func TestValidateStructPointers(t *testing.T) {
  3390  	// Struct which uses pointers for values
  3391  	type UserWithPointers struct {
  3392  		Name         *string `valid:"-"`
  3393  		Email        *string `valid:"email"`
  3394  		FavoriteFood *string `valid:"length(0|32)"`
  3395  		Nerd         *bool   `valid:"-"`
  3396  	}
  3397  
  3398  	var tests = []struct {
  3399  		param    string
  3400  		expected string
  3401  	}{
  3402  		{"Name", ""},
  3403  		{"Email", "invalid does not validate as email"},
  3404  		{"FavoriteFood", ""},
  3405  		{"Nerd", ""},
  3406  	}
  3407  
  3408  	name := "Herman"
  3409  	email := "invalid"
  3410  	food := "Pizza"
  3411  	nerd := true
  3412  	user := &UserWithPointers{&name, &email, &food, &nerd}
  3413  	_, err := ValidateStruct(user)
  3414  
  3415  	for _, test := range tests {
  3416  		actual := ErrorByField(err, test.param)
  3417  		if actual != test.expected {
  3418  			t.Errorf("Expected ErrorByField(%q) to be %v, got %v", test.param, test.expected, actual)
  3419  		}
  3420  	}
  3421  }
  3422  
  3423  func ExampleValidateStruct() {
  3424  	type Post struct {
  3425  		Title    string `valid:"alphanum,required"`
  3426  		Message  string `valid:"duck,ascii"`
  3427  		AuthorIP string `valid:"ipv4"`
  3428  	}
  3429  	post := &Post{"My Example Post", "duck", "123.234.54.3"}
  3430  
  3431  	//Add your own struct validation tags
  3432  	TagMap["duck"] = Validator(func(str string) bool {
  3433  		return str == "duck"
  3434  	})
  3435  
  3436  	result, err := ValidateStruct(post)
  3437  	if err != nil {
  3438  		println("error: " + err.Error())
  3439  	}
  3440  	println(result)
  3441  }
  3442  
  3443  func TestValidateStructParamValidatorInt(t *testing.T) {
  3444  	type Test1 struct {
  3445  		Int   int   `valid:"range(1|10)"`
  3446  		Int8  int8  `valid:"range(1|10)"`
  3447  		Int16 int16 `valid:"range(1|10)"`
  3448  		Int32 int32 `valid:"range(1|10)"`
  3449  		Int64 int64 `valid:"range(1|10)"`
  3450  
  3451  		Uint   uint   `valid:"range(1|10)"`
  3452  		Uint8  uint8  `valid:"range(1|10)"`
  3453  		Uint16 uint16 `valid:"range(1|10)"`
  3454  		Uint32 uint32 `valid:"range(1|10)"`
  3455  		Uint64 uint64 `valid:"range(1|10)"`
  3456  
  3457  		Float32 float32 `valid:"range(1|10)"`
  3458  		Float64 float64 `valid:"range(1|10)"`
  3459  	}
  3460  	test1Ok := &Test1{5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}
  3461  	test1NotOk := &Test1{11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11}
  3462  
  3463  	_, err := ValidateStruct(test1Ok)
  3464  	if err != nil {
  3465  		t.Errorf("Test failed: %s", err)
  3466  	}
  3467  
  3468  	_, err = ValidateStruct(test1NotOk)
  3469  	if err == nil {
  3470  		t.Errorf("Test failed: nil")
  3471  	}
  3472  
  3473  	type Test2 struct {
  3474  		Int   int   `valid:"in(1|10)"`
  3475  		Int8  int8  `valid:"in(1|10)"`
  3476  		Int16 int16 `valid:"in(1|10)"`
  3477  		Int32 int32 `valid:"in(1|10)"`
  3478  		Int64 int64 `valid:"in(1|10)"`
  3479  
  3480  		Uint   uint   `valid:"in(1|10)"`
  3481  		Uint8  uint8  `valid:"in(1|10)"`
  3482  		Uint16 uint16 `valid:"in(1|10)"`
  3483  		Uint32 uint32 `valid:"in(1|10)"`
  3484  		Uint64 uint64 `valid:"in(1|10)"`
  3485  
  3486  		Float32 float32 `valid:"in(1|10)"`
  3487  		Float64 float64 `valid:"in(1|10)"`
  3488  	}
  3489  
  3490  	test2Ok1 := &Test2{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
  3491  	test2Ok2 := &Test2{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}
  3492  	test2NotOk := &Test2{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}
  3493  
  3494  	_, err = ValidateStruct(test2Ok1)
  3495  	if err != nil {
  3496  		t.Errorf("Test failed: %s", err)
  3497  	}
  3498  
  3499  	_, err = ValidateStruct(test2Ok2)
  3500  	if err != nil {
  3501  		t.Errorf("Test failed: %s", err)
  3502  	}
  3503  
  3504  	_, err = ValidateStruct(test2NotOk)
  3505  	if err == nil {
  3506  		t.Errorf("Test failed: nil")
  3507  	}
  3508  
  3509  	type Test3 struct {
  3510  		Int   int   `valid:"in(1|10),int"`
  3511  		Int8  int8  `valid:"in(1|10),int8"`
  3512  		Int16 int16 `valid:"in(1|10),int16"`
  3513  		Int32 int32 `valid:"in(1|10),int32"`
  3514  		Int64 int64 `valid:"in(1|10),int64"`
  3515  
  3516  		Uint   uint   `valid:"in(1|10),uint"`
  3517  		Uint8  uint8  `valid:"in(1|10),uint8"`
  3518  		Uint16 uint16 `valid:"in(1|10),uint16"`
  3519  		Uint32 uint32 `valid:"in(1|10),uint32"`
  3520  		Uint64 uint64 `valid:"in(1|10),uint64"`
  3521  
  3522  		Float32 float32 `valid:"in(1|10),float32"`
  3523  		Float64 float64 `valid:"in(1|10),float64"`
  3524  	}
  3525  
  3526  	test3Ok1 := &Test2{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
  3527  	test3Ok2 := &Test2{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}
  3528  	test3NotOk := &Test2{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}
  3529  
  3530  	_, err = ValidateStruct(test3Ok1)
  3531  	if err != nil {
  3532  		t.Errorf("Test failed: %s", err)
  3533  	}
  3534  
  3535  	_, err = ValidateStruct(test3Ok2)
  3536  	if err != nil {
  3537  		t.Errorf("Test failed: %s", err)
  3538  	}
  3539  
  3540  	_, err = ValidateStruct(test3NotOk)
  3541  	if err == nil {
  3542  		t.Errorf("Test failed: nil")
  3543  	}
  3544  }
  3545  
  3546  func TestValidateStructUpperAndLowerCaseWithNumTypeCheck(t *testing.T) {
  3547  
  3548  	type StructCapital struct {
  3549  		Total float32 `valid:"float,required"`
  3550  	}
  3551  
  3552  	structCapital := &StructCapital{53.3535}
  3553  	_, err := ValidateStruct(structCapital)
  3554  	if err != nil {
  3555  		t.Errorf("Test failed: nil")
  3556  		fmt.Println(err)
  3557  	}
  3558  
  3559  	type StructLower struct {
  3560  		total float32 `valid:"float,required"`
  3561  	}
  3562  
  3563  	structLower := &StructLower{53.3535}
  3564  	_, err = ValidateStruct(structLower)
  3565  	if err != nil {
  3566  		t.Errorf("Test failed: nil")
  3567  		fmt.Println(err)
  3568  	}
  3569  }
  3570  
  3571  func TestIsCIDR(t *testing.T) {
  3572  	t.Parallel()
  3573  
  3574  	var tests = []struct {
  3575  		param    string
  3576  		expected bool
  3577  	}{
  3578  		{"193.168.3.20/7", true},
  3579  		{"2001:db8::/32", true},
  3580  		{"2001:0db8:85a3:0000:0000:8a2e:0370:7334/64", true},
  3581  		{"193.138.3.20/60", false},
  3582  		{"500.323.2.23/43", false},
  3583  		{"", false},
  3584  	}
  3585  	for _, test := range tests {
  3586  		actual := IsCIDR(test.param)
  3587  		if actual != test.expected {
  3588  			t.Errorf("Expected IsCIDR(%q) to be %v, got %v", test.param, test.expected, actual)
  3589  		}
  3590  	}
  3591  }
  3592  
  3593  func TestOptionalCustomValidators(t *testing.T) {
  3594  
  3595  	CustomTypeTagMap.Set("f2", CustomTypeValidator(func(i interface{}, o interface{}) bool {
  3596  		return false
  3597  	}))
  3598  
  3599  	var val struct {
  3600  		WithCustomError    string `valid:"f2~boom,optional"`
  3601  		WithoutCustomError string `valid:"f2,optional"`
  3602  		OptionalFirst      string `valid:"optional,f2"`
  3603  	}
  3604  
  3605  	ok, err := ValidateStruct(val)
  3606  
  3607  	if err != nil {
  3608  		t.Errorf("Expected nil err with optional validation, got %v", err)
  3609  	}
  3610  
  3611  	if !ok {
  3612  		t.Error("Expected validation to return true, got false")
  3613  	}
  3614  }
  3615  
  3616  func TestJSONValidator(t *testing.T) {
  3617  
  3618  	var val struct {
  3619  		WithJSONName      string `json:"with_json_name" valid:"-,required"`
  3620  		WithoutJSONName   string `valid:"-,required"`
  3621  		WithJSONOmit      string `json:"with_other_json_name,omitempty" valid:"-,required"`
  3622  		WithJSONOption    string `json:",omitempty" valid:"-,required"`
  3623  		WithEmptyJSONName string `json:"-" valid:"-,required"`
  3624  	}
  3625  
  3626  	_, err := ValidateStruct(val)
  3627  
  3628  	if err == nil {
  3629  		t.Error("Expected error but got no error")
  3630  	}
  3631  
  3632  	if Contains(err.Error(), "WithJSONName") {
  3633  		t.Errorf("Expected error message to contain with_json_name but actual error is: %s", err.Error())
  3634  	}
  3635  
  3636  	if !Contains(err.Error(), "WithoutJSONName") {
  3637  		t.Errorf("Expected error message to contain WithoutJSONName but actual error is: %s", err.Error())
  3638  	}
  3639  
  3640  	if Contains(err.Error(), "omitempty") {
  3641  		t.Errorf("Expected error message to not contain ',omitempty' but actual error is: %s", err.Error())
  3642  	}
  3643  
  3644  	if !Contains(err.Error(), "WithEmptyJSONName") {
  3645  		t.Errorf("Expected error message to contain WithEmptyJSONName but actual error is: %s", err.Error())
  3646  	}
  3647  }
  3648  
  3649  func TestValidatorIncludedInError(t *testing.T) {
  3650  	post := Post{
  3651  		Title:    "",
  3652  		Message:  "👍",
  3653  		AuthorIP: "xyz",
  3654  	}
  3655  
  3656  	validatorMap := map[string]string{
  3657  		"Title":    "required",
  3658  		"Message":  "ascii",
  3659  		"AuthorIP": "ipv4",
  3660  	}
  3661  
  3662  	ok, errors := ValidateStruct(post)
  3663  	if ok {
  3664  		t.Errorf("expected validation to fail %v", ok)
  3665  	}
  3666  
  3667  	for _, e := range errors.(Errors) {
  3668  		casted := e.(Error)
  3669  		if validatorMap[casted.Name] != casted.Validator {
  3670  			t.Errorf("expected validator for %s to be %s, but was %s", casted.Name, validatorMap[casted.Name], casted.Validator)
  3671  		}
  3672  	}
  3673  
  3674  	// checks to make sure that validators with arguments (like length(1|10)) don't include the arguments
  3675  	// in the validator name
  3676  	message := MessageWithSeveralFieldsStruct{
  3677  		Title: "",
  3678  		Body:  "asdfasdfasdfasdfasdf",
  3679  	}
  3680  
  3681  	validatorMap = map[string]string{
  3682  		"Title": "length",
  3683  		"Body":  "length",
  3684  	}
  3685  
  3686  	ok, errors = ValidateStruct(message)
  3687  	if ok {
  3688  		t.Errorf("expected validation to fail, %v", ok)
  3689  	}
  3690  
  3691  	for _, e := range errors.(Errors) {
  3692  		casted := e.(Error)
  3693  		if validatorMap[casted.Name] != casted.Validator {
  3694  			t.Errorf("expected validator for %s to be %s, but was %s", casted.Name, validatorMap[casted.Name], casted.Validator)
  3695  		}
  3696  	}
  3697  
  3698  	// make sure validators with custom messages don't show up in the validator string
  3699  	type CustomMessage struct {
  3700  		Text string `valid:"length(1|10)~Custom message"`
  3701  	}
  3702  	cs := CustomMessage{Text: "asdfasdfasdfasdf"}
  3703  
  3704  	ok, errors = ValidateStruct(&cs)
  3705  	if ok {
  3706  		t.Errorf("expected validation to fail, %v", ok)
  3707  	}
  3708  
  3709  	validator := errors.(Errors)[0].(Error).Validator
  3710  	if validator != "length" {
  3711  		t.Errorf("expected validator for Text to be length, but was %s", validator)
  3712  	}
  3713  
  3714  }
  3715  
  3716  func TestIsRsaPublicKey(t *testing.T) {
  3717  	var tests = []struct {
  3718  		rsastr   string
  3719  		keylen   int
  3720  		expected bool
  3721  	}{
  3722  		{`fubar`, 2048, false},
  3723  		{`MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuu
  3724  XwKYLq0DKUE3t/HHsNdowfD9+NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9BmMEcI3uoKbeXCbJRI
  3725  HoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzTUmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZ
  3726  B7ucimFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUvbQIDAQAB`, 2048, true},
  3727  		{`MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuu
  3728  XwKYLq0DKUE3t/HHsNdowfD9+NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9BmMEcI3uoKbeXCbJRI
  3729  HoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzTUmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZ
  3730  B7ucimFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUvbQIDAQAB`, 1024, false},
  3731  		{`-----BEGIN PUBLIC KEY-----
  3732  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7
  3733  x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuuXwKYLq0DKUE3t/HHsNdowfD9
  3734  +NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9
  3735  BmMEcI3uoKbeXCbJRIHoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzT
  3736  UmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZB7uc
  3737  imFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUv
  3738  bQIDAQAB
  3739  -----END PUBLIC KEY-----`, 2048, true},
  3740  		{`-----BEGIN PUBLIC KEY-----
  3741  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7
  3742  x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuuXwKYLq0DKUE3t/HHsNdowfD9
  3743  +NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9
  3744  BmMEcI3uoKbeXCbJRIHoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzT
  3745  UmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZB7uc
  3746  imFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUv
  3747  bQIDAQAB
  3748  -----END PUBLIC KEY-----`, 4096, false},
  3749  	}
  3750  	for i, test := range tests {
  3751  		actual := IsRsaPublicKey(test.rsastr, test.keylen)
  3752  		if actual != test.expected {
  3753  			t.Errorf("Expected TestIsRsaPublicKey(%d, %d) to be %v, got %v", i, test.keylen, test.expected, actual)
  3754  		}
  3755  	}
  3756  }
  3757  
  3758  func TestIsRegex(t *testing.T) {
  3759  	t.Parallel()
  3760  
  3761  	var tests = []struct {
  3762  		param    string
  3763  		expected bool
  3764  	}{
  3765  		{"^$", true},
  3766  		{"$^", true},
  3767  		{"^^", true},
  3768  		{"$$", true},
  3769  		{"a+", true},
  3770  		{"a++", false},
  3771  		{"a*", true},
  3772  		{"a**", false},
  3773  		{"a+*", false},
  3774  		{"a*+", false},
  3775  		{"[a+]+", true},
  3776  		{"\\w+", true},
  3777  		{"\\y+", false},
  3778  		{"[asdf][qwer]", true},
  3779  		{"[asdf[", false},
  3780  		{"[asdf[]", true},
  3781  		{"[asdf[][]", false},
  3782  		{"(group2)(group3)", true},
  3783  		{"(invalid_paranthesis(asdf)", false},
  3784  		{"a?", true},
  3785  		{"a??", true},
  3786  		{"a???", false},
  3787  		{"a\\???", true},
  3788  		{"asdf\\/", true},
  3789  		{"asdf/", true},
  3790  		{"\\x61", true},
  3791  		{"\\xg1", false},
  3792  		{"\\x6h", false},
  3793  		{"[asdf[", false},
  3794  		{"[A-z]+", true},
  3795  		{"[z-A]+", false},
  3796  		{"[a-z-A]", true},
  3797  		{"a{3,6}", true},
  3798  		{"a{6,3|3,6}", true},
  3799  		{"a{6,3}", false},
  3800  		{"a|b", true},
  3801  		{"a|b|", true},
  3802  		{"a|b||", true}, //But false in python RE
  3803  		{"(?:)", true},
  3804  		{"(?)", true}, //But false in python RE
  3805  		{"?", false},
  3806  		{"(?::?)", true},
  3807  		{"(?:?)", false},
  3808  		{"(()?)", true},
  3809  		{"(?:?)", false},
  3810  		{"(A conditional matching)? (?(1)matched|not matched)", false}, //But true in python RE
  3811  		{"(A conditional matching)? (?(2)matched|not matched)", false},
  3812  		{"(?:A conditional matching)? (?(1)matched|not matched)", false},
  3813  		{"(?:[a-z]+)?", true},
  3814  		{"(?#[a-z]+)?", false},
  3815  		{"(?P<name>[a-z]+)", true},
  3816  		{"(?P<name<>>[a-z]+)", false},
  3817  	}
  3818  	for _, test := range tests {
  3819  		actual := IsRegex(test.param)
  3820  		if actual != test.expected {
  3821  			t.Errorf("Expected IsNumeric(%q) to be %v, got %v", test.param, test.expected, actual)
  3822  		}
  3823  	}
  3824  }
  3825  
  3826  func TestIsIMSI(t *testing.T) {
  3827  	tests := []struct {
  3828  		param    string
  3829  		expected bool
  3830  	}{
  3831  		{"234150999999999", true},
  3832  		{"429011234567890", true},
  3833  		{"310150123456789", true},
  3834  		{"460001234567890", true},
  3835  		{"4600012345678", false},
  3836  		{"4600012345678901", false},
  3837  		{"462001234567890", false},
  3838  		{"1", false},
  3839  	}
  3840  	for _, test := range tests {
  3841  		actual := IsIMSI(test.param)
  3842  		if actual != test.expected {
  3843  			t.Errorf("Expected IsIMSI(%q) to be %v, got %v", test.param, test.expected, actual)
  3844  		}
  3845  	}
  3846  }
  3847  
  3848  func TestIsE164(t *testing.T) {
  3849  	t.Parallel()
  3850  
  3851  	var tests = []struct {
  3852  		param    string
  3853  		expected bool
  3854  	}{
  3855  		{"+14155552671", true},
  3856  		{"+442071838750", true},
  3857  		{"+551155256325", true},
  3858  		{"+226071234567 ", false},
  3859  		{"+06071234567 ", false},
  3860  	}
  3861  	for _, test := range tests {
  3862  		actual := IsE164(test.param)
  3863  		if actual != test.expected {
  3864  			t.Errorf("Expected IsURL(%q) to be %v, got %v", test.param, test.expected, actual)
  3865  		}
  3866  	}
  3867  }