go-hep.org/x/hep@v0.38.1/sliceop/sliceop_test.go (about)

     1  // Copyright ©2021 The go-hep Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build go1.18
     6  
     7  package sliceop
     8  
     9  import (
    10  	"fmt"
    11  	"math/rand"
    12  	"reflect"
    13  	"testing"
    14  )
    15  
    16  func panics(t *testing.T, want error) func() {
    17  	t.Helper()
    18  	return func() {
    19  		err := recover()
    20  		if err == nil {
    21  			t.Fatalf("expected a panic")
    22  		}
    23  		if got, want := err.(error).Error(), want.Error(); got != want {
    24  			t.Fatalf("invalid panic message.\ngot= %v\nwant=%v",
    25  				got, want,
    26  			)
    27  		}
    28  	}
    29  }
    30  
    31  func TestMap(t *testing.T) {
    32  	defer panics(t, errLength)()
    33  
    34  	_ = Map(make([]float64, 3), make([]float64, 5), nil)
    35  }
    36  
    37  func TestTake(t *testing.T) {
    38  	for _, tc := range []struct {
    39  		dst, src []float64
    40  		inds     []int
    41  		want     []float64
    42  		panics   error
    43  	}{
    44  		{
    45  			dst:  nil,
    46  			src:  []float64{1, 2, 3},
    47  			inds: []int{1},
    48  			want: []float64{2},
    49  		},
    50  		{
    51  			dst:  make([]float64, 1),
    52  			src:  []float64{1, 2, 3},
    53  			inds: []int{1},
    54  			want: []float64{2},
    55  		},
    56  		{
    57  			dst:  make([]float64, 0),
    58  			src:  []float64{1, 2, 3},
    59  			inds: []int{},
    60  			want: []float64{},
    61  		},
    62  		{
    63  			dst:  []float64{},
    64  			src:  []float64{1, 2, 3},
    65  			inds: nil,
    66  			want: []float64{},
    67  		},
    68  		{
    69  			dst:  make([]float64, 2),
    70  			src:  []float64{1, 2, 3},
    71  			inds: []int{1, 2},
    72  			want: []float64{2, 3},
    73  		},
    74  		{
    75  			dst:    nil,
    76  			src:    []float64{1, 2, 3},
    77  			inds:   []int{1, 0},
    78  			panics: errSortedIndices,
    79  		},
    80  		{
    81  			dst:    nil,
    82  			src:    []float64{1, 2, 3},
    83  			inds:   []int{0, 1, 2, 3},
    84  			panics: errLength,
    85  		},
    86  		{
    87  			dst:    make([]float64, 1),
    88  			src:    []float64{1, 2, 3},
    89  			inds:   []int{0, 1},
    90  			panics: errLength,
    91  		},
    92  		{
    93  			dst:    make([]float64, 4),
    94  			src:    []float64{1, 2, 3},
    95  			inds:   []int{0, 1},
    96  			panics: errLength,
    97  		},
    98  		{
    99  			dst:    nil,
   100  			src:    []float64{1, 2, 3},
   101  			inds:   []int{1, 1},
   102  			panics: errDuplicateIndices,
   103  		},
   104  	} {
   105  		t.Run("", func(t *testing.T) {
   106  			if tc.panics != nil {
   107  				defer panics(t, tc.panics)()
   108  			}
   109  			got := Take(tc.dst, tc.src, tc.inds)
   110  			if !reflect.DeepEqual(got, tc.want) {
   111  				t.Fatalf("got= %v\nwant=%v", got, tc.want)
   112  			}
   113  		})
   114  	}
   115  }
   116  
   117  var takeSink []float64
   118  
   119  func BenchmarkTake(b *testing.B) {
   120  	for _, size := range []int{2, 4, 8, 128, 1024, 1024 * 1024} {
   121  		b.Run(fmt.Sprintf("Len=%d", size), func(b *testing.B) {
   122  			src := make([]float64, size)
   123  			ind := make([]int, 0, len(src))
   124  			rnd := rand.New(rand.NewSource(0))
   125  			for i := range src {
   126  				src[i] = rnd.Float64()
   127  				if rnd.Float64() > 0.5 {
   128  					ind = append(ind, i)
   129  				}
   130  			}
   131  			dst := make([]float64, len(ind))
   132  			b.ReportAllocs()
   133  
   134  			b.ResetTimer()
   135  			for i := 0; i < b.N; i++ {
   136  				takeSink = Take(dst, src, ind)
   137  			}
   138  		})
   139  	}
   140  }