github.com/gogf/gf@v1.16.9/util/gconv/gconv_z_unit_struct_test.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gconv_test 8 9 import ( 10 "github.com/gogf/gf/container/gvar" 11 "github.com/gogf/gf/frame/g" 12 "github.com/gogf/gf/internal/json" 13 "github.com/gogf/gf/os/gtime" 14 "github.com/gogf/gf/test/gtest" 15 "github.com/gogf/gf/util/gconv" 16 "testing" 17 "time" 18 ) 19 20 func Test_Struct_Basic1(t *testing.T) { 21 gtest.C(t, func(t *gtest.T) { 22 type User struct { 23 Uid int 24 Name string 25 Site_Url string 26 NickName string 27 Pass1 string `gconv:"password1"` 28 Pass2 string `gconv:"password2"` 29 } 30 user := new(User) 31 params1 := g.Map{ 32 "uid": 1, 33 "Name": "john", 34 "siteurl": "https://goframe.org", 35 "nick_name": "johng", 36 "PASS1": "123", 37 "PASS2": "456", 38 } 39 if err := gconv.Struct(params1, user); err != nil { 40 t.Error(err) 41 } 42 t.Assert(user, &User{ 43 Uid: 1, 44 Name: "john", 45 Site_Url: "https://goframe.org", 46 NickName: "johng", 47 Pass1: "123", 48 Pass2: "456", 49 }) 50 51 user = new(User) 52 params2 := g.Map{ 53 "uid": 2, 54 "name": "smith", 55 "site-url": "https://goframe.org", 56 "nick name": "johng", 57 "password1": "111", 58 "password2": "222", 59 } 60 if err := gconv.Struct(params2, user); err != nil { 61 t.Error(err) 62 } 63 t.Assert(user, &User{ 64 Uid: 2, 65 Name: "smith", 66 Site_Url: "https://goframe.org", 67 NickName: "johng", 68 Pass1: "111", 69 Pass2: "222", 70 }) 71 }) 72 } 73 74 func Test_Struct_Basic2(t *testing.T) { 75 gtest.C(t, func(t *gtest.T) { 76 type User struct { 77 Uid int 78 Name string 79 SiteUrl string 80 Pass1 string 81 Pass2 string 82 } 83 user := new(User) 84 params := g.Map{ 85 "uid": 1, 86 "Name": "john", 87 "site_url": "https://goframe.org", 88 "PASS1": "123", 89 "PASS2": "456", 90 } 91 if err := gconv.Struct(params, user); err != nil { 92 t.Error(err) 93 } 94 t.Assert(user, &User{ 95 Uid: 1, 96 Name: "john", 97 SiteUrl: "https://goframe.org", 98 Pass1: "123", 99 Pass2: "456", 100 }) 101 }) 102 } 103 104 func Test_Struct_Attr_Pointer(t *testing.T) { 105 gtest.C(t, func(t *gtest.T) { 106 type User struct { 107 Uid *int 108 Name *string 109 } 110 user := new(User) 111 params := g.Map{ 112 "uid": "1", 113 "Name": "john", 114 } 115 if err := gconv.Struct(params, user); err != nil { 116 t.Error(err) 117 } 118 t.Assert(user.Uid, 1) 119 t.Assert(*user.Name, "john") 120 }) 121 } 122 123 func Test_Struct_Attr_Slice1(t *testing.T) { 124 gtest.C(t, func(t *gtest.T) { 125 type User struct { 126 Scores []int 127 } 128 scores := []interface{}{99, 100, 60, 140} 129 user := new(User) 130 if err := gconv.Struct(g.Map{"Scores": scores}, user); err != nil { 131 t.Error(err) 132 } else { 133 t.Assert(user, &User{ 134 Scores: []int{99, 100, 60, 140}, 135 }) 136 } 137 }) 138 } 139 140 // It does not support this kind of converting yet. 141 //func Test_Struct_Attr_Slice2(t *testing.T) { 142 // gtest.C(t, func(t *gtest.T) { 143 // type User struct { 144 // Scores [][]int 145 // } 146 // scores := []interface{}{[]interface{}{99, 100, 60, 140}} 147 // user := new(User) 148 // if err := gconv.Struct(g.Map{"Scores": scores}, user); err != nil { 149 // t.Error(err) 150 // } else { 151 // t.Assert(user, &User{ 152 // Scores: [][]int{{99, 100, 60, 140}}, 153 // }) 154 // } 155 // }) 156 //} 157 158 func Test_Struct_Attr_Struct(t *testing.T) { 159 gtest.C(t, func(t *gtest.T) { 160 type Score struct { 161 Name string 162 Result int 163 } 164 type User struct { 165 Scores Score 166 } 167 168 user := new(User) 169 scores := map[string]interface{}{ 170 "Scores": map[string]interface{}{ 171 "Name": "john", 172 "Result": 100, 173 }, 174 } 175 176 // 嵌套struct转换 177 if err := gconv.Struct(scores, user); err != nil { 178 t.Error(err) 179 } else { 180 t.Assert(user, &User{ 181 Scores: Score{ 182 Name: "john", 183 Result: 100, 184 }, 185 }) 186 } 187 }) 188 } 189 190 func Test_Struct_Attr_Struct_Ptr(t *testing.T) { 191 gtest.C(t, func(t *gtest.T) { 192 type Score struct { 193 Name string 194 Result int 195 } 196 type User struct { 197 Scores *Score 198 } 199 200 user := new(User) 201 scores := map[string]interface{}{ 202 "Scores": map[string]interface{}{ 203 "Name": "john", 204 "Result": 100, 205 }, 206 } 207 208 // 嵌套struct转换 209 if err := gconv.Struct(scores, user); err != nil { 210 t.Error(err) 211 } else { 212 t.Assert(user.Scores, &Score{ 213 Name: "john", 214 Result: 100, 215 }) 216 } 217 }) 218 } 219 220 func Test_Struct_Attr_Struct_Slice1(t *testing.T) { 221 gtest.C(t, func(t *gtest.T) { 222 type Score struct { 223 Name string 224 Result int 225 } 226 type User struct { 227 Scores []Score 228 } 229 230 user := new(User) 231 scores := map[string]interface{}{ 232 "Scores": map[string]interface{}{ 233 "Name": "john", 234 "Result": 100, 235 }, 236 } 237 238 if err := gconv.Struct(scores, user); err != nil { 239 t.Error(err) 240 } else { 241 t.Assert(user.Scores, []Score{ 242 { 243 Name: "john", 244 Result: 100, 245 }, 246 }) 247 } 248 }) 249 } 250 251 func Test_Struct_Attr_Struct_Slice2(t *testing.T) { 252 gtest.C(t, func(t *gtest.T) { 253 type Score struct { 254 Name string 255 Result int 256 } 257 type User struct { 258 Scores []Score 259 } 260 261 user := new(User) 262 scores := map[string]interface{}{ 263 "Scores": []interface{}{ 264 map[string]interface{}{ 265 "Name": "john", 266 "Result": 100, 267 }, 268 map[string]interface{}{ 269 "Name": "smith", 270 "Result": 60, 271 }, 272 }, 273 } 274 275 if err := gconv.Struct(scores, user); err != nil { 276 t.Error(err) 277 } else { 278 t.Assert(user.Scores, []Score{ 279 { 280 Name: "john", 281 Result: 100, 282 }, 283 { 284 Name: "smith", 285 Result: 60, 286 }, 287 }) 288 } 289 }) 290 } 291 292 func Test_Struct_Attr_Struct_Slice_Ptr(t *testing.T) { 293 gtest.C(t, func(t *gtest.T) { 294 type Score struct { 295 Name string 296 Result int 297 } 298 type User struct { 299 Scores []*Score 300 } 301 302 user := new(User) 303 scores := map[string]interface{}{ 304 "Scores": []interface{}{ 305 map[string]interface{}{ 306 "Name": "john", 307 "Result": 100, 308 }, 309 map[string]interface{}{ 310 "Name": "smith", 311 "Result": 60, 312 }, 313 }, 314 } 315 316 // 嵌套struct转换,属性为slice类型,数值为slice map类型 317 if err := gconv.Struct(scores, user); err != nil { 318 t.Error(err) 319 } else { 320 t.Assert(len(user.Scores), 2) 321 t.Assert(user.Scores[0], &Score{ 322 Name: "john", 323 Result: 100, 324 }) 325 t.Assert(user.Scores[1], &Score{ 326 Name: "smith", 327 Result: 60, 328 }) 329 } 330 }) 331 } 332 333 func Test_Struct_Attr_CustomType1(t *testing.T) { 334 type MyInt int 335 type User struct { 336 Id MyInt 337 Name string 338 } 339 gtest.C(t, func(t *gtest.T) { 340 user := new(User) 341 err := gconv.Struct(g.Map{"id": 1, "name": "john"}, user) 342 t.Assert(err, nil) 343 t.Assert(user.Id, 1) 344 t.Assert(user.Name, "john") 345 }) 346 } 347 348 func Test_Struct_Attr_CustomType2(t *testing.T) { 349 type MyInt int 350 type User struct { 351 Id []MyInt 352 Name string 353 } 354 gtest.C(t, func(t *gtest.T) { 355 user := new(User) 356 err := gconv.Struct(g.Map{"id": g.Slice{1, 2}, "name": "john"}, user) 357 t.Assert(err, nil) 358 t.Assert(user.Id, g.Slice{1, 2}) 359 t.Assert(user.Name, "john") 360 }) 361 } 362 363 // From: k8s.io/apimachinery@v0.22.0/pkg/apis/meta/v1/duration.go 364 type MyDuration struct { 365 time.Duration 366 } 367 368 // UnmarshalJSON implements the json.Unmarshaller interface. 369 func (d *MyDuration) UnmarshalJSON(b []byte) error { 370 var str string 371 err := json.Unmarshal(b, &str) 372 if err != nil { 373 return err 374 } 375 376 pd, err := time.ParseDuration(str) 377 if err != nil { 378 return err 379 } 380 d.Duration = pd 381 return nil 382 } 383 384 func Test_Struct_Attr_CustomType3(t *testing.T) { 385 type Config struct { 386 D MyDuration 387 } 388 gtest.C(t, func(t *gtest.T) { 389 config := new(Config) 390 err := gconv.Struct(g.Map{"d": "15s"}, config) 391 t.AssertNil(err) 392 t.Assert(config.D, "15s") 393 }) 394 gtest.C(t, func(t *gtest.T) { 395 config := new(Config) 396 err := gconv.Struct(g.Map{"d": `"15s"`}, config) 397 t.AssertNil(err) 398 t.Assert(config.D, "15s") 399 }) 400 } 401 402 func Test_Struct_PrivateAttribute(t *testing.T) { 403 type User struct { 404 Id int 405 name string 406 } 407 gtest.C(t, func(t *gtest.T) { 408 user := new(User) 409 err := gconv.Struct(g.Map{"id": 1, "name": "john"}, user) 410 t.Assert(err, nil) 411 t.Assert(user.Id, 1) 412 t.Assert(user.name, "") 413 }) 414 } 415 416 func Test_StructEmbedded1(t *testing.T) { 417 type Base struct { 418 Age int 419 } 420 type User struct { 421 Id int 422 Name string 423 Base 424 } 425 gtest.C(t, func(t *gtest.T) { 426 user := new(User) 427 params := g.Map{ 428 "id": 1, 429 "name": "john", 430 "age": 18, 431 } 432 err := gconv.Struct(params, user) 433 t.Assert(err, nil) 434 t.Assert(user.Id, params["id"]) 435 t.Assert(user.Name, params["name"]) 436 t.Assert(user.Age, 18) 437 }) 438 } 439 440 func Test_StructEmbedded2(t *testing.T) { 441 type Ids struct { 442 Id int 443 Uid int 444 } 445 type Base struct { 446 Ids 447 Time string 448 } 449 type User struct { 450 Base 451 Name string 452 } 453 params := g.Map{ 454 "id": 1, 455 "uid": 10, 456 "name": "john", 457 } 458 gtest.C(t, func(t *gtest.T) { 459 user := new(User) 460 err := gconv.Struct(params, user) 461 t.Assert(err, nil) 462 t.Assert(user.Id, 1) 463 t.Assert(user.Uid, 10) 464 t.Assert(user.Name, "john") 465 }) 466 } 467 468 func Test_StructEmbedded3(t *testing.T) { 469 gtest.C(t, func(t *gtest.T) { 470 type Ids struct { 471 Id int `json:"id"` 472 Uid int `json:"uid"` 473 } 474 type Base struct { 475 Ids 476 CreateTime string `json:"create_time"` 477 } 478 type User struct { 479 Base 480 Passport string `json:"passport"` 481 Password string `json:"password"` 482 Nickname string `json:"nickname"` 483 } 484 data := g.Map{ 485 "id": 100, 486 "uid": 101, 487 "passport": "t1", 488 "password": "123456", 489 "nickname": "T1", 490 "create_time": "2019", 491 } 492 user := new(User) 493 err := gconv.Struct(data, user) 494 t.Assert(err, nil) 495 t.Assert(user.Id, 100) 496 t.Assert(user.Uid, 101) 497 t.Assert(user.Nickname, "T1") 498 t.Assert(user.CreateTime, "2019") 499 }) 500 } 501 502 // https://github.com/gogf/gf/issues/775 503 func Test_StructEmbedded4(t *testing.T) { 504 gtest.C(t, func(t *gtest.T) { 505 type Sub2 struct { 506 SubName string 507 } 508 type sub1 struct { 509 Sub2 510 Name string 511 } 512 type Test struct { 513 Sub sub1 `json:"sub"` 514 } 515 516 data := `{ 517 "sub": { 518 "map":{"k":"v"}, 519 "Name": "name", 520 "SubName": "subname" 521 }}` 522 523 expect := Test{ 524 Sub: sub1{ 525 Name: "name", 526 Sub2: Sub2{ 527 SubName: "subname", 528 }, 529 }, 530 } 531 tx := new(Test) 532 if err := gconv.Struct(data, &tx); err != nil { 533 panic(err) 534 } 535 t.Assert(tx, expect) 536 }) 537 } 538 539 func Test_StructEmbedded5(t *testing.T) { 540 gtest.C(t, func(t *gtest.T) { 541 type Base struct { 542 Pass1 string `params:"password1"` 543 Pass2 string `params:"password2"` 544 } 545 type UserWithBase1 struct { 546 Id int 547 Name string 548 Base 549 } 550 type UserWithBase2 struct { 551 Id int 552 Name string 553 Pass Base 554 } 555 556 data := g.Map{ 557 "id": 1, 558 "name": "john", 559 "password1": "123", 560 "password2": "456", 561 } 562 var err error 563 user1 := new(UserWithBase1) 564 user2 := new(UserWithBase2) 565 err = gconv.Struct(data, user1) 566 t.Assert(err, nil) 567 t.Assert(user1, &UserWithBase1{1, "john", Base{"123", "456"}}) 568 569 err = gconv.Struct(data, user2) 570 t.Assert(err, nil) 571 t.Assert(user2, &UserWithBase2{1, "john", Base{"", ""}}) 572 573 var user3 *UserWithBase1 574 err = gconv.Struct(user1, &user3) 575 t.Assert(err, nil) 576 t.Assert(user3, user1) 577 }) 578 } 579 580 func Test_Struct_Time(t *testing.T) { 581 gtest.C(t, func(t *gtest.T) { 582 type User struct { 583 CreateTime time.Time 584 } 585 now := time.Now() 586 user := new(User) 587 gconv.Struct(g.Map{ 588 "create_time": now, 589 }, user) 590 t.Assert(user.CreateTime.UTC().String(), now.UTC().String()) 591 }) 592 593 gtest.C(t, func(t *gtest.T) { 594 type User struct { 595 CreateTime *time.Time 596 } 597 now := time.Now() 598 user := new(User) 599 gconv.Struct(g.Map{ 600 "create_time": &now, 601 }, user) 602 t.Assert(user.CreateTime.UTC().String(), now.UTC().String()) 603 }) 604 605 gtest.C(t, func(t *gtest.T) { 606 type User struct { 607 CreateTime *gtime.Time 608 } 609 now := time.Now() 610 user := new(User) 611 gconv.Struct(g.Map{ 612 "create_time": &now, 613 }, user) 614 t.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String()) 615 }) 616 617 gtest.C(t, func(t *gtest.T) { 618 type User struct { 619 CreateTime gtime.Time 620 } 621 now := time.Now() 622 user := new(User) 623 gconv.Struct(g.Map{ 624 "create_time": &now, 625 }, user) 626 t.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String()) 627 }) 628 629 gtest.C(t, func(t *gtest.T) { 630 type User struct { 631 CreateTime gtime.Time 632 } 633 now := time.Now() 634 user := new(User) 635 gconv.Struct(g.Map{ 636 "create_time": now, 637 }, user) 638 t.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String()) 639 }) 640 } 641 642 func Test_Struct_GTime(t *testing.T) { 643 // https://github.com/gogf/gf/issues/1387 644 gtest.C(t, func(t *gtest.T) { 645 type User struct { 646 Name string 647 CreateTime *gtime.Time 648 } 649 var user *User 650 err := gconv.Struct(`{"Name":"John","CreateTime":""}`, &user) 651 t.AssertNil(err) 652 t.AssertNE(user, nil) 653 t.Assert(user.Name, `John`) 654 t.Assert(user.CreateTime, nil) 655 }) 656 } 657 658 // Auto create struct when given pointer. 659 func Test_Struct_Create(t *testing.T) { 660 gtest.C(t, func(t *gtest.T) { 661 type User struct { 662 Uid int 663 Name string 664 } 665 user := (*User)(nil) 666 params := g.Map{ 667 "uid": 1, 668 "Name": "john", 669 } 670 err := gconv.Struct(params, &user) 671 t.Assert(err, nil) 672 t.Assert(user.Uid, 1) 673 t.Assert(user.Name, "john") 674 }) 675 676 gtest.C(t, func(t *gtest.T) { 677 type User struct { 678 Uid int 679 Name string 680 } 681 user := (*User)(nil) 682 params := g.Map{ 683 "uid": 1, 684 "Name": "john", 685 } 686 err := gconv.Struct(params, user) 687 t.AssertNE(err, nil) 688 t.Assert(user, nil) 689 }) 690 } 691 692 func Test_Struct_Interface(t *testing.T) { 693 gtest.C(t, func(t *gtest.T) { 694 type User struct { 695 Uid interface{} 696 Name interface{} 697 } 698 user := (*User)(nil) 699 params := g.Map{ 700 "uid": 1, 701 "Name": nil, 702 } 703 err := gconv.Struct(params, &user) 704 t.Assert(err, nil) 705 t.Assert(user.Uid, 1) 706 t.Assert(user.Name, nil) 707 }) 708 } 709 710 func Test_Struct_NilAttribute(t *testing.T) { 711 gtest.C(t, func(t *gtest.T) { 712 type Item struct { 713 Title string `json:"title"` 714 Key string `json:"key"` 715 } 716 717 type M struct { 718 Id string `json:"id"` 719 Me map[string]interface{} `json:"me"` 720 Txt string `json:"txt"` 721 Items []*Item `json:"items"` 722 } 723 m := new(M) 724 err := gconv.Struct(g.Map{ 725 "id": "88888", 726 "me": g.Map{ 727 "name": "mikey", 728 "day": "20009", 729 }, 730 "txt": "hello", 731 "items": nil, 732 }, m) 733 t.Assert(err, nil) 734 t.AssertNE(m.Me, nil) 735 t.Assert(m.Me["day"], "20009") 736 t.Assert(m.Items, nil) 737 }) 738 } 739 740 func Test_Struct_Complex(t *testing.T) { 741 gtest.C(t, func(t *gtest.T) { 742 type ApplyReportDetail struct { 743 ApplyScore string `json:"apply_score"` 744 ApplyCredibility string `json:"apply_credibility"` 745 QueryOrgCount string `json:"apply_query_org_count"` 746 QueryFinanceCount string `json:"apply_query_finance_count"` 747 QueryCashCount string `json:"apply_query_cash_count"` 748 QuerySumCount string `json:"apply_query_sum_count"` 749 LatestQueryTime string `json:"apply_latest_query_time"` 750 LatestOneMonth string `json:"apply_latest_one_month"` 751 LatestThreeMonth string `json:"apply_latest_three_month"` 752 LatestSixMonth string `json:"apply_latest_six_month"` 753 } 754 type BehaviorReportDetail struct { 755 LoansScore string `json:"behavior_report_detailloans_score"` 756 LoansCredibility string `json:"behavior_report_detailloans_credibility"` 757 LoansCount string `json:"behavior_report_detailloans_count"` 758 LoansSettleCount string `json:"behavior_report_detailloans_settle_count"` 759 LoansOverdueCount string `json:"behavior_report_detailloans_overdue_count"` 760 LoansOrgCount string `json:"behavior_report_detailloans_org_count"` 761 ConsfinOrgCount string `json:"behavior_report_detailconsfin_org_count"` 762 LoansCashCount string `json:"behavior_report_detailloans_cash_count"` 763 LatestOneMonth string `json:"behavior_report_detaillatest_one_month"` 764 LatestThreeMonth string `json:"behavior_report_detaillatest_three_month"` 765 LatestSixMonth string `json:"behavior_report_detaillatest_six_month"` 766 HistorySucFee string `json:"behavior_report_detailhistory_suc_fee"` 767 HistoryFailFee string `json:"behavior_report_detailhistory_fail_fee"` 768 LatestOneMonthSuc string `json:"behavior_report_detaillatest_one_month_suc"` 769 LatestOneMonthFail string `json:"behavior_report_detaillatest_one_month_fail"` 770 LoansLongTime string `json:"behavior_report_detailloans_long_time"` 771 LoansLatestTime string `json:"behavior_report_detailloans_latest_time"` 772 } 773 type CurrentReportDetail struct { 774 LoansCreditLimit string `json:"current_report_detailloans_credit_limit"` 775 LoansCredibility string `json:"current_report_detailloans_credibility"` 776 LoansOrgCount string `json:"current_report_detailloans_org_count"` 777 LoansProductCount string `json:"current_report_detailloans_product_count"` 778 LoansMaxLimit string `json:"current_report_detailloans_max_limit"` 779 LoansAvgLimit string `json:"current_report_detailloans_avg_limit"` 780 ConsfinCreditLimit string `json:"current_report_detailconsfin_credit_limit"` 781 ConsfinCredibility string `json:"current_report_detailconsfin_credibility"` 782 ConsfinOrgCount string `json:"current_report_detailconsfin_org_count"` 783 ConsfinProductCount string `json:"current_report_detailconsfin_product_count"` 784 ConsfinMaxLimit string `json:"current_report_detailconsfin_max_limit"` 785 ConsfinAvgLimit string `json:"current_report_detailconsfin_avg_limit"` 786 } 787 type ResultDetail struct { 788 ApplyReportDetail ApplyReportDetail `json:"apply_report_detail"` 789 BehaviorReportDetail BehaviorReportDetail `json:"behavior_report_detail"` 790 CurrentReportDetail CurrentReportDetail `json:"current_report_detail"` 791 } 792 793 type Data struct { 794 Code string `json:"code"` 795 Desc string `json:"desc"` 796 TransID string `json:"trans_id"` 797 TradeNo string `json:"trade_no"` 798 Fee string `json:"fee"` 799 IDNo string `json:"id_no"` 800 IDName string `json:"id_name"` 801 Versions string `json:"versions"` 802 ResultDetail ResultDetail `json:"result_detail"` 803 } 804 805 type XinYanModel struct { 806 Success bool `json:"success"` 807 Data Data `json:"data"` 808 ErrorCode interface{} `json:"errorCode"` 809 ErrorMsg interface{} `json:"errorMsg"` 810 } 811 812 var data = `{ 813 "success": true, 814 "data": { 815 "code": "0", 816 "desc": "查询成功", 817 "trans_id": "14910304379231213", 818 "trade_no": "201704011507240100057329", 819 "fee": "Y", 820 "id_no": "0783231bcc39f4957e99907e02ae401c", 821 "id_name": "dd67a5943781369ddd7c594e231e9e70", 822 "versions": "1.0.0", 823 "result_detail":{ 824 "apply_report_detail": { 825 "apply_score": "189", 826 "apply_credibility": "84", 827 "query_org_count": "7", 828 "query_finance_count": "2", 829 "query_cash_count": "2", 830 "query_sum_count": "13", 831 "latest_query_time": "2017-09-03", 832 "latest_one_month": "1", 833 "latest_three_month": "5", 834 "latest_six_month": "12" 835 }, 836 "behavior_report_detail": { 837 "loans_score": "199", 838 "loans_credibility": "90", 839 "loans_count": "300", 840 "loans_settle_count": "280", 841 "loans_overdue_count": "20", 842 "loans_org_count": "5", 843 "consfin_org_count": "3", 844 "loans_cash_count": "2", 845 "latest_one_month": "3", 846 "latest_three_month": "20", 847 "latest_six_month": "23", 848 "history_suc_fee": "30", 849 "history_fail_fee": "25", 850 "latest_one_month_suc": "5", 851 "latest_one_month_fail": "20", 852 "loans_long_time": "130", 853 "loans_latest_time": "2017-09-16" 854 }, 855 "current_report_detail": { 856 "loans_credit_limit": "1400", 857 "loans_credibility": "80", 858 "loans_org_count": "7", 859 "loans_product_count": "8", 860 "loans_max_limit": "2000", 861 "loans_avg_limit": "1000", 862 "consfin_credit_limit": "1500", 863 "consfin_credibility": "90", 864 "consfin_org_count": "8", 865 "consfin_product_count": "5", 866 "consfin_max_limit": "5000", 867 "consfin_avg_limit": "3000" 868 } 869 } 870 }, 871 "errorCode": null, 872 "errorMsg": null 873 }` 874 m := make(g.Map) 875 err := json.UnmarshalUseNumber([]byte(data), &m) 876 t.Assert(err, nil) 877 878 model := new(XinYanModel) 879 err = gconv.Struct(m, model) 880 t.Assert(err, nil) 881 t.Assert(model.ErrorCode, nil) 882 t.Assert(model.ErrorMsg, nil) 883 t.Assert(model.Success, true) 884 t.Assert(model.Data.IDName, "dd67a5943781369ddd7c594e231e9e70") 885 t.Assert(model.Data.TradeNo, "201704011507240100057329") 886 t.Assert(model.Data.ResultDetail.ApplyReportDetail.ApplyScore, "189") 887 t.Assert(model.Data.ResultDetail.BehaviorReportDetail.LoansSettleCount, "280") 888 t.Assert(model.Data.ResultDetail.CurrentReportDetail.LoansProductCount, "8") 889 }) 890 } 891 892 func Test_Struct_CatchPanic(t *testing.T) { 893 gtest.C(t, func(t *gtest.T) { 894 type Score struct { 895 Name string 896 Result int 897 } 898 type User struct { 899 Score Score 900 } 901 902 user := new(User) 903 scores := map[string]interface{}{ 904 "Score": 1, 905 } 906 err := gconv.Struct(scores, user) 907 t.AssertNE(err, nil) 908 }) 909 } 910 911 type T struct { 912 Name string 913 } 914 915 func (t *T) Test() string { 916 return t.Name 917 } 918 919 type TestInterface interface { 920 Test() string 921 } 922 923 type TestStruct struct { 924 TestInterface 925 } 926 927 func Test_Struct_Embedded(t *testing.T) { 928 // Implemented interface attribute. 929 gtest.C(t, func(t *gtest.T) { 930 v1 := TestStruct{ 931 TestInterface: &T{"john"}, 932 } 933 v2 := g.Map{} 934 err := gconv.Struct(v2, &v1) 935 t.Assert(err, nil) 936 t.Assert(v1.Test(), "john") 937 }) 938 // Implemented interface attribute. 939 gtest.C(t, func(t *gtest.T) { 940 v1 := TestStruct{ 941 TestInterface: &T{"john"}, 942 } 943 v2 := g.Map{ 944 "name": "test", 945 } 946 err := gconv.Struct(v2, &v1) 947 t.Assert(err, nil) 948 t.Assert(v1.Test(), "test") 949 }) 950 // No implemented interface attribute. 951 gtest.C(t, func(t *gtest.T) { 952 v1 := TestStruct{} 953 v2 := g.Map{ 954 "name": "test", 955 } 956 err := gconv.Struct(v2, &v1) 957 t.Assert(err, nil) 958 t.Assert(v1.TestInterface, nil) 959 }) 960 } 961 962 func Test_Struct_Slice(t *testing.T) { 963 gtest.C(t, func(t *gtest.T) { 964 type User struct { 965 Scores []int 966 } 967 user := new(User) 968 array := g.Slice{1, 2, 3} 969 err := gconv.Struct(g.Map{"scores": array}, user) 970 t.Assert(err, nil) 971 t.Assert(user.Scores, array) 972 }) 973 gtest.C(t, func(t *gtest.T) { 974 type User struct { 975 Scores []int32 976 } 977 user := new(User) 978 array := g.Slice{1, 2, 3} 979 err := gconv.Struct(g.Map{"scores": array}, user) 980 t.Assert(err, nil) 981 t.Assert(user.Scores, array) 982 }) 983 gtest.C(t, func(t *gtest.T) { 984 type User struct { 985 Scores []int64 986 } 987 user := new(User) 988 array := g.Slice{1, 2, 3} 989 err := gconv.Struct(g.Map{"scores": array}, user) 990 t.Assert(err, nil) 991 t.Assert(user.Scores, array) 992 }) 993 gtest.C(t, func(t *gtest.T) { 994 type User struct { 995 Scores []uint 996 } 997 user := new(User) 998 array := g.Slice{1, 2, 3} 999 err := gconv.Struct(g.Map{"scores": array}, user) 1000 t.Assert(err, nil) 1001 t.Assert(user.Scores, array) 1002 }) 1003 gtest.C(t, func(t *gtest.T) { 1004 type User struct { 1005 Scores []uint32 1006 } 1007 user := new(User) 1008 array := g.Slice{1, 2, 3} 1009 err := gconv.Struct(g.Map{"scores": array}, user) 1010 t.Assert(err, nil) 1011 t.Assert(user.Scores, array) 1012 }) 1013 gtest.C(t, func(t *gtest.T) { 1014 type User struct { 1015 Scores []uint64 1016 } 1017 user := new(User) 1018 array := g.Slice{1, 2, 3} 1019 err := gconv.Struct(g.Map{"scores": array}, user) 1020 t.Assert(err, nil) 1021 t.Assert(user.Scores, array) 1022 }) 1023 gtest.C(t, func(t *gtest.T) { 1024 type User struct { 1025 Scores []float32 1026 } 1027 user := new(User) 1028 array := g.Slice{1, 2, 3} 1029 err := gconv.Struct(g.Map{"scores": array}, user) 1030 t.Assert(err, nil) 1031 t.Assert(user.Scores, array) 1032 }) 1033 gtest.C(t, func(t *gtest.T) { 1034 type User struct { 1035 Scores []float64 1036 } 1037 user := new(User) 1038 array := g.Slice{1, 2, 3} 1039 err := gconv.Struct(g.Map{"scores": array}, user) 1040 t.Assert(err, nil) 1041 t.Assert(user.Scores, array) 1042 }) 1043 } 1044 1045 func Test_Struct_To_Struct(t *testing.T) { 1046 var TestA struct { 1047 Id int `p:"id"` 1048 Date time.Time `p:"date"` 1049 } 1050 1051 var TestB struct { 1052 Id int `p:"id"` 1053 Date time.Time `p:"date"` 1054 } 1055 TestB.Id = 666 1056 TestB.Date = time.Now() 1057 1058 gtest.C(t, func(t *gtest.T) { 1059 t.Assert(gconv.Struct(TestB, &TestA), nil) 1060 t.Assert(TestA.Id, TestB.Id) 1061 t.Assert(TestA.Date, TestB.Date) 1062 }) 1063 } 1064 1065 func Test_Struct_WithJson(t *testing.T) { 1066 type A struct { 1067 Name string 1068 } 1069 type B struct { 1070 A 1071 Score int 1072 } 1073 gtest.C(t, func(t *gtest.T) { 1074 b1 := &B{} 1075 b1.Name = "john" 1076 b1.Score = 100 1077 b, _ := json.Marshal(b1) 1078 b2 := &B{} 1079 err := gconv.Struct(b, b2) 1080 t.Assert(err, nil) 1081 t.Assert(b2, b1) 1082 }) 1083 } 1084 1085 func Test_Struct_AttrStructHasTheSameTag(t *testing.T) { 1086 type Product struct { 1087 Id int `json:"id"` 1088 UpdatedAt time.Time `json:"-" ` 1089 UpdatedAtFormat string `json:"updated_at" ` 1090 } 1091 1092 type Order struct { 1093 Id int `json:"id"` 1094 UpdatedAt time.Time `json:"updated_at"` 1095 Product Product `json:"products"` 1096 } 1097 gtest.C(t, func(t *gtest.T) { 1098 data := g.Map{ 1099 "id": 1, 1100 "updated_at": time.Now(), 1101 } 1102 order := new(Order) 1103 err := gconv.Struct(data, order) 1104 t.Assert(err, nil) 1105 t.Assert(order.Id, data["id"]) 1106 t.Assert(order.UpdatedAt, data["updated_at"]) 1107 t.Assert(order.Product.Id, 0) 1108 t.Assert(order.Product.UpdatedAt.IsZero(), true) 1109 t.Assert(order.Product.UpdatedAtFormat, "") 1110 }) 1111 } 1112 1113 func Test_Struct_DirectReflectSet(t *testing.T) { 1114 type A struct { 1115 Id int 1116 Name string 1117 } 1118 1119 gtest.C(t, func(t *gtest.T) { 1120 var ( 1121 a = &A{ 1122 Id: 1, 1123 Name: "john", 1124 } 1125 b *A 1126 ) 1127 err := gconv.Struct(a, &b) 1128 t.Assert(err, nil) 1129 t.AssertEQ(a, b) 1130 }) 1131 gtest.C(t, func(t *gtest.T) { 1132 var ( 1133 a = A{ 1134 Id: 1, 1135 Name: "john", 1136 } 1137 b A 1138 ) 1139 err := gconv.Struct(a, &b) 1140 t.Assert(err, nil) 1141 t.AssertEQ(a, b) 1142 }) 1143 } 1144 1145 func Test_Struct_NilEmbeddedStructAttribute(t *testing.T) { 1146 type A struct { 1147 Name string 1148 } 1149 type B struct { 1150 *A 1151 Id int 1152 } 1153 1154 gtest.C(t, func(t *gtest.T) { 1155 var ( 1156 b *B 1157 ) 1158 err := gconv.Struct(g.Map{ 1159 "id": 1, 1160 "name": nil, 1161 }, &b) 1162 t.Assert(err, nil) 1163 t.Assert(b.Id, 1) 1164 t.Assert(b.Name, "") 1165 }) 1166 } 1167 1168 func Test_Struct_JsonParam(t *testing.T) { 1169 type A struct { 1170 Id int `json:"id"` 1171 Name string `json:"name"` 1172 } 1173 // struct 1174 gtest.C(t, func(t *gtest.T) { 1175 var a = A{} 1176 err := gconv.Struct([]byte(`{"id":1,"name":"john"}`), &a) 1177 t.Assert(err, nil) 1178 t.Assert(a.Id, 1) 1179 t.Assert(a.Name, "john") 1180 }) 1181 // *struct 1182 gtest.C(t, func(t *gtest.T) { 1183 var a = &A{} 1184 err := gconv.Struct([]byte(`{"id":1,"name":"john"}`), a) 1185 t.Assert(err, nil) 1186 t.Assert(a.Id, 1) 1187 t.Assert(a.Name, "john") 1188 }) 1189 // *struct nil 1190 gtest.C(t, func(t *gtest.T) { 1191 var a *A 1192 err := gconv.Struct([]byte(`{"id":1,"name":"john"}`), &a) 1193 t.Assert(err, nil) 1194 t.Assert(a.Id, 1) 1195 t.Assert(a.Name, "john") 1196 }) 1197 } 1198 1199 func Test_Struct_GVarAttribute(t *testing.T) { 1200 type A struct { 1201 Id int `json:"id"` 1202 Name string `json:"name"` 1203 Status bool `json:"status"` 1204 } 1205 gtest.C(t, func(t *gtest.T) { 1206 var ( 1207 a = A{} 1208 data = g.Map{ 1209 "id": 100, 1210 "name": "john", 1211 "status": gvar.New(false), 1212 } 1213 ) 1214 err := gconv.Struct(data, &a) 1215 t.Assert(err, nil) 1216 t.Assert(a.Id, data["id"]) 1217 t.Assert(a.Name, data["name"]) 1218 t.Assert(a.Status, data["status"]) 1219 }) 1220 1221 } 1222 1223 func Test_Struct_MapAttribute(t *testing.T) { 1224 type NodeStatus struct { 1225 ID int 1226 } 1227 type Nodes map[string]NodeStatus 1228 type Output struct { 1229 Nodes Nodes 1230 } 1231 1232 gtest.C(t, func(t *gtest.T) { 1233 var ( 1234 out = Output{} 1235 data = g.Map{ 1236 "nodes": g.Map{ 1237 "name": g.Map{ 1238 "id": 10000, 1239 }, 1240 }, 1241 } 1242 ) 1243 err := gconv.Struct(data, &out) 1244 t.AssertNil(err) 1245 }) 1246 }