github.com/qioalice/ekago/v3@v3.3.2-0.20221202205325-5c262d586ee4/ekaunsafe/rtype_test.go (about) 1 // Copyright © 2020. All rights reserved. 2 // Author: Ilya Stroy. 3 // Contacts: iyuryevich@pm.me, https://github.com/qioalice 4 // License: https://opensource.org/licenses/MIT 5 6 package ekaunsafe_test 7 8 import ( 9 "fmt" 10 "testing" 11 12 "github.com/qioalice/ekago/v3/ekamath" 13 "github.com/qioalice/ekago/v3/ekaunsafe" 14 15 "github.com/stretchr/testify/assert" 16 17 "github.com/modern-go/reflect2" 18 ) 19 20 //goland:noinspection GoRedundantConversion,GoBoolExpressions 21 var ( 22 tda = []any{ 23 // DO NOT CHANGE AN ORDER OF EXISTED ELEMENTS! 24 // DO NOT CHANGE AN EXISTED ELEMENTS AT ALL! 25 // ONLY ADD A NEW ONES IF YOU NEED. 26 bool(0 == 0), // 0 27 byte(0), // 1 28 rune(0), // 2 29 int(0), // 3 30 int8(0), // 4 31 int16(0), // 5 32 int32(0), // 6 33 int64(0), // 7 34 uint(0), // 8 35 uint8(0), // 9 36 uint16(0), // 10 37 uint32(0), // 11 38 uint64(0), // 12 39 float32(0), // 13 40 float64(0), // 14 41 string(""), // 15 42 []string(nil), // 16 43 []byte(nil), // 17 44 [][]byte(nil), // 18 45 map[string]string(nil), // 19 46 map[string]any(nil), // 20 47 complex64(0), // 21 48 complex128(0), // 22 49 } 50 td1 = []struct { 51 f func() uintptr 52 eq uint64 53 }{ 54 {f: ekaunsafe.RTypeBool, eq: 1 << 0}, 55 {f: ekaunsafe.RTypeByte, eq: 1<<1 | 1<<9}, 56 {f: ekaunsafe.RTypeRune, eq: 1<<2 | 1<<6}, 57 {f: ekaunsafe.RTypeInt, eq: 1 << 3}, 58 {f: ekaunsafe.RTypeInt8, eq: 1 << 4}, 59 {f: ekaunsafe.RTypeInt16, eq: 1 << 5}, 60 {f: ekaunsafe.RTypeInt32, eq: 1<<6 | 1<<2}, 61 {f: ekaunsafe.RTypeInt64, eq: 1 << 7}, 62 {f: ekaunsafe.RTypeUint, eq: 1 << 8}, 63 {f: ekaunsafe.RTypeUint8, eq: 1<<9 | 1<<1}, 64 {f: ekaunsafe.RTypeUint16, eq: 1 << 10}, 65 {f: ekaunsafe.RTypeUint32, eq: 1 << 11}, 66 {f: ekaunsafe.RTypeUint64, eq: 1 << 12}, 67 {f: ekaunsafe.RTypeFloat32, eq: 1 << 13}, 68 {f: ekaunsafe.RTypeFloat64, eq: 1 << 14}, 69 {f: ekaunsafe.RTypeString, eq: 1 << 15}, 70 {f: ekaunsafe.RTypeStringArray, eq: 1 << 16}, 71 {f: ekaunsafe.RTypeBytes, eq: 1 << 17}, 72 {f: ekaunsafe.RTypeBytesArray, eq: 1 << 18}, 73 {f: ekaunsafe.RTypeMapStringString, eq: 1 << 19}, 74 {f: ekaunsafe.RTypeMapStringInterface, eq: 1 << 20}, 75 {f: ekaunsafe.RTypeComplex64, eq: 1 << 21}, 76 {f: ekaunsafe.RTypeComplex128, eq: 1 << 22}, 77 } 78 td2 = []struct { 79 f func(uintptr) bool 80 eq uint64 81 }{ 82 {f: ekaunsafe.RTypeIsAnyNumeric, eq: 4095 << 1}, // [1..12] as idx 83 {f: ekaunsafe.RTypeIsAnyReal, eq: 16383 << 1}, // [1..14] as idx 84 {f: ekaunsafe.RTypeIsIntAny, eq: 31<<3 | 1<<2}, // [3..7,2] as idx 85 {f: ekaunsafe.RTypeIsIntFixed, eq: 15<<4 | 1<<2}, // [4..7,2] as idx 86 {f: ekaunsafe.RTypeIsUintAny, eq: 31<<8 | 1<<1}, // [8..12,1] as idx 87 {f: ekaunsafe.RTypeIsUintFixed, eq: 15<<9 | 1<<1}, // [9..12,1] as idx 88 {f: ekaunsafe.RTypeIsFloatAny, eq: 3 << 13}, // [13..14] as idx 89 {f: ekaunsafe.RTypeIsComplexAny, eq: 3 << 21}, // [21..22] as idx 90 } 91 pt = []struct { 92 f func() uintptr 93 z uintptr 94 name string 95 }{ 96 {f: ekaunsafe.RTypeBool, z: reflect2.RTypeOf(tda[0]), name: "RTypeBool"}, 97 {f: ekaunsafe.RTypeByte, z: reflect2.RTypeOf(tda[1]), name: "RTypeByte"}, 98 {f: ekaunsafe.RTypeRune, z: reflect2.RTypeOf(tda[2]), name: "RTypeRune"}, 99 {f: ekaunsafe.RTypeInt, z: reflect2.RTypeOf(tda[3]), name: "RTypeInt"}, 100 {f: ekaunsafe.RTypeInt8, z: reflect2.RTypeOf(tda[4]), name: "RTypeInt8"}, 101 {f: ekaunsafe.RTypeInt16, z: reflect2.RTypeOf(tda[5]), name: "RTypeInt16"}, 102 {f: ekaunsafe.RTypeInt32, z: reflect2.RTypeOf(tda[6]), name: "RTypeInt32"}, 103 {f: ekaunsafe.RTypeInt64, z: reflect2.RTypeOf(tda[7]), name: "RTypeInt64"}, 104 {f: ekaunsafe.RTypeUint, z: reflect2.RTypeOf(tda[8]), name: "RTypeUint"}, 105 {f: ekaunsafe.RTypeUint8, z: reflect2.RTypeOf(tda[9]), name: "RTypeUint8"}, 106 {f: ekaunsafe.RTypeUint16, z: reflect2.RTypeOf(tda[10]), name: "RTypeUint16"}, 107 {f: ekaunsafe.RTypeUint32, z: reflect2.RTypeOf(tda[11]), name: "RTypeUint32"}, 108 {f: ekaunsafe.RTypeUint64, z: reflect2.RTypeOf(tda[12]), name: "RTypeUint64"}, 109 {f: ekaunsafe.RTypeFloat32, z: reflect2.RTypeOf(tda[13]), name: "RTypeFloat32"}, 110 {f: ekaunsafe.RTypeFloat64, z: reflect2.RTypeOf(tda[14]), name: "RTypeFloat64"}, 111 {f: ekaunsafe.RTypeString, z: reflect2.RTypeOf(tda[15]), name: "RTypeString"}, 112 {f: ekaunsafe.RTypeStringArray, z: reflect2.RTypeOf(tda[16]), name: "RTypeStringArray"}, 113 {f: ekaunsafe.RTypeBytes, z: reflect2.RTypeOf(tda[17]), name: "RTypeBytes"}, 114 {f: ekaunsafe.RTypeBytesArray, z: reflect2.RTypeOf(tda[18]), name: "RTypeBytesArray"}, 115 {f: ekaunsafe.RTypeMapStringString, z: reflect2.RTypeOf(tda[19]), name: "RTypeMapStringString"}, 116 {f: ekaunsafe.RTypeMapStringInterface, z: reflect2.RTypeOf(tda[20]), name: "RTypeMapStringInterface"}, 117 {f: ekaunsafe.RTypeComplex64, z: reflect2.RTypeOf(tda[21]), name: "RTypeComplex64"}, 118 {f: ekaunsafe.RTypeComplex128, z: reflect2.RTypeOf(tda[22]), name: "RTypeComplex128"}, 119 } 120 ) 121 122 func testRType(t *testing.T, tdIdx uint8) { 123 eqIdx := td1[tdIdx].eq 124 for i, z, n := 0, uint64(1), ekamath.Min(64, len(td1)); i < n; i++ { 125 if eqIdx&z > 0 { 126 assert.Equal(t, reflect2.RTypeOf(tda[i]), td1[tdIdx].f()) 127 } else { 128 assert.NotEqual(t, reflect2.RTypeOf(tda[i]), td1[tdIdx].f()) 129 } 130 z <<= 1 131 } 132 } 133 134 func testRTypeIs(t *testing.T, tdIdx uint8) { 135 eqIdx := td2[tdIdx].eq 136 for i, z, n := 0, uint64(1), ekamath.Min(64, len(td1)); i < n; i++ { 137 if eqIdx&z > 0 { 138 assert.True(t, td2[tdIdx].f(reflect2.RTypeOf(tda[i]))) 139 } else { 140 assert.False(t, td2[tdIdx].f(reflect2.RTypeOf(tda[i]))) 141 } 142 z <<= 1 143 } 144 } 145 146 func TestRTypePrintTable(t *testing.T) { 147 maxWidth := 0 148 for i, n := 0, len(pt); i < n; i++ { 149 if l := len(pt[i].name); l > maxWidth { 150 maxWidth = l 151 } 152 } 153 fmt.Println() 154 fmt.Printf("%-[2]*[1]s | Ekadanger RType | reflect2 RType\n", "RType name", maxWidth) 155 lines := make([]byte, maxWidth+36) 156 for i, n := 0, len(lines); i < n; i++ { 157 lines[i] = '-' 158 } 159 fmt.Println(string(lines)) 160 for i, n := 0, len(pt); i < n; i++ { 161 fmt.Printf("%-[4]*[1]s | 0x%-13[2]x | 0x%[3]x\n", pt[i].name, pt[i].f(), pt[i].z, maxWidth) 162 } 163 fmt.Println() 164 } 165 166 func TestRTypeBool(t *testing.T) { testRType(t, 0) } 167 func TestRTypeByte(t *testing.T) { testRType(t, 1) } 168 func TestRTypeRune(t *testing.T) { testRType(t, 2) } 169 func TestRTypeInt(t *testing.T) { testRType(t, 3) } 170 func TestRTypeInt8(t *testing.T) { testRType(t, 4) } 171 func TestRTypeInt16(t *testing.T) { testRType(t, 5) } 172 func TestRTypeInt32(t *testing.T) { testRType(t, 6) } 173 func TestRTypeInt64(t *testing.T) { testRType(t, 7) } 174 func TestRTypeUint(t *testing.T) { testRType(t, 8) } 175 func TestRTypeUint8(t *testing.T) { testRType(t, 9) } 176 func TestRTypeUint16(t *testing.T) { testRType(t, 10) } 177 func TestRTypeUint32(t *testing.T) { testRType(t, 11) } 178 func TestRTypeUint64(t *testing.T) { testRType(t, 12) } 179 func TestRTypeFloat32(t *testing.T) { testRType(t, 13) } 180 func TestRTypeFloat64(t *testing.T) { testRType(t, 14) } 181 func TestRTypeString(t *testing.T) { testRType(t, 15) } 182 func TestRTypeStringArray(t *testing.T) { testRType(t, 16) } 183 func TestRTypeBytes(t *testing.T) { testRType(t, 17) } 184 func TestRTypeBytesArray(t *testing.T) { testRType(t, 18) } 185 func TestRTypeMapStringString(t *testing.T) { testRType(t, 19) } 186 func TestRTypeMapStringInterface(t *testing.T) { testRType(t, 20) } 187 func TestRTypeComplex64(t *testing.T) { testRType(t, 21) } 188 func TestRTypeComplex128(t *testing.T) { testRType(t, 22) } 189 190 func TestRTypeIsAnyNumeric(t *testing.T) { testRTypeIs(t, 0) } 191 func TestRTypeIsAnyReal(t *testing.T) { testRTypeIs(t, 1) } 192 func TestRTypeIsIntAny(t *testing.T) { testRTypeIs(t, 2) } 193 func TestRTypeIsIntFixed(t *testing.T) { testRTypeIs(t, 3) } 194 func TestRTypeIsUintAny(t *testing.T) { testRTypeIs(t, 4) } 195 func TestRTypeIsUintFixed(t *testing.T) { testRTypeIs(t, 5) } 196 func TestRTypeIsFloatAny(t *testing.T) { testRTypeIs(t, 6) } 197 func TestRTypeIsComplexAny(t *testing.T) { testRTypeIs(t, 7) }