github.com/gopherjs/gopherjs@v1.19.0-beta1.0.20240506212314-27071a8796e4/tests/slice_to_array_ptr_test.go (about) 1 package tests 2 3 import ( 4 "runtime" 5 "testing" 6 ) 7 8 // https://tip.golang.org/ref/spec#Conversions_from_slice_to_array_pointer 9 func TestSliceToArrayPointerConversion(t *testing.T) { 10 // GopherJS uses TypedArray for numeric types and Array for everything else 11 // since those are substantially different types, the tests are repeated 12 // for both. 13 expectOutOfBoundsPanic := func(t *testing.T) { 14 t.Helper() 15 if recover() == nil { 16 t.Error("out-of-bounds conversion of s should panic") 17 } 18 } 19 20 t.Run("Numeric", func(t *testing.T) { 21 s := make([]byte, 2, 4) 22 t.Run("NotNil", func(t *testing.T) { 23 s0 := (*[0]byte)(s) 24 if s0 == nil { 25 t.Error("s0 should not be nil") 26 } 27 }) 28 29 t.Run("ElementPointerEquality", func(t *testing.T) { 30 s2 := (*[2]byte)(s) 31 if &s2[0] != &s[0] { 32 t.Error("&s2[0] should match &s[0]") 33 } 34 s3 := (*[1]byte)(s[1:]) 35 if &s3[0] != &s[1] { 36 t.Error("&s3[0] should match &s[1]") 37 } 38 }) 39 40 t.Run("SliceToLargerArray", func(t *testing.T) { 41 defer expectOutOfBoundsPanic(t) 42 s4 := (*[4]byte)(s) 43 _ = s4 44 }) 45 46 t.Run("SharedMemory", func(t *testing.T) { 47 s2 := (*[2]byte)(s) 48 (*s2)[0] = 'x' 49 if s[0] != 'x' { 50 t.Errorf("s[0] should be changed") 51 } 52 53 s3 := (*[1]byte)(s[1:]) 54 (*s3)[0] = 'y' 55 if s[1] != 'y' { 56 t.Errorf("s[1] should be changed") 57 } 58 }) 59 60 var q []byte 61 t.Run("NilSlice", func(t *testing.T) { 62 q0 := (*[0]byte)(q) 63 if q0 != nil { 64 t.Error("q0 should be nil") 65 } 66 }) 67 68 t.Run("NilSliceToLargerArray", func(t *testing.T) { 69 defer expectOutOfBoundsPanic(t) 70 q1 := (*[1]byte)(q) 71 _ = q1 72 }) 73 74 t.Run("ZeroLenSlice", func(t *testing.T) { 75 u := make([]byte, 0) 76 u0 := (*[0]byte)(u) 77 if u0 == nil { 78 t.Error("u0 should not be nil") 79 } 80 }) 81 82 t.Run("SliceToShorterArray", func(t *testing.T) { 83 s[0] = 'x' 84 s[1] = 'y' 85 s4 := (*[1]byte)(s[:]) 86 if got := s4[0]; got != 'x' { 87 t.Errorf("Got s0[0] = %q, want 'x'", got) 88 } 89 if got := len(s4); got != 1 { 90 t.Errorf("Got len(s0) = %d, want 1.", got) 91 } 92 93 // Verify that the backing array size has been reduced to match the Go 94 // type. If not, a "source too large" runtime exception will be thrown 95 // upon the copy attempt. 96 s5 := [1]byte{} 97 s5 = *s4 98 runtime.KeepAlive(s5) 99 }) 100 }) 101 102 t.Run("String", func(t *testing.T) { 103 s := make([]string, 2, 2) 104 t.Run("NotNil", func(t *testing.T) { 105 s0 := (*[0]string)(s) 106 if s0 == nil { 107 t.Error("s0 should not be nil") 108 } 109 }) 110 111 t.Run("ElementPointerEquality", func(t *testing.T) { 112 s2 := (*[2]string)(s) 113 if &s2[0] != &s[0] { 114 t.Error("&s2[0] should match &s[0]") 115 } 116 117 t.Skip("non-numeric slice to underlying array conversion is not supported for subslices") 118 s3 := (*[1]string)(s[1:]) 119 if &s3[0] != &s[1] { 120 t.Error("&s3[0] should match &s[1]") 121 } 122 }) 123 124 t.Run("SliceToLargerArray", func(t *testing.T) { 125 defer expectOutOfBoundsPanic(t) 126 s4 := (*[4]string)(s) 127 _ = s4 128 }) 129 130 t.Run("SharedMemory", func(t *testing.T) { 131 s2 := (*[2]string)(s) 132 (*s2)[0] = "x" 133 if s[0] != "x" { 134 t.Errorf("s[0] should be changed") 135 } 136 137 t.Skip("non-numeric slice to underlying array conversion is not supported for subslices") 138 s3 := (*[1]string)(s[1:]) 139 (*s3)[0] = "y" 140 if s[1] != "y" { 141 t.Errorf("s[1] should be changed") 142 } 143 }) 144 145 var q []string 146 t.Run("NilSlice", func(t *testing.T) { 147 q0 := (*[0]string)(q) 148 if q0 != nil { 149 t.Error("q0 should be nil") 150 } 151 }) 152 153 t.Run("NilSliceToLargerArray", func(t *testing.T) { 154 defer expectOutOfBoundsPanic(t) 155 q1 := (*[1]string)(q) 156 _ = q1 157 }) 158 159 t.Run("ZeroLenSlice", func(t *testing.T) { 160 u := make([]string, 0) 161 u0 := (*[0]string)(u) 162 if u0 == nil { 163 t.Error("u0 should not be nil") 164 } 165 }) 166 }) 167 }