github.com/grailbio/bigslice@v0.0.0-20230519005545-30c4c12152ad/internal/zero/zero_test.go (about)

     1  // Copyright 2018 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache 2.0
     3  // license that can be found in the LICENSE file.
     4  package zero_test
     5  
     6  import (
     7  	"fmt"
     8  	"reflect"
     9  	"testing"
    10  
    11  	fuzz "github.com/google/gofuzz"
    12  	"github.com/grailbio/bigslice/internal/zero"
    13  )
    14  
    15  var zeroTypes = []reflect.Type{
    16  	reflect.TypeOf(int8(0)),
    17  	reflect.TypeOf(int16(0)),
    18  	reflect.TypeOf(int32(0)),
    19  	reflect.TypeOf(int64(0)),
    20  	reflect.TypeOf(0),
    21  	reflect.TypeOf(""),
    22  	reflect.TypeOf([]byte{}),
    23  	reflect.TypeOf(struct{ A, B int }{}),
    24  	reflect.TypeOf([]int{}),
    25  	reflect.TypeOf([10]int16{}),
    26  	reflect.TypeOf([]*int{}),
    27  	reflect.TypeOf(struct{ A, B *int }{}),
    28  	reflect.TypeOf([][]int{}),
    29  }
    30  
    31  func TestZeroSlice(t *testing.T) {
    32  	const N = 100
    33  	fz := fuzz.New()
    34  
    35  	for _, typ := range zeroTypes {
    36  		slice := reflect.MakeSlice(reflect.SliceOf(typ), N, N)
    37  		for i := 0; i < N; i++ {
    38  			fz.Fuzz(slice.Index(i).Addr().Interface())
    39  		}
    40  		// We have to pass a slice in
    41  		zero.SliceValue(slice)
    42  		zeroValue := reflect.Zero(typ)
    43  		for i := 0; i < N; i++ {
    44  			if got, want := slice.Index(i), zeroValue; !reflect.DeepEqual(got.Interface(), want.Interface()) {
    45  				t.Errorf("got %v, want %v", got, want)
    46  			}
    47  		}
    48  	}
    49  }
    50  
    51  type testIface interface {
    52  	Test()
    53  }
    54  
    55  type testPtr int
    56  
    57  func (*testPtr) Test() {}
    58  
    59  type testVal int
    60  
    61  func (testVal) Test() {}
    62  
    63  func TestZeroInterFace(t *testing.T) {
    64  	const N = 100
    65  	slice := make([]testIface, N)
    66  	for i := range slice {
    67  		if i%2 == 0 {
    68  			p := new(testPtr)
    69  			*p = testPtr(i)
    70  			slice[i] = p
    71  		} else {
    72  			slice[i] = testVal(i)
    73  		}
    74  	}
    75  	zero.Slice(slice)
    76  	for i, val := range slice {
    77  		if val != nil {
    78  			t.Errorf("index %d, non-nil value %v", i, val)
    79  		}
    80  	}
    81  }
    82  
    83  func BenchmarkZero(b *testing.B) {
    84  	const N = 1 << 20
    85  	for _, typ := range zeroTypes {
    86  		b.Run(fmt.Sprintf("type=%v", typ), func(b *testing.B) {
    87  			b.ReportAllocs()
    88  			b.SetBytes(N)
    89  			n := int(N / typ.Size())
    90  			slice := reflect.MakeSlice(reflect.SliceOf(typ), n, n)
    91  			zero.Slice(slice)
    92  			b.ResetTimer()
    93  			for i := 0; i < b.N; i++ {
    94  				zero.SliceValue(slice)
    95  			}
    96  		})
    97  	}
    98  }