github.com/wangyougui/gf/v2@v2.6.5/util/gconv/gconv_z_unit_scan_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/wangyougui/gf. 6 7 package gconv_test 8 9 import ( 10 "fmt" 11 "math/big" 12 "testing" 13 14 "github.com/wangyougui/gf/v2/container/gvar" 15 "github.com/wangyougui/gf/v2/frame/g" 16 "github.com/wangyougui/gf/v2/test/gtest" 17 "github.com/wangyougui/gf/v2/util/gconv" 18 ) 19 20 func Test_Scan_WithMapParameter(t *testing.T) { 21 type User struct { 22 Uid int 23 Name string 24 } 25 gtest.C(t, func(t *gtest.T) { 26 for i := 0; i < 100; i++ { 27 var ( 28 user = new(User) 29 params = g.Map{ 30 "uid": 1, 31 "myname": "john", 32 "name": "smith", 33 } 34 ) 35 err := gconv.Scan(params, user, g.MapStrStr{ 36 "myname": "Name", 37 }) 38 t.AssertNil(err) 39 t.Assert(user, &User{ 40 Uid: 1, 41 Name: "john", 42 }) 43 } 44 }) 45 } 46 47 func Test_Scan_StructStructs(t *testing.T) { 48 type User struct { 49 Uid int 50 Name string 51 Pass1 string `gconv:"password1"` 52 Pass2 string `gconv:"password2"` 53 } 54 gtest.C(t, func(t *gtest.T) { 55 var ( 56 user = new(User) 57 params = g.Map{ 58 "uid": 1, 59 "name": "john", 60 "PASS1": "123", 61 "PASS2": "456", 62 } 63 ) 64 err := gconv.Scan(params, user) 65 t.AssertNil(err) 66 t.Assert(user, &User{ 67 Uid: 1, 68 Name: "john", 69 Pass1: "123", 70 Pass2: "456", 71 }) 72 }) 73 gtest.C(t, func(t *gtest.T) { 74 var ( 75 users []User 76 params = g.Slice{ 77 g.Map{ 78 "uid": 1, 79 "name": "john1", 80 "PASS1": "111", 81 "PASS2": "222", 82 }, 83 g.Map{ 84 "uid": 2, 85 "name": "john2", 86 "PASS1": "333", 87 "PASS2": "444", 88 }, 89 } 90 ) 91 err := gconv.Scan(params, &users) 92 t.AssertNil(err) 93 t.Assert(users, g.Slice{ 94 &User{ 95 Uid: 1, 96 Name: "john1", 97 Pass1: "111", 98 Pass2: "222", 99 }, 100 &User{ 101 Uid: 2, 102 Name: "john2", 103 Pass1: "333", 104 Pass2: "444", 105 }, 106 }) 107 }) 108 } 109 110 func Test_Scan_StructStr(t *testing.T) { 111 type User struct { 112 Uid int 113 Name string 114 Pass1 string `gconv:"password1"` 115 Pass2 string `gconv:"password2"` 116 } 117 gtest.C(t, func(t *gtest.T) { 118 var ( 119 user = new(User) 120 params = `{"uid":1,"name":"john", "pass1":"123","pass2":"456"}` 121 ) 122 err := gconv.Scan(params, user) 123 t.AssertNil(err) 124 t.Assert(user, &User{ 125 Uid: 1, 126 Name: "john", 127 Pass1: "123", 128 Pass2: "456", 129 }) 130 }) 131 gtest.C(t, func(t *gtest.T) { 132 var ( 133 users []User 134 params = `[ 135 {"uid":1,"name":"john1", "pass1":"111","pass2":"222"}, 136 {"uid":2,"name":"john2", "pass1":"333","pass2":"444"} 137 ]` 138 ) 139 err := gconv.Scan(params, &users) 140 t.AssertNil(err) 141 t.Assert(users, g.Slice{ 142 &User{ 143 Uid: 1, 144 Name: "john1", 145 Pass1: "111", 146 Pass2: "222", 147 }, 148 &User{ 149 Uid: 2, 150 Name: "john2", 151 Pass1: "333", 152 Pass2: "444", 153 }, 154 }) 155 }) 156 } 157 158 func Test_Scan_Map(t *testing.T) { 159 gtest.C(t, func(t *gtest.T) { 160 var m map[string]string 161 data := g.Map{ 162 "k1": "v1", 163 "k2": "v2", 164 } 165 err := gconv.Scan(data, &m) 166 t.AssertNil(err) 167 t.Assert(data, m) 168 }) 169 gtest.C(t, func(t *gtest.T) { 170 var m map[int]int 171 data := g.Map{ 172 "1": "11", 173 "2": "22", 174 } 175 err := gconv.Scan(data, &m) 176 t.AssertNil(err) 177 t.Assert(data, m) 178 }) 179 // json string parameter. 180 gtest.C(t, func(t *gtest.T) { 181 var m map[string]string 182 data := `{"k1":"v1","k2":"v2"}` 183 err := gconv.Scan(data, &m) 184 t.AssertNil(err) 185 t.Assert(m, g.Map{ 186 "k1": "v1", 187 "k2": "v2", 188 }) 189 }) 190 } 191 192 func Test_Scan_Maps(t *testing.T) { 193 gtest.C(t, func(t *gtest.T) { 194 var maps []map[string]string 195 data := g.Slice{ 196 g.Map{ 197 "k1": "v1", 198 "k2": "v2", 199 }, 200 g.Map{ 201 "k3": "v3", 202 "k4": "v4", 203 }, 204 } 205 err := gconv.Scan(data, &maps) 206 t.AssertNil(err) 207 t.Assert(data, maps) 208 }) 209 // json string parameter. 210 gtest.C(t, func(t *gtest.T) { 211 var maps []map[string]string 212 data := `[{"k1":"v1","k2":"v2"},{"k3":"v3","k4":"v4"}]` 213 err := gconv.Scan(data, &maps) 214 t.AssertNil(err) 215 t.Assert(maps, g.Slice{ 216 g.Map{ 217 "k1": "v1", 218 "k2": "v2", 219 }, 220 g.Map{ 221 "k3": "v3", 222 "k4": "v4", 223 }, 224 }) 225 }) 226 } 227 228 func Test_Scan_JsonAttributes(t *testing.T) { 229 gtest.C(t, func(t *gtest.T) { 230 type Sku struct { 231 GiftId int64 `json:"gift_id"` 232 Name string `json:"name"` 233 ScorePrice int `json:"score_price"` 234 MarketPrice int `json:"market_price"` 235 CostPrice int `json:"cost_price"` 236 Stock int `json:"stock"` 237 } 238 v := gvar.New(` 239 [ 240 {"name": "red", "stock": 10, "gift_id": 1, "cost_price": 80, "score_price": 188, "market_price": 188}, 241 {"name": "blue", "stock": 100, "gift_id": 2, "cost_price": 81, "score_price": 200, "market_price": 288} 242 ]`) 243 type Product struct { 244 Skus []Sku 245 } 246 var p *Product 247 err := gconv.Scan(g.Map{ 248 "Skus": v, 249 }, &p) 250 t.AssertNil(err) 251 t.Assert(len(p.Skus), 2) 252 253 t.Assert(p.Skus[0].Name, "red") 254 t.Assert(p.Skus[0].Stock, 10) 255 t.Assert(p.Skus[0].GiftId, 1) 256 t.Assert(p.Skus[0].CostPrice, 80) 257 t.Assert(p.Skus[0].ScorePrice, 188) 258 t.Assert(p.Skus[0].MarketPrice, 188) 259 260 t.Assert(p.Skus[1].Name, "blue") 261 t.Assert(p.Skus[1].Stock, 100) 262 t.Assert(p.Skus[1].GiftId, 2) 263 t.Assert(p.Skus[1].CostPrice, 81) 264 t.Assert(p.Skus[1].ScorePrice, 200) 265 t.Assert(p.Skus[1].MarketPrice, 288) 266 }) 267 } 268 269 func Test_Scan_JsonAttributes_StringArray(t *testing.T) { 270 gtest.C(t, func(t *gtest.T) { 271 type S struct { 272 Array []string 273 } 274 var s *S 275 err := gconv.Scan(g.Map{ 276 "Array": `["a", "b"]`, 277 }, &s) 278 t.AssertNil(err) 279 t.Assert(len(s.Array), 2) 280 t.Assert(s.Array[0], "a") 281 t.Assert(s.Array[1], "b") 282 }) 283 284 gtest.C(t, func(t *gtest.T) { 285 type S struct { 286 Array []string 287 } 288 var s *S 289 err := gconv.Scan(g.Map{ 290 "Array": `[]`, 291 }, &s) 292 t.AssertNil(err) 293 t.Assert(len(s.Array), 0) 294 }) 295 296 gtest.C(t, func(t *gtest.T) { 297 type S struct { 298 Array []int64 299 } 300 var s *S 301 err := gconv.Scan(g.Map{ 302 "Array": `[]`, 303 }, &s) 304 t.AssertNil(err) 305 t.Assert(len(s.Array), 0) 306 }) 307 } 308 309 func Test_Scan_SameType_Just_Assign(t *testing.T) { 310 // Struct. 311 gtest.C(t, func(t *gtest.T) { 312 type User struct { 313 Uid int 314 Name string 315 Pass1 string 316 Pass2 string 317 Pointer *int 318 } 319 var ( 320 int1 = 1 321 int2 = 1 322 user1 = new(User) 323 user2 *User 324 ) 325 user1.Pointer = &int1 326 err := gconv.Scan(user1, &user2) 327 t.AssertNil(err) 328 t.Assert(fmt.Sprintf(`%p`, user1), fmt.Sprintf(`%p`, user2)) 329 t.Assert(*user1.Pointer, *user2.Pointer) 330 user1.Pointer = &int2 331 t.Assert(*user1.Pointer, *user2.Pointer) 332 }) 333 // Map. 334 gtest.C(t, func(t *gtest.T) { 335 var ( 336 int1 = 1 337 int2 = 1 338 m1 = map[string]*int{ 339 "int": &int1, 340 } 341 m2 map[string]*int 342 ) 343 err := gconv.Scan(m1, &m2) 344 t.AssertNil(err) 345 t.Assert(fmt.Sprintf(`%p`, m1), fmt.Sprintf(`%p`, m2)) 346 t.Assert(*m1["int"], *m2["int"]) 347 m1["int"] = &int2 348 t.Assert(*m1["int"], *m2["int"]) 349 }) 350 } 351 352 func Test_ScanList_Basic(t *testing.T) { 353 // Struct attribute. 354 gtest.C(t, func(t *gtest.T) { 355 type EntityUser struct { 356 Uid int 357 Name string 358 } 359 360 type EntityUserDetail struct { 361 Uid int 362 Address string 363 } 364 365 type EntityUserScores struct { 366 Id int 367 Uid int 368 Score int 369 } 370 371 type Entity struct { 372 User EntityUser 373 UserDetail EntityUserDetail 374 UserScores []EntityUserScores 375 } 376 377 var ( 378 err error 379 entities []Entity 380 entityUsers = []EntityUser{ 381 {Uid: 1, Name: "name1"}, 382 {Uid: 2, Name: "name2"}, 383 {Uid: 3, Name: "name3"}, 384 } 385 userDetails = []EntityUserDetail{ 386 {Uid: 1, Address: "address1"}, 387 {Uid: 2, Address: "address2"}, 388 } 389 userScores = []EntityUserScores{ 390 {Id: 10, Uid: 1, Score: 100}, 391 {Id: 11, Uid: 1, Score: 60}, 392 {Id: 20, Uid: 2, Score: 99}, 393 } 394 ) 395 err = gconv.ScanList(entityUsers, &entities, "User") 396 t.AssertNil(err) 397 398 err = gconv.ScanList(userDetails, &entities, "UserDetail", "User", "uid") 399 t.AssertNil(err) 400 401 err = gconv.ScanList(userScores, &entities, "UserScores", "User", "uid") 402 t.AssertNil(err) 403 404 t.Assert(len(entities), 3) 405 t.Assert(entities[0].User, entityUsers[0]) 406 t.Assert(entities[1].User, entityUsers[1]) 407 t.Assert(entities[2].User, entityUsers[2]) 408 409 t.Assert(entities[0].UserDetail, userDetails[0]) 410 t.Assert(entities[1].UserDetail, userDetails[1]) 411 t.Assert(entities[2].UserDetail, EntityUserDetail{}) 412 413 t.Assert(len(entities[0].UserScores), 2) 414 t.Assert(entities[0].UserScores[0], userScores[0]) 415 t.Assert(entities[0].UserScores[1], userScores[1]) 416 417 t.Assert(len(entities[1].UserScores), 1) 418 t.Assert(entities[1].UserScores[0], userScores[2]) 419 420 t.Assert(len(entities[2].UserScores), 0) 421 }) 422 // Pointer attribute. 423 gtest.C(t, func(t *gtest.T) { 424 type EntityUser struct { 425 Uid int 426 Name string 427 } 428 429 type EntityUserDetail struct { 430 Uid int 431 Address string 432 } 433 434 type EntityUserScores struct { 435 Id int 436 Uid int 437 Score int 438 } 439 440 type Entity struct { 441 User *EntityUser 442 UserDetail *EntityUserDetail 443 UserScores []*EntityUserScores 444 } 445 446 var ( 447 err error 448 entities []*Entity 449 entityUsers = []*EntityUser{ 450 {Uid: 1, Name: "name1"}, 451 {Uid: 2, Name: "name2"}, 452 {Uid: 3, Name: "name3"}, 453 } 454 userDetails = []*EntityUserDetail{ 455 {Uid: 1, Address: "address1"}, 456 {Uid: 2, Address: "address2"}, 457 } 458 userScores = []*EntityUserScores{ 459 {Id: 10, Uid: 1, Score: 100}, 460 {Id: 11, Uid: 1, Score: 60}, 461 {Id: 20, Uid: 2, Score: 99}, 462 } 463 ) 464 err = gconv.ScanList(entityUsers, &entities, "User") 465 t.AssertNil(err) 466 467 err = gconv.ScanList(userDetails, &entities, "UserDetail", "User", "uid") 468 t.AssertNil(err) 469 470 err = gconv.ScanList(userScores, &entities, "UserScores", "User", "uid") 471 t.AssertNil(err) 472 473 t.Assert(len(entities), 3) 474 t.Assert(entities[0].User, entityUsers[0]) 475 t.Assert(entities[1].User, entityUsers[1]) 476 t.Assert(entities[2].User, entityUsers[2]) 477 478 t.Assert(entities[0].UserDetail, userDetails[0]) 479 t.Assert(entities[1].UserDetail, userDetails[1]) 480 t.Assert(entities[2].UserDetail, nil) 481 482 t.Assert(len(entities[0].UserScores), 2) 483 t.Assert(entities[0].UserScores[0], userScores[0]) 484 t.Assert(entities[0].UserScores[1], userScores[1]) 485 486 t.Assert(len(entities[1].UserScores), 1) 487 t.Assert(entities[1].UserScores[0], userScores[2]) 488 489 t.Assert(len(entities[2].UserScores), 0) 490 }) 491 } 492 493 func Test_ScanList_Embedded(t *testing.T) { 494 // Struct attribute. 495 gtest.C(t, func(t *gtest.T) { 496 type EntityUser struct { 497 Uid int 498 Name string 499 } 500 501 type EntityUserDetail struct { 502 Uid int 503 Address string 504 } 505 506 type EntityUserScores struct { 507 Id int 508 Uid int 509 Score int 510 } 511 512 type Entity struct { 513 EntityUser 514 UserDetail EntityUserDetail 515 UserScores []EntityUserScores 516 } 517 518 var ( 519 err error 520 entities []Entity 521 entityUsers = []EntityUser{ 522 {Uid: 1, Name: "name1"}, 523 {Uid: 2, Name: "name2"}, 524 {Uid: 3, Name: "name3"}, 525 } 526 userDetails = []EntityUserDetail{ 527 {Uid: 1, Address: "address1"}, 528 {Uid: 2, Address: "address2"}, 529 } 530 userScores = []EntityUserScores{ 531 {Id: 10, Uid: 1, Score: 100}, 532 {Id: 11, Uid: 1, Score: 60}, 533 {Id: 20, Uid: 2, Score: 99}, 534 } 535 ) 536 err = gconv.Scan(entityUsers, &entities) 537 t.AssertNil(err) 538 539 err = gconv.ScanList(userDetails, &entities, "UserDetail", "uid") 540 t.AssertNil(err) 541 542 err = gconv.ScanList(userScores, &entities, "UserScores", "uid") 543 t.AssertNil(err) 544 545 t.Assert(len(entities), 3) 546 t.Assert(entities[0].EntityUser, entityUsers[0]) 547 t.Assert(entities[1].EntityUser, entityUsers[1]) 548 t.Assert(entities[2].EntityUser, entityUsers[2]) 549 550 t.Assert(entities[0].UserDetail, userDetails[0]) 551 t.Assert(entities[1].UserDetail, userDetails[1]) 552 t.Assert(entities[2].UserDetail, EntityUserDetail{}) 553 554 t.Assert(len(entities[0].UserScores), 2) 555 t.Assert(entities[0].UserScores[0], userScores[0]) 556 t.Assert(entities[0].UserScores[1], userScores[1]) 557 558 t.Assert(len(entities[1].UserScores), 1) 559 t.Assert(entities[1].UserScores[0], userScores[2]) 560 561 t.Assert(len(entities[2].UserScores), 0) 562 }) 563 // Pointer attribute. 564 gtest.C(t, func(t *gtest.T) { 565 type EntityUser struct { 566 Uid int 567 Name string 568 } 569 570 type EntityUserDetail struct { 571 Uid int 572 Address string 573 } 574 575 type EntityUserScores struct { 576 Id int 577 Uid int 578 Score int 579 } 580 581 type Entity struct { 582 *EntityUser 583 UserDetail *EntityUserDetail 584 UserScores []*EntityUserScores 585 } 586 587 var ( 588 err error 589 entities []Entity 590 entityUsers = []EntityUser{ 591 {Uid: 1, Name: "name1"}, 592 {Uid: 2, Name: "name2"}, 593 {Uid: 3, Name: "name3"}, 594 } 595 userDetails = []EntityUserDetail{ 596 {Uid: 1, Address: "address1"}, 597 {Uid: 2, Address: "address2"}, 598 } 599 userScores = []EntityUserScores{ 600 {Id: 10, Uid: 1, Score: 100}, 601 {Id: 11, Uid: 1, Score: 60}, 602 {Id: 20, Uid: 2, Score: 99}, 603 } 604 ) 605 err = gconv.Scan(entityUsers, &entities) 606 t.AssertNil(err) 607 608 err = gconv.ScanList(userDetails, &entities, "UserDetail", "uid") 609 t.AssertNil(err) 610 611 err = gconv.ScanList(userScores, &entities, "UserScores", "uid") 612 t.AssertNil(err) 613 614 t.Assert(len(entities), 3) 615 t.Assert(entities[0].EntityUser, entityUsers[0]) 616 t.Assert(entities[1].EntityUser, entityUsers[1]) 617 t.Assert(entities[2].EntityUser, entityUsers[2]) 618 619 t.Assert(entities[0].UserDetail, userDetails[0]) 620 t.Assert(entities[1].UserDetail, userDetails[1]) 621 t.Assert(entities[2].UserDetail, nil) 622 623 t.Assert(len(entities[0].UserScores), 2) 624 t.Assert(entities[0].UserScores[0], userScores[0]) 625 t.Assert(entities[0].UserScores[1], userScores[1]) 626 627 t.Assert(len(entities[1].UserScores), 1) 628 t.Assert(entities[1].UserScores[0], userScores[2]) 629 630 t.Assert(len(entities[2].UserScores), 0) 631 }) 632 } 633 634 type Float64 float64 635 636 func (f *Float64) UnmarshalValue(value interface{}) error { 637 if v, ok := value.(*big.Rat); ok { 638 f64, _ := v.Float64() 639 *f = Float64(f64) 640 } 641 return nil 642 } 643 644 func Test_Scan_AutoCreatingPointerElem(t *testing.T) { 645 type A struct { 646 Name string 647 } 648 gtest.C(t, func(t *gtest.T) { 649 var dst A 650 var src = A{ 651 Name: "john", 652 } 653 err := gconv.Scan(src, &dst) 654 t.AssertNil(err) 655 t.Assert(src, dst) 656 }) 657 gtest.C(t, func(t *gtest.T) { 658 var dst = &A{ 659 Name: "smith", 660 } 661 var src = A{ 662 Name: "john", 663 } 664 err := gconv.Scan(src, &dst) 665 t.AssertNil(err) 666 t.Assert(src, dst) 667 }) 668 gtest.C(t, func(t *gtest.T) { 669 var dst = A{ 670 Name: "smith", 671 } 672 var src = &A{ 673 Name: "john", 674 } 675 err := gconv.Scan(src, &dst) 676 t.AssertNil(err) 677 t.Assert(src, dst) 678 }) 679 gtest.C(t, func(t *gtest.T) { 680 var dst *A 681 var src = &A{ 682 Name: "john", 683 } 684 err := gconv.Scan(src, &dst) 685 t.AssertNil(err) 686 t.Assert(src, dst) 687 688 // Note that the dst points to src. 689 src.Name = "smith" 690 t.Assert(src, dst) 691 }) 692 }