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) }