github.com/avicd/go-utilx@v0.1.0/refx/op_test.go (about)

     1  package refx
     2  
     3  import (
     4  	"errors"
     5  	"github.com/stretchr/testify/assert"
     6  	"reflect"
     7  	"testing"
     8  )
     9  
    10  type testOp struct {
    11  	A string
    12  	B int
    13  	C map[string]any
    14  	D []string
    15  	E *testOp
    16  }
    17  
    18  func TestValueOf(t *testing.T) {
    19  	v1 := reflect.ValueOf(0)
    20  	assert.Equal(t, true, v1 == ValueOf(v1))
    21  	assert.Equal(t, true, v1 == ValueOf(&v1))
    22  }
    23  
    24  func TestKindOf(t *testing.T) {
    25  	var p *testOp
    26  	var v1 = &p
    27  	var v2 = ValueOf(p)
    28  	var v3 = TypeOf(p)
    29  
    30  	// Wrap Test
    31  	assert.Equal(t, reflect.Pointer, KindOf(p))
    32  	assert.Equal(t, reflect.Pointer, KindOf(v1))
    33  	assert.Equal(t, reflect.Pointer, KindOf(v2))
    34  	assert.Equal(t, reflect.Pointer, KindOf(v3))
    35  
    36  	// Basic
    37  	assert.Equal(t, reflect.Bool, KindOf(TBool))
    38  	assert.Equal(t, reflect.Uint8, KindOf(TByte))
    39  	assert.Equal(t, reflect.Int8, KindOf(TInt8))
    40  	assert.Equal(t, reflect.Int16, KindOf(TInt16))
    41  	assert.Equal(t, reflect.Int32, KindOf(TInt32))
    42  	assert.Equal(t, reflect.Int64, KindOf(TInt64))
    43  	assert.Equal(t, reflect.Uint8, KindOf(TUint8))
    44  	assert.Equal(t, reflect.Uint16, KindOf(TUint16))
    45  	assert.Equal(t, reflect.Uint32, KindOf(TUint32))
    46  	assert.Equal(t, reflect.Uint64, KindOf(TUint64))
    47  	assert.Equal(t, reflect.Uintptr, KindOf(TUintptr))
    48  	assert.Equal(t, reflect.Float32, KindOf(TFloat32))
    49  	assert.Equal(t, reflect.Float64, KindOf(TFloat64))
    50  	assert.Equal(t, reflect.Complex64, KindOf(TComplex64))
    51  	assert.Equal(t, reflect.Complex128, KindOf(TComplex128))
    52  	assert.Equal(t, reflect.Array, KindOf(TArray))
    53  	assert.Equal(t, reflect.Chan, KindOf(TChan))
    54  	assert.Equal(t, reflect.Func, KindOf(TFunc))
    55  	assert.Equal(t, reflect.Slice, KindOf(TSlice))
    56  	assert.Equal(t, reflect.Struct, KindOf(TStruct))
    57  	assert.Equal(t, reflect.UnsafePointer, KindOf(TUnsafePointer))
    58  	assert.Equal(t, reflect.Invalid, KindOf(TAny))
    59  }
    60  
    61  func TestIndirectKind(t *testing.T) {
    62  	var v1 *testOp
    63  	var v2 *[]string
    64  	var v3 *[1]string
    65  	assert.Equal(t, reflect.Struct, IndirectKind(v1))
    66  	assert.Equal(t, reflect.Slice, IndirectKind(v2))
    67  	assert.Equal(t, reflect.Array, IndirectKind(v3))
    68  
    69  	v4 := &v1
    70  	v5 := &v2
    71  	v6 := &v3
    72  	assert.Equal(t, reflect.Struct, IndirectKind(v4))
    73  	assert.Equal(t, reflect.Slice, IndirectKind(v5))
    74  	assert.Equal(t, reflect.Array, IndirectKind(v6))
    75  
    76  	v1 = &testOp{E: &testOp{A: "A"}}
    77  	v2 = &[]string{"A", "B", "C"}
    78  	v3 = &[1]string{"A"}
    79  
    80  	assert.Equal(t, reflect.Struct, IndirectKind(v1))
    81  	assert.Equal(t, reflect.Struct, IndirectKind(v1.E))
    82  	assert.Equal(t, reflect.Slice, IndirectKind(v2))
    83  	assert.Equal(t, reflect.Array, IndirectKind(v3))
    84  }
    85  
    86  func TestIndirect(t *testing.T) {
    87  	p0 := "A"
    88  	p1 := &p0
    89  	p2 := &p1
    90  	p3 := &p2
    91  	assert.Equal(t, "A", Indirect(p1).Interface())
    92  	assert.Equal(t, "A", Indirect(p2).Interface())
    93  	assert.Equal(t, "A", Indirect(p3).Interface())
    94  
    95  	v1 := &testOp{A: "A"}
    96  	v2 := &v1
    97  	v3 := &v2
    98  	assert.Equal(t, Indirect(v1).UnsafeAddr(), Indirect(v2).UnsafeAddr())
    99  	assert.Equal(t, Indirect(v2).UnsafeAddr(), Indirect(v3).UnsafeAddr())
   100  }
   101  
   102  func TestIndirectType(t *testing.T) {
   103  	var p0 testOp
   104  	p1 := &p0
   105  	p2 := &p1
   106  	p3 := &p2
   107  
   108  	assert.Equal(t, reflect.TypeOf(p0), IndirectType(p1))
   109  	assert.Equal(t, reflect.TypeOf(p0), IndirectType(p2))
   110  	assert.Equal(t, reflect.TypeOf(p0), IndirectType(p3))
   111  }
   112  
   113  func TestNewOf(t *testing.T) {
   114  	p0 := 10
   115  	v1 := NewOf(p0)
   116  	v1.Set(ValueOf(p0))
   117  	assert.Equal(t, true, v1.Interface() == 10)
   118  	assert.Equal(t, reflect.Int, v1.Kind())
   119  
   120  	var list []string
   121  	v2 := NewOf(list)
   122  	v2.Set(ValueOf([]string{"A1", "AN"}))
   123  	if list2, ok := v2.Interface().([]string); ok {
   124  		assert.Equal(t, "A1", list2[0])
   125  		assert.Equal(t, "AN", list2[1])
   126  	} else {
   127  		panic(errors.New("new of Slice failed"))
   128  	}
   129  
   130  	var s0 *testOp
   131  	v3 := NewOf(s0)
   132  	v3.Set(ValueOf(&testOp{A: "A1", B: 22}))
   133  	if s1, ok := v3.Interface().(*testOp); ok {
   134  		assert.Equal(t, "A1", s1.A)
   135  		assert.Equal(t, 22, s1.B)
   136  	} else {
   137  		panic(errors.New("new of Struct failed"))
   138  	}
   139  }
   140  
   141  func TestAssign(t *testing.T) {
   142  	// String
   143  	var str string
   144  
   145  	Assign(&str, 10)
   146  	assert.Equal(t, "10", str)
   147  
   148  	Assign(&str, "A1")
   149  	assert.Equal(t, "A1", str)
   150  
   151  	Assign(&str, nil)
   152  	assert.Equal(t, "", str)
   153  
   154  	// Int
   155  	var num int
   156  	Assign(&num, 10)
   157  	assert.Equal(t, 10, num)
   158  
   159  	Assign(&num, "10")
   160  	assert.Equal(t, 10, num)
   161  
   162  	Assign(&num, "203.312")
   163  	assert.Equal(t, 203, num)
   164  
   165  	// Float
   166  	var decimal float64
   167  	Assign(&decimal, 10)
   168  	assert.Equal(t, 10.0, decimal)
   169  
   170  	Assign(&decimal, "10")
   171  	assert.Equal(t, 10.0, decimal)
   172  
   173  	Assign(&decimal, "203.312")
   174  	assert.Equal(t, 203.312, decimal)
   175  
   176  	// Struct
   177  	var p0 *testOp
   178  
   179  	Assign(&p0, &testOp{A: "A", B: 203})
   180  	assert.Equal(t, "A", p0.A)
   181  	assert.Equal(t, 203, p0.B)
   182  
   183  	// Auto Addr
   184  	p0 = nil
   185  	Assign(&p0, testOp{A: "A", B: 203})
   186  	assert.Equal(t, "A", p0.A)
   187  	assert.Equal(t, 203, p0.B)
   188  
   189  	// Map
   190  
   191  	var map0 map[string]any
   192  	Assign(&map0, map[string]any{"A": "A"})
   193  	assert.Equal(t, "A", map0["A"])
   194  
   195  }
   196  
   197  func TestClone(t *testing.T) {
   198  	// basic
   199  	var str string
   200  	s1 := "A<-B"
   201  	Clone(&str, s1)
   202  	assert.Equal(t, s1, str)
   203  
   204  	var num int64
   205  	s2 := int64(200)
   206  	Clone(&num, s2)
   207  	assert.Equal(t, s2, num)
   208  
   209  	// Struct
   210  	var p0 *testOp
   211  	s3 := &testOp{A: "AAAA", B: 10, C: map[string]any{"C1": 11}, D: []string{"L0"}}
   212  	p1 := &testOp{A: "AAAA"}
   213  	p2 := s3
   214  	Clone(&p0, s3)
   215  	assert.Equal(t, false, p0 == s3)
   216  	assert.Equal(t, true, p2 == s3)
   217  	assert.Equal(t, true, reflect.DeepEqual(p0, p2))
   218  	assert.Equal(t, true, reflect.DeepEqual(p0, p2))
   219  	assert.Equal(t, false, reflect.DeepEqual(p1, p2))
   220  
   221  	// Slice
   222  	var s4 []string
   223  	s4 = append(s4, "A1")
   224  	s4 = append(s4, "A1")
   225  	s4 = append(s4, "A1")
   226  
   227  	var list []string
   228  	Clone(&list, s4)
   229  	assert.Equal(t, true, reflect.DeepEqual(s4, list))
   230  
   231  	// Map
   232  	s5 := map[string]any{
   233  		"Names": []string{"Allen", "FlashMan"},
   234  		"Age":   78,
   235  	}
   236  	var map0 map[string]any
   237  	Clone(&map0, s5)
   238  	assert.Equal(t, true, reflect.DeepEqual(s5, map0))
   239  
   240  }
   241  
   242  func TestMerge(t *testing.T) {
   243  	// Cover
   244  	p0 := &testOp{A: "", B: 10, C: map[string]any{"C1": 11}}
   245  	p1 := &testOp{A: "A", B: 20, C: map[string]any{"C1": 21}}
   246  	Merge(p0, p1)
   247  	refP0 := &testOp{A: "A", B: 20, C: map[string]any{"C1": 21}}
   248  	assert.Equal(t, true, reflect.DeepEqual(p0, refP0))
   249  
   250  	// Ignore Zero Value When Covering
   251  	p0 = &testOp{A: "A", B: 20, C: map[string]any{"C1": 21}}
   252  	p1 = &testOp{A: "", B: 0, C: map[string]any{"C1": ""}}
   253  	Merge(p0, p1)
   254  	refP0 = &testOp{A: "A", B: 20, C: map[string]any{"C1": 21}}
   255  	assert.Equal(t, true, reflect.DeepEqual(p0, refP0))
   256  
   257  	// Create new When Dest is nil
   258  	p0 = nil
   259  	p1 = &testOp{C: map[string]any{"C1": "21", "C2": "C2"}, D: []string{"D3", "D4"}}
   260  
   261  	Merge(&p0, p1)
   262  	assert.Equal(t, true, reflect.DeepEqual(p0, p1))
   263  
   264  	// Map
   265  	p0 = &testOp{C: map[string]any{"C1": 21}, D: []string{"D1", "D2"}}
   266  	p1 = &testOp{C: map[string]any{"C1": "", "C2": "C2"}, D: []string{"D3", "D4"}}
   267  	Merge(p0, p1)
   268  	refP0 = &testOp{C: map[string]any{"C1": 21, "C2": "C2"}, D: []string{"D1", "D2", "D3", "D4"}}
   269  	assert.Equal(t, true, reflect.DeepEqual(p0, refP0))
   270  
   271  	// Slice
   272  	list0 := []string{"D1", "D2"}
   273  	list1 := []string{"D3", "D4"}
   274  	refList := []string{"D1", "D2", "D3", "D4"}
   275  	Merge(&list0, list1)
   276  	assert.Equal(t, true, reflect.DeepEqual(list0, refList))
   277  
   278  	// Slice->Array
   279  	arr0 := [3]string{"D1", "D2"}
   280  	list1 = []string{"D3", "D4"}
   281  
   282  	refArr := [3]string{"D3", "D4", ""}
   283  	Merge(&arr0, list1)
   284  	assert.Equal(t, true, reflect.DeepEqual(arr0, refArr))
   285  
   286  	// Basic
   287  	var str string
   288  	var num float64
   289  
   290  	Merge(&str, "STR0")
   291  	Merge(&num, 201.232)
   292  	assert.Equal(t, "STR0", str)
   293  	assert.Equal(t, 201.232, num)
   294  }
   295  
   296  func TestFieldOf(t *testing.T) {
   297  	list0 := []*testOp{
   298  		{A: "A-Field", B: 10, C: map[string]any{"C1": 11}},
   299  		{C: map[string]any{"C1": "", "C2": "C2"}, D: []string{"D3", "D4"}},
   300  	}
   301  	v0, exist := FieldOf(list0, 0, "A")
   302  	assert.Equal(t, true, exist)
   303  	assert.Equal(t, "A-Field", v0.Interface())
   304  
   305  	v0, exist = FieldOf(list0, 0, "C", "C1")
   306  	assert.Equal(t, true, exist)
   307  	assert.Equal(t, 11, v0.Interface())
   308  }
   309  
   310  func TestTypeOfField(t *testing.T) {
   311  	list0 := []*testOp{
   312  		{A: "A-Field", B: 10, C: map[string]any{"C1": 11}},
   313  		{C: map[string]any{"C1": "", "C2": "C2"}, D: []string{"D3", "D4"}},
   314  	}
   315  	v0, exist := TypeOfField(list0, 0, "B")
   316  	assert.Equal(t, true, exist)
   317  	assert.Equal(t, reflect.Int, v0.Kind())
   318  
   319  	v0, exist = TypeOfField(list0, 1, "C", "C2")
   320  	assert.Equal(t, true, exist)
   321  	assert.Equal(t, reflect.String, v0.Kind())
   322  
   323  	var p *testOp
   324  	v0, exist = TypeOfField(p, "A")
   325  	assert.Equal(t, true, exist)
   326  	assert.Equal(t, reflect.String, v0.Kind())
   327  
   328  	v0, exist = TypeOfField(p, "E", "E", "E")
   329  	assert.Equal(t, true, exist)
   330  	assert.Equal(t, reflect.Pointer, v0.Kind())
   331  }
   332  
   333  func TestPropOf(t *testing.T) {
   334  	list0 := []*testOp{
   335  		{A: "A-Field", B: 10, C: map[string]any{"C1": 11}},
   336  		{C: map[string]any{"C1": "", "C2": "C2"}, D: []string{"D3", "D4"}},
   337  	}
   338  
   339  	v0, exist := PropOf(list0, 0, "A")
   340  	assert.Equal(t, true, exist)
   341  	assert.Equal(t, "A-Field", v0)
   342  
   343  	v0, exist = PropOf(list0, 0, "C", "C1")
   344  	assert.Equal(t, true, exist)
   345  	assert.Equal(t, 11, v0)
   346  
   347  	map0 := map[string]any{
   348  		"10": "Value A",
   349  	}
   350  	v0, exist = PropOf(map0, "10")
   351  	assert.Equal(t, true, exist)
   352  	assert.Equal(t, "Value A", v0)
   353  
   354  	v0, exist = PropOf(map0, "21")
   355  	assert.Equal(t, false, exist)
   356  	assert.Equal(t, nil, v0)
   357  }
   358  
   359  func TestSet(t *testing.T) {
   360  	n0 := 1
   361  	n1 := 20
   362  	Set(&n0, n1)
   363  	assert.Equal(t, 20, n0)
   364  
   365  	p0 := &testOp{A: "A-Field", B: 10, C: map[string]any{"C1": 11}}
   366  	Set(p0, "A-Field-Changed", "A")
   367  	Set(p0, "MAP:D", "C", "D")
   368  	assert.Equal(t, "A-Field-Changed", p0.A)
   369  	assert.Equal(t, "MAP:D", p0.C["D"])
   370  
   371  	p0 = nil
   372  	Set(&p0, "MAP:D", "C", "D")
   373  	assert.Equal(t, "MAP:D", p0.C["D"])
   374  
   375  	var list0 [4]string
   376  	ok := Set(&list0, "A", 2)
   377  	assert.Equal(t, true, ok)
   378  }