package validate import ( "errors" "fmt" "testing" ) func ExampleEmail() { fmt.Println(Email("not an email")) // Output: invalid email address } func FuzzEmail(f *testing.F) { for _, seed := range []string{ "", "alice@example.com", "not an email", "a@b", "Alice ", "alice@example.com ", } { f.Add(seed) } f.Fuzz(func(t *testing.T, input string) { err := Email(input) // The only error Email ever returns is ErrInvalidEmail. if err != nil && !errors.Is(err, ErrInvalidEmail) { t.Fatalf("unexpected error for %q: %v", input, err) } // A verdict of "valid" must be stable on re-validation. if err == nil { if err2 := Email(input); err2 != nil { t.Fatalf("inconsistent verdict for %q: first nil, then %v", input, err2) } } }) } func TestEmail(t *testing.T) { testCases := map[string]error{ "test@example.com": nil, "firstname.lastname@some-website.co.uk": nil, "alice+tag@example.com": nil, "alice@localhost": nil, // ParseAddress does not require a dotted domain "not an email": ErrInvalidEmail, "testexample.com": ErrInvalidEmail, "Alice ": ErrInvalidEmail, // display name "": ErrInvalidEmail, // angle brackets "alice@example.com ": ErrInvalidEmail, // trailing space "a@b.com, c@d.com": ErrInvalidEmail, // address list } for input, want := range testCases { t.Run(input, func(t *testing.T) { got := Email(input) if !errors.Is(got, want) { t.Error("got", got) t.Error("want", want) } }) } }