github.com/hedzr/evendeep@v0.4.8/cvts_tool_test.go (about) 1 package evendeep 2 3 import ( 4 "bytes" 5 "fmt" 6 "math" 7 "reflect" 8 "strconv" 9 "strings" 10 "testing" 11 "time" 12 "unsafe" 13 14 "github.com/hedzr/evendeep/dbglog" 15 "github.com/hedzr/evendeep/flags/cms" 16 "github.com/hedzr/evendeep/internal/cl" 17 "github.com/hedzr/evendeep/internal/tool" 18 "github.com/hedzr/evendeep/typ" 19 ) 20 21 type sample struct { 22 a int 23 b string 24 } 25 26 func TestUintptrAndUnsafePointer(t *testing.T) { 27 s := &sample{a: 1, b: "test"} 28 29 // Getting the address of field b in struct s 30 p := unsafe.Pointer(uintptr(unsafe.Pointer(s)) + unsafe.Offsetof(s.b)) 31 32 // Typecasting it to a string pointer and printing the value of it 33 fmt.Println(*(*string)(p)) 34 35 u := uintptr(unsafe.Pointer(s)) 36 us := fmt.Sprintf("%v", u) 37 t.Logf("us = 0x%v", us) 38 v := reflect.ValueOf(us) 39 ret := rToUIntegerHex(v, reflect.TypeOf(uintptr(unsafe.Pointer(s)))) 40 t.Logf("ret.type: %v, %v / 0x%x", ret.Type(), ret.Interface(), ret.Interface()) 41 42 // t.Logf("ret.type: %v, %v", ret.Type(), ret.Pointer()) 43 } 44 45 func TestGetPointerAsUintptr(t *testing.T) { 46 s := &sample{a: 1, b: "test"} 47 48 v := reflect.ValueOf(s) 49 u := getPointerAsUintptr(v) 50 fmt.Println(u) 51 } 52 53 func TestForBool(t *testing.T) { 54 var b1, b2 bool 55 b2 = true 56 57 v1, v2 := reflect.ValueOf(b1), reflect.ValueOf(b2) 58 if rForBool(v1).Interface() != "false" { 59 t.Fail() 60 } 61 62 if rForBool(v2).Interface() != "true" { 63 t.Fail() 64 } 65 } 66 67 func TestToBool(t *testing.T) { 68 69 for _, vi := range []typ.Any{ 70 false, 71 0, 72 uint(0), 73 math.Float64frombits(0), 74 complex(math.Float64frombits(0), math.Float64frombits(0)), 75 [0]int{}, 76 [1]int{0}, 77 (func())(nil), // nolint:gocritic // cannot remove paran 78 struct{}{}, 79 "f", 80 "false", 81 "off", 82 "no", 83 "famale", 84 } { 85 v1 := reflect.ValueOf(vi) 86 v2, _ := tool.Rdecode(v1) 87 if rToBool(v2).Interface() != false { 88 t.Fatalf("for %v (%v) toBool failed", vi, tool.Typfmtv(&v2)) 89 } 90 } 91 92 for _, vi := range []typ.Any{ 93 true, 94 -1, 95 uint(1), 96 math.Float64frombits(1), 97 complex(math.Float64frombits(1), math.Float64frombits(0)), 98 [1]int{1}, 99 [1]int{3}, 100 map[int]int{1: 1}, 101 struct{ v int }{1}, 102 "1", "t", "y", "m", 103 "true", 104 "on", 105 "yes", 106 "male", 107 } { 108 v1 := reflect.ValueOf(vi) 109 v2, _ := tool.Rdecode(v1) 110 if rToBool(v2).Interface() != true { 111 t.Fatalf("for %v (%v) toBool failed", vi, tool.Typfmtv(&v2)) 112 } 113 } 114 115 } 116 117 func TestForInteger(t *testing.T) { 118 for _, src := range []typ.Any{ 119 13579, 120 uint(13579), 121 } { 122 v1 := reflect.ValueOf(src) 123 v1 = tool.Rdecodesimple(v1) 124 if rForInteger(v1).Interface() != "13579" { 125 t.Fail() 126 } 127 } 128 129 var z typ.Any 130 v1 := reflect.ValueOf(z) 131 v1 = tool.Rdecodesimple(v1) 132 if x := rForInteger(v1).Interface(); x != "0" { 133 t.Fatalf("failed, x = %v", x) 134 } 135 136 z = "bug" //nolint:goconst 137 v1 = reflect.ValueOf(z) 138 v1 = tool.Rdecodesimple(v1) 139 if x := rForInteger(v1).Interface(); x != "0" { 140 t.Fatalf("failed, x = %v", x) 141 } 142 143 } 144 145 func TestToInteger(t *testing.T) { 146 for _, dt := range []reflect.Type{ 147 reflect.TypeOf((*int)(nil)).Elem(), 148 reflect.TypeOf((*int64)(nil)).Elem(), 149 reflect.TypeOf((*int32)(nil)).Elem(), 150 reflect.TypeOf((*int16)(nil)).Elem(), 151 reflect.TypeOf((*int8)(nil)).Elem(), 152 } { 153 for vv, ii := range map[string]int64{ 154 "123": 123, 155 "-123": -123, 156 "8.75": 9, 157 "8.49": 8, 158 } { 159 v := reflect.ValueOf(vv) 160 ret, err := rToInteger(v, dt) 161 if err != nil { 162 t.Fatalf("err: %v", err) 163 } 164 if ret.Int() != ii { 165 t.Fatalf("expect %v but got %v", ii, ret.Int()) 166 } 167 } 168 } 169 } 170 171 func TestForUInteger(t *testing.T) { 172 for _, src := range []typ.Any{ 173 13579, 174 uint(13579), 175 } { 176 v1 := reflect.ValueOf(src) 177 v1 = tool.Rdecodesimple(v1) 178 if rForUInteger(v1).Interface() != "13579" { 179 t.Fail() 180 } 181 } 182 183 var z typ.Any 184 v1 := reflect.ValueOf(z) 185 v1 = tool.Rdecodesimple(v1) 186 if x := rForUInteger(v1).Interface(); x != "0" { 187 t.Fatalf("failed, x = %v", x) 188 } 189 190 z = "bug" 191 v1 = reflect.ValueOf(z) 192 v1 = tool.Rdecodesimple(v1) 193 if x := rForUInteger(v1).Interface(); x != "0" { 194 t.Fatalf("failed, x = %v", x) 195 } 196 } 197 198 func TestToUInteger(t *testing.T) { 199 for _, dt := range []reflect.Type{ 200 reflect.TypeOf((*uint)(nil)).Elem(), 201 reflect.TypeOf((*uint64)(nil)).Elem(), 202 reflect.TypeOf((*uint32)(nil)).Elem(), 203 reflect.TypeOf((*uint16)(nil)).Elem(), 204 reflect.TypeOf((*uint8)(nil)).Elem(), 205 } { 206 for vv, ii := range map[string]uint64{ 207 "123": 123, 208 "9": 9, 209 "8.75": 9, 210 "8.49": 8, 211 } { 212 v := reflect.ValueOf(vv) 213 ret, err := rToUInteger(v, dt) 214 if err != nil { 215 t.Fatalf("err: %v", err) 216 } 217 if ret.Uint() != ii { 218 t.Fatalf("expect %v but got %v", ii, ret.Int()) 219 } 220 } 221 } 222 } 223 224 func TestForUIntegerHex(t *testing.T) { 225 for _, src := range []uint64{ 226 0x3e67, 227 uint64(0x3e67), 228 } { 229 // v1 := reflect.ValueOf(src) 230 // v1 = rdecodesimple(v1) 231 if x := rForUIntegerHex(uintptr(src)).Interface(); x != "0x3e67" { 232 t.Fatalf("expect %v but got %v", "0x3e67", x) 233 } 234 } 235 236 var z typ.Any 237 v1 := reflect.ValueOf(z) 238 v1 = tool.Rdecodesimple(v1) 239 if x := rForUInteger(v1).Interface(); x != "0" { 240 t.Fatalf("failed, x = %v", x) 241 } 242 243 z = "bug" 244 v1 = reflect.ValueOf(z) 245 v1 = tool.Rdecodesimple(v1) 246 if x := rForUInteger(v1).Interface(); x != "0" { 247 t.Fatalf("failed, x = %v", x) 248 } 249 250 z = "0x3e59" 251 v1 = reflect.ValueOf(z) 252 v1 = tool.Rdecodesimple(v1) 253 uintptrType := reflect.TypeOf(uintptr(0)) 254 if x := uintptr(rToUIntegerHex(v1, uintptrType).Uint()); x != uintptr(0x3e59) { 255 t.Fatalf("failed, x = %v", x) 256 } 257 258 vz := "0x3e59" 259 v1 = reflect.ValueOf(vz) 260 ptrType := reflect.TypeOf(&vz) 261 t.Logf("v1.kind: %v, ptrType.kind: %v", v1.Kind(), ptrType.Kind()) 262 if x := uintptr(rToUIntegerHex(v1, ptrType).Uint()); x == 0 { 263 t.Fatalf("failed, x = %v", x) 264 } 265 } 266 267 func TestForFloat(t *testing.T) { 268 for _, src := range []typ.Any{ 269 13579, 270 uint(13579), 271 } { 272 v1 := reflect.ValueOf(src) 273 v1 = tool.Rdecodesimple(v1) 274 if rForFloat(v1).Interface() != "13579" { 275 t.Fail() 276 } 277 } 278 279 var z typ.Any 280 v1 := reflect.ValueOf(z) 281 v1 = tool.Rdecodesimple(v1) 282 if x := rForFloat(v1).Interface(); x != "0" { 283 t.Fatalf("failed, x = %v", x) 284 } 285 286 z = "bug" 287 v1 = reflect.ValueOf(z) 288 v1 = tool.Rdecodesimple(v1) 289 if x := rForFloat(v1).Interface(); x != "0" { 290 t.Fatalf("failed, x = %v", x) 291 } 292 293 } 294 295 func TestToFloat(t *testing.T) { 296 for _, dt := range []reflect.Type{ 297 reflect.TypeOf((*float64)(nil)).Elem(), 298 // reflect.TypeOf((*float32)(nil)).Elem(), 299 } { 300 for vv, ii := range map[string]float64{ 301 "123": 123, 302 "-123": -123, 303 "8.75": 8.75, 304 strconv.FormatUint(math.MaxUint64, 10): 1.8446744073709552e+19, 305 "(8.1+3.5i)": 8.1, 306 } { 307 v := reflect.ValueOf(vv) 308 ret, err := rToFloat(v, dt) 309 if err != nil { 310 t.Fatalf("err: %v", err) 311 } 312 if ret.Float() != ii { 313 t.Fatalf("expect %v but got %v", ii, ret.Float()) 314 } 315 } 316 } 317 } 318 319 func TestForComplex(t *testing.T) { 320 for src, exp := range map[typ.Any]string{ 321 13579: "(13579+0i)", 322 uint(13579): "(13579+0i)", 323 1.316: "(1.316+0i)", 324 8.5 + 7.13i: "(8.5+7.13i)", 325 -8.5 - 7.13i: "(-8.5-7.13i)", 326 } { 327 v1 := reflect.ValueOf(src) 328 v1 = tool.Rdecodesimple(v1) 329 if x := rForComplex(v1).Interface(); x != exp { 330 t.Fatalf("failed, x = %v, expect = %v", x, exp) 331 } 332 } 333 334 var z typ.Any 335 v1 := reflect.ValueOf(z) 336 v1 = tool.Rdecodesimple(v1) 337 if x := rForComplex(v1).Interface(); x != "(0+0i)" { 338 t.Fatalf("failed, x = %v", x) 339 } 340 341 z = "bug" 342 v1 = reflect.ValueOf(z) 343 v1 = tool.Rdecodesimple(v1) 344 if x := rForComplex(v1).Interface(); x != "(0+0i)" { 345 t.Fatalf("failed, x = %v", x) 346 } 347 348 } 349 350 func TestToComplex(t *testing.T) { 351 for _, dt := range []reflect.Type{ 352 // reflect.TypeOf((*complex64)(nil)).Elem(), 353 reflect.TypeOf((*complex128)(nil)).Elem(), 354 } { 355 for vv, ii := range map[string]complex128{ 356 "123+1i": 123 + 1i, 357 "-123-7i": -123 - 7i, 358 "8.75-3.13i": 8.75 - 3.13i, 359 // strconv.FormatUint(math.MaxUint64, 10): 1.8446744073709552e+19, 360 "(8.1+3.5i)": 8.1 + 3.5i, 361 } { 362 v := reflect.ValueOf(vv) 363 ret, err := rToComplex(v, dt) 364 if err != nil { 365 t.Fatalf("err: %v, for src: %q", err, vv) 366 } 367 if ret.Complex() != ii { 368 t.Fatalf("expect %v but got %v", ii, ret.Complex()) 369 } 370 } 371 } 372 } 373 374 func TestBytesBufferConverter_Transform(t *testing.T) { 375 var bbc fromBytesBufferConverter 376 tgtType := reflect.TypeOf((*bytes.Buffer)(nil)).Elem() 377 var bb bytes.Buffer 378 bb.WriteString("hello") 379 src := reflect.ValueOf(bb) 380 tgt, err := bbc.Transform(nil, src, tgtType) 381 if err != nil { 382 t.Fatalf("err: %v", err) 383 } 384 if x, ok := tgt.Interface().(bytes.Buffer); !ok { 385 t.Fatalf("unexpect target value type: %v", tgt.Type()) 386 } else if x.String() != "hello" { //nolint:goconst 387 t.Fatalf("convert failed, want 'hello' but got %q", x.String()) 388 } 389 } 390 391 func TestToStringConverter_Transform(t *testing.T) { 392 var bbc toStringConverter 393 tgtType := reflect.TypeOf((*string)(nil)).Elem() 394 395 var bb bytes.Buffer 396 bb.WriteString("hello") 397 var sb strings.Builder 398 sb.WriteString("hello") 399 400 for sv, exp := range map[typ.Any]string{ 401 "sss": "sss", 402 true: "true", 403 false: "false", 404 123: "123", 405 -123: "-123", 406 uint(123): "123", 407 8.79: "8.79", 408 uintptr(0x3e7c): "0x3e7c", 409 9 + 3i: "(9+3i)", 410 &bb: "hello", 411 &sb: "hello", 412 nil: "", 413 } { 414 svv := reflect.ValueOf(sv) 415 // src := rdecodesimple(svv) 416 tgt, err := bbc.Transform(nil, svv, tgtType) 417 if err != nil { 418 t.Fatalf("err: %v", err) 419 } 420 if x, ok := tgt.Interface().(string); !ok { 421 t.Fatalf("unexpect target value type: %v", tgt.Type()) 422 } else if x != exp { 423 t.Fatalf("convert failed, want %q but got %q", exp, x) 424 } 425 426 var tgtstr = "1" 427 tgt = reflect.ValueOf(&tgtstr).Elem() 428 dbglog.Log("target/; %v %v", tool.Valfmt(&tgt), tool.Typfmtv(&tgt)) 429 err = bbc.CopyTo(nil, svv, tgt) 430 if err != nil { 431 t.Fatalf("err: %v", err) 432 } 433 if x, ok := tgt.Interface().(string); !ok { 434 t.Fatalf("unexpect target value type: %v", tgt.Type()) 435 } else if x != exp { 436 t.Fatalf("convert failed, want %q but got %q", exp, x) 437 } 438 t.Logf(" tgtstr = %v", tgtstr) 439 } 440 441 // 442 443 type sss struct { 444 string 445 } 446 var sss1 = sss{"hello"} 447 var exp = "{hello}" 448 449 svv := reflect.ValueOf(sss1) 450 // src := rdecodesimple(svv) 451 tgt, err := bbc.Transform(nil, svv, tgtType) 452 if err != nil { 453 t.Fatalf("err: %v", err) 454 } 455 if x, ok := tgt.Interface().(string); !ok { 456 t.Fatalf("unexpect target value type: %v", tgt.Type()) 457 } else if x != exp { 458 t.Fatalf("convert failed, want %q but got %q", exp, x) 459 } 460 } 461 462 var tgtTypes = map[reflect.Kind]reflect.Type{ 463 reflect.String: reflect.TypeOf((*string)(nil)).Elem(), 464 reflect.Bool: reflect.TypeOf((*bool)(nil)).Elem(), 465 reflect.Uint: reflect.TypeOf((*uint)(nil)).Elem(), 466 reflect.Int: reflect.TypeOf((*int)(nil)).Elem(), 467 reflect.Float64: reflect.TypeOf((*float64)(nil)).Elem(), 468 reflect.Complex128: reflect.TypeOf((*complex128)(nil)).Elem(), 469 reflect.Ptr: reflect.TypeOf((*int)(nil)).Elem(), 470 reflect.Uintptr: reflect.TypeOf((*uintptr)(nil)).Elem(), 471 } 472 473 func TestFromStringConverter_Transform(t *testing.T) { 474 var bbc fromStringConverter 475 476 for src, tgtm := range map[string]map[reflect.Kind]typ.Any{ 477 "sss": {reflect.String: "sss"}, 478 "true": {reflect.Bool: true}, 479 "false": {reflect.Bool: false}, 480 "123": {reflect.Uint: uint(123)}, 481 "-123": {reflect.Int: -123}, 482 "8.79": {reflect.Float64: 8.79}, 483 "(3+4i)": {reflect.Complex128: 3 + 4i}, 484 "0x3e4a": {reflect.Uintptr: uintptr(0x3e4a)}, 485 // "": {reflect.Ptr: uintptr(0)}, 486 } { 487 for kind, exp := range tgtm { 488 svv := reflect.ValueOf(src) 489 tgtType := tgtTypes[kind] 490 // src := rdecodesimple(svv) 491 tgt, err := bbc.Transform(nil, svv, tgtType) 492 if err != nil { 493 t.Fatalf("err: %v", err) 494 } 495 496 if x := tgt.Interface(); x != exp { 497 t.Fatalf("convert failed, want %v but got %v (%v)", exp, x, tool.Typfmt(tgt.Type())) 498 } 499 500 tgt = reflect.New(tgtType).Elem() 501 err = bbc.CopyTo(nil, svv, tgt) 502 if err != nil { 503 t.Fatalf("err: %v", err) 504 } 505 if x := tgt.Interface(); x != exp { 506 t.Fatalf("convert failed, want %v but got %v (%v)", exp, x, tool.Typfmt(tgt.Type())) 507 } 508 } 509 } 510 511 } 512 513 func TestToDurationConverter_Transform(t *testing.T) { 514 var bbc fromStringConverter 515 var dur = 3 * time.Second 516 517 var v = reflect.ValueOf(dur) 518 t.Logf("dur: %v (%v, kind: %v, name: %v, pkgpath: %v)", dur, tool.Typfmtv(&v), v.Kind(), v.Type().Name(), v.Type().PkgPath()) 519 520 tgtType := reflect.TypeOf((*time.Duration)(nil)).Elem() 521 522 var src typ.Any = int64(13 * time.Hour) 523 svv := reflect.ValueOf(src) 524 tgt, err := bbc.Transform(nil, svv, tgtType) 525 if err != nil { 526 t.Fatalf("err: %v", err) 527 } 528 t.Logf("res: %v (%v)", tgt.Interface(), tool.Typfmtv(&tgt)) 529 530 t.Run("toDurationConverter = pre", func(t *testing.T) { 531 532 for ix, cas := range []struct { 533 src, tgt, expect typ.Any 534 }{ 535 {"71ms", &dur, 71 * time.Millisecond}, 536 {"9h71ms", &dur, 9*time.Hour + 71*time.Millisecond}, 537 {int64(13 * time.Hour), &dur, 13 * time.Hour}, 538 } { 539 var c = newDeepCopier() 540 // var ctx = newValueConverterContextForTest(c) 541 svv = reflect.ValueOf(cas.src) 542 err = c.CopyTo(cas.src, cas.tgt) 543 // tgt, err = bbc.Transform(ctx, svv, tgtType) 544 if err != nil { 545 t.Fatalf("err: %v", err) 546 } 547 if reflect.DeepEqual(dur, cas.expect) == false { 548 t.Fatalf("err transform: expect %v but got %v", cas.expect, tgt) 549 } 550 t.Logf("res #%d: %v", ix, dur) 551 } 552 553 }) 554 555 // 556 557 t.Run("fromDurationConverter - normal test", func(t *testing.T) { 558 559 inttyp := reflect.TypeOf((*int)(nil)).Elem() 560 int64typ := reflect.TypeOf((*int64)(nil)).Elem() 561 stringtyp := reflect.TypeOf((*string)(nil)).Elem() 562 booltyp := reflect.TypeOf((*bool)(nil)).Elem() 563 564 var fdc fromDurationConverter 565 566 for ix, cas := range []struct { 567 src, tgt, expect interface{} 568 desiredType reflect.Type 569 }{ 570 {13 * time.Hour, &dur, "13h0m0s", stringtyp}, 571 {71 * time.Millisecond, &dur, int(71 * time.Millisecond), inttyp}, 572 {9*time.Hour + 71*time.Millisecond, &dur, int64(9*time.Hour + 71*time.Millisecond), int64typ}, 573 {13 * time.Hour, &dur, true, booltyp}, 574 {0 * time.Hour, &dur, false, booltyp}, 575 } { 576 var c = newDeepCopier() 577 var ctx = newValueConverterContextForTest(c) 578 svv = reflect.ValueOf(cas.src) 579 // err = c.CopyTo(cas.src, cas.tgt) 580 tgt, err = fdc.Transform(ctx, svv, cas.desiredType) 581 if err != nil { 582 t.Fatalf("err: %v", err) 583 } 584 if reflect.DeepEqual(tgt.Interface(), cas.expect) == false { 585 t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, tgt.Interface(), tool.Typfmt(tgt.Type())) 586 } 587 t.Logf("res #%d: %v (%v)", ix, tgt.Interface(), tool.Typfmt(tgt.Type())) 588 } 589 590 }) 591 592 // 593 594 t.Run("toDurationConverter - normal test", func(t *testing.T) { 595 596 var tdc toDurationConverter 597 598 for ix, cas := range []struct { 599 src, tgt, expect interface{} 600 }{ 601 {"71ms", &dur, 71 * time.Millisecond}, 602 {"9h71ms", &dur, 9*time.Hour + 71*time.Millisecond}, 603 {int64(13 * time.Hour), &dur, 13 * time.Hour}, 604 {false, &dur, 0 * time.Second}, 605 {true, &dur, 1 * time.Nanosecond}, 606 } { 607 var c = newDeepCopier() 608 var ctx = newValueConverterContextForTest(c) 609 svv = reflect.ValueOf(cas.src) 610 // err = c.CopyTo(cas.src, cas.tgt) 611 tgt, err = tdc.Transform(ctx, svv, tgtType) 612 if err != nil { 613 t.Fatalf("err: %v", err) 614 } 615 if reflect.DeepEqual(tgt.Interface(), cas.expect) == false { 616 t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, tgt.Interface(), tool.Typfmt(tgt.Type())) 617 } 618 t.Logf("res #%d: %v (%v)", ix, tgt.Interface(), tool.Typfmt(tgt.Type())) 619 } 620 621 }) 622 623 // var c = newDeepCopier() 624 // c.withConverters(&toDurationConverter{}) 625 // var ctx = newValueConverterContextForTest(c) 626 // src = "71ms" 627 // svv = reflect.ValueOf(src) 628 // tgt, err = bbc.Transform(ctx, svv, tgtType) 629 // if err != nil { 630 // t.Fatalf("err: %v", err) 631 // } 632 // t.Logf("res: %v (%v)", tgt.Interface(), typfmtv(&tgt)) 633 // 634 // src = "9h71ms" 635 // svv = reflect.ValueOf(src) 636 // err = bbc.CopyTo(ctx, svv, reflect.ValueOf(&dur).Elem()) 637 // if err != nil { 638 // t.Fatalf("err: %v", err) 639 // } 640 // t.Logf("res: %v", dur) 641 // 642 // // 643 // 644 // c = newDeepCopier() 645 // c.withCopiers(&toDurationConverter{}) 646 // ctx = newValueConverterContextForTest(c) 647 // src = "71ms" 648 // svv = reflect.ValueOf(src) 649 // tgt, err = bbc.Transform(ctx, svv, tgtType) 650 // if err != nil { 651 // t.Fatalf("err: %v", err) 652 // } 653 // t.Logf("res: %v (%v)", tgt.Interface(), typfmtv(&tgt)) 654 // 655 // src = "9h71ms" 656 // svv = reflect.ValueOf(src) 657 // err = bbc.CopyTo(ctx, svv, reflect.ValueOf(&dur).Elem()) 658 // if err != nil { 659 // t.Fatalf("err: %v", err) 660 // } 661 // t.Logf("res: %v", dur) 662 663 // 664 665 c := newCopier() 666 c.withFlags(cms.SliceMerge) 667 c.withFlags(cms.MapMerge) 668 } 669 670 func TestToDurationConverter_fallback(t *testing.T) { 671 var tdfs toDurationConverter 672 var dur = 3 * time.Second 673 var v = reflect.ValueOf(&dur) 674 _ = tdfs.fallback(v) 675 t.Logf("dur: %v", dur) 676 } 677 678 func TestToTimeConverter_Transform(t *testing.T) { 679 680 t.Run("fromTimeConverter - normal test", func(t *testing.T) { 681 682 inttyp := reflect.TypeOf((*int)(nil)).Elem() 683 int64typ := reflect.TypeOf((*int64)(nil)).Elem() 684 stringtyp := reflect.TypeOf((*string)(nil)).Elem() 685 // booltyp := reflect.TypeOf((*bool)(nil)).Elem() 686 floattyp := reflect.TypeOf((*float64)(nil)).Elem() 687 688 var ftc fromTimeConverter 689 var dur int 690 691 for ix, cas := range []struct { 692 src string 693 tgt, expect interface{} 694 desiredType reflect.Type 695 }{ 696 {"2001-02-03 04:05:06.078912", &dur, "2001-02-03T04:05:06Z", stringtyp}, 697 {"2001-02-03 04:05:06.078912", &dur, int(981173106), inttyp}, 698 {"2001-02-03 04:05:06.078912", &dur, int64(981173106), int64typ}, 699 {"2001-02-03 04:05:06.078912", &dur, float64(981173106.078912), floattyp}, 700 } { 701 var c = newDeepCopier() 702 var ctx = newValueConverterContextForTest(c) 703 var tm, err = time.Parse("2006-01-02 15:04:05.000000", cas.src) 704 t.Logf("%q parsed: %v (%v)", cas.src, tm, err) 705 var svv = reflect.ValueOf(tm) 706 // err = c.CopyTo(cas.src, cas.tgt) 707 tgt, err := ftc.Transform(ctx, svv, cas.desiredType) 708 if err != nil { 709 t.Fatalf("err: %v", err) 710 } 711 if reflect.DeepEqual(tgt.Interface(), cas.expect) == false { 712 t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, tgt.Interface(), tool.Typfmt(tgt.Type())) 713 } 714 t.Logf("res #%d: %v (%v)", ix, tgt.Interface(), tool.Typfmt(tgt.Type())) 715 } 716 717 }) 718 719 t.Run("toTimeConverter - normal test", func(t *testing.T) { 720 721 var tdc toTimeConverter 722 var tm time.Time 723 layout := "2006-01-02 15:04:05.999999999Z07:00" 724 tgtType := reflect.TypeOf((*time.Time)(nil)).Elem() 725 726 for ix, cas := range []struct { 727 src, tgt, expect interface{} 728 }{ 729 {"2001-02-03 04:05:06.078912", &tm, "2001-02-03 04:05:06.078912Z"}, 730 {"2001-02-03 04:05:06.078912345", &tm, "2001-02-03 04:05:06.078912345Z"}, 731 {int(981173106), &tm, "2001-02-03 04:05:06Z"}, 732 {int64(981173106), &tm, "2001-02-03 04:05:06Z"}, 733 {float64(981173106.078912), &tm, "2001-02-03 04:05:06.078912019Z"}, 734 } { 735 var c = newDeepCopier() 736 var ctx = newValueConverterContextForTest(c) 737 var svv = reflect.ValueOf(cas.src) 738 // err = c.CopyTo(cas.src, cas.tgt) 739 var tgt, err = tdc.Transform(ctx, svv, tgtType) 740 if err != nil { 741 t.Fatalf("err: %v", err) 742 } 743 got := tgt.Interface().(time.Time).UTC().Format(layout) 744 if reflect.DeepEqual(got, cas.expect) == false { 745 t.Fatalf("err transform: expect %v but got %v (%v)", cas.expect, got, tool.Typfmt(tgt.Type())) 746 } 747 t.Logf("res #%d: %v (%v)", ix, got, tool.Typfmt(tgt.Type())) 748 } 749 750 }) 751 } 752 753 func TestFromStringConverter_defaultTypes(t *testing.T) { 754 var fss fromStringConverter 755 var src = "987" 756 var dst = 3.3 757 var svv = reflect.ValueOf(src) 758 var dvv = reflect.ValueOf(&dst) 759 760 ctx := newValueConverterContextForTest(newDeepCopier()) 761 ret, err := fss.convertToOrZeroTarget(ctx, svv, dvv.Type().Elem()) 762 if err != nil { 763 t.Fatalf("err: %v", err) 764 } 765 t.Logf("ret: %v (%v)", tool.Valfmt(&ret), tool.Typfmtv(&ret)) 766 } 767 768 func TestFromStringConverter_postCopyTo(t *testing.T) { 769 var fss fromStringConverter 770 771 var src = "987" 772 var dst = 3.3 773 var svv = reflect.ValueOf(src) 774 var dvv = reflect.ValueOf(&dst) 775 776 c := newDeepCopier().withFlags(cms.ClearIfInvalid) 777 ctx := newValueConverterContextForTest(c) 778 err := fss.postCopyTo(ctx, svv, dvv.Elem()) 779 if err != nil { 780 t.Fatalf("err: %v", err) 781 } 782 t.Logf("ret: %v (%v)", dst, tool.Typfmtv(&dvv)) 783 } 784 785 func TestToStringConverter_postCopyTo(t *testing.T) { 786 var fss toStringConverter 787 var src = struct { 788 fval float64 789 }{3.3} 790 var dst = struct { 791 fval string 792 }{} 793 var svv = reflect.ValueOf(&src) 794 var dvv = reflect.ValueOf(&dst) 795 var sf1 = tool.Rindirect(svv).Field(0) 796 var df1 = tool.Rindirect(dvv).Field(0) 797 // var sft = reflect.TypeOf(src).Field(0) 798 799 ctx := &ValueConverterContext{ 800 Params: &Params{ 801 srcOwner: &svv, 802 dstOwner: &dvv, 803 // field: &sft, 804 // fieldTags: parseFieldTags(sft.Tag), 805 targetIterator: newStructIterator(dvv, 806 withStructPtrAutoExpand(true), 807 withStructFieldPtrAutoNew(true), 808 withStructSource(&svv, true), 809 ), 810 controller: newDeepCopier(), 811 }, 812 } 813 814 ctx.nextTargetField() // call ctx.targetIterator.Next() to locate the first field 815 816 sf2 := cl.GetUnexportedField(sf1) 817 818 err := fss.postCopyTo(ctx, sf2, df1) 819 if err != nil { 820 t.Fatalf("err: %v", err) 821 } 822 if dst.fval != "3.3" { 823 t.Fatalf("want '3.3' but got %v", dst.fval) 824 } 825 t.Logf("ret: %v (%v)", dst, tool.Typfmtv(&dvv)) 826 } 827 828 type si1 struct{} 829 type si2 struct{} 830 831 func (*si2) String() string { return "i2" } 832 833 func TestHasStringer(t *testing.T) { 834 var i1 si1 835 var i2 si2 836 837 v := reflect.ValueOf(i1) 838 t.Logf("si1: %v", tool.HasStringer(&v)) 839 v = reflect.ValueOf(i2) 840 t.Logf("si2: %v", tool.HasStringer(&v)) 841 v = reflect.ValueOf(&i2) 842 t.Logf("*si2: %v", tool.HasStringer(&v)) 843 } 844 845 func TestNameToMapKey(t *testing.T) { 846 name := "9527" 847 // value := 789 848 mapslice := []interface{}{ 849 map[int]interface{}{ 850 111: 333, 851 }, 852 map[int]interface{}{ 853 9527: 333, 854 }, 855 map[float32]interface{}{ 856 9527: 333, 857 }, 858 map[complex128]interface{}{ 859 9527: 333, 860 }, 861 map[string]interface{}{ 862 "my": 12, 863 }, 864 map[string]interface{}{ 865 "9527": 33, 866 }, 867 } 868 869 for _, m := range mapslice { 870 mv := reflect.ValueOf(&m) // nolint:gosec // G601: Implicit memory aliasing in for loop 871 mvind := tool.Rdecodesimple(mv) 872 t.Logf(" target map is %v", tool.Typfmtv(&mvind)) 873 mt := tool.Rdecodetypesimple(mvind.Type()) 874 key, err := nameToMapKey(name, mt) 875 if err != nil { 876 t.Errorf("nameToMapKey, has error: %v", err) 877 } else { 878 t.Logf("for target map %v, got key from nameToMapKey: %v %v", tool.Typfmt(mt), tool.Valfmt(&key), tool.Typfmt(key.Type())) 879 } 880 } 881 } 882 883 func TestFromFuncConverterAlongMainEntry(t *testing.T) { 884 type A1 struct { 885 Bv func() (int, error) 886 } 887 type B1 struct { 888 Bv int 889 } 890 891 var a1 = A1{func() (int, error) { return 3, nil }} 892 var b1 = B1{1} 893 894 // test for fromFuncConverter along Copy -> cpController.findConverters 895 Copy(&a1, &b1) 896 897 if b1.Bv != 3 { 898 t.Fatalf("expect %v but got %v", 3, b1.Bv) 899 } 900 } 901 902 func TestFromFuncConverter(t *testing.T) { 903 fn0 := func() string { return "hello" } 904 905 type C struct { 906 A int 907 B bool 908 } 909 type A struct { 910 A func() C 911 B func() bool 912 } 913 type B struct { 914 C *C 915 B bool 916 } 917 var a0 = A{ 918 func() C { return C{7, true} }, 919 func() bool { return false }, 920 } 921 var b0 = B{nil, true} 922 var b1 = B{&C{7, true}, false} 923 924 var boolTgt bool 925 var intTgt = 1 926 var stringTgt = "world" 927 928 lazyInitRoutines() 929 930 for ix, fnCase := range []struct { 931 fn interface{} 932 target interface{} 933 expect interface{} 934 }{ 935 {func() ([]int, error) { return []int{2, 3}, nil }, &[]int{1}, []int{1, 2, 3}}, 936 937 // {func() ([2]int, error) { return [2]int{2, 3}, nil }, &[2]int{1}, [2]int{2, 3}}, 938 939 {func() A { return a0 }, 940 &b0, 941 b1, 942 }, 943 944 {func() map[string]interface{} { return map[string]interface{}{"hello": "world"} }, 945 &map[string]interface{}{"k": 1, "hello": "bob"}, 946 map[string]interface{}{"hello": "world", "k": 1}, 947 }, 948 949 {func() string { return "hello" }, &stringTgt, "hello"}, 950 {func() string { return "hello" }, &intTgt, 1}, 951 {func() string { return "789" }, &intTgt, 789}, 952 {&fn0, &stringTgt, "hello"}, 953 954 {func() ([2]int, error) { return [2]int{2, 3}, nil }, &[2]int{1}, [2]int{2, 3}}, 955 {func() ([2]int, error) { return [2]int{2, 3}, nil }, &[3]int{1}, [3]int{2, 3}}, 956 {func() ([3]int, error) { return [3]int{2, 3, 5}, nil }, &[2]int{1}, [2]int{2, 3}}, 957 {func() ([]int, error) { return []int{2, 3}, nil }, &[]int{1}, []int{1, 2, 3}}, 958 959 {func() bool { return true }, &boolTgt, true}, 960 {func() int { return 3 }, &intTgt, 3}, 961 {func() (int, error) { return 5, nil }, &intTgt, 5}, 962 } { 963 if fnCase.fn != nil { //nolint:gocritic //nestingReduce: invert if cond, replace body with `continue`, move old body after the statement 964 fnv := reflect.ValueOf(&fnCase.fn) 965 tgtv := reflect.ValueOf(&fnCase.target) 966 ff, tt := tool.Rdecodesimple(fnv), tool.Rdecodesimple(tgtv) 967 dbglog.Log("---- CASE %d. %v -> %v", ix, tool.Typfmtv(&ff), tool.Typfmtv(&tt)) 968 969 c := fromFuncConverter{} 970 ctx := newValueConverterContextForTest(nil) 971 err := c.CopyTo(ctx, fnv, tgtv) 972 973 if err != nil { 974 t.Fatalf("has error: %v", err) 975 } else if ret := tt.Interface(); reflect.DeepEqual(ret, fnCase.expect) == false { 976 t.Fatalf("unexpect result: expect %v but got %v", fnCase.expect, ret) 977 } 978 } 979 } 980 } 981 982 func newValueConverterContextForTest(c *cpController) *ValueConverterContext { 983 if c == nil { 984 c = newDeepCopier() 985 } 986 return &ValueConverterContext{newParams(withOwnersSimple(c, nil))} 987 }