github.com/searKing/golang/go@v1.2.117/unsafe/conv_test.go (about)

     1  // Copyright 2023 The searKing Author. 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  package unsafe
     6  
     7  import (
     8  	"bytes"
     9  	"math/rand"
    10  	"testing"
    11  
    12  	rand_ "github.com/searKing/golang/go/crypto/rand"
    13  )
    14  
    15  var testString = "Albert Einstein: Logic will get you from A to B. Imagination will take you everywhere."
    16  var testBytes = []byte(testString)
    17  
    18  func rawBytesToString(b []byte) string {
    19  	return string(b)
    20  }
    21  
    22  func rawStringToBytes(s string) []byte {
    23  	return []byte(s)
    24  }
    25  
    26  func TestUnsafeConversions(t *testing.T) {
    27  	t.Parallel()
    28  
    29  	// needs to be large to force allocations so we pick a random value between [1024, 2048]
    30  	size := 1024 + rand.Intn(1024+1)
    31  
    32  	t.Run("StringToBytes semantics", func(t *testing.T) {
    33  		t.Parallel()
    34  
    35  		s := rand_.String(size)
    36  		b := StringToBytes(s)
    37  		if len(b) != size {
    38  			t.Errorf("unexpected length: %d", len(b))
    39  		}
    40  		if cap(b) != size {
    41  			t.Errorf("unexpected capacity: %d", cap(b))
    42  		}
    43  		if !bytes.Equal(b, []byte(s)) {
    44  			t.Errorf("unexpected equality failure: %#v", b)
    45  		}
    46  	})
    47  
    48  	t.Run("StringToBytes allocations", func(t *testing.T) {
    49  		t.Parallel()
    50  
    51  		s := rand_.String(size)
    52  		f := func() {
    53  			b := StringToBytes(s)
    54  			if len(b) != size {
    55  				t.Errorf("invalid length: %d", len(b))
    56  			}
    57  		}
    58  		allocs := testing.AllocsPerRun(100, f)
    59  		if allocs > 0 {
    60  			t.Errorf("expected zero allocations, got %v", allocs)
    61  		}
    62  	})
    63  
    64  	t.Run("BytesToString semantics", func(t *testing.T) {
    65  		t.Parallel()
    66  
    67  		b := make([]byte, size)
    68  		if _, err := rand.Read(b); err != nil {
    69  			t.Fatal(err)
    70  		}
    71  		s := BytesToString(b)
    72  		if len(s) != size {
    73  			t.Errorf("unexpected length: %d", len(s))
    74  		}
    75  		if s != string(b) {
    76  			t.Errorf("unexpected equality failure: %#v", s)
    77  		}
    78  	})
    79  
    80  	t.Run("BytesToString allocations", func(t *testing.T) {
    81  		t.Parallel()
    82  
    83  		b := make([]byte, size)
    84  		if _, err := rand.Read(b); err != nil {
    85  			t.Fatal(err)
    86  		}
    87  		f := func() {
    88  			s := BytesToString(b)
    89  			if len(s) != size {
    90  				t.Errorf("invalid length: %d", len(s))
    91  			}
    92  		}
    93  		allocs := testing.AllocsPerRun(100, f)
    94  		if allocs > 0 {
    95  			t.Errorf("expected zero allocations, got %v", allocs)
    96  		}
    97  	})
    98  }
    99  
   100  func BenchmarkBytesToStringRaw(b *testing.B) {
   101  	for i := 0; i < b.N; i++ {
   102  		rawBytesToString(testBytes)
   103  	}
   104  }
   105  
   106  func BenchmarkBytesToString(b *testing.B) {
   107  	for i := 0; i < b.N; i++ {
   108  		BytesToString(testBytes)
   109  	}
   110  }
   111  
   112  func BenchmarkStringToBytesRaw(b *testing.B) {
   113  	for i := 0; i < b.N; i++ {
   114  		rawStringToBytes(testString)
   115  	}
   116  }
   117  
   118  func BenchmarkStringToBytes(b *testing.B) {
   119  	for i := 0; i < b.N; i++ {
   120  		StringToBytes(testString)
   121  	}
   122  }