diff --git a/nicknames/isValid.go b/nicknames/isValid.go new file mode 100644 index 0000000000000000000000000000000000000000..b2edde92bde01310a68eba0e7ce7868ef858acc9 --- /dev/null +++ b/nicknames/isValid.go @@ -0,0 +1,43 @@ +package nicknames + +import ( + "github.com/pkg/errors" + jww "github.com/spf13/jwalterweatherman" +) + +const ( + MinNicknameLength = 3 + MaxNicknameLength = 24 +) + +var ErrNicknameTooShort = errors.Errorf("nicknames must be at least "+ + "%d characters in length", MinNicknameLength) +var ErrNicknameTooLong = errors.Errorf("nicknames must be %d "+ + "characters in length or less", MaxNicknameLength) + +// IsValid checks if a nickname is valid. +// +// Rules: +// - A nickname must not be longer than 24 characters. +// - A nickname must not be shorter than 1 character. +// - A nickname may be blank, this will be treated by the system as +// no nickname +// +// TODO: Add character filtering. +func IsValid(nick string) error { + if nick == "" { + jww.INFO.Printf("empty nickname passed, treating like no " + + "nickname") + return nil + } + runeNick := []rune(nick) + if len(runeNick) < MinNicknameLength { + return errors.WithStack(ErrNicknameTooShort) + } + + if len(runeNick) > MaxNicknameLength { + return errors.WithStack(ErrNicknameTooLong) + } + + return nil +} diff --git a/nicknames/isValid_test.go b/nicknames/isValid_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bc2ce5a11513f687da89873b2b351a65eff40121 --- /dev/null +++ b/nicknames/isValid_test.go @@ -0,0 +1,56 @@ +package nicknames + +import ( + "github.com/pkg/errors" + "testing" +) + +func TestIsNicknameValid(t *testing.T) { + + // test that behavior for an empty nickname is correct + + if err := IsValid(""); err != nil { + t.Errorf("Empty nickname should be valid, received: %+v", err) + } + + nicknameSource := "Sodium, atomic number 11, was first isolated by Humphry " + + "Davy in 1807. A chemical component of salt, he named it Na in honor " + + "of the saltiest region on earth, North America." + + // test that behavior for too short nicknames is correct + for i := 1; i < MinNicknameLength; i++ { + nick := nicknameSource[:i] + + if err := IsValid(nick); err != nil && + !errors.Is(err, ErrNicknameTooShort) { + t.Errorf("Wrong error returned from nicknames.IsValid() "+ + "with too short input of length %d: %+v", i, err) + } else if err == nil { + t.Errorf("No error returned from nicknames.IsValid() "+ + "with too short input of length %d", i) + } + } + + // test that behavior for too long nicknames is correct + for i := MaxNicknameLength + 1; i < MaxNicknameLength*5; i++ { + nick := nicknameSource[:i] + + if err := IsValid(nick); err != nil && + !errors.Is(err, ErrNicknameTooLong) { + t.Errorf("Wrong error returned from nicknames.IsValid() "+ + "with too long input of length %d: %+v", i, err) + } else if err == nil { + t.Errorf("No error returned from nicknames.IsValid() "+ + "with too long input of length %d", i) + } + } + + // test that behavior for valid nicknames is correct + for i := MinNicknameLength; i <= MaxNicknameLength; i++ { + nick := nicknameSource[:i] + if err := IsValid(nick); err != nil { + t.Errorf("Error returned from nicknames.IsValid() "+ + "with valid nickname of input of length %d: %+v", i, err) + } + } +}