From f576b0b81eba47063f71c4133932fb57f396a483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serhat=20=C5=9Eevki=20Din=C3=A7er?= Date: Tue, 22 Mar 2022 23:24:47 +0300 Subject: [PATCH 1/2] :mag: utils: add/improve tests for ToLower/ToUpper/EqualFold --- utils/bytes_test.go | 23 ++++++++++++----------- utils/strings_test.go | 34 ++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/utils/bytes_test.go b/utils/bytes_test.go index ccae826bfb..a449856db1 100644 --- a/utils/bytes_test.go +++ b/utils/bytes_test.go @@ -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/*")) diff --git a/utils/strings_test.go b/utils/strings_test.go index ab312617e2..c0de5875c6 100644 --- a/utils/strings_test.go +++ b/utils/strings_test.go @@ -15,21 +15,25 @@ func Test_ToUpper(t *testing.T) { AssertEqual(t, "/MY/NAME/IS/:PARAM/*", res) } +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) { - 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 = 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/*") From 6cfb9ae6a220b68d772ca7c9ec7af097cb845c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Serhat=20=C5=9Eevki=20Din=C3=A7er?= Date: Wed, 23 Mar 2022 00:50:47 +0300 Subject: [PATCH 2/2] :bug: utils: fix EqualFold and docs --- utils/bytes.go | 23 +++++++++++------------ utils/strings.go | 23 +++++++++++------------ 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/utils/bytes.go b/utils/bytes.go index 8d39a92766..49f55b2de7 100644 --- a/utils/bytes.go +++ b/utils/bytes.go @@ -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 } diff --git a/utils/strings.go b/utils/strings.go index 466413af6a..109d132f1e 100644 --- a/utils/strings.go +++ b/utils/strings.go @@ -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 }