github.com/hedzr/evendeep@v0.4.8/internal/natsort/natsort_test.go (about) 1 package natsort 2 3 import ( 4 "math/rand" 5 "reflect" 6 "sort" 7 "strconv" 8 "testing" 9 ) 10 11 func TestStrings(t *testing.T) { 12 golden := []struct { 13 in []string 14 want []string 15 }{ 16 { 17 in: []string{"abc5", "abc1", "abc01", "ab", "abc10", "abc2"}, 18 want: []string{ 19 "ab", 20 "abc1", 21 "abc01", 22 "abc2", 23 "abc5", 24 "abc10", 25 }, 26 }, 27 { 28 in: []string{"foo20", "foo.bar", "foo2", "foo.10", "foo.1", "foo.20", "foo.11", "foo1", "foobar", "foo21", "foo10", "foo11", "foo.21", "foo.2"}, 29 want: []string{ 30 "foo.1", 31 "foo.2", 32 "foo.10", 33 "foo.11", 34 "foo.20", 35 "foo.21", 36 "foo.bar", 37 "foo1", 38 "foo2", 39 "foo10", 40 "foo11", 41 "foo20", 42 "foo21", 43 "foobar", 44 }, 45 }, 46 } 47 for _, g := range golden { 48 Strings(g.in) 49 if !reflect.DeepEqual(g.want, g.in) { 50 t.Errorf("Error: sort failed, expected: %#q, got: %#q", g.want, g.in) 51 } 52 } 53 } 54 55 func TestLess(t *testing.T) { 56 testset := []struct { 57 s1, s2 string 58 less bool 59 }{ 60 {"0", "00", true}, 61 {"00", "0", false}, 62 {"aa", "ab", true}, 63 {"ab", "abc", true}, 64 {"abc", "ad", true}, 65 {"ab1", "ab2", true}, 66 {"ab1c", "ab1c", false}, 67 {"ab12", "abc", true}, 68 {"ab2a", "ab10", true}, 69 {"a0001", "a0000001", true}, 70 {"a10", "abcdefgh2", true}, 71 {"аб2аб", "аб10аб", true}, 72 {"2аб", "3аб", true}, 73 // 74 {"a1b", "a01b", true}, 75 {"a01b", "a1b", false}, 76 {"ab01b", "ab010b", true}, 77 {"ab010b", "ab01b", false}, 78 {"a01b001", "a001b01", true}, 79 {"a001b01", "a01b001", false}, 80 {"a1", "a1x", true}, 81 {"1ax", "1b", false}, 82 {"1b", "1ax", true}, 83 // 84 {"082", "83", true}, 85 // 86 {"083a", "9a", false}, 87 {"9a", "083a", true}, 88 // 89 {"foo.bar", "foo123", true}, 90 {"foo123", "foo.bar", false}, 91 } 92 for _, v := range testset { 93 if res := Less(v.s1, v.s2); res != v.less { 94 t.Errorf("Compared %#q to %#q: expected %v, got %v", 95 v.s1, v.s2, v.less, res) 96 } 97 } 98 } 99 100 func BenchmarkStdStrings(b *testing.B) { 101 set := testSet(300) 102 arr := make([]string, len(set[0])) 103 b.ResetTimer() 104 for i := 0; i < b.N; i++ { 105 for _, list := range set { 106 b.StopTimer() 107 copy(arr, list) 108 b.StartTimer() 109 110 sort.Strings(arr) 111 } 112 } 113 } 114 115 func BenchmarkStrings(b *testing.B) { 116 set := testSet(300) 117 arr := make([]string, len(set[0])) 118 b.ResetTimer() 119 for i := 0; i < b.N; i++ { 120 for _, list := range set { 121 b.StopTimer() 122 copy(arr, list) 123 b.StartTimer() 124 125 Strings(arr) 126 } 127 } 128 } 129 130 func BenchmarkStdLess(b *testing.B) { 131 set := testSet(300) 132 b.ResetTimer() 133 for i := 0; i < b.N; i++ { 134 for j := range set[0] { 135 k := (j + 1) % len(set[0]) 136 _ = set[0][j] < set[0][k] 137 } 138 } 139 } 140 141 func BenchmarkLess(b *testing.B) { 142 set := testSet(300) 143 b.ResetTimer() 144 for i := 0; i < b.N; i++ { 145 for j := range set[0] { 146 k := (j + 1) % len(set[0]) 147 _ = Less(set[0][j], set[0][k]) 148 } 149 } 150 } 151 152 // Get 1000 arrays of 10000-string-arrays (less if -short is specified). 153 func testSet(seed int) [][]string { 154 gen := &generator{ 155 src: rand.New(rand.NewSource( // nolint:gosec //yes,just for test 156 int64(seed), 157 )), 158 } 159 n := 1000 160 if testing.Short() { 161 n = 1 162 } 163 set := make([][]string, n) 164 for i := range set { 165 strings := make([]string, 10000) 166 for idx := range strings { 167 // Generate a random string 168 strings[idx] = gen.NextString() 169 } 170 set[i] = strings 171 } 172 return set 173 } 174 175 type generator struct { 176 src *rand.Rand 177 } 178 179 func (g *generator) NextInt(max int) int { 180 return g.src.Intn(max) 181 } 182 183 // Gets random random-length alphanumeric string. 184 func (g *generator) NextString() (str string) { 185 // Random-length 3-8 chars part 186 strlen := g.src.Intn(6) + 3 187 // Random-length 1-3 num 188 numlen := g.src.Intn(3) + 1 189 // Random position for num in string 190 numpos := g.src.Intn(strlen + 1) 191 // Generate the number 192 var num string 193 for i := 0; i < numlen; i++ { 194 num += strconv.Itoa(g.src.Intn(10)) 195 } 196 // Put it all together 197 for i := 0; i < strlen+1; i++ { 198 if i == numpos { 199 str += num 200 } else { 201 str += g.randchartostring() // nolint:govet //yes 202 } 203 } 204 return str 205 } 206 207 func (g *generator) randchartostring() string { 208 var runes = []rune{rune('a' + g.src.Intn(16))} // nolint:govet //yes 209 return string(runes) 210 }