diff --git a/g/text/gstr/gstr.go b/g/text/gstr/gstr.go
index 49403b136..4e56d10d8 100644
--- a/g/text/gstr/gstr.go
+++ b/g/text/gstr/gstr.go
@@ -588,7 +588,7 @@ func HideStr(str string, percent int, hide string) string {
buffer.WriteString(string(hideStr))
buffer.WriteString(string(rs[start + hideLen : ]))
if len(array) > 1 {
- buffer.WriteString(array[1])
+ buffer.WriteString("@" + array[1])
}
return buffer.String()
}
diff --git a/g/text/gstr/gstr_pos.go b/g/text/gstr/gstr_pos.go
index 107cb5c58..1225e5332 100644
--- a/g/text/gstr/gstr_pos.go
+++ b/g/text/gstr/gstr_pos.go
@@ -46,11 +46,10 @@ func PosI(haystack, needle string, startOffset...int) int {
return -1
}
- haystack = haystack[offset : ]
if offset < 0 {
offset += length
}
- pos := strings.Index(strings.ToLower(haystack), strings.ToLower(needle))
+ pos := strings.Index(strings.ToLower(haystack[offset : ]), strings.ToLower(needle))
if pos == -1 {
return -1
}
diff --git a/g/text/gstr/gstr_z_unit_basic_test.go b/g/text/gstr/gstr_z_unit_basic_test.go
index 198e014d7..b69939236 100644
--- a/g/text/gstr/gstr_z_unit_basic_test.go
+++ b/g/text/gstr/gstr_z_unit_basic_test.go
@@ -85,7 +85,9 @@ func Test_UcFirst(t *testing.T) {
gtest.Case(t, func() {
s1 := "abcdEFG乱入的中文abcdefg"
e1 := "AbcdEFG乱入的中文abcdefg"
+ gtest.Assert(gstr.UcFirst(""), "")
gtest.Assert(gstr.UcFirst(s1), e1)
+ gtest.Assert(gstr.UcFirst(e1), e1)
})
}
@@ -93,7 +95,9 @@ func Test_LcFirst(t *testing.T) {
gtest.Case(t, func() {
s1 := "AbcdEFG乱入的中文abcdefg"
e1 := "abcdEFG乱入的中文abcdefg"
+ gtest.Assert(gstr.LcFirst(""), "")
gtest.Assert(gstr.LcFirst(s1), e1)
+ gtest.Assert(gstr.LcFirst(e1), e1)
})
}
@@ -131,9 +135,11 @@ func Test_IsNumeric(t *testing.T) {
func Test_SubStr(t *testing.T) {
gtest.Case(t, func() {
- gtest.Assert(gstr.SubStr("我爱GoFrame", 0), "我爱GoFrame")
- gtest.Assert(gstr.SubStr("我爱GoFrame", 2), "GoFrame")
- gtest.Assert(gstr.SubStr("我爱GoFrame", 2, 2), "Go")
+ gtest.Assert(gstr.SubStr("我爱GoFrame", 0), "我爱GoFrame")
+ gtest.Assert(gstr.SubStr("我爱GoFrame", 2), "GoFrame")
+ gtest.Assert(gstr.SubStr("我爱GoFrame", 2, 2), "Go")
+ gtest.Assert(gstr.SubStr("我爱GoFrame", -1, 30), "我爱GoFrame")
+ gtest.Assert(gstr.SubStr("我爱GoFrame", 30, 30), "")
})
}
@@ -143,6 +149,7 @@ func Test_StrLimit(t *testing.T) {
gtest.Assert(gstr.StrLimit("我爱GoFrame", 2, ""), "我爱")
gtest.Assert(gstr.StrLimit("我爱GoFrame", 2, "**"), "我爱**")
gtest.Assert(gstr.StrLimit("我爱GoFrame", 4, ""), "我爱Go")
+ gtest.Assert(gstr.StrLimit("*", 4, ""), "*")
})
}
@@ -154,8 +161,9 @@ func Test_Reverse(t *testing.T) {
func Test_NumberFormat(t *testing.T) {
gtest.Case(t, func() {
- gtest.Assert(gstr.NumberFormat(1234567.8910, 2, ".", ","), "1,234,567.89")
- gtest.Assert(gstr.NumberFormat(1234567.8910, 2, "#", "/"), "1/234/567#89")
+ gtest.Assert(gstr.NumberFormat(1234567.8910, 2, ".", ","), "1,234,567.89")
+ gtest.Assert(gstr.NumberFormat(1234567.8910, 2, "#", "/"), "1/234/567#89")
+ gtest.Assert(gstr.NumberFormat(-1234567.8910, 2, "#", "/"), "-1/234/567#89")
})
}
@@ -163,6 +171,7 @@ func Test_ChunkSplit(t *testing.T) {
gtest.Case(t, func() {
gtest.Assert(gstr.ChunkSplit("1234", 1, "#"), "1#2#3#4#")
gtest.Assert(gstr.ChunkSplit("我爱123", 1, "#"), "我#爱#1#2#3#")
+ gtest.Assert(gstr.ChunkSplit("1234", 1, ""), "1\r\n2\r\n3\r\n4\r\n")
})
}
@@ -204,6 +213,7 @@ func Test_CountChars(t *testing.T) {
func Test_WordWrap(t *testing.T) {
gtest.Case(t, func() {
gtest.Assert(gstr.WordWrap("12 34", 2, "
"), "12
34")
+ gtest.Assert(gstr.WordWrap("12 34", 2, "\n"), "12\n34")
gtest.Assert(gstr.WordWrap("A very long woooooooooooooooooord. and something", 7, "
"),
"A very
long
woooooooooooooooooord.
and
something")
})
@@ -226,6 +236,8 @@ func Test_Repeat(t *testing.T) {
func Test_Str(t *testing.T) {
gtest.Case(t, func() {
gtest.Assert(gstr.Str("name@example.com", "@"), "@example.com")
+ gtest.Assert(gstr.Str("name@example.com", ""), "")
+ gtest.Assert(gstr.Str("name@example.com", "z"), "")
})
}
@@ -274,7 +286,8 @@ func Test_Ord(t *testing.T) {
func Test_HideStr(t *testing.T) {
gtest.Case(t, func() {
- gtest.Assert(gstr.HideStr("15928008611", 40, "*"), "159****8611")
+ gtest.Assert(gstr.HideStr("15928008611", 40, "*"), "159****8611")
+ gtest.Assert(gstr.HideStr("john@kohg.cn", 40, "*"), "jo*n@kohg.cn")
})
}
@@ -322,4 +335,51 @@ func Test_CountI(t *testing.T) {
gtest.Assert(gstr.CountI(s, "b"), 1)
gtest.Assert(gstr.CountI(s, "d"), 2)
})
-}
\ No newline at end of file
+}
+
+func Test_Compare(t *testing.T) {
+ gtest.Case(t, func() {
+ gtest.Assert(gstr.Compare("a", "b"), -1)
+ gtest.Assert(gstr.Compare("a", "a"), 0)
+ gtest.Assert(gstr.Compare("b", "a"), 1)
+ })
+}
+
+func Test_Equal(t *testing.T) {
+ gtest.Case(t, func() {
+ gtest.Assert(gstr.Equal("a", "A"), true)
+ gtest.Assert(gstr.Equal("a", "a"), true)
+ gtest.Assert(gstr.Equal("b", "a"), false)
+ })
+}
+
+
+func Test_Contains(t *testing.T) {
+ gtest.Case(t, func() {
+ gtest.Assert(gstr.Contains("abc", "a"), true)
+ gtest.Assert(gstr.Contains("abc", "A"), false)
+ gtest.Assert(gstr.Contains("abc", "ab"), true)
+ gtest.Assert(gstr.Contains("abc", "abc"), true)
+ })
+}
+
+func Test_ContainsI(t *testing.T) {
+ gtest.Case(t, func() {
+ gtest.Assert(gstr.ContainsI("abc", "a"), true)
+ gtest.Assert(gstr.ContainsI("abc", "A"), true)
+ gtest.Assert(gstr.ContainsI("abc", "Ab"), true)
+ gtest.Assert(gstr.ContainsI("abc", "ABC"), true)
+ gtest.Assert(gstr.ContainsI("abc", "ABCD"), false)
+ gtest.Assert(gstr.ContainsI("abc", "D"), false)
+ })
+}
+
+func Test_ContainsAny(t *testing.T) {
+ gtest.Case(t, func() {
+ gtest.Assert(gstr.ContainsAny("abc", "a"), true)
+ gtest.Assert(gstr.ContainsAny("abc", "cd"), true)
+ gtest.Assert(gstr.ContainsAny("abc", "de"), false)
+ gtest.Assert(gstr.ContainsAny("abc", "A"), false)
+ })
+}
+
diff --git a/g/text/gstr/gstr_z_unit_pos_test.go b/g/text/gstr/gstr_z_unit_pos_test.go
index 49bb339d5..b05b947d4 100644
--- a/g/text/gstr/gstr_z_unit_pos_test.go
+++ b/g/text/gstr/gstr_z_unit_pos_test.go
@@ -17,17 +17,21 @@ import (
func Test_Pos(t *testing.T) {
gtest.Case(t, func() {
s1 := "abcdEFGabcdefg"
- gtest.Assert(gstr.Pos(s1, "ab"), 0)
- gtest.Assert(gstr.Pos(s1, "ab", 2), 7)
+ gtest.Assert(gstr.Pos(s1, "ab"), 0)
+ gtest.Assert(gstr.Pos(s1, "ab", 2), 7)
+ gtest.Assert(gstr.Pos(s1, "abd", 0), -1)
+ gtest.Assert(gstr.Pos(s1, "e", -4), 11)
})
}
func Test_PosI(t *testing.T) {
gtest.Case(t, func() {
s1 := "abcdEFGabcdefg"
- gtest.Assert(gstr.PosI(s1, "zz"), -1)
- gtest.Assert(gstr.PosI(s1, "ab"), 0)
- gtest.Assert(gstr.PosI(s1, "ef", 2), 4)
+ gtest.Assert(gstr.PosI(s1, "zz"), -1)
+ gtest.Assert(gstr.PosI(s1, "ab"), 0)
+ gtest.Assert(gstr.PosI(s1, "ef", 2), 4)
+ gtest.Assert(gstr.PosI(s1, "abd", 0), -1)
+ gtest.Assert(gstr.PosI(s1, "E", -4), 11)
})
}
@@ -38,7 +42,9 @@ func Test_PosR(t *testing.T) {
gtest.Assert(gstr.PosR(s1, "zz"), -1)
gtest.Assert(gstr.PosR(s1, "ab"), 7)
gtest.Assert(gstr.PosR(s2, "ab", -2), 0)
- gtest.Assert(gstr.PosR(s1, "ef"), 11)
+ gtest.Assert(gstr.PosR(s1, "ef"), 11)
+ gtest.Assert(gstr.PosR(s1, "abd", 0), -1)
+ gtest.Assert(gstr.PosR(s1, "e", -4), -1)
})
}
@@ -46,9 +52,11 @@ func Test_PosRI(t *testing.T) {
gtest.Case(t, func() {
s1 := "abcdEFGabcdefg"
s2 := "abcdEFGz1cdeab"
- gtest.Assert(gstr.PosRI(s1, "zz"), -1)
- gtest.Assert(gstr.PosRI(s1, "AB"), 7)
- gtest.Assert(gstr.PosRI(s2, "AB", -2), 0)
- gtest.Assert(gstr.PosRI(s1, "EF"), 11)
+ gtest.Assert(gstr.PosRI(s1, "zz"), -1)
+ gtest.Assert(gstr.PosRI(s1, "AB"), 7)
+ gtest.Assert(gstr.PosRI(s2, "AB", -2), 0)
+ gtest.Assert(gstr.PosRI(s1, "EF"), 11)
+ gtest.Assert(gstr.PosRI(s1, "abd", 0), -1)
+ gtest.Assert(gstr.PosRI(s1, "e", -5), 4)
})
}
\ No newline at end of file
diff --git a/g/util/grand/grand.go b/g/util/grand/grand.go
index 7f4bd5306..77278110f 100644
--- a/g/util/grand/grand.go
+++ b/g/util/grand/grand.go
@@ -16,12 +16,12 @@ var (
// 随机计算是否满足给定的概率(分子/分母)
func Meet(num, total int) bool {
- return Rand(0, total) <= num
+ return Intn(total) < num
}
// 随机计算是否满足给定的概率(float32)
func MeetProb(prob float32) bool {
- return Rand(0, 1e7) <= int(prob*1e7)
+ return Intn(1e7) < int(prob*1e7)
}
// Rand 别名, 返回: [min, max]
@@ -92,6 +92,8 @@ func RandLetters(n int) string {
}
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
+//
+// 返回[0, n)的随机数组成的slice。
func Perm(n int) []int {
m := make([]int, n)
for i := 0; i < n; i++ {
diff --git a/g/util/grand/grand_test.go b/g/util/grand/grand_z_bench_test.go
similarity index 100%
rename from g/util/grand/grand_test.go
rename to g/util/grand/grand_z_bench_test.go
diff --git a/g/util/grand/grand_z_unit_test.go b/g/util/grand/grand_z_unit_test.go
new file mode 100644
index 000000000..0a1b6b25d
--- /dev/null
+++ b/g/util/grand/grand_z_unit_test.go
@@ -0,0 +1,137 @@
+// Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
+//
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file,
+// You can obtain one at https://github.com/gogf/gf.
+
+// go test *.go -bench=".*"
+
+package grand_test
+
+import (
+ "github.com/gogf/gf/g/test/gtest"
+ "github.com/gogf/gf/g/util/grand"
+ "testing"
+)
+
+
+func Test_Intn(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ n := grand.Intn(100)
+ gtest.AssertLT(n, 100)
+ }
+ })
+}
+
+func Test_Meet(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ gtest.Assert(grand.Meet(100, 100), true)
+ }
+ for i := 0; i < 100; i++ {
+ gtest.Assert(grand.Meet(0, 100), false)
+ }
+ for i := 0; i < 100; i++ {
+ gtest.AssertIN(grand.Meet(50, 100), []bool{true, false})
+ }
+ })
+}
+
+func Test_MeetProb(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ gtest.Assert(grand.MeetProb(1), true)
+ }
+ for i := 0; i < 100; i++ {
+ gtest.Assert(grand.MeetProb(0), false)
+ }
+ for i := 0; i < 100; i++ {
+ gtest.AssertIN(grand.MeetProb(0.5), []bool{true, false})
+ }
+ })
+}
+
+func Test_N(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ gtest.Assert(grand.N(1, 1), 1)
+ }
+ for i := 0; i < 100; i++ {
+ gtest.Assert(grand.N(0, 0), 0)
+ }
+ for i := 0; i < 100; i++ {
+ gtest.AssertIN(grand.N(1, 2), []int{1, 2})
+ }
+ })
+}
+
+func Test_Rand(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ gtest.Assert(grand.Rand(1, 1), 1)
+ }
+ for i := 0; i < 100; i++ {
+ gtest.Assert(grand.Rand(0, 0), 0)
+ }
+ for i := 0; i < 100; i++ {
+ gtest.AssertIN(grand.Rand(1, 2), []int{1, 2})
+ }
+ })
+}
+
+func Test_Str(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ gtest.Assert(len(grand.Str(5)), 5)
+ }
+ })
+}
+
+func Test_RandStr(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ gtest.Assert(len(grand.RandStr(5)), 5)
+ }
+ })
+}
+
+func Test_Digits(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ gtest.Assert(len(grand.Digits(5)), 5)
+ }
+ })
+}
+
+func Test_RandDigits(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ gtest.Assert(len(grand.RandDigits(5)), 5)
+ }
+ })
+}
+
+func Test_Letters(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ gtest.Assert(len(grand.Letters(5)), 5)
+ }
+ })
+}
+
+func Test_RandLetters(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ gtest.Assert(len(grand.RandLetters(5)), 5)
+ }
+ })
+}
+
+func Test_Perm(t *testing.T) {
+ gtest.Case(t, func() {
+ for i := 0; i < 100; i++ {
+ gtest.AssertIN(grand.Perm(5), []int{0,1,2,3,4})
+ }
+ })
+}
\ No newline at end of file