🐛 utils: fix EqualFold and docs (#1833)

* 🔍 utils: add/improve tests for ToLower/ToUpper/EqualFold

* 🐛 utils: fix EqualFold and docs
pull/1841/head
Serhat Şevki Dinçer 2022-03-23 15:55:13 +03:00 committed by GitHub
parent 2f0d745b5a
commit 2b5b6b24ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 52 deletions

View File

@ -4,7 +4,7 @@
package utils
// ToLowerBytes is the equivalent of bytes.ToLower
// ToLowerBytes converts ascii slice to lower-case
func ToLowerBytes(b []byte) []byte {
for i := 0; i < len(b); i++ {
b[i] = toLowerTable[b[i]]
@ -12,7 +12,7 @@ func ToLowerBytes(b []byte) []byte {
return b
}
// ToUpperBytes is the equivalent of bytes.ToUpper
// ToUpperBytes converts ascii slice to upper-case
func ToUpperBytes(b []byte) []byte {
for i := 0; i < len(b); i++ {
b[i] = toUpperTable[b[i]]
@ -55,16 +55,15 @@ func TrimBytes(b []byte, cutset byte) []byte {
return b[i : j+1]
}
// EqualFold the equivalent of bytes.EqualFold
func EqualFoldBytes(b, s []byte) (equals bool) {
n := len(b)
equals = n == len(s)
if equals {
for i := 0; i < n; i++ {
if equals = b[i]|0x20 == s[i]|0x20; !equals {
break
}
// EqualFoldBytes tests ascii slices for equality case-insensitively
func EqualFoldBytes(b, s []byte) bool {
if len(b) != len(s) {
return false
}
for i := len(b) - 1; i >= 0; i-- {
if toUpperTable[b[i]] != toUpperTable[s[i]] {
return false
}
}
return
return true
}

View File

@ -24,20 +24,20 @@ func Test_ToLowerBytes(t *testing.T) {
}
func Benchmark_ToLowerBytes(b *testing.B) {
path := []byte("/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts")
path := []byte(largeStr)
want := []byte(lowerStr)
var res []byte
b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = ToLowerBytes(path)
}
AssertEqual(b, bytes.Equal(UnsafeBytes("/repos/gofiber/fiber/issues/187643/comments"), res), true)
AssertEqual(b, bytes.Equal(want, res), true)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = bytes.ToLower(path)
}
AssertEqual(b, bytes.Equal(UnsafeBytes("/repos/gofiber/fiber/issues/187643/comments"), res), true)
AssertEqual(b, bytes.Equal(want, res), true)
})
}
@ -56,20 +56,20 @@ func Test_ToUpperBytes(t *testing.T) {
}
func Benchmark_ToUpperBytes(b *testing.B) {
path := []byte("/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts")
path := []byte(largeStr)
want := []byte(upperStr)
var res []byte
b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = ToUpperBytes(path)
}
AssertEqual(b, bytes.Equal(UnsafeBytes("/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS"), res), true)
AssertEqual(b, bytes.Equal(want, res), true)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = bytes.ToUpper(path)
}
AssertEqual(b, bytes.Equal(UnsafeBytes("/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS"), res), true)
AssertEqual(b, bytes.Equal(want, res), true)
})
}
@ -182,10 +182,9 @@ func Benchmark_TrimBytes(b *testing.B) {
}
func Benchmark_EqualFoldBytes(b *testing.B) {
left := []byte("/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts")
right := []byte("/RePos/goFiber/Fiber/issues/187643/COMMENTS")
left := []byte(upperStr)
right := []byte(lowerStr)
var res bool
b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = EqualFoldBytes(left, right)
@ -210,6 +209,8 @@ func Test_EqualFoldBytes(t *testing.T) {
AssertEqual(t, false, res)
res = EqualFoldBytes([]byte("/dddddd"), []byte("eeeeee"))
AssertEqual(t, false, res)
res = EqualFoldBytes([]byte("\na"), []byte("*A"))
AssertEqual(t, false, res)
res = EqualFoldBytes([]byte("/MY3/NAME/IS/:PARAM/*"), []byte("/my3/name/is/:param/*"))
AssertEqual(t, true, res)
res = EqualFoldBytes([]byte("/MY4/NAME/IS/:PARAM/*"), []byte("/my4/nAME/IS/:param/*"))

View File

@ -4,7 +4,7 @@
package utils
// ToLower is the equivalent of strings.ToLower
// ToLower converts ascii string to lower-case
func ToLower(b string) string {
res := make([]byte, len(b))
copy(res, b)
@ -15,7 +15,7 @@ func ToLower(b string) string {
return UnsafeString(res)
}
// ToUpper is the equivalent of strings.ToUpper
// ToUpper converts ascii string to upper-case
func ToUpper(b string) string {
res := make([]byte, len(b))
copy(res, b)
@ -61,16 +61,15 @@ func TrimRight(s string, cutset byte) string {
return s[:lenStr]
}
// EqualFold the equivalent of strings.EqualFold
func EqualFold(b, s string) (equals bool) {
n := len(b)
equals = n == len(s)
if equals {
for i := 0; i < n; i++ {
if equals = b[i]|0x20 == s[i]|0x20; !equals {
break
}
// EqualFold tests ascii strings for equality case-insensitively
func EqualFold(b, s string) bool {
if len(b) != len(s) {
return false
}
for i := len(b) - 1; i >= 0; i-- {
if toUpperTable[b[i]] != toUpperTable[s[i]] {
return false
}
}
return
return true
}

View File

@ -15,21 +15,25 @@ func Test_ToUpper(t *testing.T) {
AssertEqual(t, "/MY/NAME/IS/:PARAM/*", res)
}
func Benchmark_ToUpper(b *testing.B) {
path := "/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts"
var res string
const (
largeStr = "/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts/RePos/GoFiBer/FibEr/iSsues/CoMmEnts"
upperStr = "/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS/REPOS/GOFIBER/FIBER/ISSUES/COMMENTS"
lowerStr = "/repos/gofiber/fiber/issues/187643/comments/repos/gofiber/fiber/issues/comments"
)
func Benchmark_ToUpper(b *testing.B) {
var res string
b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = ToUpper(path)
res = ToUpper(largeStr)
}
AssertEqual(b, "/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS", res)
AssertEqual(b, upperStr, res)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = strings.ToUpper(path)
res = strings.ToUpper(largeStr)
}
AssertEqual(b, "/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS", res)
AssertEqual(b, upperStr, res)
})
}
@ -48,19 +52,18 @@ func Test_ToLower(t *testing.T) {
}
func Benchmark_ToLower(b *testing.B) {
path := "/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts"
var res string
b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = ToLower(path)
res = ToLower(largeStr)
}
AssertEqual(b, "/repos/gofiber/fiber/issues/187643/comments", res)
AssertEqual(b, lowerStr, res)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = strings.ToLower(path)
res = strings.ToLower(largeStr)
}
AssertEqual(b, "/repos/gofiber/fiber/issues/187643/comments", res)
AssertEqual(b, lowerStr, res)
})
}
@ -180,19 +183,16 @@ func Benchmark_Trim(b *testing.B) {
// go test -v -run=^$ -bench=Benchmark_EqualFold -benchmem -count=4
func Benchmark_EqualFold(b *testing.B) {
left := "/RePos/GoFiBer/FibEr/iSsues/187643/CoMmEnts"
right := "/RePos/goFiber/Fiber/issues/187643/COMMENTS"
var res bool
b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = EqualFold(left, right)
res = EqualFold(upperStr, lowerStr)
}
AssertEqual(b, true, res)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = strings.EqualFold(left, right)
res = strings.EqualFold(upperStr, lowerStr)
}
AssertEqual(b, true, res)
})
@ -208,6 +208,8 @@ func Test_EqualFold(t *testing.T) {
AssertEqual(t, false, res)
res = EqualFold("/dddddd", "eeeeee")
AssertEqual(t, false, res)
res = EqualFold("\na", "*A")
AssertEqual(t, false, res)
res = EqualFold("/MY3/NAME/IS/:PARAM/*", "/my3/name/is/:param/*")
AssertEqual(t, true, res)
res = EqualFold("/MY4/NAME/IS/:PARAM/*", "/my4/nAME/IS/:param/*")