1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-03-01 00:35:28 +08:00

Compare commits

..

2 Commits

Author SHA1 Message Date
dudaodong 27667f8b3a fix: fix bugs in test 2025-04-21 15:08:16 +08:00
dudaodong 0b5dc86d70 refactor: refact some strutil functions 2025-04-21 14:07:52 +08:00
8 changed files with 140 additions and 140 deletions
+49 -49
View File
@@ -1,51 +1,51 @@
-----BEGIN rsa private key----- -----BEGIN rsa private key-----
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
-----END rsa private key----- -----END rsa private key-----
+12 -12
View File
@@ -1,14 +1,14 @@
-----BEGIN rsa public key----- -----BEGIN rsa public key-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtKEukXkdl8ggX5I5Us0M MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtXr+2FbR6Prdf9U0gfq2
BcsrFzbTgwOn8u72IhJzruvsHcjlGGF5L1eXh3C0zbcoWq+Bxf8NnXvSXASZlZHT OJbTD82m84bbdeyfsakabYp8Haw6mZW6ebRNPJvQ87H6DbA55hK1E7y6m+wjvbUo
iSVLFerxFw2LwTNcyfOz/Y/wIbtrYu4ZdttLKdJS607UvnZ57O7SQni5rxYAP5j+ pnkGh75Cp04CoQvaU8Rs7MrQcJ2Zz1VRRgugmqwJMWE/FC5eGXvvpDjF2h2lqThK
veKHEJgAO7Sn0lEEWwkeudsfVrQmQx6JHYtCtx78p2GHXPj9wXWHxWHKMkczKtmB ZTKcvhqfZ3dNX+6v4EQ4BbjSGKdzpyexzR1WSV9IzZYRHMk8jCoEHOx9ItEzoToB
FDLlYocPhQfWzx87sYKjGmTMGzVddsrllAqVozlxXTQndOdozx8BWHSBiYWguOvW f9yAq0DhufylqSRbjKLhR7A3IiRSLVNfu0Sz5cfNlS7eUA060QS8AV9BgGNTkl75
iYjvryrIf0B7wn4wt3o2Yre3w4BkwrTUE73JWG2q1NLuPoT27m7WcdVFGGcKAygA aj8BCOmoHIW85SsSZvdQWYwmlM76Jn+tfNNnY7Uuqtz2gI1odcy1nXembXWJryxu
dMMSwS530v8tnAw876/w1SfUmtkIcqknysMjsvxHx1fbEfkl3b0yBnzcUrT1qxzm YCkSAwpU8UNIQpZeKwBnBxaf0pj3W1m3UzEqhGkkCrKq8LkNSGZSkhT+bI65fNx2
NEqJSQXBtFYFyGgyeL8J1ul/T5hPSNz0we5TO/xRkX5Y1HNJ+a2r8EnE1PU8zgQG LZ7lS165szkeyqS8aikxcBpdx7Z/bqbFFuI42KX+IpXAJCAtvsQ0XXinr83MLcY/
BxYSIub4ajSUccyn5yHQ/k2FlsolZiu/UzfnzMgdg55svgf5x1ntKYBoVHuYe84A I2Ic/5Sgz7txfZsKKwKt48ETS9BjxGPWo1Dd5YjM8ZJWJv2Rf0mwVjUMClFSNBm8
b3WRAeVlUi0OphvFlBzfIQvrG2sRbiPZRZZ0E8kBH94zPmrFmyX+7TwlSqVHtNFc x+aWGVIKjpocN/plpEZmFrWdPcWM4ZH3qGCEnVVkqPvqClahNSQXsM4W7msYts1I
+Ynz+hrHcd4z6N7fIb+D1gSYuukkcRqr4ANO0ugZk0YYKaWDf86H7OZOXna8ObIA Uq31tjBSV5bL6l2K8jFJa4PRYdzh1vHhDOAYTpgDkQbNaoDlDS2o/0TkAGUfXWJt
i+3gx+Wcp1lm7Ffk9sn+dGkCAwEAAQ== R3D35wRJzoa7bCMt5BuFE3sCAwEAAQ==
-----END rsa public key----- -----END rsa public key-----
-3
View File
@@ -15,7 +15,6 @@ func TestSinglyLink_InsertAtFirst(t *testing.T) {
link.InsertAtHead(1) link.InsertAtHead(1)
link.InsertAtHead(2) link.InsertAtHead(2)
link.InsertAtHead(3) link.InsertAtHead(3)
link.Print()
expected := []int{3, 2, 1} expected := []int{3, 2, 1}
values := link.Values() values := link.Values()
@@ -32,7 +31,6 @@ func TestSinglyLink_InsertAtTail(t *testing.T) {
link.InsertAtTail(1) link.InsertAtTail(1)
link.InsertAtTail(2) link.InsertAtTail(2)
link.InsertAtTail(3) link.InsertAtTail(3)
link.Print()
expected := []int{1, 2, 3} expected := []int{1, 2, 3}
values := link.Values() values := link.Values()
@@ -77,7 +75,6 @@ func TestSinglyLink_DeleteAtHead(t *testing.T) {
link.InsertAtTail(4) link.InsertAtTail(4)
link.DeleteAtHead() link.DeleteAtHead()
link.Print()
expected := []int{2, 3, 4} expected := []int{2, 3, 4}
values := link.Values() values := link.Values()
+2
View File
@@ -2,6 +2,7 @@ package eventbus
import ( import (
"fmt" "fmt"
"sort"
"sync" "sync"
"time" "time"
) )
@@ -224,6 +225,7 @@ func ExampleEventBus_GetEvents() {
eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) eb.Subscribe("event2", func(eventData int) {}, false, 0, nil)
events := eb.GetEvents() events := eb.GetEvents()
sort.Strings(events)
for _, event := range events { for _, event := range events {
fmt.Println(event) fmt.Println(event)
+3 -1
View File
@@ -1,6 +1,7 @@
package eventbus package eventbus
import ( import (
"sort"
"sync" "sync"
"testing" "testing"
"time" "time"
@@ -213,7 +214,8 @@ func TestEventBus_GetEvents(t *testing.T) {
eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) eb.Subscribe("event2", func(eventData int) {}, false, 0, nil)
events := eb.GetEvents() events := eb.GetEvents()
sort.Strings(events)
assert.Equal(2, len(events)) assert.Equal(2, len(events))
assert.EqualValues([]string{"event1", "event2"}, events) assert.Equal([]string{"event1", "event2"}, events)
} }
+14 -15
View File
@@ -3,7 +3,6 @@ package netutil
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
@@ -27,8 +26,8 @@ func TestHttpGet(t *testing.T) {
return return
} }
body, _ := io.ReadAll(resp.Body) defer resp.Body.Close()
t.Log("response: ", resp.StatusCode, string(body)) t.Log("response status:", resp.StatusCode)
} }
func TestHttpPost(t *testing.T) { func TestHttpPost(t *testing.T) {
@@ -49,8 +48,8 @@ func TestHttpPost(t *testing.T) {
return return
} }
body, _ := io.ReadAll(resp.Body) defer resp.Body.Close()
t.Log("response: ", resp.StatusCode, string(body)) t.Log("response status:", resp.StatusCode)
} }
func TestHttpPostFormData(t *testing.T) { func TestHttpPostFormData(t *testing.T) {
@@ -69,8 +68,8 @@ func TestHttpPostFormData(t *testing.T) {
return return
} }
body, _ := io.ReadAll(resp.Body) defer resp.Body.Close()
t.Log("response: ", resp.StatusCode, string(body)) t.Log("response status:", resp.StatusCode)
} }
func TestHttpPut(t *testing.T) { func TestHttpPut(t *testing.T) {
@@ -92,8 +91,8 @@ func TestHttpPut(t *testing.T) {
return return
} }
body, _ := io.ReadAll(resp.Body) defer resp.Body.Close()
t.Log("response: ", resp.StatusCode, string(body)) t.Log("response status:", resp.StatusCode)
} }
func TestHttpPatch(t *testing.T) { func TestHttpPatch(t *testing.T) {
@@ -115,8 +114,8 @@ func TestHttpPatch(t *testing.T) {
return return
} }
body, _ := io.ReadAll(resp.Body) defer resp.Body.Close()
t.Log("response: ", resp.StatusCode, string(body)) t.Log("response status:", resp.StatusCode)
} }
func TestHttpDelete(t *testing.T) { func TestHttpDelete(t *testing.T) {
@@ -127,8 +126,8 @@ func TestHttpDelete(t *testing.T) {
return return
} }
body, _ := io.ReadAll(resp.Body) defer resp.Body.Close()
t.Log("response: ", resp.StatusCode, string(body)) t.Log("response status:", resp.StatusCode)
} }
func TestConvertMapToQueryString(t *testing.T) { func TestConvertMapToQueryString(t *testing.T) {
@@ -229,8 +228,8 @@ func TestHttpClent_Post(t *testing.T) {
return return
} }
body, _ := io.ReadAll(resp.Body) defer resp.Body.Close()
t.Log("response: ", resp.StatusCode, string(body)) t.Log("response status:", resp.StatusCode)
} }
func TestStructToUrlValues(t *testing.T) { func TestStructToUrlValues(t *testing.T) {
+42 -39
View File
@@ -37,16 +37,17 @@ func CamelCase(s string) string {
// Capitalize converts the first character of a string to upper case and the remaining to lower case. // Capitalize converts the first character of a string to upper case and the remaining to lower case.
// Play: https://go.dev/play/p/2OAjgbmAqHZ // Play: https://go.dev/play/p/2OAjgbmAqHZ
func Capitalize(s string) string { func Capitalize(s string) string {
result := make([]rune, len(s)) if s == "" {
for i, v := range s { return s
if i == 0 {
result[i] = unicode.ToUpper(v)
} else {
result[i] = unicode.ToLower(v)
}
} }
return string(result) runes := []rune(s)
runes[0] = unicode.ToUpper(runes[0])
for i := 1; i < len(runes); i++ {
runes[i] = unicode.ToLower(runes[i])
}
return string(runes)
} }
// UpperFirst converts the first character of string to upper case. // UpperFirst converts the first character of string to upper case.
@@ -127,51 +128,59 @@ func UpperSnakeCase(s string) string {
// Before returns the substring of the source string up to the first occurrence of the specified string. // Before returns the substring of the source string up to the first occurrence of the specified string.
// Play: https://go.dev/play/p/JAWTZDS4F5w // Play: https://go.dev/play/p/JAWTZDS4F5w
func Before(s, char string) string { func Before(s, char string) string {
i := strings.Index(s, char) if char == "" {
if s == "" || char == "" || i == -1 {
return s return s
} }
return s[0:i] if i := strings.Index(s, char); i >= 0 {
return s[:i]
}
return s
} }
// BeforeLast returns the substring of the source string up to the last occurrence of the specified string. // BeforeLast returns the substring of the source string up to the last occurrence of the specified string.
// Play: https://go.dev/play/p/pJfXXAoG_Te // Play: https://go.dev/play/p/pJfXXAoG_Te
func BeforeLast(s, char string) string { func BeforeLast(s, char string) string {
i := strings.LastIndex(s, char) if char == "" {
if s == "" || char == "" || i == -1 {
return s return s
} }
return s[0:i] if i := strings.LastIndex(s, char); i >= 0 {
return s[:i]
}
return s
} }
// After returns the substring after the first occurrence of a specified string in the source string. // After returns the substring after the first occurrence of a specified string in the source string.
// Play: https://go.dev/play/p/RbCOQqCDA7m // Play: https://go.dev/play/p/RbCOQqCDA7m
func After(s, char string) string { func After(s, char string) string {
i := strings.Index(s, char) if char == "" {
if s == "" || char == "" || i == -1 {
return s return s
} }
if i := strings.Index(s, char); i >= 0 {
return s[i+len(char):] return s[i+len(char):]
} }
return s
}
// AfterLast returns the substring after the last occurrence of a specified string in the source string. // AfterLast returns the substring after the last occurrence of a specified string in the source string.
// Play: https://go.dev/play/p/1TegARrb8Yn // Play: https://go.dev/play/p/1TegARrb8Yn
func AfterLast(s, char string) string { func AfterLast(s, char string) string {
i := strings.LastIndex(s, char) if char == "" {
if s == "" || char == "" || i == -1 {
return s return s
} }
if i := strings.LastIndex(s, char); i >= 0 {
return s[i+len(char):] return s[i+len(char):]
} }
return s
}
// IsString check if the value data type is string or not. // IsString check if the value data type is string or not.
// Play: https://go.dev/play/p/IOgq7oF9ERm // Play: https://go.dev/play/p/IOgq7oF9ERm
func IsString(v any) bool { func IsString(v any) bool {
@@ -213,22 +222,17 @@ func Wrap(str string, wrapWith string) string {
// Unwrap a given string from anther string. will change source string. // Unwrap a given string from anther string. will change source string.
// Play: https://go.dev/play/p/Ec2q4BzCpG- // Play: https://go.dev/play/p/Ec2q4BzCpG-
func Unwrap(str string, wrapToken string) string { func Unwrap(str string, wrapToken string) string {
if str == "" || wrapToken == "" { if wrapToken == "" || !strings.HasPrefix(str, wrapToken) || !strings.HasSuffix(str, wrapToken) {
return str return str
} }
firstIndex := strings.Index(str, wrapToken) if len(str) < 2*len(wrapToken) {
lastIndex := strings.LastIndex(str, wrapToken)
if firstIndex == 0 && lastIndex > 0 && lastIndex <= len(str)-1 {
if len(wrapToken) <= lastIndex {
str = str[len(wrapToken):lastIndex]
}
}
return str return str
} }
return str[len(wrapToken) : len(str)-len(wrapToken)]
}
// SplitEx split a given string which can control the result slice contains empty string or not. // SplitEx split a given string which can control the result slice contains empty string or not.
// Play: https://go.dev/play/p/Us-ySSbWh-3 // Play: https://go.dev/play/p/Us-ySSbWh-3
func SplitEx(s, sep string, removeEmptyString bool) []string { func SplitEx(s, sep string, removeEmptyString bool) []string {
@@ -286,22 +290,21 @@ func Substring(s string, offset int, length uint) string {
size := len(rs) size := len(rs)
if offset < 0 { if offset < 0 {
offset = size + offset offset += size
}
if offset < 0 { if offset < 0 {
offset = 0 offset = 0
} }
}
if offset > size { if offset > size {
return "" return ""
} }
if length > uint(size)-uint(offset) { end := offset + int(length)
length = uint(size - offset) if end > size {
end = size
} }
str := string(rs[offset : offset+int(length)]) return strings.ReplaceAll(string(rs[offset:end]), "\x00", "")
return strings.Replace(str, "\x00", "", -1)
} }
// SplitWords splits a string into words, word only contains alphabetic characters. // SplitWords splits a string into words, word only contains alphabetic characters.
+15 -18
View File
@@ -1,6 +1,7 @@
package strutil package strutil
import ( import (
"strings"
"unicode" "unicode"
) )
@@ -111,31 +112,27 @@ func padAtPosition(str string, length int, padStr string, position int) string {
padStr = " " padStr = " "
} }
length = length - len(str) totalPad := length - len(str)
startPadLen := 0 startPad := 0
if position == 0 { if position == 0 {
startPadLen = length / 2 startPad = totalPad / 2
} else if position == 1 { } else if position == 1 {
startPadLen = length startPad = totalPad
} else if position == 2 {
startPad = 0
} }
endPadLen := length - startPadLen endPad := totalPad - startPad
charLen := len(padStr) repeatPad := func(n int) string {
leftPad := "" repeated := strings.Repeat(padStr, (n+len(padStr)-1)/len(padStr))
cur := 0 return repeated[:n]
for cur < startPadLen {
leftPad += string(padStr[cur%charLen])
cur++
} }
cur = 0 left := repeatPad(startPad)
rightPad := "" right := repeatPad(endPad)
for cur < endPadLen {
rightPad += string(padStr[cur%charLen])
cur++
}
return leftPad + str + rightPad return left + str + right
} }
// isLetter checks r is a letter but not CJK character. // isLetter checks r is a letter but not CJK character.