Add validation for directories
Abdallah Galal
5 years ago
157 | 157 | "html": isHTML, |
158 | 158 | "html_encoded": isHTMLEncoded, |
159 | 159 | "url_encoded": isURLEncoded, |
160 | "dir": isDir, | |
160 | 161 | } |
161 | 162 | ) |
162 | 163 | |
1844 | 1845 | return strings.ContainsAny(val, ".") && |
1845 | 1846 | hostnameRegexRFC952.MatchString(val) |
1846 | 1847 | } |
1848 | ||
1849 | // IsDir is the validation function for validating if the current field's value is a valid directory. | |
1850 | func isDir(fl FieldLevel) bool { | |
1851 | field := fl.Field() | |
1852 | ||
1853 | if field.Kind() == reflect.String { | |
1854 | fileInfo, err := os.Stat(field.String()) | |
1855 | if err != nil { | |
1856 | return false | |
1857 | } | |
1858 | ||
1859 | return fileInfo.IsDir() | |
1860 | } | |
1861 | ||
1862 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) | |
1863 | } |
946 | 946 | |
947 | 947 | Usage: url_encoded |
948 | 948 | |
949 | Directory | |
950 | ||
951 | This validates that a string value contains a valid directory and that | |
952 | it exists on the machine. | |
953 | This is done using os.Stat, which is a platform independent function. | |
954 | ||
955 | Usage: dir | |
956 | ||
949 | 957 | Alias Validators and Tags |
950 | 958 | |
951 | 959 | NOTE: When returning an error, the tag returned in "FieldError" will be |
8507 | 8507 | NotEqual(t, errs, nil) |
8508 | 8508 | AssertError(t, errs, "TestStruct.StringVal", "TestStruct.String", "StringVal", "String", "badvalueteststruct") |
8509 | 8509 | } |
8510 | ||
8511 | func TestDirValidation(t *testing.T) { | |
8512 | validate := New() | |
8513 | ||
8514 | tests := []struct { | |
8515 | title string | |
8516 | param string | |
8517 | expected bool | |
8518 | }{ | |
8519 | {"existing dir", "testdata", true}, | |
8520 | {"existing self dir", ".", true}, | |
8521 | {"existing parent dir", "..", true}, | |
8522 | {"empty dir", "", false}, | |
8523 | {"missing dir", "non_existing_testdata", false}, | |
8524 | {"a file not a directory", filepath.Join("testdata", "a.go"), false}, | |
8525 | } | |
8526 | ||
8527 | for _, test := range tests { | |
8528 | errs := validate.Var(test.param, "dir") | |
8529 | ||
8530 | if test.expected { | |
8531 | if !IsEqual(errs, nil) { | |
8532 | t.Fatalf("Test: '%s' failed Error: %s", test.title, errs) | |
8533 | } | |
8534 | } else { | |
8535 | if IsEqual(errs, nil) { | |
8536 | t.Fatalf("Test: '%s' failed Error: %s", test.title, errs) | |
8537 | } | |
8538 | } | |
8539 | } | |
8540 | ||
8541 | PanicMatches(t, func() { | |
8542 | validate.Var(2, "dir") | |
8543 | }, "Bad field type int") | |
8544 | } |