github.com/richardwilkes/toolbox@v1.121.0/txt/natural_sort_test.go (about) 1 // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved. 2 // 3 // This Source Code Form is subject to the terms of the Mozilla Public 4 // License, version 2.0. If a copy of the MPL was not distributed with 5 // this file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 // 7 // This Source Code Form is "Incompatible With Secondary Licenses", as 8 // defined by the Mozilla Public License, version 2.0. 9 10 package txt_test 11 12 import ( 13 "flag" 14 "fmt" 15 "math/rand/v2" 16 "strconv" 17 "testing" 18 19 "github.com/richardwilkes/toolbox/atexit" 20 "github.com/richardwilkes/toolbox/check" 21 "github.com/richardwilkes/toolbox/txt" 22 ) 23 24 var benchSet []string 25 26 func TestMain(m *testing.M) { 27 flag.Parse() 28 if f := flag.Lookup("test.bench"); f != nil && f.Value.String() != "" { 29 initBenchSet() 30 } 31 atexit.Exit(m.Run()) 32 } 33 34 func TestNaturalLess(t *testing.T) { 35 testset := []struct { 36 s1 string 37 s2 string 38 caseInsensitive bool 39 less bool 40 }{ 41 {"0", "00", false, true}, 42 {"00", "0", false, false}, 43 {"aa", "ab", false, true}, 44 {"ab", "abc", false, true}, 45 {"abc", "ad", false, true}, 46 {"ab1", "ab2", false, true}, 47 {"ab1c", "ab1c", false, false}, 48 {"ab12", "abc", false, true}, 49 {"ab2a", "ab10", false, true}, 50 {"a0001", "a0000001", false, true}, 51 {"a10", "abcdefgh2", false, true}, 52 {"аб2аб", "аб10аб", false, true}, 53 {"2аб", "3аб", false, true}, 54 {"a1b", "a01b", false, true}, 55 {"a01b", "a1b", false, false}, 56 {"ab01b", "ab010b", false, true}, 57 {"ab010b", "ab01b", false, false}, 58 {"a01b001", "a001b01", false, true}, 59 {"a001b01", "a01b001", false, false}, 60 {"a1", "a1x", false, true}, 61 {"1ax", "1b", false, true}, 62 {"1b", "1ax", false, false}, 63 {"082", "83", false, true}, 64 {"083a", "9a", false, false}, 65 {"9a", "083a", false, true}, 66 {"a123", "A0123", true, true}, 67 {"A123", "a0123", true, true}, 68 {"ab010b", "ab01B", true, false}, 69 {"1.12.34", "1.2", false, false}, 70 {"1.2.34", "1.11.11", false, true}, 71 } 72 for _, v := range testset { 73 check.Equal(t, v.less, txt.NaturalLess(v.s1, v.s2, v.caseInsensitive), fmt.Sprintf("%q < %q", v.s1, v.s2)) 74 } 75 } 76 77 func BenchmarkStdStringLess(b *testing.B) { 78 for i := 0; i < b.N; i++ { 79 for j := range benchSet { 80 _ = benchSet[j] < benchSet[(j+1)%len(benchSet)] 81 } 82 } 83 } 84 85 func BenchmarkNaturalLess(b *testing.B) { 86 for i := 0; i < b.N; i++ { 87 for j := range benchSet { 88 _ = txt.NaturalLess(benchSet[j], benchSet[(j+1)%len(benchSet)], false) 89 } 90 } 91 } 92 93 func BenchmarkNaturalLessCaseInsensitive(b *testing.B) { 94 for i := 0; i < b.N; i++ { 95 for j := range benchSet { 96 _ = txt.NaturalLess(benchSet[j], benchSet[(j+1)%len(benchSet)], true) 97 } 98 } 99 } 100 101 func initBenchSet() { 102 rnd := rand.New(rand.NewPCG(22, 1967)) //nolint:gosec // Use of weak prng is fine here 103 benchSet = make([]string, 20000) 104 for i := range benchSet { 105 strlen := rnd.IntN(6) + 3 106 numlen := rnd.IntN(3) + 1 107 numpos := rnd.IntN(strlen + 1) 108 var num string 109 for j := 0; j < numlen; j++ { 110 num += strconv.Itoa(rnd.IntN(10)) 111 } 112 var str string 113 for j := 0; j < strlen+1; j++ { 114 if j == numpos { 115 str += num 116 } else { 117 str += string(rune('a' + rnd.IntN(16))) 118 } 119 } 120 benchSet[i] = str 121 } 122 }