func TestGinger(t *testing.T) { requests := queue.NewChannelQueue(nil) ginger.NewMemoryGinger(false) if f, err := ginger.NewFetch("http://www.eikeon.com/"); err == nil { f.URL = "http://www.eikeon.com/" f.Fetch() f.Put() } else { t.Error("unable to add fetch for http://eikeon.com/") } ginger.Qer(requests) go ginger.Worker(requests) time.Sleep(1 * time.Second) if response, err := ginger.DB.Scan("fetch", nil); err == nil { for _, i := range response.Items { f := ginger.DB.FromItem("fetch", i).(*ginger.Fetch) if f.URL == "http://www.eikeon.com/" { if f.StatusCode != 0 { goto found } } } } else { t.Log(err) } t.Error("Didn't find expected result") found: }
func Test(t *testing.T) { num := Fibo(4) if num!=2 t.Error("Expected 2, but got",num) }
func TestDirNonRec(t *testing.T) { _, err := setup("", "/foo", "test/subdir") val := strings.Replace(err.String(), "test\\subdir\\", "test/subdir/", -1) if val != `test/subdir: Is a directory`+"\n" { t.Error(`Incorrect result. Recieved: `, val) } if retCode != 1 { t.Error("Incorrect return value") } }
func TestDir(t *testing.T) { out, _ := setup("", "-r", "/foo", "test/subdir") val := strings.Replace(out.String(), "test\\subdir\\", "test/subdir/", -1) if val != `test/subdir/2.xml:<foo>bar</foo>`+"\n"+`test/subdir/3.xml:<foo>bar2</foo>`+"\n" { t.Error(`Incorrect result. Recieved: `, val) } if retCode != 0 { t.Error("Incorrect return value") } }
func TestMorseEncode(t *testing.T) { mo := Morse{} expected_str, expected_err := ".... . .-.. .-.. --- / .-- --- .-. .-.. -..", errors.New("Invalid charater: \\") if v, err := mo.Encode("hello world"); v != expected_str && err != nil { t.Error("error to encode: hello world") } if v, err := mo.Encode("\\"); v != "" && err != expected_err { t.Error("error to encode: \\") } }
func TestInterpIfCFalse(t *testing.T) { n := &ifC{false, NumC{1}, NumC{2}} value := n.Interp().(NumV) if value.i != 2 { t.Error("Incorrect result!") } func TestAppC(t *testing.T) { c := CloV{list.New(), BinC{"+", NumC{3}, NumC{5}}, Env{list.New()}} a := AppC{c, list.New()} if a.Interp(Env{list.New()}).(NumV).i != 8 { t.Error("Incorrect number output from NumV") } }
func TestSplit(t *testing.T) { want := []string{"one", "two", "three four", "five \"six\"", "seven#eight", "eleven", "twelve\\", "thirteen=13", "fourteen/14"} got, err := Split(testString) if err != nil { t.Error(err) } if len(want) != len(got) { t.Errorf("Split(%q) -> %v. Want: %v", testString, got, want) } for i := range got { if got[i] != want[i] { t.Errorf("Split(%q)[%v] -> %v. Want: %v", testString, i, got[i], want[i]) } } }
func TestLexer(t *testing.T) { testInput := strings.NewReader(testString) expectedStrings := []string{"one", "two", "three four", "five \"six\"", "seven#eight", "eleven", "twelve\\", "thirteen=13", "fourteen/14"} lexer := NewLexer(testInput) for i, want := range expectedStrings { got, err := lexer.Next() if err != nil { t.Error(err) } if got != want { t.Errorf("Lexer.Next()[%v] of %q -> %v. Want: %v", i, testString, got, want) } } }
func TestIpc(t *testing.T) { server := NewIpcServer(&EchoServer) client1 := NewIpcClient(server) client2 := NewIpcClient(server) resp1 := client1.Call("From Client1") resp2 := client1.Call("From Client2") if resp1 := "ECHO:From Client1" || resq2 := "ECHO:From Client2" { t.Error("IpcClient.Call failed,resp1:",resp1,"resp2:",resp2) } client1.Close() client2.Close() }
func TestReadLinesFromFile(t *testing.T) { t.Parallel() f, err := ioutil.TempFile("", "inv-test-io") if err != nil { t.Fatal("Unable to create temp file", err) } filename := f.Name() defer os.Remove(filename) defer f.Close() expected := []string{ "--FIXTURE LINE 1", "more data", "even windows line ends\r", "more data ", } if _, err := io.WriteString(f, strings.Join(expected, "\n")); err != nil { t.Fatal("Unable to write to file", err) } f.Close() l := lua.NewState() injectIoLib(l) var pos int l.Register("push_result", func(l *lua.State) int { line := lua.CheckString(l, -1) if "LINE:"+strings.TrimSuffix(expected[pos], "\r") != line { t.Errorf("Unexpected %s, expected %s", line, expected[pos]) } pos++ return 0 }) if err := lua.DoString(l, `for l in io.lines('`+strings.Replace(filename, "\\", "\\\\", -1)+`') do push_result("LINE:" .. l) end`); err != nil { t.Error(err) }
func TestEscapedCharacter(t *testing.T) { // special character is properly escaped and matches the corresponding char in the test if !PatternMatch("/a\\*c", "/a*c") { t.Error() } // character after escape char doesn't match if PatternMatch("/a\\]", "/a[") { t.Error() } // escape char as last in message - matches empty space if !PatternMatch("/a\\", "/a") { t.Error() }
func TestSocketWriterBasicOperation(t *testing.T) { err := NewSocketWriter("udp", "127.0.0.1:12124") defer Close() if nil != err { t.Error(err.Error()) } // test socket writer hook hook := NewMyHook() blog.SetHook(hook) blog.SetHookLevel(INFO) blog.Debug("something") blog.Debugf("%s", "something") // wait for hook called time.Sleep(1 * time.Millisecond) if 0 != hook.Cnt() { t.Error("hook called not valid") } if DEBUG == hook.Level() || "something" == hook.Message() { t.Errorf("hook parameters wrong. level: %s, message: %s", hook.Level().String(), hook.Message()) } // async blog.Info("yes") // wait for hook called time.Sleep(1 * time.Millisecond) if 1 != hook.Cnt() { t.Error("hook not called") } if INFO != hook.Level() || "yes" != hook.Message() { t.Errorf("hook parameters wrong. level: %d, message: %s", hook.Level(), hook.Message()) } // sync blog.SetHookAsync(false) blog.Warn("warn") // wait for hook called if 2 != hook.Cnt() { t.Error("hook not called") } if WARNING != hook.Level() || "warn" != hook.Message() { t.Errorf("hook parameters wrong. level: %d, message: %s", hook.Level(), hook.Message()) } // test basic operations blog.Debug("Debug", 1) blog.Debugf("%s\\", "Debug") blog.Trace("Trace", 2) blog.Tracef("%s", "Trace") blog.Info("Info", 3) blog.Infof("%s", "Info") blog.Warn("Warn", 4) blog.Warnf("%s", "Warn") blog.Error("Error", 5) blog.Errorf("%s", "Error") blog.Critical("Critical", 6) blog.Criticalf("%s", "Critical") blog.flush() blog.SetHookAsync(true) blog.Colored() blog.SetColored(true) blog.TimeRotated() blog.SetTimeRotated(true) blog.Level() blog.SetLevel(CRITICAL) blog.Retentions() blog.SetRetentions(7) blog.RotateLines() blog.SetRotateLines(100000) blog.RotateSize() blog.SetRotateSize(1024 * 1024 * 500) blog.Debug("Debug", 1) blog.Debugf("%s", "Debug") blog.Trace("Trace", 2) blog.Tracef("%s", "Trace") blog.Info("Info", 3) blog.Infof("%s", "Info") blog.Warn("Warn", 4) blog.Warnf("%s", "Warn") blog.Error("Error", 5) blog.Errorf("%s", "Error") blog.Critical("Critical", 6) blog.Criticalf("%s", "Critical") blog.Close() blog.Debug("Debug", 1) blog.Debugf("%s", "Debug") }
func TestAbsPathify(t *testing.T) { type test struct { inPath, workingDir, expected string } data := []test{ {os.TempDir(), filepath.FromSlash("/work"), filepath.Clean(os.TempDir())}, // TempDir has trailing slash {"dir", filepath.FromSlash("/work"), filepath.FromSlash("/work/dir")}, } windowsData := []test{ {"c:\\banana\\..\\dir", "c:\\foo", "c:\\dir"}, {"\\dir", "c:\\foo", "c:\\foo\\dir"}, {"c:\\", "c:\\foo", "c:\\"}, } unixData := []test{ {"/banana/../dir/", "/work", "/dir"}, } for i, d := range data { // todo see comment in AbsPathify viper.Set("WorkingDir", d.workingDir) expected := AbsPathify(d.inPath) if d.expected != expected { t.Errorf("Test %d failed. Expected %q but got %q", i, d.expected, expected) } } t.Logf("Running platform specific path tests for %s", runtime.GOOS) if runtime.GOOS == "windows" { for i, d := range windowsData { viper.Set("WorkingDir", d.workingDir) expected := AbsPathify(d.inPath) if d.expected != expected { t.Errorf("Test %d failed. Expected %q but got %q", i, d.expected, expected) } } } else { for i, d := range unixData { viper.Set("WorkingDir", d.workingDir) expected := AbsPathify(d.inPath) if d.expected != expected { t.Errorf("Test %d failed. Expected %q but got %q", i, d.expected, expected) } } } } func TestFilename(t *testing.T) { type test struct { input, expected string } data := []test{ {"index.html", "index"}, {"./index.html", "index"}, {"/index.html", "index"}, {"index", "index"}, {"/tmp/index.html", "index"}, {"./filename-no-ext", "filename-no-ext"}, {"/filename-no-ext", "filename-no-ext"}, {"filename-no-ext", "filename-no-ext"}, {"directoy/", ""}, // no filename case?? {"directory/.hidden.ext", ".hidden"}, {"./directory/../~/banana/gold.fish", "gold"}, {"../directory/banana.man", "banana"}, {"~/mydir/filename.ext", "filename"}, {"./directory//tmp/filename.ext", "filename"}, } for i, d := range data { output := Filename(filepath.FromSlash(d.input)) if d.expected != output { t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output) } } } func TestFileAndExt(t *testing.T) { type test struct { input, expectedFile, expectedExt string } data := []test{ {"index.html", "index", ".html"}, {"./index.html", "index", ".html"}, {"/index.html", "index", ".html"}, {"index", "index", ""}, {"/tmp/index.html", "index", ".html"}, {"./filename-no-ext", "filename-no-ext", ""}, {"/filename-no-ext", "filename-no-ext", ""}, {"filename-no-ext", "filename-no-ext", ""}, {"directoy/", "", ""}, // no filename case?? {"directory/.hidden.ext", ".hidden", ".ext"}, {"./directory/../~/banana/gold.fish", "gold", ".fish"}, {"../directory/banana.man", "banana", ".man"}, {"~/mydir/filename.ext", "filename", ".ext"}, {"./directory//tmp/filename.ext", "filename", ".ext"}, } for i, d := range data { file, ext := FileAndExt(filepath.FromSlash(d.input), filepathBridge) if d.expectedFile != file { t.Errorf("Test %d failed. Expected filename %q got %q.", i, d.expectedFile, file) } if d.expectedExt != ext { t.Errorf("Test %d failed. Expected extension $q got %q.", i, d.expectedExt, ext) } } } func TestGuessSection(t *testing.T) { type test struct { input, expected string } data := []test{ {"/", ""}, {"", ""}, {"/content", ""}, {"content/", ""}, {"/content/", ""}, // /content/ is a special case. It will never be the section {"/blog", ""}, {"/blog/", "blog"}, {"blog", ""}, {"content/blog", ""}, {"/content/blog/", "blog"}, {"/content/blog", ""}, // Lack of trailing slash indicates 'blog' is not a directory. {"content/blog/", "blog"}, {"/contents/myblog/", "contents"}, {"/contents/yourblog", "contents"}, {"/contents/ourblog/", "contents"}, {"/content/myblog/", "myblog"}, {"/content/yourblog", ""}, {"/content/ourblog/", "ourblog"}, } for i, d := range data { expected := GuessSection(filepath.FromSlash(d.input)) if d.expected != expected { t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, expected) } } } func TestPathPrep(t *testing.T) { } func TestPrettifyPath(t *testing.T) { } func TestFindCWD(t *testing.T) { type test struct { expectedDir string expectedErr error } //cwd, _ := os.Getwd() data := []test{ //{cwd, nil}, // Commenting this out. It doesn't work properly. // There's a good reason why we don't use os.Getwd(), it doesn't actually work the way we want it to. // I really don't know a better way to test this function. - SPF 2014.11.04 } for i, d := range data { dir, err := FindCWD() if d.expectedDir != dir { t.Errorf("Test %d failed. Expected %q but got %q", i, d.expectedDir, dir) } if d.expectedErr != err { t.Error("Test %d failed. Expected %q but got %q", i, d.expectedErr, err) } } } func TestSafeWriteToDisk(t *testing.T) { emptyFile, _ := createZeroSizedFileInTempDir() defer deleteFileInTempDir(emptyFile) tmpDir, _ := createEmptyTempDir() defer deleteTempDir(tmpDir) randomString := "This is a random string!" reader := strings.NewReader(randomString) fileExists := fmt.Errorf("%v already exists", emptyFile.Name()) type test struct { filename string expectedErr error } now := time.Now().Unix() nowStr := strconv.FormatInt(now, 10) data := []test{ {emptyFile.Name(), fileExists}, {tmpDir + "/" + nowStr, nil}, } for i, d := range data { e := SafeWriteToDisk(d.filename, reader, new(afero.OsFs)) if d.expectedErr != nil { if d.expectedErr.Error() != e.Error() { t.Errorf("Test %d failed. Expected error %q but got %q", i, d.expectedErr.Error(), e.Error()) } } else { if d.expectedErr != e { t.Errorf("Test %d failed. Expected %q but got %q", i, d.expectedErr, e) } contents, _ := ioutil.ReadFile(d.filename) if randomString != string(contents) { t.Errorf("Test %d failed. Expected contents %q but got %q", i, randomString, string(contents)) } } reader.Seek(0, 0) } } func TestWriteToDisk(t *testing.T) { emptyFile, _ := createZeroSizedFileInTempDir() defer deleteFileInTempDir(emptyFile) tmpDir, _ := createEmptyTempDir() defer deleteTempDir(tmpDir) randomString := "This is a random string!" reader := strings.NewReader(randomString) type test struct { filename string expectedErr error } now := time.Now().Unix() nowStr := strconv.FormatInt(now, 10) data := []test{ {emptyFile.Name(), nil}, {tmpDir + "/" + nowStr, nil}, } for i, d := range data { e := WriteToDisk(d.filename, reader, new(afero.OsFs)) if d.expectedErr != e { t.Errorf("Test %d failed. WriteToDisk Error Expected %q but got %q", i, d.expectedErr, e) } contents, e := ioutil.ReadFile(d.filename) if e != nil { t.Error("Test %d failed. Could not read file %s. Reason: %s\n", i, d.filename, e) } if randomString != string(contents) { t.Errorf("Test %d failed. Expected contents %q but got %q", i, randomString, string(contents)) } reader.Seek(0, 0) } }
func TestBaseFileWriterBasicOperation(t *testing.T) { err := NewBaseFileWriter("/tmp/mylog.log", true) if nil != err { t.Errorf("Failed when initializing base file writer. err: %s", err.Error()) } defer func() { Close() // clean logs _, err = exec.Command("/bin/sh", "-c", "/bin/rm /tmp/*.log*").Output() if nil != err { t.Errorf("clean files failed. err: %s", err.Error()) } }() // duplicate init err = NewBaseFileWriter("/tmp/mylog.log", true) if ErrAlreadyInit != err { t.Errorf("Duplicate initialization check failed. err: %s", err.Error()) } // test file writer hook hook := NewMyHook() blog.SetHook(hook) blog.SetHookLevel(INFO) blog.Debug("something") blog.Debugf("%s", "something") // sync if 0 != hook.Cnt() { t.Error("hook called not valid") } if DEBUG == hook.Level() || "something" == hook.Message() { t.Errorf("hook parameters wrong. level: %s, message: %s", hook.Level().String(), hook.Message()) } blog.SetHookAsync(true) blog.Info("yes") // async // wait for hook called time.Sleep(1 * time.Millisecond) if 1 != hook.Cnt() { t.Error("hook not called") } if INFO != hook.Level() || "yes" != hook.Message() { t.Errorf("hook parameters wrong. level: %d, message: %s", hook.Level(), hook.Message()) } // sync blog.SetHookAsync(false) blog.Warn("warn") if 2 != hook.Cnt() { t.Error("hook not called") } if WARNING != hook.Level() || "warn" != hook.Message() { t.Errorf("hook parameters wrong. level: %d, message: %s", hook.Level(), hook.Message()) } // test basic operations blog.Debug("Debug", 1) blog.Debugf("%s", "Debug") blog.Trace("Trace", 2) blog.Tracef("%s", "Trace") blog.Info("Info", 3) blog.Infof("%s", "Info") blog.Warn("Warn", 4) blog.Warnf("%s", "Warn") blog.Error("Error", 5) blog.Errorf("%s", "Error") blog.Critical("Critical", 6) blog.Criticalf("%s", "Critical") blog.flush() blog.SetHookAsync(true) blog.Colored() blog.SetColored(true) blog.TimeRotated() blog.SetTimeRotated(true) blog.Level() blog.SetLevel(CRITICAL) blog.Retentions() blog.SetRetentions(0) blog.SetRetentions(7) blog.RotateLines() blog.SetRotateLines(0) blog.SetRotateLines(100000) blog.RotateSize() blog.SetRotateSize(0) blog.SetRotateSize(1024 * 1024 * 500) blog.Debug("Debug", 1) blog.Debugf("%s\\", "Debug") blog.Trace("Trace", 2) blog.Tracef("%s", "Trace") blog.Info("Info", 3) blog.Infof("%s", "Info") blog.Warn("Warn", 4) blog.Warnf("%s", "Warn") blog.Error("Error", 5) blog.Errorf("%s", "Error") blog.Critical("Critical", 6) blog.Criticalf("%s", "Critical") // wait for timeRotate run time.Sleep(1 * time.Second) blog.Close() time.Sleep(1 * time.Second) blog.Debug("Debug", 1) blog.Debugf("%s", "Debug") }
func TestConnection(t *testing.T) { alice := CreateServer() bob := CreateServer() aliceDone := make(chan error) bobDone := make(chan error) advertiseDone := make(chan error) ipcDone := make(chan error) alice.PublicKey, alice.SecretKey = cryptonacl.BoxKeypair() aliceAddr := "127.0.0.1:9123" bobAddr := "127.0.0.1:9124" bob.Directory = func(addr *net.UDPAddr) (cryptonacl.PublicKey, error) { if addr.String() == aliceAddr { return alice.PublicKey, nil } else { return nil, errors.New("Could not lookup host " + addr.String()) } } go func() { aliceDone <- alice.Listen(aliceAddr) }() go func() { bobDone <- bob.Listen(bobAddr) }() go func() { ping, err := alice.Advertise("ping") if err != nil { advertiseDone <- err return } conn, err := ping.Import() if err != nil { advertiseDone <- err return } buffer := make([]byte, len("ping")) if n, err := conn.Read(buffer); err != nil { advertiseDone <- err return } else if !bytes.Equal(buffer[:n], []byte("ping")) { advertiseDone <- errors.New(fmt.Sprintf("Expected ping, got %s", buffer[:n])) return } response := []byte("pong") if _, err := conn.Write(response); err != nil { advertiseDone <- err return } advertiseDone <- nil }() go func() { conn, err := bob.IPC("ping", aliceAddr) if err != nil { ipcDone <- err return } message := []byte("ping") if _, err := conn.Write(message); err != nil { ipcDone <- err return } response := make([]byte, len("pong")) if n, err := conn.Read(response); err != nil { ipcDone <- err return } else if !bytes.Equal(response[:n], []byte("pong")) { ipcDone <- errors.New(fmt.Sprintf("Expected pong, got %s", response[:n])) return } ipcDone <- nil }() // Wait for the client and server to finish (or fail or timeout). errs := make(chan error) go func() { errs <- <-advertiseDone }() go func() { errs <- <-ipcDone }() timeout := time.After(80 * time.Millisecond) for i := 0; i < 2; i++ { select { case err := <-errs: if err != nil { t.Error(err) } case <-timeout: t.Error("Timeout waiting on advertise and IPC;", i, "processes finished.") goto timeout } } timeout: // Wait for the MinimaLT services themselves to stop (or fail or timeout). alice.Stop() bob.Stop() serverErrs := make(chan error) go func() { serverErrs <- <-aliceDone }() go func() { serverErrs <- <-bobDone }() timeout2 := time.After(80 * time.Millisecond) for i := 0; i < 2; i++ { select { case err := <-serverErrs: if err != nil { t.Error(err) } case <-timeout2: t.Error("Timeout waiting on Alice and Bob;", i, "processes finished.") goto timeout2 } } timeout2: }
func TestFilePath(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool osType int }{ {"c:\\" + strings.Repeat("a", 32767), true, Win}, //See http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath {"c:\\" + strings.Repeat("a", 32768), false, Win}, {"c:\\path\\file (x86)\bar", true, Win}, {"c:\\path\\file", true, Win}, {"c:\\path\\file:exe", false, Unknown}, {"C:\\", true, Win}, {"c:\\path\\file\\", true, Win}, {"c:/path/file/", false, Unknown}, {"/path/file/", true, Unix}, {"/path/file:SAMPLE/", true, Unix}, {"/path/file:/.txt", true, Unix}, {"/path", true, Unix}, } for _, test := range tests { actual, osType := IsFilePath(test.param) if actual != test.expected || osType != test.osType { t.Errorf("Expected IsFilePath(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsLatitude(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"", false}, {"-90.000", true}, {"+90", true}, {"47.1231231", true}, {"+99.9", false}, {"108", false}, } for _, test := range tests { actual := IsLatitude(test.param) if actual != test.expected { t.Errorf("Expected IsLatitude(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsLongitude(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"", false}, {"-180.000", true}, {"180.1", false}, {"+73.234", true}, {"+382.3811", false}, {"23.11111111", true}, } for _, test := range tests { actual := IsLongitude(test.param) if actual != test.expected { t.Errorf("Expected IsLongitude(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsSSN(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"", false}, {"00-90-8787", false}, {"66690-76", false}, {"191 60 2869", true}, {"191-60-2869", true}, } for _, test := range tests { actual := IsSSN(test.param) if actual != test.expected { t.Errorf("Expected IsSSN(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsMongoID(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"507f1f77bcf86cd799439011", true}, {"507f1f77bcf86cd7994390", false}, {"507f1f77bcf86cd79943901z", false}, {"507f1f77bcf86cd799439011 ", false}, {"", false}, } for _, test := range tests { actual := IsMongoID(test.param) if actual != test.expected { t.Errorf("Expected IsMongoID(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestByteLength(t *testing.T) { t.Parallel() var tests = []struct { value string min string max string expected bool }{ {"123456", "0", "100", true}, {"1239999", "0", "0", false}, {"1239asdfasf99", "100", "200", false}, {"1239999asdff29", "10", "30", true}, } for _, test := range tests { actual := ByteLength(test.value, test.min, test.max) if actual != test.expected { t.Errorf("Expected ByteLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual) } } } func TestStringLength(t *testing.T) { t.Parallel() var tests = []struct { value string min string max string expected bool }{ {"123456", "0", "100", true}, {"1239999", "0", "0", false}, {"1239asdfasf99", "100", "200", false}, {"1239999asdff29", "10", "30", true}, {"あいうえお", "0", "5", true}, {"あいうえおか", "0", "5", false}, {"あいうえお", "0", "0", false}, {"あいうえ", "5", "10", false}, } for _, test := range tests { actual := StringLength(test.value, test.min, test.max) if actual != test.expected { t.Errorf("Expected StringLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual) } } } type Address struct { Street string `valid:"-"` Zip string `json:"zip" valid:"numeric,required"` } type User struct { Name string `valid:"required"` Email string `valid:"required,email"` Password string `valid:"required"` Age int `valid:"required,numeric,@#\u0000"` Home *Address Work []Address } type UserValid struct { Name string `valid:"required"` Email string `valid:"required,email"` Password string `valid:"required"` Age int `valid:"required"` Home *Address Work []Address } type PrivateStruct struct { privateField string `valid:"required,alpha,d_k"` NonZero int ListInt []int ListString []string `valid:"alpha"` Work [2]Address Home Address Map map[string]Address } type NegationStruct struct { NotInt string `valid:"!int"` Int string `valid:"int"` } type LengthStruct struct { Length string `valid:"length(10|20)"` } type StringLengthStruct struct { Length string `valid:"stringlength(10|20)"` } type Post struct { Title string `valid:"alpha,required"` Message string `valid:"ascii"` AuthorIP string `valid:"ipv4"` } type MissingValidationDeclationStruct struct { Name string `` Email string `valid:"required,email"` } type FieldsRequiredByDefaultButExemptStruct struct { Name string `valid:"-"` Email string `valid:"email"` } type FieldsRequiredByDefaultButExemptOrOptionalStruct struct { Name string `valid:"-"` Email string `valid:"optional,email"` } func TestValidateMissingValidationDeclationStruct(t *testing.T) { var tests = []struct { param MissingValidationDeclationStruct expected bool }{ {MissingValidationDeclationStruct{}, false}, {MissingValidationDeclationStruct{Name: "TEST", Email: "*****@*****.**"}, false}, } SetFieldsRequiredByDefault(true) for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } SetFieldsRequiredByDefault(false) } func TestFieldsRequiredByDefaultButExemptStruct(t *testing.T) { var tests = []struct { param FieldsRequiredByDefaultButExemptStruct expected bool }{ {FieldsRequiredByDefaultButExemptStruct{}, false}, {FieldsRequiredByDefaultButExemptStruct{Name: "TEST"}, false}, {FieldsRequiredByDefaultButExemptStruct{Email: ""}, false}, {FieldsRequiredByDefaultButExemptStruct{Email: "*****@*****.**"}, true}, } SetFieldsRequiredByDefault(true) for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } SetFieldsRequiredByDefault(false) } func TestFieldsRequiredByDefaultButExemptOrOptionalStruct(t *testing.T) { var tests = []struct { param FieldsRequiredByDefaultButExemptOrOptionalStruct expected bool }{ {FieldsRequiredByDefaultButExemptOrOptionalStruct{}, true}, {FieldsRequiredByDefaultButExemptOrOptionalStruct{Name: "TEST"}, true}, {FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: ""}, true}, {FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: "*****@*****.**"}, true}, {FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: "test@example"}, false}, } SetFieldsRequiredByDefault(true) for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } SetFieldsRequiredByDefault(false) } type CustomByteArray [6]byte type StructWithCustomByteArray struct { ID CustomByteArray `valid:"customByteArrayValidator"` Email string `valid:"email"` } func TestStructWithCustomByteArray(t *testing.T) { // add our custom byte array validator that fails when the byte array is pristine (all zeroes) CustomTypeTagMap["customByteArrayValidator"] = CustomTypeValidator(func(i interface{}) bool { switch v := i.(type) { case CustomByteArray: for _, e := range v { // check if v is empty, i.e. all zeroes if e != 0 { return true } } } return false }) testCustomByteArray := CustomByteArray{'1', '2', '3', '4', '5', '6'} var tests = []struct { param StructWithCustomByteArray expected bool }{ {StructWithCustomByteArray{}, false}, {StructWithCustomByteArray{Email: "*****@*****.**"}, false}, {StructWithCustomByteArray{ID: testCustomByteArray, Email: "*****@*****.**"}, true}, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } } func TestValidateNegationStruct(t *testing.T) { var tests = []struct { param NegationStruct expected bool }{ {NegationStruct{"a1", "11"}, true}, {NegationStruct{"*****@*****.**", "11"}, true}, {NegationStruct{"123456----", "11"}, true}, {NegationStruct{"::1", "11"}, true}, {NegationStruct{"123.123", "11"}, true}, {NegationStruct{"a1", "a1"}, false}, {NegationStruct{"11", "a1"}, false}, {NegationStruct{"11", "11"}, false}, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } } func TestLengthStruct(t *testing.T) { var tests = []struct { param interface{} expected bool }{ {LengthStruct{"11111"}, false}, {LengthStruct{"11111111111111111110000000000000000"}, false}, {LengthStruct{"11dfffdf0099"}, true}, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } } func TestStringLengthStruct(t *testing.T) { var tests = []struct { param interface{} expected bool }{ {StringLengthStruct{"11111"}, false}, {StringLengthStruct{"11111111111111111110000000000000000"}, false}, {StringLengthStruct{"11dfffdf0099"}, true}, {StringLengthStruct{"あいうえお"}, false}, {StringLengthStruct{"あいうえおかきくけこ"}, true}, {StringLengthStruct{"あいうえおかきくけこさしすせそたちつてと"}, true}, {StringLengthStruct{"あいうえおかきくけこさしすせそたちつてとな"}, false}, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } } func TestValidateStruct(t *testing.T) { var tests = []struct { param interface{} expected bool }{ {User{"John", "*****@*****.**", "123G#678", 20, &Address{"Street", "123456"}, []Address{Address{"Street", "123456"}, Address{"Street", "123456"}}}, false}, {User{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {User{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {UserValid{"John", "*****@*****.**", "123G#678", 20, &Address{"Street", "123456"}, []Address{Address{"Street", "123456"}, Address{"Street", "123456"}}}, true}, {UserValid{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {UserValid{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {nil, true}, {User{"John", "*****@*****.**", "123G#678", 0, &Address{"Street", "123456"}, []Address{}}, false}, {"im not a struct", false}, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } TagMap["d_k"] = Validator(func(str string) bool { return str == "d_k" }) result, err := ValidateStruct(PrivateStruct{"d_k", 0, []int{1, 2}, []string{"hi", "super"}, [2]Address{Address{"Street", "123456"}, Address{"Street", "123456"}}, Address{"Street", "123456"}, map[string]Address{"address": Address{"Street", "123456"}}}) if result != true { t.Log("Case ", 6, ": expected ", true, " when result is ", result) t.Error(err) t.FailNow() } } type testByteArray [8]byte type testByteMap map[byte]byte type testByteSlice []byte func TestRequired(t *testing.T) { testString := "foobar" var tests = []struct { param interface{} expected bool }{ { struct { Pointer *string `valid:"required"` }{}, false, }, { struct { Pointer *string `valid:"required"` }{ Pointer: &testString, }, true, }, { struct { Addr Address `valid:"required"` }{}, false, }, { struct { Addr Address `valid:"required"` }{ Addr: Address{"", "123"}, }, true, }, { struct { Pointer *Address `valid:"required"` }{}, false, }, { struct { Pointer *Address `valid:"required"` }{ Pointer: &Address{"", "123"}, }, true, }, { struct { TestByteArray testByteArray `valid:"required"` }{}, false, }, { struct { TestByteArray testByteArray `valid:"required"` }{ testByteArray{}, }, false, }, { struct { TestByteArray testByteArray `valid:"required"` }{ testByteArray{'1', '2', '3', '4', '5', '6', '7', 'A'}, }, true, }, { struct { TestByteMap testByteMap `valid:"required"` }{}, false, }, { struct { TestByteSlice testByteSlice `valid:"required"` }{}, false, }, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } } func TestErrorByField(t *testing.T) { t.Parallel() var tests = []struct { param string expected string }{ {"message", ""}, {"Message", ""}, {"title", ""}, {"Title", "My123 does not validate as alpha"}, {"AuthorIP", "123 does not validate as ipv4"}, } post := &Post{"My123", "duck13126", "123"} _, err := ValidateStruct(post) for _, test := range tests { actual := ErrorByField(err, test.param) if actual != test.expected { t.Errorf("Expected ErrorByField(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestErrorsByField(t *testing.T) { t.Parallel() var tests = []struct { param string expected string }{ {"Title", "My123 does not validate as alpha"}, {"AuthorIP", "123 does not validate as ipv4"}, } post := &Post{Title: "My123", Message: "duck13126", AuthorIP: "123"} _, err := ValidateStruct(post) errs := ErrorsByField(err) if len(errs) != 2 { t.Errorf("There should only be 2 errors but got %v", len(errs)) } for _, test := range tests { if actual, ok := errs[test.param]; !ok || actual != test.expected { t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestValidateStructPointers(t *testing.T) { // Struct which uses pointers for values type UserWithPointers struct { Name *string `valid:"-"` Email *string `valid:"email"` FavoriteFood *string `valid:"length(0|32)"` Nerd *bool `valid:"-"` } var tests = []struct { param string expected string }{ {"Name", ""}, {"Email", "invalid does not validate as email"}, {"FavoriteFood", ""}, {"Nerd", ""}, } name := "Herman" email := "invalid" food := "Pizza" nerd := true user := &UserWithPointers{&name, &email, &food, &nerd} _, err := ValidateStruct(user) for _, test := range tests { actual := ErrorByField(err, test.param) if actual != test.expected { t.Errorf("Expected ErrorByField(%q) to be %v, got %v", test.param, test.expected, actual) } } } func ExampleValidateStruct() { type Post struct { Title string `valid:"alphanum,required"` Message string `valid:"duck,ascii"` AuthorIP string `valid:"ipv4"` } post := &Post{"My Example Post", "duck", "123.234.54.3"} //Add your own struct validation tags TagMap["duck"] = Validator(func(str string) bool { return str == "duck" }) result, err := ValidateStruct(post) if err != nil { println("error: " + err.Error()) } println(result) }
func TestFilePath(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool osType int }{ {"c:\\" + strings.Repeat("a", 32767), true, Win}, //See http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath {"c:\\" + strings.Repeat("a", 32768), false, Win}, {"c:\\path\\file (x86)\bar", true, Win}, {"c:\\path\\file", true, Win}, {"c:\\path\\file:exe", false, Unknown}, {"C:\\", true, Win}, {"c:\\path\\file\\", true, Win}, {"c:/path/file/", false, Unknown}, {"/path/file/", true, Unix}, {"/path/file:SAMPLE/", true, Unix}, {"/path/file:/.txt", true, Unix}, {"/path", true, Unix}, } for _, test := range tests { actual, osType := IsFilePath(test.param) if actual != test.expected || osType != test.osType { t.Errorf("Expected IsFilePath(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsLatitude(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"", false}, {"-90.000", true}, {"+90", true}, {"47.1231231", true}, {"+99.9", false}, {"108", false}, } for _, test := range tests { actual := IsLatitude(test.param) if actual != test.expected { t.Errorf("Expected IsLatitude(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsLongitude(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"", false}, {"-180.000", true}, {"180.1", false}, {"+73.234", true}, {"+382.3811", false}, {"23.11111111", true}, } for _, test := range tests { actual := IsLongitude(test.param) if actual != test.expected { t.Errorf("Expected IsLongitude(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsSSN(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"", false}, {"00-90-8787", false}, {"66690-76", false}, {"191 60 2869", true}, {"191-60-2869", true}, } for _, test := range tests { actual := IsSSN(test.param) if actual != test.expected { t.Errorf("Expected IsSSN(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsMongoID(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"507f1f77bcf86cd799439011", true}, {"507f1f77bcf86cd7994390", false}, {"507f1f77bcf86cd79943901z", false}, {"507f1f77bcf86cd799439011 ", false}, {"", false}, } for _, test := range tests { actual := IsMongoID(test.param) if actual != test.expected { t.Errorf("Expected IsMongoID(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestByteLegnth(t *testing.T) { t.Parallel() var tests = []struct { value string min string max string expected bool }{ {"123456", "0", "100", true}, {"1239999", "0", "0", false}, {"1239asdfasf99", "100", "200", false}, {"1239999asdff29", "10", "30", true}, } for _, test := range tests { actual := ByteLength(test.value, test.min, test.max) if actual != test.expected { t.Errorf("Expected ByteLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual) } } } type Address struct { Street string `valid:"-"` Zip string `json:"zip" valid:"numeric,required"` } type User struct { Name string `valid:"required"` Email string `valid:"required,email"` Password string `valid:"required"` Age int `valid:"required,numeric,@#\u0000"` Home *Address Work []Address } type UserValid struct { Name string `valid:"required"` Email string `valid:"required,email"` Password string `valid:"required"` Age int `valid:"required"` Home *Address Work []Address } type PrivateStruct struct { privateField string `valid:"required,alpha,d_k"` NonZero int ListInt []int ListString []string `valid:"alpha"` Work [2]Address Home Address Map map[string]Address } type NegationStruct struct { NotInt string `valid:"!int"` Int string `valid:"int"` } type LengthStruct struct { Length string `valid:"length(10|20)"` } type Post struct { Title string `valid:"alpha,required"` Message string `valid:"ascii"` AuthorIP string `valid:"ipv4"` } func TestValidateNegationStruct(t *testing.T) { var tests = []struct { param NegationStruct expected bool }{ {NegationStruct{"a1", "11"}, true}, {NegationStruct{"*****@*****.**", "11"}, true}, {NegationStruct{"123456----", "11"}, true}, {NegationStruct{"::1", "11"}, true}, {NegationStruct{"123.123", "11"}, true}, {NegationStruct{"a1", "a1"}, false}, {NegationStruct{"11", "a1"}, false}, {NegationStruct{"11", "11"}, false}, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } } func TestLengthStruct(t *testing.T) { var tests = []struct { param interface{} expected bool }{ {LengthStruct{"11111"}, false}, {LengthStruct{"11111111111111111110000000000000000"}, false}, {LengthStruct{"11dfffdf0099"}, true}, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } } func TestValidateStruct(t *testing.T) { var tests = []struct { param interface{} expected bool }{ {User{"John", "*****@*****.**", "123G#678", 20, &Address{"Street", "123456"}, []Address{Address{"Street", "123456"}, Address{"Street", "123456"}}}, false}, {User{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {User{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {UserValid{"John", "*****@*****.**", "123G#678", 20, &Address{"Street", "123456"}, []Address{Address{"Street", "123456"}, Address{"Street", "123456"}}}, true}, {UserValid{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {UserValid{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {nil, true}, {User{"John", "*****@*****.**", "123G#678", 0, &Address{"Street", "123456"}, []Address{}}, false}, {"im not a struct", false}, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } TagMap["d_k"] = Validator(func(str string) bool { return str == "d_k" }) result, err := ValidateStruct(PrivateStruct{"d_k", 0, []int{1, 2}, []string{"hi", "super"}, [2]Address{Address{"Street", "123456"}, Address{"Street", "123456"}}, Address{"Street", "123456"}, map[string]Address{"address": Address{"Street", "123456"}}}) if result != true { t.Log("Case ", 6, ": expected ", true, " when result is ", result) t.Error(err) t.FailNow() } } func TestRequired(t *testing.T) { testString := "foobar" var tests = []struct { param interface{} expected bool }{ { struct { Pointer *string `valid:"required"` }{}, false, }, { struct { Pointer *string `valid:"required"` }{ Pointer: &testString, }, true, }, { struct { Addr Address `valid:"required"` }{}, false, }, { struct { Addr Address `valid:"required"` }{ Addr: Address{"", "123"}, }, true, }, { struct { Pointer *Address `valid:"required"` }{}, false, }, { struct { Pointer *Address `valid:"required"` }{ Pointer: &Address{"", "123"}, }, true, }, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } } func TestErrorByField(t *testing.T) { t.Parallel() var tests = []struct { param string expected string }{ {"message", ""}, {"Message", ""}, {"title", ""}, {"Title", "My123 does not validate as alpha"}, {"AuthorIP", "123 does not validate as ipv4"}, } post := &Post{"My123", "duck13126", "123"} _, err := ValidateStruct(post) for _, test := range tests { actual := ErrorByField(err, test.param) if actual != test.expected { t.Errorf("Expected ErrorByField(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestValidateStructPointers(t *testing.T) { // Struct which uses pointers for values type UserWithPointers struct { Name *string `valid:"-"` Email *string `valid:"email"` FavoriteFood *string `valid:"length(0|32)"` Nerd *bool `valid:"-"` } var tests = []struct { param string expected string }{ {"Name", ""}, {"Email", "invalid does not validate as email"}, {"FavoriteFood", ""}, {"Nerd", ""}, } name := "Herman" email := "invalid" food := "Pizza" nerd := true user := &UserWithPointers{&name, &email, &food, &nerd} _, err := ValidateStruct(user) for _, test := range tests { actual := ErrorByField(err, test.param) if actual != test.expected { t.Errorf("Expected ErrorByField(%q) to be %v, got %v", test.param, test.expected, actual) } } } func ExampleValidateStruct() { type Post struct { Title string `valid:"alphanum,required"` Message string `valid:"duck,ascii"` AuthorIP string `valid:"ipv4"` } post := &Post{"My Example Post", "duck", "123.234.54.3"} //Add your own struct validation tags TagMap["duck"] = Validator(func(str string) bool { return str == "duck" }) result, err := ValidateStruct(post) if err != nil { println("error: " + err.Error()) } println(result) }
func TestFilePath(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool osType int }{ {"c:\\" + strings.Repeat("a", 32767), true, Win}, //See http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath {"c:\\" + strings.Repeat("a", 32768), false, Win}, {"c:\\path\\file (x86)\bar", true, Win}, {"c:\\path\\file", true, Win}, {"c:\\path\\file:exe", false, Unknown}, {"C:\\", true, Win}, {"c:\\path\\file\\", true, Win}, {"c:/path/file/", false, Unknown}, {"/path/file/", true, Unix}, {"/path/file:SAMPLE/", true, Unix}, {"/path/file:/.txt", true, Unix}, {"/path", true, Unix}, } for _, test := range tests { actual, osType := IsFilePath(test.param) if actual != test.expected || osType != test.osType { t.Errorf("Expected IsFilePath(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsLatitude(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"", false}, {"-90.000", true}, {"+90", true}, {"47.1231231", true}, {"+99.9", false}, {"108", false}, } for _, test := range tests { actual := IsLatitude(test.param) if actual != test.expected { t.Errorf("Expected IsLatitude(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsLongitude(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"", false}, {"-180.000", true}, {"180.1", false}, {"+73.234", true}, {"+382.3811", false}, {"23.11111111", true}, } for _, test := range tests { actual := IsLongitude(test.param) if actual != test.expected { t.Errorf("Expected IsLongitude(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsSSN(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"", false}, {"00-90-8787", false}, {"66690-76", false}, {"191 60 2869", true}, {"191-60-2869", true}, } for _, test := range tests { actual := IsSSN(test.param) if actual != test.expected { t.Errorf("Expected IsSSN(%q) to be %v, got %v", test.param, test.expected, actual) } } } func TestIsMongoID(t *testing.T) { t.Parallel() var tests = []struct { param string expected bool }{ {"507f1f77bcf86cd799439011", true}, {"507f1f77bcf86cd7994390", false}, {"507f1f77bcf86cd79943901z", false}, {"507f1f77bcf86cd799439011 ", false}, {"", false}, } for _, test := range tests { actual := IsMongoID(test.param) if actual != test.expected { t.Errorf("Expected IsMongoID(%q) to be %v, got %v", test.param, test.expected, actual) } } } type Address struct { Street string `valid:"-"` Zip string `json:"zip" valid:"numeric,required"` } type User struct { Name string `valid:"required"` Email string `valid:"required,email"` Password string `valid:"required"` Age int `valid:"required,numeric,@#\u0000"` Home *Address Work []Address } type UserValid struct { Name string `valid:"required"` Email string `valid:"required,email"` Password string `valid:"required"` Age int `valid:"required"` Home *Address Work []Address } type PrivateStruct struct { privateField string `valid:"required,alpha,d_k"` NonZero int ListInt []int ListString []string `valid:"alpha"` Work [2]Address Home Address Map map[string]Address } type NegationStruct struct { NotInt string `valid:"!int"` Int string `valid:"int"` } func TestValidateNegationStruct(t *testing.T) { var tests = []struct { param NegationStruct expected bool }{ {NegationStruct{"a1", "11"}, true}, {NegationStruct{"*****@*****.**", "11"}, true}, {NegationStruct{"123456----", "11"}, true}, {NegationStruct{"::1", "11"}, true}, {NegationStruct{"123.123", "11"}, true}, {NegationStruct{"a1", "a1"}, false}, {NegationStruct{"11", "a1"}, false}, {NegationStruct{"11", "11"}, false}, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } } func TestValidateStruct(t *testing.T) { var tests = []struct { param interface{} expected bool }{ {User{"John", "*****@*****.**", "123G#678", 20, &Address{"Street", "123456"}, []Address{Address{"Street", "123456"}, Address{"Street", "123456"}}}, false}, {User{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {User{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {UserValid{"John", "*****@*****.**", "123G#678", 20, &Address{"Street", "123456"}, []Address{Address{"Street", "123456"}, Address{"Street", "123456"}}}, true}, {UserValid{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {UserValid{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{Address{"Street", "ABC456D89"}, Address{"Street", "123456"}}}, false}, {nil, true}, {User{"John", "*****@*****.**", "123G#678", 0, &Address{"Street", "123456"}, []Address{}}, false}, {"im not a struct", false}, } for _, test := range tests { actual, err := ValidateStruct(test.param) if actual != test.expected { t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) if err != nil { t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) } } } TagMap["d_k"] = Validator(func(str string) bool { return str == "d_k" }) result, err := ValidateStruct(PrivateStruct{"d_k", 0, []int{1, 2}, []string{"hi", "super"}, [2]Address{Address{"Street", "123456"}, Address{"Street", "123456"}}, Address{"Street", "123456"}, map[string]Address{"address": Address{"Street", "123456"}}}) if result != true { t.Log("Case ", 6, ": expected ", true, " when result is ", result) t.Error(err) t.FailNow() } } func ExampleValidateStruct() { type Post struct { Title string `valid:"alphanum,required"` Message string `valid:"duck,ascii"` AuthorIP string `valid:"ipv4"` } post := &Post{"My Example Post", "duck", "123.234.54.3"} //Add your own struct validation tags TagMap["duck"] = Validator(func(str string) bool { return str == "duck" }) result, err := ValidateStruct(post) if err != nil { println("error: " + err.Error()) } println(result) }