tideland.dev/go/slices@v0.2.0/sort_test.go (about)

     1  // Tideland Go Testing - Unit Tests
     2  //
     3  // Copyright (C) 2022 Frank Mueller / Tideland / Oldenburg / Germany
     4  //
     5  // MatchesAll rights reserved. Use of this source code is governed
     6  // by the new BSD license.
     7  
     8  package slices_test // import "tideland.dev/go/slices"
     9  
    10  //--------------------
    11  // IMPORTS
    12  //--------------------
    13  
    14  import (
    15  	"testing"
    16  
    17  	"tideland.dev/go/audit/asserts"
    18  	"tideland.dev/go/audit/generators"
    19  
    20  	"tideland.dev/go/slices"
    21  )
    22  
    23  //--------------------
    24  // TESTS
    25  //--------------------
    26  
    27  // TestSort verifies the standard sorting of slices.
    28  func TestSort(t *testing.T) {
    29  	assert := asserts.NewTesting(t, asserts.FailStop)
    30  
    31  	tests := []struct {
    32  		descr  string
    33  		values []int
    34  		out    []int
    35  	}{
    36  		{
    37  			descr:  "Simple unordered slice",
    38  			values: []int{5, 7, 1, 3, 4, 2, 8, 6, 9},
    39  			out:    []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
    40  		}, {
    41  			descr:  "Unordered double value slice",
    42  			values: []int{9, 5, 7, 3, 1, 3, 5, 4, 2, 8, 5, 6, 9},
    43  			out:    []int{1, 2, 3, 3, 4, 5, 5, 5, 6, 7, 8, 9, 9},
    44  		}, {
    45  			descr:  "Already ordered slice",
    46  			values: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
    47  			out:    []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
    48  		}, {
    49  			descr:  "Reverse ordered slice",
    50  			values: []int{9, 8, 7, 6, 5, 4, 3, 2, 1},
    51  			out:    []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
    52  		}, {
    53  			descr:  "Single value slice",
    54  			values: []int{1, 1, 1, 1, 1},
    55  			out:    []int{1, 1, 1, 1, 1},
    56  		}, {
    57  			descr:  "Empty slice",
    58  			values: []int{},
    59  			out:    []int{},
    60  		}, {
    61  			descr:  "Nil slice",
    62  			values: nil,
    63  			out:    nil,
    64  		},
    65  	}
    66  
    67  	for _, test := range tests {
    68  		assert.Logf(test.descr)
    69  		assert.Equal(slices.Sort(test.values), test.out)
    70  	}
    71  }
    72  
    73  // TestSortWith verifies the sorting of slices with a less function.
    74  func TestSortWith(t *testing.T) {
    75  	assert := asserts.NewTesting(t, asserts.FailStop)
    76  
    77  	less := func(vs []string, i, j int) bool { return len(vs[i]) < len(vs[j]) }
    78  	tests := []struct {
    79  		descr  string
    80  		values []string
    81  		out    []string
    82  	}{
    83  		{
    84  			descr:  "Simple unordered slice",
    85  			values: []string{"alpha", "beta", "phi", "epsilon", "lambda", "pi"},
    86  			out:    []string{"pi", "phi", "beta", "alpha", "lambda", "epsilon"},
    87  		}, {
    88  			descr:  "Unordered double value slice",
    89  			values: []string{"phi", "alpha", "beta", "phi", "epsilon", "beta", "lambda", "pi"},
    90  			out:    []string{"pi", "phi", "phi", "beta", "beta", "alpha", "lambda", "epsilon"},
    91  		}, {
    92  			descr:  "Already ordered slice",
    93  			values: []string{"pi", "phi", "beta", "alpha", "lambda", "epsilon"},
    94  			out:    []string{"pi", "phi", "beta", "alpha", "lambda", "epsilon"},
    95  		}, {
    96  			descr:  "Reverse ordered slice",
    97  			values: []string{"epsilon", "lambda", "alpha", "beta", "phi", "pi"},
    98  			out:    []string{"pi", "phi", "beta", "alpha", "lambda", "epsilon"},
    99  		}, {
   100  			descr:  "Single value slice",
   101  			values: []string{"alpha", "alpha", "alpha", "alpha", "alpha"},
   102  			out:    []string{"alpha", "alpha", "alpha", "alpha", "alpha"},
   103  		}, {
   104  			descr:  "Empty slice",
   105  			values: []string{},
   106  			out:    []string{},
   107  		}, {
   108  			descr:  "Nil slice",
   109  			values: nil,
   110  			out:    nil,
   111  		},
   112  	}
   113  
   114  	for _, test := range tests {
   115  		assert.Logf(test.descr)
   116  		assert.Equal(slices.SortWith(test.values, less), test.out)
   117  	}
   118  }
   119  
   120  // TestIsSorted verifies the check of sorted slices.
   121  func TestIsSorted(t *testing.T) {
   122  	assert := asserts.NewTesting(t, asserts.FailStop)
   123  
   124  	tests := []struct {
   125  		descr  string
   126  		values []int
   127  		out    bool
   128  	}{
   129  		{
   130  			descr:  "Unordered slice",
   131  			values: []int{5, 7, 1, 3, 4, 2, 8, 6, 9},
   132  			out:    false,
   133  		}, {
   134  			descr:  "Ordered slice",
   135  			values: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
   136  			out:    true,
   137  		}, {
   138  			descr:  "Reverse ordered slice",
   139  			values: []int{9, 8, 7, 6, 5, 4, 3, 2, 1},
   140  			out:    false,
   141  		}, {
   142  			descr:  "Single value slice",
   143  			values: []int{1, 1, 1, 1, 1},
   144  			out:    true,
   145  		}, {
   146  			descr:  "Empty slice",
   147  			values: []int{},
   148  			out:    true,
   149  		}, {
   150  			descr:  "Nil slice",
   151  			values: nil,
   152  			out:    true,
   153  		},
   154  	}
   155  
   156  	for _, test := range tests {
   157  		assert.Logf(test.descr)
   158  		assert.Equal(slices.IsSorted(test.values), test.out)
   159  	}
   160  }
   161  
   162  // TestIsSortedWith verifies the check of sorted slices.
   163  func TestIsSortedWith(t *testing.T) {
   164  	assert := asserts.NewTesting(t, asserts.FailStop)
   165  
   166  	less := func(a, b string) bool { return len(a) < len(b) }
   167  	tests := []struct {
   168  		descr  string
   169  		values []string
   170  		out    bool
   171  	}{
   172  		{
   173  			descr:  "Unordered slice",
   174  			values: []string{"alpha", "beta", "phi", "epsilon", "lambda", "pi"},
   175  			out:    false,
   176  		}, {
   177  			descr:  "Ordered slice",
   178  			values: []string{"pi", "phi", "beta", "alpha", "lambda", "epsilon"},
   179  			out:    true,
   180  		}, {
   181  			descr:  "Reverse ordered slice",
   182  			values: []string{"epsilon", "lambda", "alpha", "beta", "phi", "pi"},
   183  			out:    false,
   184  		}, {
   185  			descr:  "Single value slice",
   186  			values: []string{"alpha", "alpha", "alpha", "alpha", "alpha"},
   187  			out:    true,
   188  		}, {
   189  			descr:  "Empty slice",
   190  			values: []string{},
   191  			out:    true,
   192  		}, {
   193  			descr:  "Nil slice",
   194  			values: nil,
   195  			out:    true,
   196  		},
   197  	}
   198  
   199  	for _, test := range tests {
   200  		assert.Logf(test.descr)
   201  		assert.Equal(slices.IsSortedWith(test.values, less), test.out)
   202  	}
   203  }
   204  
   205  //--------------------
   206  // BENCHMARKS AND FUZZ TESTS
   207  //--------------------
   208  
   209  // BenchmarkSort runs a performance test on standard sorting.
   210  func BenchmarkSort(b *testing.B) {
   211  	gen := generators.New(generators.FixedRand())
   212  	vs := gen.Ints(0, 1000, 10000)
   213  
   214  	slices.Sort(vs)
   215  }
   216  
   217  // BenchmarkSortWith runs a performance test on sorting with comparator.
   218  func BenchmarkSortWith(b *testing.B) {
   219  	gen := generators.New(generators.FixedRand())
   220  	vs := gen.Words(10000)
   221  	less := func(vs []string, i, j int) bool { return len(vs[i]) < len(vs[j]) }
   222  
   223  	slices.SortWith(vs, less)
   224  }
   225  
   226  // FuzzSort runs a fuzz test on the standard sorting.
   227  func FuzzSort(f *testing.F) {
   228  	gen := generators.New(generators.FixedRand())
   229  
   230  	f.Add(5)
   231  	f.Fuzz(func(t *testing.T, i int) {
   232  		vs := gen.Ints(0, 1000, 10000)
   233  
   234  		slices.Sort(vs)
   235  	})
   236  }
   237  
   238  // EOF