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 }