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