CI / test (pull_request) Successful in 34s
MinLength/MaxLength measured len(value), so a string of 8 accented characters (9+ bytes) failed MaxLength(8) despite the error message promising "characters". Count with utf8.RuneCountInString so the check matches the wording and the common-sense intent. Still not grapheme-cluster aware (combining marks, emoji ZWJ sequences count as several runes), which is out of scope for a stdlib-only helper. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
76 lines
1.6 KiB
Go
76 lines
1.6 KiB
Go
package validate
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
func ExampleMaxLength() {
|
|
testMaxLength := MaxLength(8)
|
|
fmt.Println(testMaxLength("this string is too long"))
|
|
// Output: must contain no more than 8 characters
|
|
}
|
|
|
|
func ExampleMinLength() {
|
|
testMinLength := MinLength(8)
|
|
fmt.Println(testMinLength("2short"))
|
|
// Output: must contain at least 8 characters
|
|
}
|
|
|
|
func TestMaxLength(t *testing.T) {
|
|
testCases := map[int]map[string]error{
|
|
8: {
|
|
"abcd": nil,
|
|
"abcdefgh": nil,
|
|
"abcd efg": nil,
|
|
"abcdéfgh": nil, // 8 runes, 9 bytes
|
|
"abcdefghi": ErrMustBeShorter.With(8),
|
|
"abcdéfghi": ErrMustBeShorter.With(8), // 9 runes, 10 bytes
|
|
},
|
|
}
|
|
|
|
for setup, values := range testCases {
|
|
testMaxLength := MaxLength(setup)
|
|
|
|
for input, want := range values {
|
|
t.Run(fmt.Sprintf("%d/%s", setup, input), func(t *testing.T) {
|
|
got := testMaxLength(input)
|
|
|
|
if !errors.Is(got, want) {
|
|
t.Error("got", got)
|
|
t.Error("want", want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMinLength(t *testing.T) {
|
|
testCases := map[int]map[string]error{
|
|
8: {
|
|
"abcd": ErrMustBeLonger.With(8),
|
|
"abcdéfg": ErrMustBeLonger.With(8), // 7 runes, 8 bytes
|
|
"abcdefgh": nil,
|
|
"abcdéfgh": nil, // 8 runes, 9 bytes
|
|
"abcd efg": nil,
|
|
"abcdefghi": nil,
|
|
},
|
|
}
|
|
|
|
for setup, values := range testCases {
|
|
testMinLength := MinLength(setup)
|
|
|
|
for input, want := range values {
|
|
t.Run(fmt.Sprintf("%d/%s", setup, input), func(t *testing.T) {
|
|
got := testMinLength(input)
|
|
|
|
if !errors.Is(got, want) {
|
|
t.Error("got", got)
|
|
t.Error("want", want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|