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  }