github.com/hduhelp/go-zero@v1.4.3/core/mapping/unmarshaler_test.go (about) 1 package mapping 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strconv" 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/google/uuid" 12 "github.com/stretchr/testify/assert" 13 14 "github.com/hduhelp/go-zero/core/stringx" 15 ) 16 17 // because json.Number doesn't support strconv.ParseUint(...), 18 // so we only can test to 62 bits. 19 const maxUintBitsToTest = 62 20 21 func TestUnmarshalWithFullNameNotStruct(t *testing.T) { 22 var s map[string]interface{} 23 content := []byte(`{"name":"xiaoming"}`) 24 err := UnmarshalJsonBytes(content, &s) 25 assert.Equal(t, errValueNotStruct, err) 26 } 27 28 func TestUnmarshalWithoutTagName(t *testing.T) { 29 type inner struct { 30 Optional bool `key:",optional"` 31 } 32 m := map[string]interface{}{ 33 "Optional": true, 34 } 35 36 var in inner 37 assert.Nil(t, UnmarshalKey(m, &in)) 38 assert.True(t, in.Optional) 39 } 40 41 func TestUnmarshalBool(t *testing.T) { 42 type inner struct { 43 True bool `key:"yes"` 44 False bool `key:"no"` 45 TrueFromOne bool `key:"yesone,string"` 46 FalseFromZero bool `key:"nozero,string"` 47 TrueFromTrue bool `key:"yestrue,string"` 48 FalseFromFalse bool `key:"nofalse,string"` 49 DefaultTrue bool `key:"defaulttrue,default=1"` 50 Optional bool `key:"optional,optional"` 51 } 52 m := map[string]interface{}{ 53 "yes": true, 54 "no": false, 55 "yesone": "1", 56 "nozero": "0", 57 "yestrue": "true", 58 "nofalse": "false", 59 } 60 61 var in inner 62 ast := assert.New(t) 63 ast.Nil(UnmarshalKey(m, &in)) 64 ast.True(in.True) 65 ast.False(in.False) 66 ast.True(in.TrueFromOne) 67 ast.False(in.FalseFromZero) 68 ast.True(in.TrueFromTrue) 69 ast.False(in.FalseFromFalse) 70 ast.True(in.DefaultTrue) 71 } 72 73 func TestUnmarshalDuration(t *testing.T) { 74 type inner struct { 75 Duration time.Duration `key:"duration"` 76 LessDuration time.Duration `key:"less"` 77 MoreDuration time.Duration `key:"more"` 78 } 79 m := map[string]interface{}{ 80 "duration": "5s", 81 "less": "100ms", 82 "more": "24h", 83 } 84 var in inner 85 assert.Nil(t, UnmarshalKey(m, &in)) 86 assert.Equal(t, time.Second*5, in.Duration) 87 assert.Equal(t, time.Millisecond*100, in.LessDuration) 88 assert.Equal(t, time.Hour*24, in.MoreDuration) 89 } 90 91 func TestUnmarshalDurationDefault(t *testing.T) { 92 type inner struct { 93 Int int `key:"int"` 94 Duration time.Duration `key:"duration,default=5s"` 95 } 96 m := map[string]interface{}{ 97 "int": 5, 98 } 99 var in inner 100 assert.Nil(t, UnmarshalKey(m, &in)) 101 assert.Equal(t, 5, in.Int) 102 assert.Equal(t, time.Second*5, in.Duration) 103 } 104 105 func TestUnmarshalDurationPtr(t *testing.T) { 106 type inner struct { 107 Duration *time.Duration `key:"duration"` 108 } 109 m := map[string]interface{}{ 110 "duration": "5s", 111 } 112 var in inner 113 assert.Nil(t, UnmarshalKey(m, &in)) 114 assert.Equal(t, time.Second*5, *in.Duration) 115 } 116 117 func TestUnmarshalDurationPtrDefault(t *testing.T) { 118 type inner struct { 119 Int int `key:"int"` 120 Value *int `key:",default=5"` 121 Duration *time.Duration `key:"duration,default=5s"` 122 } 123 m := map[string]interface{}{ 124 "int": 5, 125 } 126 var in inner 127 assert.Nil(t, UnmarshalKey(m, &in)) 128 assert.Equal(t, 5, in.Int) 129 assert.Equal(t, 5, *in.Value) 130 assert.Equal(t, time.Second*5, *in.Duration) 131 } 132 133 func TestUnmarshalInt(t *testing.T) { 134 type inner struct { 135 Int int `key:"int"` 136 IntFromStr int `key:"intstr,string"` 137 Int8 int8 `key:"int8"` 138 Int8FromStr int8 `key:"int8str,string"` 139 Int16 int16 `key:"int16"` 140 Int16FromStr int16 `key:"int16str,string"` 141 Int32 int32 `key:"int32"` 142 Int32FromStr int32 `key:"int32str,string"` 143 Int64 int64 `key:"int64"` 144 Int64FromStr int64 `key:"int64str,string"` 145 DefaultInt int64 `key:"defaultint,default=11"` 146 Optional int `key:"optional,optional"` 147 } 148 m := map[string]interface{}{ 149 "int": 1, 150 "intstr": "2", 151 "int8": int8(3), 152 "int8str": "4", 153 "int16": int16(5), 154 "int16str": "6", 155 "int32": int32(7), 156 "int32str": "8", 157 "int64": int64(9), 158 "int64str": "10", 159 } 160 161 var in inner 162 ast := assert.New(t) 163 ast.Nil(UnmarshalKey(m, &in)) 164 ast.Equal(1, in.Int) 165 ast.Equal(2, in.IntFromStr) 166 ast.Equal(int8(3), in.Int8) 167 ast.Equal(int8(4), in.Int8FromStr) 168 ast.Equal(int16(5), in.Int16) 169 ast.Equal(int16(6), in.Int16FromStr) 170 ast.Equal(int32(7), in.Int32) 171 ast.Equal(int32(8), in.Int32FromStr) 172 ast.Equal(int64(9), in.Int64) 173 ast.Equal(int64(10), in.Int64FromStr) 174 ast.Equal(int64(11), in.DefaultInt) 175 } 176 177 func TestUnmarshalIntPtr(t *testing.T) { 178 type inner struct { 179 Int *int `key:"int"` 180 } 181 m := map[string]interface{}{ 182 "int": 1, 183 } 184 185 var in inner 186 assert.Nil(t, UnmarshalKey(m, &in)) 187 assert.NotNil(t, in.Int) 188 assert.Equal(t, 1, *in.Int) 189 } 190 191 func TestUnmarshalIntWithDefault(t *testing.T) { 192 type inner struct { 193 Int int `key:"int,default=5"` 194 } 195 m := map[string]interface{}{ 196 "int": 1, 197 } 198 199 var in inner 200 assert.Nil(t, UnmarshalKey(m, &in)) 201 assert.Equal(t, 1, in.Int) 202 } 203 204 func TestUnmarshalBoolSliceRequired(t *testing.T) { 205 type inner struct { 206 Bools []bool `key:"bools"` 207 } 208 209 var in inner 210 assert.NotNil(t, UnmarshalKey(map[string]interface{}{}, &in)) 211 } 212 213 func TestUnmarshalBoolSliceNil(t *testing.T) { 214 type inner struct { 215 Bools []bool `key:"bools,optional"` 216 } 217 218 var in inner 219 assert.Nil(t, UnmarshalKey(map[string]interface{}{}, &in)) 220 assert.Nil(t, in.Bools) 221 } 222 223 func TestUnmarshalBoolSliceNilExplicit(t *testing.T) { 224 type inner struct { 225 Bools []bool `key:"bools,optional"` 226 } 227 228 var in inner 229 assert.Nil(t, UnmarshalKey(map[string]interface{}{ 230 "bools": nil, 231 }, &in)) 232 assert.Nil(t, in.Bools) 233 } 234 235 func TestUnmarshalBoolSliceEmpty(t *testing.T) { 236 type inner struct { 237 Bools []bool `key:"bools,optional"` 238 } 239 240 var in inner 241 assert.Nil(t, UnmarshalKey(map[string]interface{}{ 242 "bools": []bool{}, 243 }, &in)) 244 assert.Empty(t, in.Bools) 245 } 246 247 func TestUnmarshalBoolSliceWithDefault(t *testing.T) { 248 type inner struct { 249 Bools []bool `key:"bools,default=[true,false]"` 250 } 251 252 var in inner 253 assert.Nil(t, UnmarshalKey(nil, &in)) 254 assert.ElementsMatch(t, []bool{true, false}, in.Bools) 255 } 256 257 func TestUnmarshalIntSliceWithDefault(t *testing.T) { 258 type inner struct { 259 Ints []int `key:"ints,default=[1,2,3]"` 260 } 261 262 var in inner 263 assert.Nil(t, UnmarshalKey(nil, &in)) 264 assert.ElementsMatch(t, []int{1, 2, 3}, in.Ints) 265 } 266 267 func TestUnmarshalIntSliceWithDefaultHasSpaces(t *testing.T) { 268 type inner struct { 269 Ints []int `key:"ints,default=[1, 2, 3]"` 270 } 271 272 var in inner 273 assert.Nil(t, UnmarshalKey(nil, &in)) 274 assert.ElementsMatch(t, []int{1, 2, 3}, in.Ints) 275 } 276 277 func TestUnmarshalFloatSliceWithDefault(t *testing.T) { 278 type inner struct { 279 Floats []float32 `key:"floats,default=[1.1,2.2,3.3]"` 280 } 281 282 var in inner 283 assert.Nil(t, UnmarshalKey(nil, &in)) 284 assert.ElementsMatch(t, []float32{1.1, 2.2, 3.3}, in.Floats) 285 } 286 287 func TestUnmarshalStringSliceWithDefault(t *testing.T) { 288 type inner struct { 289 Strs []string `key:"strs,default=[foo,bar,woo]"` 290 } 291 292 var in inner 293 assert.Nil(t, UnmarshalKey(nil, &in)) 294 assert.ElementsMatch(t, []string{"foo", "bar", "woo"}, in.Strs) 295 } 296 297 func TestUnmarshalStringSliceWithDefaultHasSpaces(t *testing.T) { 298 type inner struct { 299 Strs []string `key:"strs,default=[foo, bar, woo]"` 300 } 301 302 var in inner 303 assert.Nil(t, UnmarshalKey(nil, &in)) 304 assert.ElementsMatch(t, []string{"foo", "bar", "woo"}, in.Strs) 305 } 306 307 func TestUnmarshalUint(t *testing.T) { 308 type inner struct { 309 Uint uint `key:"uint"` 310 UintFromStr uint `key:"uintstr,string"` 311 Uint8 uint8 `key:"uint8"` 312 Uint8FromStr uint8 `key:"uint8str,string"` 313 Uint16 uint16 `key:"uint16"` 314 Uint16FromStr uint16 `key:"uint16str,string"` 315 Uint32 uint32 `key:"uint32"` 316 Uint32FromStr uint32 `key:"uint32str,string"` 317 Uint64 uint64 `key:"uint64"` 318 Uint64FromStr uint64 `key:"uint64str,string"` 319 DefaultUint uint `key:"defaultuint,default=11"` 320 Optional uint `key:"optional,optional"` 321 } 322 m := map[string]interface{}{ 323 "uint": uint(1), 324 "uintstr": "2", 325 "uint8": uint8(3), 326 "uint8str": "4", 327 "uint16": uint16(5), 328 "uint16str": "6", 329 "uint32": uint32(7), 330 "uint32str": "8", 331 "uint64": uint64(9), 332 "uint64str": "10", 333 } 334 335 var in inner 336 ast := assert.New(t) 337 ast.Nil(UnmarshalKey(m, &in)) 338 ast.Equal(uint(1), in.Uint) 339 ast.Equal(uint(2), in.UintFromStr) 340 ast.Equal(uint8(3), in.Uint8) 341 ast.Equal(uint8(4), in.Uint8FromStr) 342 ast.Equal(uint16(5), in.Uint16) 343 ast.Equal(uint16(6), in.Uint16FromStr) 344 ast.Equal(uint32(7), in.Uint32) 345 ast.Equal(uint32(8), in.Uint32FromStr) 346 ast.Equal(uint64(9), in.Uint64) 347 ast.Equal(uint64(10), in.Uint64FromStr) 348 ast.Equal(uint(11), in.DefaultUint) 349 } 350 351 func TestUnmarshalFloat(t *testing.T) { 352 type inner struct { 353 Float32 float32 `key:"float32"` 354 Float32Str float32 `key:"float32str,string"` 355 Float64 float64 `key:"float64"` 356 Float64Str float64 `key:"float64str,string"` 357 DefaultFloat float32 `key:"defaultfloat,default=5.5"` 358 Optional float32 `key:",optional"` 359 } 360 m := map[string]interface{}{ 361 "float32": float32(1.5), 362 "float32str": "2.5", 363 "float64": float64(3.5), 364 "float64str": "4.5", 365 } 366 367 var in inner 368 ast := assert.New(t) 369 ast.Nil(UnmarshalKey(m, &in)) 370 ast.Equal(float32(1.5), in.Float32) 371 ast.Equal(float32(2.5), in.Float32Str) 372 ast.Equal(3.5, in.Float64) 373 ast.Equal(4.5, in.Float64Str) 374 ast.Equal(float32(5.5), in.DefaultFloat) 375 } 376 377 func TestUnmarshalInt64Slice(t *testing.T) { 378 var v struct { 379 Ages []int64 `key:"ages"` 380 Slice []int64 `key:"slice"` 381 } 382 m := map[string]interface{}{ 383 "ages": []int64{1, 2}, 384 "slice": []interface{}{}, 385 } 386 387 ast := assert.New(t) 388 ast.Nil(UnmarshalKey(m, &v)) 389 ast.ElementsMatch([]int64{1, 2}, v.Ages) 390 ast.Equal([]int64{}, v.Slice) 391 } 392 393 func TestUnmarshalIntSlice(t *testing.T) { 394 var v struct { 395 Ages []int `key:"ages"` 396 Slice []int `key:"slice"` 397 } 398 m := map[string]interface{}{ 399 "ages": []int{1, 2}, 400 "slice": []interface{}{}, 401 } 402 403 ast := assert.New(t) 404 ast.Nil(UnmarshalKey(m, &v)) 405 ast.ElementsMatch([]int{1, 2}, v.Ages) 406 ast.Equal([]int{}, v.Slice) 407 } 408 409 func TestUnmarshalString(t *testing.T) { 410 type inner struct { 411 Name string `key:"name"` 412 NameStr string `key:"namestr,string"` 413 NotPresent string `key:",optional"` 414 NotPresentWithTag string `key:"notpresent,optional"` 415 DefaultString string `key:"defaultstring,default=hello"` 416 Optional string `key:",optional"` 417 } 418 m := map[string]interface{}{ 419 "name": "kevin", 420 "namestr": "namewithstring", 421 } 422 423 var in inner 424 ast := assert.New(t) 425 ast.Nil(UnmarshalKey(m, &in)) 426 ast.Equal("kevin", in.Name) 427 ast.Equal("namewithstring", in.NameStr) 428 ast.Empty(in.NotPresent) 429 ast.Empty(in.NotPresentWithTag) 430 ast.Equal("hello", in.DefaultString) 431 } 432 433 func TestUnmarshalStringWithMissing(t *testing.T) { 434 type inner struct { 435 Name string `key:"name"` 436 } 437 m := map[string]interface{}{} 438 439 var in inner 440 assert.NotNil(t, UnmarshalKey(m, &in)) 441 } 442 443 func TestUnmarshalStringSliceFromString(t *testing.T) { 444 var v struct { 445 Names []string `key:"names"` 446 } 447 m := map[string]interface{}{ 448 "names": `["first", "second"]`, 449 } 450 451 ast := assert.New(t) 452 ast.Nil(UnmarshalKey(m, &v)) 453 ast.Equal(2, len(v.Names)) 454 ast.Equal("first", v.Names[0]) 455 ast.Equal("second", v.Names[1]) 456 } 457 458 func TestUnmarshalIntSliceFromString(t *testing.T) { 459 var v struct { 460 Values []int `key:"values"` 461 } 462 m := map[string]interface{}{ 463 "values": `[1, 2]`, 464 } 465 466 ast := assert.New(t) 467 ast.Nil(UnmarshalKey(m, &v)) 468 ast.Equal(2, len(v.Values)) 469 ast.Equal(1, v.Values[0]) 470 ast.Equal(2, v.Values[1]) 471 } 472 473 func TestUnmarshalIntMapFromString(t *testing.T) { 474 var v struct { 475 Sort map[string]int `key:"sort"` 476 } 477 m := map[string]interface{}{ 478 "sort": `{"value":12345,"zeroVal":0,"nullVal":null}`, 479 } 480 481 ast := assert.New(t) 482 ast.Nil(UnmarshalKey(m, &v)) 483 ast.Equal(3, len(v.Sort)) 484 ast.Equal(12345, v.Sort["value"]) 485 ast.Equal(0, v.Sort["zeroVal"]) 486 ast.Equal(0, v.Sort["nullVal"]) 487 } 488 489 func TestUnmarshalBoolMapFromString(t *testing.T) { 490 var v struct { 491 Sort map[string]bool `key:"sort"` 492 } 493 m := map[string]interface{}{ 494 "sort": `{"value":true,"zeroVal":false,"nullVal":null}`, 495 } 496 497 ast := assert.New(t) 498 ast.Nil(UnmarshalKey(m, &v)) 499 ast.Equal(3, len(v.Sort)) 500 ast.Equal(true, v.Sort["value"]) 501 ast.Equal(false, v.Sort["zeroVal"]) 502 ast.Equal(false, v.Sort["nullVal"]) 503 } 504 505 type CustomStringer string 506 507 type UnsupportedStringer string 508 509 func (c CustomStringer) String() string { 510 return fmt.Sprintf("{%s}", string(c)) 511 } 512 513 func TestUnmarshalStringMapFromStringer(t *testing.T) { 514 var v struct { 515 Sort map[string]string `key:"sort"` 516 } 517 m := map[string]interface{}{ 518 "sort": CustomStringer(`"value":"ascend","emptyStr":""`), 519 } 520 521 ast := assert.New(t) 522 ast.Nil(UnmarshalKey(m, &v)) 523 ast.Equal(2, len(v.Sort)) 524 ast.Equal("ascend", v.Sort["value"]) 525 ast.Equal("", v.Sort["emptyStr"]) 526 } 527 528 func TestUnmarshalStringMapFromUnsupportedType(t *testing.T) { 529 var v struct { 530 Sort map[string]string `key:"sort"` 531 } 532 m := map[string]interface{}{ 533 "sort": UnsupportedStringer(`{"value":"ascend","emptyStr":""}`), 534 } 535 536 ast := assert.New(t) 537 ast.NotNil(UnmarshalKey(m, &v)) 538 } 539 540 func TestUnmarshalStringMapFromNotSettableValue(t *testing.T) { 541 var v struct { 542 sort map[string]string `key:"sort"` 543 psort *map[string]string `key:"psort"` 544 } 545 m := map[string]interface{}{ 546 "sort": `{"value":"ascend","emptyStr":""}`, 547 "psort": `{"value":"ascend","emptyStr":""}`, 548 } 549 550 ast := assert.New(t) 551 ast.NotNil(UnmarshalKey(m, &v)) 552 } 553 554 func TestUnmarshalStringMapFromString(t *testing.T) { 555 var v struct { 556 Sort map[string]string `key:"sort"` 557 } 558 m := map[string]interface{}{ 559 "sort": `{"value":"ascend","emptyStr":""}`, 560 } 561 562 ast := assert.New(t) 563 ast.Nil(UnmarshalKey(m, &v)) 564 ast.Equal(2, len(v.Sort)) 565 ast.Equal("ascend", v.Sort["value"]) 566 ast.Equal("", v.Sort["emptyStr"]) 567 } 568 569 func TestUnmarshalStructMapFromString(t *testing.T) { 570 var v struct { 571 Filter map[string]struct { 572 Field1 bool `json:"field1"` 573 Field2 int64 `json:"field2,string"` 574 Field3 string `json:"field3"` 575 Field4 *string `json:"field4"` 576 Field5 []string `json:"field5"` 577 } `key:"filter"` 578 } 579 m := map[string]interface{}{ 580 "filter": `{"obj":{"field1":true,"field2":"1573570455447539712","field3":"this is a string", 581 "field4":"this is a string pointer","field5":["str1","str2"]}}`, 582 } 583 584 ast := assert.New(t) 585 ast.Nil(UnmarshalKey(m, &v)) 586 ast.Equal(1, len(v.Filter)) 587 ast.NotNil(v.Filter["obj"]) 588 ast.Equal(true, v.Filter["obj"].Field1) 589 ast.Equal(int64(1573570455447539712), v.Filter["obj"].Field2) 590 ast.Equal("this is a string", v.Filter["obj"].Field3) 591 ast.Equal("this is a string pointer", *v.Filter["obj"].Field4) 592 ast.ElementsMatch([]string{"str1", "str2"}, v.Filter["obj"].Field5) 593 } 594 595 func TestUnmarshalStringSliceMapFromString(t *testing.T) { 596 var v struct { 597 Filter map[string][]string `key:"filter"` 598 } 599 m := map[string]interface{}{ 600 "filter": `{"assignType":null,"status":["process","comment"],"rate":[]}`, 601 } 602 603 ast := assert.New(t) 604 ast.Nil(UnmarshalKey(m, &v)) 605 ast.Equal(3, len(v.Filter)) 606 ast.Equal([]string(nil), v.Filter["assignType"]) 607 ast.Equal(2, len(v.Filter["status"])) 608 ast.Equal("process", v.Filter["status"][0]) 609 ast.Equal("comment", v.Filter["status"][1]) 610 ast.Equal(0, len(v.Filter["rate"])) 611 } 612 613 func TestUnmarshalStruct(t *testing.T) { 614 type address struct { 615 City string `key:"city"` 616 ZipCode int `key:"zipcode,string"` 617 DefaultString string `key:"defaultstring,default=hello"` 618 Optional string `key:",optional"` 619 } 620 type inner struct { 621 Name string `key:"name"` 622 Address address `key:"address"` 623 } 624 m := map[string]interface{}{ 625 "name": "kevin", 626 "address": map[string]interface{}{ 627 "city": "shanghai", 628 "zipcode": "200000", 629 }, 630 } 631 632 var in inner 633 ast := assert.New(t) 634 ast.Nil(UnmarshalKey(m, &in)) 635 ast.Equal("kevin", in.Name) 636 ast.Equal("shanghai", in.Address.City) 637 ast.Equal(200000, in.Address.ZipCode) 638 ast.Equal("hello", in.Address.DefaultString) 639 } 640 641 func TestUnmarshalStructOptionalDepends(t *testing.T) { 642 type address struct { 643 City string `key:"city"` 644 Optional string `key:",optional"` 645 OptionalDepends string `key:",optional=Optional"` 646 } 647 type inner struct { 648 Name string `key:"name"` 649 Address address `key:"address"` 650 } 651 652 tests := []struct { 653 input map[string]string 654 pass bool 655 }{ 656 { 657 pass: true, 658 }, 659 { 660 input: map[string]string{ 661 "OptionalDepends": "b", 662 }, 663 pass: false, 664 }, 665 { 666 input: map[string]string{ 667 "Optional": "a", 668 }, 669 pass: false, 670 }, 671 { 672 input: map[string]string{ 673 "Optional": "a", 674 "OptionalDepends": "b", 675 }, 676 pass: true, 677 }, 678 } 679 680 for _, test := range tests { 681 t.Run(stringx.Rand(), func(t *testing.T) { 682 m := map[string]interface{}{ 683 "name": "kevin", 684 "address": map[string]interface{}{ 685 "city": "shanghai", 686 }, 687 } 688 for k, v := range test.input { 689 m["address"].(map[string]interface{})[k] = v 690 } 691 692 var in inner 693 ast := assert.New(t) 694 if test.pass { 695 ast.Nil(UnmarshalKey(m, &in)) 696 ast.Equal("kevin", in.Name) 697 ast.Equal("shanghai", in.Address.City) 698 ast.Equal(test.input["Optional"], in.Address.Optional) 699 ast.Equal(test.input["OptionalDepends"], in.Address.OptionalDepends) 700 } else { 701 ast.NotNil(UnmarshalKey(m, &in)) 702 } 703 }) 704 } 705 } 706 707 func TestUnmarshalStructOptionalDependsNot(t *testing.T) { 708 type address struct { 709 City string `key:"city"` 710 Optional string `key:",optional"` 711 OptionalDepends string `key:",optional=!Optional"` 712 } 713 type inner struct { 714 Name string `key:"name"` 715 Address address `key:"address"` 716 } 717 718 tests := []struct { 719 input map[string]string 720 pass bool 721 }{ 722 { 723 input: map[string]string{}, 724 pass: false, 725 }, 726 { 727 input: map[string]string{ 728 "Optional": "a", 729 "OptionalDepends": "b", 730 }, 731 pass: false, 732 }, 733 { 734 input: map[string]string{ 735 "Optional": "a", 736 }, 737 pass: true, 738 }, 739 { 740 input: map[string]string{ 741 "OptionalDepends": "b", 742 }, 743 pass: true, 744 }, 745 } 746 747 for _, test := range tests { 748 t.Run(stringx.Rand(), func(t *testing.T) { 749 m := map[string]interface{}{ 750 "name": "kevin", 751 "address": map[string]interface{}{ 752 "city": "shanghai", 753 }, 754 } 755 for k, v := range test.input { 756 m["address"].(map[string]interface{})[k] = v 757 } 758 759 var in inner 760 ast := assert.New(t) 761 if test.pass { 762 ast.Nil(UnmarshalKey(m, &in)) 763 ast.Equal("kevin", in.Name) 764 ast.Equal("shanghai", in.Address.City) 765 ast.Equal(test.input["Optional"], in.Address.Optional) 766 ast.Equal(test.input["OptionalDepends"], in.Address.OptionalDepends) 767 } else { 768 ast.NotNil(UnmarshalKey(m, &in)) 769 } 770 }) 771 } 772 } 773 774 func TestUnmarshalStructOptionalDependsNotErrorDetails(t *testing.T) { 775 type address struct { 776 Optional string `key:",optional"` 777 OptionalDepends string `key:",optional=!Optional"` 778 } 779 type inner struct { 780 Name string `key:"name"` 781 Address address `key:"address"` 782 } 783 784 m := map[string]interface{}{ 785 "name": "kevin", 786 } 787 788 var in inner 789 err := UnmarshalKey(m, &in) 790 assert.NotNil(t, err) 791 } 792 793 func TestUnmarshalStructOptionalDependsNotNested(t *testing.T) { 794 type address struct { 795 Optional string `key:",optional"` 796 OptionalDepends string `key:",optional=!Optional"` 797 } 798 type combo struct { 799 Name string `key:"name,optional"` 800 Address address `key:"address"` 801 } 802 type inner struct { 803 Name string `key:"name"` 804 Combo combo `key:"combo"` 805 } 806 807 m := map[string]interface{}{ 808 "name": "kevin", 809 } 810 811 var in inner 812 err := UnmarshalKey(m, &in) 813 assert.NotNil(t, err) 814 } 815 816 func TestUnmarshalStructOptionalNestedDifferentKey(t *testing.T) { 817 type address struct { 818 Optional string `dkey:",optional"` 819 OptionalDepends string `key:",optional"` 820 } 821 type combo struct { 822 Name string `key:"name,optional"` 823 Address address `key:"address"` 824 } 825 type inner struct { 826 Name string `key:"name"` 827 Combo combo `key:"combo"` 828 } 829 830 m := map[string]interface{}{ 831 "name": "kevin", 832 } 833 834 var in inner 835 assert.NotNil(t, UnmarshalKey(m, &in)) 836 } 837 838 func TestUnmarshalStructOptionalDependsNotEnoughValue(t *testing.T) { 839 type address struct { 840 Optional string `key:",optional"` 841 OptionalDepends string `key:",optional=!"` 842 } 843 type inner struct { 844 Name string `key:"name"` 845 Address address `key:"address"` 846 } 847 848 m := map[string]interface{}{ 849 "name": "kevin", 850 "address": map[string]interface{}{}, 851 } 852 853 var in inner 854 err := UnmarshalKey(m, &in) 855 assert.NotNil(t, err) 856 } 857 858 func TestUnmarshalAnonymousStructOptionalDepends(t *testing.T) { 859 type AnonAddress struct { 860 City string `key:"city"` 861 Optional string `key:",optional"` 862 OptionalDepends string `key:",optional=Optional"` 863 } 864 type inner struct { 865 Name string `key:"name"` 866 AnonAddress 867 } 868 869 tests := []struct { 870 input map[string]string 871 pass bool 872 }{ 873 { 874 pass: true, 875 }, 876 { 877 input: map[string]string{ 878 "OptionalDepends": "b", 879 }, 880 pass: false, 881 }, 882 { 883 input: map[string]string{ 884 "Optional": "a", 885 }, 886 pass: false, 887 }, 888 { 889 input: map[string]string{ 890 "Optional": "a", 891 "OptionalDepends": "b", 892 }, 893 pass: true, 894 }, 895 } 896 897 for _, test := range tests { 898 t.Run(stringx.Rand(), func(t *testing.T) { 899 m := map[string]interface{}{ 900 "name": "kevin", 901 "city": "shanghai", 902 } 903 for k, v := range test.input { 904 m[k] = v 905 } 906 907 var in inner 908 ast := assert.New(t) 909 if test.pass { 910 ast.Nil(UnmarshalKey(m, &in)) 911 ast.Equal("kevin", in.Name) 912 ast.Equal("shanghai", in.City) 913 ast.Equal(test.input["Optional"], in.Optional) 914 ast.Equal(test.input["OptionalDepends"], in.OptionalDepends) 915 } else { 916 ast.NotNil(UnmarshalKey(m, &in)) 917 } 918 }) 919 } 920 } 921 922 func TestUnmarshalStructPtr(t *testing.T) { 923 type address struct { 924 City string `key:"city"` 925 ZipCode int `key:"zipcode,string"` 926 DefaultString string `key:"defaultstring,default=hello"` 927 Optional string `key:",optional"` 928 } 929 type inner struct { 930 Name string `key:"name"` 931 Address *address `key:"address"` 932 } 933 m := map[string]interface{}{ 934 "name": "kevin", 935 "address": map[string]interface{}{ 936 "city": "shanghai", 937 "zipcode": "200000", 938 }, 939 } 940 941 var in inner 942 ast := assert.New(t) 943 ast.Nil(UnmarshalKey(m, &in)) 944 ast.Equal("kevin", in.Name) 945 ast.Equal("shanghai", in.Address.City) 946 ast.Equal(200000, in.Address.ZipCode) 947 ast.Equal("hello", in.Address.DefaultString) 948 } 949 950 func TestUnmarshalWithStringIgnored(t *testing.T) { 951 type inner struct { 952 True bool `key:"yes"` 953 False bool `key:"no"` 954 Int int `key:"int"` 955 Int8 int8 `key:"int8"` 956 Int16 int16 `key:"int16"` 957 Int32 int32 `key:"int32"` 958 Int64 int64 `key:"int64"` 959 Uint uint `key:"uint"` 960 Uint8 uint8 `key:"uint8"` 961 Uint16 uint16 `key:"uint16"` 962 Uint32 uint32 `key:"uint32"` 963 Uint64 uint64 `key:"uint64"` 964 Float32 float32 `key:"float32"` 965 Float64 float64 `key:"float64"` 966 } 967 m := map[string]interface{}{ 968 "yes": "1", 969 "no": "0", 970 "int": "1", 971 "int8": "3", 972 "int16": "5", 973 "int32": "7", 974 "int64": "9", 975 "uint": "1", 976 "uint8": "3", 977 "uint16": "5", 978 "uint32": "7", 979 "uint64": "9", 980 "float32": "1.5", 981 "float64": "3.5", 982 } 983 984 var in inner 985 um := NewUnmarshaler("key", WithStringValues()) 986 ast := assert.New(t) 987 ast.Nil(um.Unmarshal(m, &in)) 988 ast.True(in.True) 989 ast.False(in.False) 990 ast.Equal(1, in.Int) 991 ast.Equal(int8(3), in.Int8) 992 ast.Equal(int16(5), in.Int16) 993 ast.Equal(int32(7), in.Int32) 994 ast.Equal(int64(9), in.Int64) 995 ast.Equal(uint(1), in.Uint) 996 ast.Equal(uint8(3), in.Uint8) 997 ast.Equal(uint16(5), in.Uint16) 998 ast.Equal(uint32(7), in.Uint32) 999 ast.Equal(uint64(9), in.Uint64) 1000 ast.Equal(float32(1.5), in.Float32) 1001 ast.Equal(3.5, in.Float64) 1002 } 1003 1004 func TestUnmarshalJsonNumberInt64(t *testing.T) { 1005 for i := 0; i <= maxUintBitsToTest; i++ { 1006 var intValue int64 = 1 << uint(i) 1007 strValue := strconv.FormatInt(intValue, 10) 1008 number := json.Number(strValue) 1009 m := map[string]interface{}{ 1010 "ID": number, 1011 } 1012 var v struct { 1013 ID int64 1014 } 1015 assert.Nil(t, UnmarshalKey(m, &v)) 1016 assert.Equal(t, intValue, v.ID) 1017 } 1018 } 1019 1020 func TestUnmarshalJsonNumberUint64(t *testing.T) { 1021 for i := 0; i <= maxUintBitsToTest; i++ { 1022 var intValue uint64 = 1 << uint(i) 1023 strValue := strconv.FormatUint(intValue, 10) 1024 number := json.Number(strValue) 1025 m := map[string]interface{}{ 1026 "ID": number, 1027 } 1028 var v struct { 1029 ID uint64 1030 } 1031 assert.Nil(t, UnmarshalKey(m, &v)) 1032 assert.Equal(t, intValue, v.ID) 1033 } 1034 } 1035 1036 func TestUnmarshalJsonNumberUint64Ptr(t *testing.T) { 1037 for i := 0; i <= maxUintBitsToTest; i++ { 1038 var intValue uint64 = 1 << uint(i) 1039 strValue := strconv.FormatUint(intValue, 10) 1040 number := json.Number(strValue) 1041 m := map[string]interface{}{ 1042 "ID": number, 1043 } 1044 var v struct { 1045 ID *uint64 1046 } 1047 ast := assert.New(t) 1048 ast.Nil(UnmarshalKey(m, &v)) 1049 ast.NotNil(v.ID) 1050 ast.Equal(intValue, *v.ID) 1051 } 1052 } 1053 1054 func TestUnmarshalMapOfInt(t *testing.T) { 1055 m := map[string]interface{}{ 1056 "Ids": map[string]bool{"first": true}, 1057 } 1058 var v struct { 1059 Ids map[string]bool 1060 } 1061 assert.Nil(t, UnmarshalKey(m, &v)) 1062 assert.True(t, v.Ids["first"]) 1063 } 1064 1065 func TestUnmarshalMapOfStructError(t *testing.T) { 1066 m := map[string]interface{}{ 1067 "Ids": map[string]interface{}{"first": "second"}, 1068 } 1069 var v struct { 1070 Ids map[string]struct { 1071 Name string 1072 } 1073 } 1074 assert.NotNil(t, UnmarshalKey(m, &v)) 1075 } 1076 1077 func TestUnmarshalSlice(t *testing.T) { 1078 m := map[string]interface{}{ 1079 "Ids": []interface{}{"first", "second"}, 1080 } 1081 var v struct { 1082 Ids []string 1083 } 1084 ast := assert.New(t) 1085 ast.Nil(UnmarshalKey(m, &v)) 1086 ast.Equal(2, len(v.Ids)) 1087 ast.Equal("first", v.Ids[0]) 1088 ast.Equal("second", v.Ids[1]) 1089 } 1090 1091 func TestUnmarshalSliceOfStruct(t *testing.T) { 1092 m := map[string]interface{}{ 1093 "Ids": []map[string]interface{}{ 1094 { 1095 "First": 1, 1096 "Second": 2, 1097 }, 1098 }, 1099 } 1100 var v struct { 1101 Ids []struct { 1102 First int 1103 Second int 1104 } 1105 } 1106 ast := assert.New(t) 1107 ast.Nil(UnmarshalKey(m, &v)) 1108 ast.Equal(1, len(v.Ids)) 1109 ast.Equal(1, v.Ids[0].First) 1110 ast.Equal(2, v.Ids[0].Second) 1111 } 1112 1113 func TestUnmarshalWithStringOptionsCorrect(t *testing.T) { 1114 type inner struct { 1115 Value string `key:"value,options=first|second"` 1116 Foo string `key:"foo,options=[bar,baz]"` 1117 Correct string `key:"correct,options=1|2"` 1118 } 1119 m := map[string]interface{}{ 1120 "value": "first", 1121 "foo": "bar", 1122 "correct": "2", 1123 } 1124 1125 var in inner 1126 ast := assert.New(t) 1127 ast.Nil(UnmarshalKey(m, &in)) 1128 ast.Equal("first", in.Value) 1129 ast.Equal("bar", in.Foo) 1130 ast.Equal("2", in.Correct) 1131 } 1132 1133 func TestUnmarshalOptionsOptional(t *testing.T) { 1134 type inner struct { 1135 Value string `key:"value,options=first|second,optional"` 1136 OptionalValue string `key:"optional_value,options=first|second,optional"` 1137 Foo string `key:"foo,options=[bar,baz]"` 1138 Correct string `key:"correct,options=1|2"` 1139 } 1140 m := map[string]interface{}{ 1141 "value": "first", 1142 "foo": "bar", 1143 "correct": "2", 1144 } 1145 1146 var in inner 1147 ast := assert.New(t) 1148 ast.Nil(UnmarshalKey(m, &in)) 1149 ast.Equal("first", in.Value) 1150 ast.Equal("", in.OptionalValue) 1151 ast.Equal("bar", in.Foo) 1152 ast.Equal("2", in.Correct) 1153 } 1154 1155 func TestUnmarshalOptionsOptionalWrongValue(t *testing.T) { 1156 type inner struct { 1157 Value string `key:"value,options=first|second,optional"` 1158 OptionalValue string `key:"optional_value,options=first|second,optional"` 1159 WrongValue string `key:"wrong_value,options=first|second,optional"` 1160 } 1161 m := map[string]interface{}{ 1162 "value": "first", 1163 "wrong_value": "third", 1164 } 1165 1166 var in inner 1167 assert.NotNil(t, UnmarshalKey(m, &in)) 1168 } 1169 1170 func TestUnmarshalStringOptionsWithStringOptionsNotString(t *testing.T) { 1171 type inner struct { 1172 Value string `key:"value,options=first|second"` 1173 Correct string `key:"correct,options=1|2"` 1174 } 1175 m := map[string]interface{}{ 1176 "value": "first", 1177 "correct": 2, 1178 } 1179 1180 var in inner 1181 unmarshaler := NewUnmarshaler(defaultKeyName, WithStringValues()) 1182 ast := assert.New(t) 1183 ast.NotNil(unmarshaler.Unmarshal(m, &in)) 1184 } 1185 1186 func TestUnmarshalStringOptionsWithStringOptions(t *testing.T) { 1187 type inner struct { 1188 Value string `key:"value,options=first|second"` 1189 Correct string `key:"correct,options=1|2"` 1190 } 1191 m := map[string]interface{}{ 1192 "value": "first", 1193 "correct": "2", 1194 } 1195 1196 var in inner 1197 unmarshaler := NewUnmarshaler(defaultKeyName, WithStringValues()) 1198 ast := assert.New(t) 1199 ast.Nil(unmarshaler.Unmarshal(m, &in)) 1200 ast.Equal("first", in.Value) 1201 ast.Equal("2", in.Correct) 1202 } 1203 1204 func TestUnmarshalStringOptionsWithStringOptionsPtr(t *testing.T) { 1205 type inner struct { 1206 Value *string `key:"value,options=first|second"` 1207 Correct *int `key:"correct,options=1|2"` 1208 } 1209 m := map[string]interface{}{ 1210 "value": "first", 1211 "correct": "2", 1212 } 1213 1214 var in inner 1215 unmarshaler := NewUnmarshaler(defaultKeyName, WithStringValues()) 1216 ast := assert.New(t) 1217 ast.Nil(unmarshaler.Unmarshal(m, &in)) 1218 ast.True(*in.Value == "first") 1219 ast.True(*in.Correct == 2) 1220 } 1221 1222 func TestUnmarshalStringOptionsWithStringOptionsIncorrect(t *testing.T) { 1223 type inner struct { 1224 Value string `key:"value,options=first|second"` 1225 Correct string `key:"correct,options=1|2"` 1226 } 1227 m := map[string]interface{}{ 1228 "value": "third", 1229 "correct": "2", 1230 } 1231 1232 var in inner 1233 unmarshaler := NewUnmarshaler(defaultKeyName, WithStringValues()) 1234 ast := assert.New(t) 1235 ast.NotNil(unmarshaler.Unmarshal(m, &in)) 1236 } 1237 1238 func TestUnmarshalStringOptionsWithStringOptionsIncorrectGrouped(t *testing.T) { 1239 type inner struct { 1240 Value string `key:"value,options=[first,second]"` 1241 Correct string `key:"correct,options=1|2"` 1242 } 1243 m := map[string]interface{}{ 1244 "value": "third", 1245 "correct": "2", 1246 } 1247 1248 var in inner 1249 unmarshaler := NewUnmarshaler(defaultKeyName, WithStringValues()) 1250 ast := assert.New(t) 1251 ast.NotNil(unmarshaler.Unmarshal(m, &in)) 1252 } 1253 1254 func TestUnmarshalWithStringOptionsIncorrect(t *testing.T) { 1255 type inner struct { 1256 Value string `key:"value,options=first|second"` 1257 Incorrect string `key:"incorrect,options=1|2"` 1258 } 1259 m := map[string]interface{}{ 1260 "value": "first", 1261 "incorrect": "3", 1262 } 1263 1264 var in inner 1265 assert.NotNil(t, UnmarshalKey(m, &in)) 1266 } 1267 1268 func TestUnmarshalWithIntOptionsCorrect(t *testing.T) { 1269 type inner struct { 1270 Value string `key:"value,options=first|second"` 1271 Number int `key:"number,options=1|2"` 1272 } 1273 m := map[string]interface{}{ 1274 "value": "first", 1275 "number": 2, 1276 } 1277 1278 var in inner 1279 ast := assert.New(t) 1280 ast.Nil(UnmarshalKey(m, &in)) 1281 ast.Equal("first", in.Value) 1282 ast.Equal(2, in.Number) 1283 } 1284 1285 func TestUnmarshalWithIntOptionsCorrectPtr(t *testing.T) { 1286 type inner struct { 1287 Value *string `key:"value,options=first|second"` 1288 Number *int `key:"number,options=1|2"` 1289 } 1290 m := map[string]interface{}{ 1291 "value": "first", 1292 "number": 2, 1293 } 1294 1295 var in inner 1296 ast := assert.New(t) 1297 ast.Nil(UnmarshalKey(m, &in)) 1298 ast.True(*in.Value == "first") 1299 ast.True(*in.Number == 2) 1300 } 1301 1302 func TestUnmarshalWithIntOptionsIncorrect(t *testing.T) { 1303 type inner struct { 1304 Value string `key:"value,options=first|second"` 1305 Incorrect int `key:"incorrect,options=1|2"` 1306 } 1307 m := map[string]interface{}{ 1308 "value": "first", 1309 "incorrect": 3, 1310 } 1311 1312 var in inner 1313 assert.NotNil(t, UnmarshalKey(m, &in)) 1314 } 1315 1316 func TestUnmarshalWithJsonNumberOptionsIncorrect(t *testing.T) { 1317 type inner struct { 1318 Value string `key:"value,options=first|second"` 1319 Incorrect int `key:"incorrect,options=1|2"` 1320 } 1321 m := map[string]interface{}{ 1322 "value": "first", 1323 "incorrect": json.Number("3"), 1324 } 1325 1326 var in inner 1327 assert.NotNil(t, UnmarshalKey(m, &in)) 1328 } 1329 1330 func TestUnmarshaler_UnmarshalIntOptions(t *testing.T) { 1331 var val struct { 1332 Sex int `json:"sex,options=0|1"` 1333 } 1334 input := []byte(`{"sex": 2}`) 1335 assert.NotNil(t, UnmarshalJsonBytes(input, &val)) 1336 } 1337 1338 func TestUnmarshalWithUintOptionsCorrect(t *testing.T) { 1339 type inner struct { 1340 Value string `key:"value,options=first|second"` 1341 Number uint `key:"number,options=1|2"` 1342 } 1343 m := map[string]interface{}{ 1344 "value": "first", 1345 "number": uint(2), 1346 } 1347 1348 var in inner 1349 ast := assert.New(t) 1350 ast.Nil(UnmarshalKey(m, &in)) 1351 ast.Equal("first", in.Value) 1352 ast.Equal(uint(2), in.Number) 1353 } 1354 1355 func TestUnmarshalWithUintOptionsIncorrect(t *testing.T) { 1356 type inner struct { 1357 Value string `key:"value,options=first|second"` 1358 Incorrect uint `key:"incorrect,options=1|2"` 1359 } 1360 m := map[string]interface{}{ 1361 "value": "first", 1362 "incorrect": uint(3), 1363 } 1364 1365 var in inner 1366 assert.NotNil(t, UnmarshalKey(m, &in)) 1367 } 1368 1369 func TestUnmarshalWithOptionsAndDefault(t *testing.T) { 1370 type inner struct { 1371 Value string `key:"value,options=first|second|third,default=second"` 1372 } 1373 m := map[string]interface{}{} 1374 1375 var in inner 1376 assert.Nil(t, UnmarshalKey(m, &in)) 1377 assert.Equal(t, "second", in.Value) 1378 } 1379 1380 func TestUnmarshalWithOptionsAndSet(t *testing.T) { 1381 type inner struct { 1382 Value string `key:"value,options=first|second|third,default=second"` 1383 } 1384 m := map[string]interface{}{ 1385 "value": "first", 1386 } 1387 1388 var in inner 1389 assert.Nil(t, UnmarshalKey(m, &in)) 1390 assert.Equal(t, "first", in.Value) 1391 } 1392 1393 func TestUnmarshalNestedKey(t *testing.T) { 1394 var c struct { 1395 ID int `json:"Persons.first.ID"` 1396 } 1397 m := map[string]interface{}{ 1398 "Persons": map[string]interface{}{ 1399 "first": map[string]interface{}{ 1400 "ID": 1, 1401 }, 1402 }, 1403 } 1404 1405 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c)) 1406 assert.Equal(t, 1, c.ID) 1407 } 1408 1409 func TestUnmarhsalNestedKeyArray(t *testing.T) { 1410 var c struct { 1411 First []struct { 1412 ID int 1413 } `json:"Persons.first"` 1414 } 1415 m := map[string]interface{}{ 1416 "Persons": map[string]interface{}{ 1417 "first": []map[string]interface{}{ 1418 {"ID": 1}, 1419 {"ID": 2}, 1420 }, 1421 }, 1422 } 1423 1424 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c)) 1425 assert.Equal(t, 2, len(c.First)) 1426 assert.Equal(t, 1, c.First[0].ID) 1427 } 1428 1429 func TestUnmarshalAnonymousOptionalRequiredProvided(t *testing.T) { 1430 type ( 1431 Foo struct { 1432 Value string `json:"v"` 1433 } 1434 1435 Bar struct { 1436 Foo `json:",optional"` 1437 } 1438 ) 1439 m := map[string]interface{}{ 1440 "v": "anything", 1441 } 1442 1443 var b Bar 1444 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1445 assert.Equal(t, "anything", b.Value) 1446 } 1447 1448 func TestUnmarshalAnonymousOptionalRequiredMissed(t *testing.T) { 1449 type ( 1450 Foo struct { 1451 Value string `json:"v"` 1452 } 1453 1454 Bar struct { 1455 Foo `json:",optional"` 1456 } 1457 ) 1458 m := map[string]interface{}{} 1459 1460 var b Bar 1461 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1462 assert.True(t, len(b.Value) == 0) 1463 } 1464 1465 func TestUnmarshalAnonymousOptionalOptionalProvided(t *testing.T) { 1466 type ( 1467 Foo struct { 1468 Value string `json:"v,optional"` 1469 } 1470 1471 Bar struct { 1472 Foo `json:",optional"` 1473 } 1474 ) 1475 m := map[string]interface{}{ 1476 "v": "anything", 1477 } 1478 1479 var b Bar 1480 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1481 assert.Equal(t, "anything", b.Value) 1482 } 1483 1484 func TestUnmarshalAnonymousOptionalOptionalMissed(t *testing.T) { 1485 type ( 1486 Foo struct { 1487 Value string `json:"v,optional"` 1488 } 1489 1490 Bar struct { 1491 Foo `json:",optional"` 1492 } 1493 ) 1494 m := map[string]interface{}{} 1495 1496 var b Bar 1497 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1498 assert.True(t, len(b.Value) == 0) 1499 } 1500 1501 func TestUnmarshalAnonymousOptionalRequiredBothProvided(t *testing.T) { 1502 type ( 1503 Foo struct { 1504 Name string `json:"n"` 1505 Value string `json:"v"` 1506 } 1507 1508 Bar struct { 1509 Foo `json:",optional"` 1510 } 1511 ) 1512 m := map[string]interface{}{ 1513 "n": "kevin", 1514 "v": "anything", 1515 } 1516 1517 var b Bar 1518 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1519 assert.Equal(t, "kevin", b.Name) 1520 assert.Equal(t, "anything", b.Value) 1521 } 1522 1523 func TestUnmarshalAnonymousOptionalRequiredOneProvidedOneMissed(t *testing.T) { 1524 type ( 1525 Foo struct { 1526 Name string `json:"n"` 1527 Value string `json:"v"` 1528 } 1529 1530 Bar struct { 1531 Foo `json:",optional"` 1532 } 1533 ) 1534 m := map[string]interface{}{ 1535 "v": "anything", 1536 } 1537 1538 var b Bar 1539 assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1540 } 1541 1542 func TestUnmarshalAnonymousOptionalRequiredBothMissed(t *testing.T) { 1543 type ( 1544 Foo struct { 1545 Name string `json:"n"` 1546 Value string `json:"v"` 1547 } 1548 1549 Bar struct { 1550 Foo `json:",optional"` 1551 } 1552 ) 1553 m := map[string]interface{}{} 1554 1555 var b Bar 1556 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1557 assert.True(t, len(b.Name) == 0) 1558 assert.True(t, len(b.Value) == 0) 1559 } 1560 1561 func TestUnmarshalAnonymousOptionalOneRequiredOneOptionalBothProvided(t *testing.T) { 1562 type ( 1563 Foo struct { 1564 Name string `json:"n,optional"` 1565 Value string `json:"v"` 1566 } 1567 1568 Bar struct { 1569 Foo `json:",optional"` 1570 } 1571 ) 1572 m := map[string]interface{}{ 1573 "n": "kevin", 1574 "v": "anything", 1575 } 1576 1577 var b Bar 1578 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1579 assert.Equal(t, "kevin", b.Name) 1580 assert.Equal(t, "anything", b.Value) 1581 } 1582 1583 func TestUnmarshalAnonymousOptionalOneRequiredOneOptionalBothMissed(t *testing.T) { 1584 type ( 1585 Foo struct { 1586 Name string `json:"n,optional"` 1587 Value string `json:"v"` 1588 } 1589 1590 Bar struct { 1591 Foo `json:",optional"` 1592 } 1593 ) 1594 m := map[string]interface{}{} 1595 1596 var b Bar 1597 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1598 assert.True(t, len(b.Name) == 0) 1599 assert.True(t, len(b.Value) == 0) 1600 } 1601 1602 func TestUnmarshalAnonymousOptionalOneRequiredOneOptionalRequiredProvidedOptionalMissed(t *testing.T) { 1603 type ( 1604 Foo struct { 1605 Name string `json:"n,optional"` 1606 Value string `json:"v"` 1607 } 1608 1609 Bar struct { 1610 Foo `json:",optional"` 1611 } 1612 ) 1613 m := map[string]interface{}{ 1614 "v": "anything", 1615 } 1616 1617 var b Bar 1618 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1619 assert.True(t, len(b.Name) == 0) 1620 assert.Equal(t, "anything", b.Value) 1621 } 1622 1623 func TestUnmarshalAnonymousOptionalOneRequiredOneOptionalRequiredMissedOptionalProvided(t *testing.T) { 1624 type ( 1625 Foo struct { 1626 Name string `json:"n,optional"` 1627 Value string `json:"v"` 1628 } 1629 1630 Bar struct { 1631 Foo `json:",optional"` 1632 } 1633 ) 1634 m := map[string]interface{}{ 1635 "n": "anything", 1636 } 1637 1638 var b Bar 1639 assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1640 } 1641 1642 func TestUnmarshalAnonymousOptionalBothOptionalBothProvided(t *testing.T) { 1643 type ( 1644 Foo struct { 1645 Name string `json:"n,optional"` 1646 Value string `json:"v,optional"` 1647 } 1648 1649 Bar struct { 1650 Foo `json:",optional"` 1651 } 1652 ) 1653 m := map[string]interface{}{ 1654 "n": "kevin", 1655 "v": "anything", 1656 } 1657 1658 var b Bar 1659 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1660 assert.Equal(t, "kevin", b.Name) 1661 assert.Equal(t, "anything", b.Value) 1662 } 1663 1664 func TestUnmarshalAnonymousOptionalBothOptionalOneProvidedOneMissed(t *testing.T) { 1665 type ( 1666 Foo struct { 1667 Name string `json:"n,optional"` 1668 Value string `json:"v,optional"` 1669 } 1670 1671 Bar struct { 1672 Foo `json:",optional"` 1673 } 1674 ) 1675 m := map[string]interface{}{ 1676 "v": "anything", 1677 } 1678 1679 var b Bar 1680 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1681 assert.True(t, len(b.Name) == 0) 1682 assert.Equal(t, "anything", b.Value) 1683 } 1684 1685 func TestUnmarshalAnonymousOptionalBothOptionalBothMissed(t *testing.T) { 1686 type ( 1687 Foo struct { 1688 Name string `json:"n,optional"` 1689 Value string `json:"v,optional"` 1690 } 1691 1692 Bar struct { 1693 Foo `json:",optional"` 1694 } 1695 ) 1696 m := map[string]interface{}{} 1697 1698 var b Bar 1699 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1700 assert.True(t, len(b.Name) == 0) 1701 assert.True(t, len(b.Value) == 0) 1702 } 1703 1704 func TestUnmarshalAnonymousRequiredProvided(t *testing.T) { 1705 type ( 1706 Foo struct { 1707 Value string `json:"v"` 1708 } 1709 1710 Bar struct { 1711 Foo 1712 } 1713 ) 1714 m := map[string]interface{}{ 1715 "v": "anything", 1716 } 1717 1718 var b Bar 1719 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1720 assert.Equal(t, "anything", b.Value) 1721 } 1722 1723 func TestUnmarshalAnonymousRequiredMissed(t *testing.T) { 1724 type ( 1725 Foo struct { 1726 Value string `json:"v"` 1727 } 1728 1729 Bar struct { 1730 Foo 1731 } 1732 ) 1733 m := map[string]interface{}{} 1734 1735 var b Bar 1736 assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1737 } 1738 1739 func TestUnmarshalAnonymousOptionalProvided(t *testing.T) { 1740 type ( 1741 Foo struct { 1742 Value string `json:"v,optional"` 1743 } 1744 1745 Bar struct { 1746 Foo 1747 } 1748 ) 1749 m := map[string]interface{}{ 1750 "v": "anything", 1751 } 1752 1753 var b Bar 1754 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1755 assert.Equal(t, "anything", b.Value) 1756 } 1757 1758 func TestUnmarshalAnonymousOptionalMissed(t *testing.T) { 1759 type ( 1760 Foo struct { 1761 Value string `json:"v,optional"` 1762 } 1763 1764 Bar struct { 1765 Foo 1766 } 1767 ) 1768 m := map[string]interface{}{} 1769 1770 var b Bar 1771 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1772 assert.True(t, len(b.Value) == 0) 1773 } 1774 1775 func TestUnmarshalAnonymousRequiredBothProvided(t *testing.T) { 1776 type ( 1777 Foo struct { 1778 Name string `json:"n"` 1779 Value string `json:"v"` 1780 } 1781 1782 Bar struct { 1783 Foo 1784 } 1785 ) 1786 m := map[string]interface{}{ 1787 "n": "kevin", 1788 "v": "anything", 1789 } 1790 1791 var b Bar 1792 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1793 assert.Equal(t, "kevin", b.Name) 1794 assert.Equal(t, "anything", b.Value) 1795 } 1796 1797 func TestUnmarshalAnonymousRequiredOneProvidedOneMissed(t *testing.T) { 1798 type ( 1799 Foo struct { 1800 Name string `json:"n"` 1801 Value string `json:"v"` 1802 } 1803 1804 Bar struct { 1805 Foo 1806 } 1807 ) 1808 m := map[string]interface{}{ 1809 "v": "anything", 1810 } 1811 1812 var b Bar 1813 assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1814 } 1815 1816 func TestUnmarshalAnonymousRequiredBothMissed(t *testing.T) { 1817 type ( 1818 Foo struct { 1819 Name string `json:"n"` 1820 Value string `json:"v"` 1821 } 1822 1823 Bar struct { 1824 Foo 1825 } 1826 ) 1827 m := map[string]interface{}{ 1828 "v": "anything", 1829 } 1830 1831 var b Bar 1832 assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1833 } 1834 1835 func TestUnmarshalAnonymousOneRequiredOneOptionalBothProvided(t *testing.T) { 1836 type ( 1837 Foo struct { 1838 Name string `json:"n,optional"` 1839 Value string `json:"v"` 1840 } 1841 1842 Bar struct { 1843 Foo 1844 } 1845 ) 1846 m := map[string]interface{}{ 1847 "n": "kevin", 1848 "v": "anything", 1849 } 1850 1851 var b Bar 1852 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1853 assert.Equal(t, "kevin", b.Name) 1854 assert.Equal(t, "anything", b.Value) 1855 } 1856 1857 func TestUnmarshalAnonymousOneRequiredOneOptionalBothMissed(t *testing.T) { 1858 type ( 1859 Foo struct { 1860 Name string `json:"n,optional"` 1861 Value string `json:"v"` 1862 } 1863 1864 Bar struct { 1865 Foo 1866 } 1867 ) 1868 m := map[string]interface{}{} 1869 1870 var b Bar 1871 assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1872 } 1873 1874 func TestUnmarshalAnonymousOneRequiredOneOptionalRequiredProvidedOptionalMissed(t *testing.T) { 1875 type ( 1876 Foo struct { 1877 Name string `json:"n,optional"` 1878 Value string `json:"v"` 1879 } 1880 1881 Bar struct { 1882 Foo 1883 } 1884 ) 1885 m := map[string]interface{}{ 1886 "v": "anything", 1887 } 1888 1889 var b Bar 1890 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1891 assert.True(t, len(b.Name) == 0) 1892 assert.Equal(t, "anything", b.Value) 1893 } 1894 1895 func TestUnmarshalAnonymousOneRequiredOneOptionalRequiredMissedOptionalProvided(t *testing.T) { 1896 type ( 1897 Foo struct { 1898 Name string `json:"n,optional"` 1899 Value string `json:"v"` 1900 } 1901 1902 Bar struct { 1903 Foo 1904 } 1905 ) 1906 m := map[string]interface{}{ 1907 "n": "anything", 1908 } 1909 1910 var b Bar 1911 assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1912 } 1913 1914 func TestUnmarshalAnonymousBothOptionalBothProvided(t *testing.T) { 1915 type ( 1916 Foo struct { 1917 Name string `json:"n,optional"` 1918 Value string `json:"v,optional"` 1919 } 1920 1921 Bar struct { 1922 Foo 1923 } 1924 ) 1925 m := map[string]interface{}{ 1926 "n": "kevin", 1927 "v": "anything", 1928 } 1929 1930 var b Bar 1931 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1932 assert.Equal(t, "kevin", b.Name) 1933 assert.Equal(t, "anything", b.Value) 1934 } 1935 1936 func TestUnmarshalAnonymousBothOptionalOneProvidedOneMissed(t *testing.T) { 1937 type ( 1938 Foo struct { 1939 Name string `json:"n,optional"` 1940 Value string `json:"v,optional"` 1941 } 1942 1943 Bar struct { 1944 Foo 1945 } 1946 ) 1947 m := map[string]interface{}{ 1948 "v": "anything", 1949 } 1950 1951 var b Bar 1952 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1953 assert.True(t, len(b.Name) == 0) 1954 assert.Equal(t, "anything", b.Value) 1955 } 1956 1957 func TestUnmarshalAnonymousBothOptionalBothMissed(t *testing.T) { 1958 type ( 1959 Foo struct { 1960 Name string `json:"n,optional"` 1961 Value string `json:"v,optional"` 1962 } 1963 1964 Bar struct { 1965 Foo 1966 } 1967 ) 1968 m := map[string]interface{}{} 1969 1970 var b Bar 1971 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1972 assert.True(t, len(b.Name) == 0) 1973 assert.True(t, len(b.Value) == 0) 1974 } 1975 1976 func TestUnmarshalAnonymousWrappedToMuch(t *testing.T) { 1977 type ( 1978 Foo struct { 1979 Name string `json:"n"` 1980 Value string `json:"v"` 1981 } 1982 1983 Bar struct { 1984 Foo 1985 } 1986 ) 1987 m := map[string]interface{}{ 1988 "Foo": map[string]interface{}{ 1989 "n": "name", 1990 "v": "anything", 1991 }, 1992 } 1993 1994 var b Bar 1995 assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 1996 } 1997 1998 func TestUnmarshalWrappedObject(t *testing.T) { 1999 type ( 2000 Foo struct { 2001 Value string `json:"v"` 2002 } 2003 2004 Bar struct { 2005 Inner Foo 2006 } 2007 ) 2008 m := map[string]interface{}{ 2009 "Inner": map[string]interface{}{ 2010 "v": "anything", 2011 }, 2012 } 2013 2014 var b Bar 2015 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 2016 assert.Equal(t, "anything", b.Inner.Value) 2017 } 2018 2019 func TestUnmarshalWrappedObjectOptional(t *testing.T) { 2020 type ( 2021 Foo struct { 2022 Hosts []string 2023 Key string 2024 } 2025 2026 Bar struct { 2027 Inner Foo `json:",optional"` 2028 Name string 2029 } 2030 ) 2031 m := map[string]interface{}{ 2032 "Name": "anything", 2033 } 2034 2035 var b Bar 2036 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 2037 assert.Equal(t, "anything", b.Name) 2038 } 2039 2040 func TestUnmarshalWrappedObjectOptionalFilled(t *testing.T) { 2041 type ( 2042 Foo struct { 2043 Hosts []string 2044 Key string 2045 } 2046 2047 Bar struct { 2048 Inner Foo `json:",optional"` 2049 Name string 2050 } 2051 ) 2052 hosts := []string{"1", "2"} 2053 m := map[string]interface{}{ 2054 "Inner": map[string]interface{}{ 2055 "Hosts": hosts, 2056 "Key": "key", 2057 }, 2058 "Name": "anything", 2059 } 2060 2061 var b Bar 2062 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 2063 assert.EqualValues(t, hosts, b.Inner.Hosts) 2064 assert.Equal(t, "key", b.Inner.Key) 2065 assert.Equal(t, "anything", b.Name) 2066 } 2067 2068 func TestUnmarshalWrappedNamedObjectOptional(t *testing.T) { 2069 type ( 2070 Foo struct { 2071 Host string 2072 Key string 2073 } 2074 2075 Bar struct { 2076 Inner Foo `json:",optional"` 2077 Name string 2078 } 2079 ) 2080 m := map[string]interface{}{ 2081 "Inner": map[string]interface{}{ 2082 "Host": "thehost", 2083 "Key": "thekey", 2084 }, 2085 "Name": "anything", 2086 } 2087 2088 var b Bar 2089 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 2090 assert.Equal(t, "thehost", b.Inner.Host) 2091 assert.Equal(t, "thekey", b.Inner.Key) 2092 assert.Equal(t, "anything", b.Name) 2093 } 2094 2095 func TestUnmarshalWrappedObjectNamedPtr(t *testing.T) { 2096 type ( 2097 Foo struct { 2098 Value string `json:"v"` 2099 } 2100 2101 Bar struct { 2102 Inner *Foo `json:"foo,optional"` 2103 } 2104 ) 2105 m := map[string]interface{}{ 2106 "foo": map[string]interface{}{ 2107 "v": "anything", 2108 }, 2109 } 2110 2111 var b Bar 2112 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 2113 assert.Equal(t, "anything", b.Inner.Value) 2114 } 2115 2116 func TestUnmarshalWrappedObjectPtr(t *testing.T) { 2117 type ( 2118 Foo struct { 2119 Value string `json:"v"` 2120 } 2121 2122 Bar struct { 2123 Inner *Foo 2124 } 2125 ) 2126 m := map[string]interface{}{ 2127 "Inner": map[string]interface{}{ 2128 "v": "anything", 2129 }, 2130 } 2131 2132 var b Bar 2133 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b)) 2134 assert.Equal(t, "anything", b.Inner.Value) 2135 } 2136 2137 func TestUnmarshalInt2String(t *testing.T) { 2138 type inner struct { 2139 Int string `key:"int"` 2140 } 2141 m := map[string]interface{}{ 2142 "int": 123, 2143 } 2144 2145 var in inner 2146 assert.NotNil(t, UnmarshalKey(m, &in)) 2147 } 2148 2149 func TestUnmarshalZeroValues(t *testing.T) { 2150 type inner struct { 2151 False bool `key:"no"` 2152 Int int `key:"int"` 2153 String string `key:"string"` 2154 } 2155 m := map[string]interface{}{ 2156 "no": false, 2157 "int": 0, 2158 "string": "", 2159 } 2160 2161 var in inner 2162 ast := assert.New(t) 2163 ast.Nil(UnmarshalKey(m, &in)) 2164 ast.False(in.False) 2165 ast.Equal(0, in.Int) 2166 ast.Equal("", in.String) 2167 } 2168 2169 func TestUnmarshalUsingDifferentKeys(t *testing.T) { 2170 type inner struct { 2171 False bool `key:"no"` 2172 Int int `key:"int"` 2173 String string `bson:"string"` 2174 } 2175 m := map[string]interface{}{ 2176 "no": false, 2177 "int": 9, 2178 "string": "value", 2179 } 2180 2181 var in inner 2182 ast := assert.New(t) 2183 ast.Nil(UnmarshalKey(m, &in)) 2184 ast.False(in.False) 2185 ast.Equal(9, in.Int) 2186 ast.True(len(in.String) == 0) 2187 } 2188 2189 func TestUnmarshalNumberRangeInt(t *testing.T) { 2190 type inner struct { 2191 Value1 int `key:"value1,range=[1:]"` 2192 Value2 int8 `key:"value2,range=[1:5]"` 2193 Value3 int16 `key:"value3,range=[1:5]"` 2194 Value4 int32 `key:"value4,range=[1:5]"` 2195 Value5 int64 `key:"value5,range=[1:5]"` 2196 Value6 uint `key:"value6,range=[:5]"` 2197 Value8 uint8 `key:"value8,range=[1:5],string"` 2198 Value9 uint16 `key:"value9,range=[1:5],string"` 2199 Value10 uint32 `key:"value10,range=[1:5],string"` 2200 Value11 uint64 `key:"value11,range=[1:5],string"` 2201 } 2202 m := map[string]interface{}{ 2203 "value1": 10, 2204 "value2": int8(1), 2205 "value3": int16(2), 2206 "value4": int32(4), 2207 "value5": int64(5), 2208 "value6": uint(0), 2209 "value8": "1", 2210 "value9": "2", 2211 "value10": "4", 2212 "value11": "5", 2213 } 2214 2215 var in inner 2216 ast := assert.New(t) 2217 ast.Nil(UnmarshalKey(m, &in)) 2218 ast.Equal(10, in.Value1) 2219 ast.Equal(int8(1), in.Value2) 2220 ast.Equal(int16(2), in.Value3) 2221 ast.Equal(int32(4), in.Value4) 2222 ast.Equal(int64(5), in.Value5) 2223 ast.Equal(uint(0), in.Value6) 2224 ast.Equal(uint8(1), in.Value8) 2225 ast.Equal(uint16(2), in.Value9) 2226 ast.Equal(uint32(4), in.Value10) 2227 ast.Equal(uint64(5), in.Value11) 2228 } 2229 2230 func TestUnmarshalNumberRangeJsonNumber(t *testing.T) { 2231 type inner struct { 2232 Value3 uint `key:"value3,range=(1:5]"` 2233 Value4 uint8 `key:"value4,range=(1:5]"` 2234 Value5 uint16 `key:"value5,range=(1:5]"` 2235 } 2236 m := map[string]interface{}{ 2237 "value3": json.Number("2"), 2238 "value4": json.Number("4"), 2239 "value5": json.Number("5"), 2240 } 2241 2242 var in inner 2243 ast := assert.New(t) 2244 ast.Nil(UnmarshalKey(m, &in)) 2245 ast.Equal(uint(2), in.Value3) 2246 ast.Equal(uint8(4), in.Value4) 2247 ast.Equal(uint16(5), in.Value5) 2248 2249 type inner1 struct { 2250 Value int `key:"value,range=(1:5]"` 2251 } 2252 m = map[string]interface{}{ 2253 "value": json.Number("a"), 2254 } 2255 2256 var in1 inner1 2257 ast.NotNil(UnmarshalKey(m, &in1)) 2258 } 2259 2260 func TestUnmarshalNumberRangeIntLeftExclude(t *testing.T) { 2261 type inner struct { 2262 Value3 uint `key:"value3,range=(1:5]"` 2263 Value4 uint32 `key:"value4,default=4,range=(1:5]"` 2264 Value5 uint64 `key:"value5,range=(1:5]"` 2265 Value9 int `key:"value9,range=(1:5],string"` 2266 Value10 int `key:"value10,range=(1:5],string"` 2267 Value11 int `key:"value11,range=(1:5],string"` 2268 } 2269 m := map[string]interface{}{ 2270 "value3": uint(2), 2271 "value4": uint32(4), 2272 "value5": uint64(5), 2273 "value9": "2", 2274 "value10": "4", 2275 "value11": "5", 2276 } 2277 2278 var in inner 2279 ast := assert.New(t) 2280 ast.Nil(UnmarshalKey(m, &in)) 2281 ast.Equal(uint(2), in.Value3) 2282 ast.Equal(uint32(4), in.Value4) 2283 ast.Equal(uint64(5), in.Value5) 2284 ast.Equal(2, in.Value9) 2285 ast.Equal(4, in.Value10) 2286 ast.Equal(5, in.Value11) 2287 } 2288 2289 func TestUnmarshalNumberRangeIntRightExclude(t *testing.T) { 2290 type inner struct { 2291 Value2 uint `key:"value2,range=[1:5)"` 2292 Value3 uint8 `key:"value3,range=[1:5)"` 2293 Value4 uint16 `key:"value4,range=[1:5)"` 2294 Value8 int `key:"value8,range=[1:5),string"` 2295 Value9 int `key:"value9,range=[1:5),string"` 2296 Value10 int `key:"value10,range=[1:5),string"` 2297 } 2298 m := map[string]interface{}{ 2299 "value2": uint(1), 2300 "value3": uint8(2), 2301 "value4": uint16(4), 2302 "value8": "1", 2303 "value9": "2", 2304 "value10": "4", 2305 } 2306 2307 var in inner 2308 ast := assert.New(t) 2309 ast.Nil(UnmarshalKey(m, &in)) 2310 ast.Equal(uint(1), in.Value2) 2311 ast.Equal(uint8(2), in.Value3) 2312 ast.Equal(uint16(4), in.Value4) 2313 ast.Equal(1, in.Value8) 2314 ast.Equal(2, in.Value9) 2315 ast.Equal(4, in.Value10) 2316 } 2317 2318 func TestUnmarshalNumberRangeIntExclude(t *testing.T) { 2319 type inner struct { 2320 Value3 int `key:"value3,range=(1:5)"` 2321 Value4 int `key:"value4,range=(1:5)"` 2322 Value9 int `key:"value9,range=(1:5),string"` 2323 Value10 int `key:"value10,range=(1:5),string"` 2324 } 2325 m := map[string]interface{}{ 2326 "value3": 2, 2327 "value4": 4, 2328 "value9": "2", 2329 "value10": "4", 2330 } 2331 2332 var in inner 2333 ast := assert.New(t) 2334 ast.Nil(UnmarshalKey(m, &in)) 2335 ast.Equal(2, in.Value3) 2336 ast.Equal(4, in.Value4) 2337 ast.Equal(2, in.Value9) 2338 ast.Equal(4, in.Value10) 2339 } 2340 2341 func TestUnmarshalNumberRangeIntOutOfRange(t *testing.T) { 2342 type inner1 struct { 2343 Value int64 `key:"value,default=3,range=(1:5)"` 2344 } 2345 2346 var in1 inner1 2347 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2348 "value": int64(1), 2349 }, &in1)) 2350 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2351 "value": int64(0), 2352 }, &in1)) 2353 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2354 "value": int64(5), 2355 }, &in1)) 2356 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2357 "value": json.Number("6"), 2358 }, &in1)) 2359 2360 type inner2 struct { 2361 Value int64 `key:"value,optional,range=[1:5)"` 2362 } 2363 2364 var in2 inner2 2365 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2366 "value": int64(0), 2367 }, &in2)) 2368 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2369 "value": int64(5), 2370 }, &in2)) 2371 2372 type inner3 struct { 2373 Value int64 `key:"value,range=(1:5]"` 2374 } 2375 2376 var in3 inner3 2377 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2378 "value": int64(1), 2379 }, &in3)) 2380 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2381 "value": int64(6), 2382 }, &in3)) 2383 2384 type inner4 struct { 2385 Value int64 `key:"value,range=[1:5]"` 2386 } 2387 2388 var in4 inner4 2389 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2390 "value": int64(0), 2391 }, &in4)) 2392 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2393 "value": int64(6), 2394 }, &in4)) 2395 } 2396 2397 func TestUnmarshalNumberRangeFloat(t *testing.T) { 2398 type inner struct { 2399 Value2 float32 `key:"value2,range=[1:5]"` 2400 Value3 float32 `key:"value3,range=[1:5]"` 2401 Value4 float64 `key:"value4,range=[1:5]"` 2402 Value5 float64 `key:"value5,range=[1:5]"` 2403 Value8 float64 `key:"value8,range=[1:5],string"` 2404 Value9 float64 `key:"value9,range=[1:5],string"` 2405 Value10 float64 `key:"value10,range=[1:5],string"` 2406 Value11 float64 `key:"value11,range=[1:5],string"` 2407 } 2408 m := map[string]interface{}{ 2409 "value2": float32(1), 2410 "value3": float32(2), 2411 "value4": float64(4), 2412 "value5": float64(5), 2413 "value8": "1", 2414 "value9": "2", 2415 "value10": "4", 2416 "value11": "5", 2417 } 2418 2419 var in inner 2420 ast := assert.New(t) 2421 ast.Nil(UnmarshalKey(m, &in)) 2422 ast.Equal(float32(1), in.Value2) 2423 ast.Equal(float32(2), in.Value3) 2424 ast.Equal(float64(4), in.Value4) 2425 ast.Equal(float64(5), in.Value5) 2426 ast.Equal(float64(1), in.Value8) 2427 ast.Equal(float64(2), in.Value9) 2428 ast.Equal(float64(4), in.Value10) 2429 ast.Equal(float64(5), in.Value11) 2430 } 2431 2432 func TestUnmarshalNumberRangeFloatLeftExclude(t *testing.T) { 2433 type inner struct { 2434 Value3 float64 `key:"value3,range=(1:5]"` 2435 Value4 float64 `key:"value4,range=(1:5]"` 2436 Value5 float64 `key:"value5,range=(1:5]"` 2437 Value9 float64 `key:"value9,range=(1:5],string"` 2438 Value10 float64 `key:"value10,range=(1:5],string"` 2439 Value11 float64 `key:"value11,range=(1:5],string"` 2440 } 2441 m := map[string]interface{}{ 2442 "value3": float64(2), 2443 "value4": float64(4), 2444 "value5": float64(5), 2445 "value9": "2", 2446 "value10": "4", 2447 "value11": "5", 2448 } 2449 2450 var in inner 2451 ast := assert.New(t) 2452 ast.Nil(UnmarshalKey(m, &in)) 2453 ast.Equal(float64(2), in.Value3) 2454 ast.Equal(float64(4), in.Value4) 2455 ast.Equal(float64(5), in.Value5) 2456 ast.Equal(float64(2), in.Value9) 2457 ast.Equal(float64(4), in.Value10) 2458 ast.Equal(float64(5), in.Value11) 2459 } 2460 2461 func TestUnmarshalNumberRangeFloatRightExclude(t *testing.T) { 2462 type inner struct { 2463 Value2 float64 `key:"value2,range=[1:5)"` 2464 Value3 float64 `key:"value3,range=[1:5)"` 2465 Value4 float64 `key:"value4,range=[1:5)"` 2466 Value8 float64 `key:"value8,range=[1:5),string"` 2467 Value9 float64 `key:"value9,range=[1:5),string"` 2468 Value10 float64 `key:"value10,range=[1:5),string"` 2469 } 2470 m := map[string]interface{}{ 2471 "value2": float64(1), 2472 "value3": float64(2), 2473 "value4": float64(4), 2474 "value8": "1", 2475 "value9": "2", 2476 "value10": "4", 2477 } 2478 2479 var in inner 2480 ast := assert.New(t) 2481 ast.Nil(UnmarshalKey(m, &in)) 2482 ast.Equal(float64(1), in.Value2) 2483 ast.Equal(float64(2), in.Value3) 2484 ast.Equal(float64(4), in.Value4) 2485 ast.Equal(float64(1), in.Value8) 2486 ast.Equal(float64(2), in.Value9) 2487 ast.Equal(float64(4), in.Value10) 2488 } 2489 2490 func TestUnmarshalNumberRangeFloatExclude(t *testing.T) { 2491 type inner struct { 2492 Value3 float64 `key:"value3,range=(1:5)"` 2493 Value4 float64 `key:"value4,range=(1:5)"` 2494 Value9 float64 `key:"value9,range=(1:5),string"` 2495 Value10 float64 `key:"value10,range=(1:5),string"` 2496 } 2497 m := map[string]interface{}{ 2498 "value3": float64(2), 2499 "value4": float64(4), 2500 "value9": "2", 2501 "value10": "4", 2502 } 2503 2504 var in inner 2505 ast := assert.New(t) 2506 ast.Nil(UnmarshalKey(m, &in)) 2507 ast.Equal(float64(2), in.Value3) 2508 ast.Equal(float64(4), in.Value4) 2509 ast.Equal(float64(2), in.Value9) 2510 ast.Equal(float64(4), in.Value10) 2511 } 2512 2513 func TestUnmarshalNumberRangeFloatOutOfRange(t *testing.T) { 2514 type inner1 struct { 2515 Value float64 `key:"value,range=(1:5)"` 2516 } 2517 2518 var in1 inner1 2519 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2520 "value": float64(1), 2521 }, &in1)) 2522 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2523 "value": float64(0), 2524 }, &in1)) 2525 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2526 "value": float64(5), 2527 }, &in1)) 2528 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2529 "value": json.Number("6"), 2530 }, &in1)) 2531 2532 type inner2 struct { 2533 Value float64 `key:"value,range=[1:5)"` 2534 } 2535 2536 var in2 inner2 2537 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2538 "value": float64(0), 2539 }, &in2)) 2540 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2541 "value": float64(5), 2542 }, &in2)) 2543 2544 type inner3 struct { 2545 Value float64 `key:"value,range=(1:5]"` 2546 } 2547 2548 var in3 inner3 2549 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2550 "value": float64(1), 2551 }, &in3)) 2552 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2553 "value": float64(6), 2554 }, &in3)) 2555 2556 type inner4 struct { 2557 Value float64 `key:"value,range=[1:5]"` 2558 } 2559 2560 var in4 inner4 2561 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2562 "value": float64(0), 2563 }, &in4)) 2564 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2565 "value": float64(6), 2566 }, &in4)) 2567 } 2568 2569 func TestUnmarshalRangeError(t *testing.T) { 2570 type inner1 struct { 2571 Value int `key:",range="` 2572 } 2573 var in1 inner1 2574 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2575 "Value": 1, 2576 }, &in1)) 2577 2578 type inner2 struct { 2579 Value int `key:",range=["` 2580 } 2581 var in2 inner2 2582 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2583 "Value": 1, 2584 }, &in2)) 2585 2586 type inner3 struct { 2587 Value int `key:",range=[:"` 2588 } 2589 var in3 inner3 2590 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2591 "Value": 1, 2592 }, &in3)) 2593 2594 type inner4 struct { 2595 Value int `key:",range=[:]"` 2596 } 2597 var in4 inner4 2598 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2599 "Value": 1, 2600 }, &in4)) 2601 2602 type inner5 struct { 2603 Value int `key:",range={:]"` 2604 } 2605 var in5 inner5 2606 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2607 "Value": 1, 2608 }, &in5)) 2609 2610 type inner6 struct { 2611 Value int `key:",range=[:}"` 2612 } 2613 var in6 inner6 2614 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2615 "Value": 1, 2616 }, &in6)) 2617 2618 type inner7 struct { 2619 Value int `key:",range=[]"` 2620 } 2621 var in7 inner7 2622 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2623 "Value": 1, 2624 }, &in7)) 2625 2626 type inner8 struct { 2627 Value int `key:",range=[a:]"` 2628 } 2629 var in8 inner8 2630 assert.NotNil(t, UnmarshalKey(map[string]interface{}{ 2631 "Value": 1, 2632 }, &in8)) 2633 2634 type inner9 struct { 2635 Value int `key:",range=[:a]"` 2636 } 2637 var in9 inner9 2638 assert.NotNil(t, UnmarshalKey(map[string]interface{}{ 2639 "Value": 1, 2640 }, &in9)) 2641 2642 type inner10 struct { 2643 Value int `key:",range"` 2644 } 2645 var in10 inner10 2646 assert.NotNil(t, UnmarshalKey(map[string]interface{}{ 2647 "Value": 1, 2648 }, &in10)) 2649 2650 type inner11 struct { 2651 Value int `key:",range=[1,2]"` 2652 } 2653 var in11 inner11 2654 assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{ 2655 "Value": "a", 2656 }, &in11)) 2657 } 2658 2659 func TestUnmarshalNestedMap(t *testing.T) { 2660 var c struct { 2661 Anything map[string]map[string]string `json:"anything"` 2662 } 2663 m := map[string]interface{}{ 2664 "anything": map[string]map[string]interface{}{ 2665 "inner": { 2666 "id": "1", 2667 "name": "any", 2668 }, 2669 }, 2670 } 2671 2672 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c)) 2673 assert.Equal(t, "1", c.Anything["inner"]["id"]) 2674 } 2675 2676 func TestUnmarshalNestedMapMismatch(t *testing.T) { 2677 var c struct { 2678 Anything map[string]map[string]map[string]string `json:"anything"` 2679 } 2680 m := map[string]interface{}{ 2681 "anything": map[string]map[string]interface{}{ 2682 "inner": { 2683 "name": "any", 2684 }, 2685 }, 2686 } 2687 2688 assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &c)) 2689 } 2690 2691 func TestUnmarshalNestedMapSimple(t *testing.T) { 2692 var c struct { 2693 Anything map[string]string `json:"anything"` 2694 } 2695 m := map[string]interface{}{ 2696 "anything": map[string]interface{}{ 2697 "id": "1", 2698 "name": "any", 2699 }, 2700 } 2701 2702 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c)) 2703 assert.Equal(t, "1", c.Anything["id"]) 2704 } 2705 2706 func TestUnmarshalNestedMapSimpleTypeMatch(t *testing.T) { 2707 var c struct { 2708 Anything map[string]string `json:"anything"` 2709 } 2710 m := map[string]interface{}{ 2711 "anything": map[string]string{ 2712 "id": "1", 2713 "name": "any", 2714 }, 2715 } 2716 2717 assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c)) 2718 assert.Equal(t, "1", c.Anything["id"]) 2719 } 2720 2721 func TestUnmarshalValuer(t *testing.T) { 2722 unmarshaler := NewUnmarshaler(jsonTagKey) 2723 var foo string 2724 err := unmarshaler.UnmarshalValuer(nil, foo) 2725 assert.NotNil(t, err) 2726 } 2727 2728 func BenchmarkUnmarshalString(b *testing.B) { 2729 type inner struct { 2730 Value string `key:"value"` 2731 } 2732 m := map[string]interface{}{ 2733 "value": "first", 2734 } 2735 2736 for i := 0; i < b.N; i++ { 2737 var in inner 2738 if err := UnmarshalKey(m, &in); err != nil { 2739 b.Fatal(err) 2740 } 2741 } 2742 } 2743 2744 func BenchmarkUnmarshalStruct(b *testing.B) { 2745 b.ReportAllocs() 2746 2747 m := map[string]interface{}{ 2748 "Ids": []map[string]interface{}{ 2749 { 2750 "First": 1, 2751 "Second": 2, 2752 }, 2753 }, 2754 } 2755 2756 for i := 0; i < b.N; i++ { 2757 var v struct { 2758 Ids []struct { 2759 First int 2760 Second int 2761 } 2762 } 2763 if err := UnmarshalKey(m, &v); err != nil { 2764 b.Fatal(err) 2765 } 2766 } 2767 } 2768 2769 func BenchmarkMapToStruct(b *testing.B) { 2770 data := map[string]interface{}{ 2771 "valid": "1", 2772 "age": "5", 2773 "name": "liao", 2774 } 2775 type anonymous struct { 2776 Valid bool 2777 Age int 2778 Name string 2779 } 2780 2781 for i := 0; i < b.N; i++ { 2782 var an anonymous 2783 if valid, ok := data["valid"]; ok { 2784 an.Valid = valid == "1" 2785 } 2786 if age, ok := data["age"]; ok { 2787 ages, _ := age.(string) 2788 an.Age, _ = strconv.Atoi(ages) 2789 } 2790 if name, ok := data["name"]; ok { 2791 names, _ := name.(string) 2792 an.Name = names 2793 } 2794 } 2795 } 2796 2797 func BenchmarkUnmarshal(b *testing.B) { 2798 data := map[string]interface{}{ 2799 "valid": "1", 2800 "age": "5", 2801 "name": "liao", 2802 } 2803 type anonymous struct { 2804 Valid bool `key:"valid,string"` 2805 Age int `key:"age,string"` 2806 Name string `key:"name"` 2807 } 2808 2809 for i := 0; i < b.N; i++ { 2810 var an anonymous 2811 UnmarshalKey(data, &an) 2812 } 2813 } 2814 2815 func TestUnmarshalJsonReaderMultiArray(t *testing.T) { 2816 payload := `{"a": "133", "b": [["add", "cccd"], ["eeee"]]}` 2817 var res struct { 2818 A string `json:"a"` 2819 B [][]string `json:"b"` 2820 } 2821 reader := strings.NewReader(payload) 2822 err := UnmarshalJsonReader(reader, &res) 2823 assert.Nil(t, err) 2824 assert.Equal(t, 2, len(res.B)) 2825 } 2826 2827 func TestUnmarshalJsonReaderPtrMultiArrayString(t *testing.T) { 2828 payload := `{"a": "133", "b": [["add", "cccd"], ["eeee"]]}` 2829 var res struct { 2830 A string `json:"a"` 2831 B [][]*string `json:"b"` 2832 } 2833 reader := strings.NewReader(payload) 2834 err := UnmarshalJsonReader(reader, &res) 2835 assert.Nil(t, err) 2836 assert.Equal(t, 2, len(res.B)) 2837 assert.Equal(t, 2, len(res.B[0])) 2838 } 2839 2840 func TestUnmarshalJsonReaderPtrMultiArrayString_Int(t *testing.T) { 2841 payload := `{"a": "133", "b": [[11, 22], [33]]}` 2842 var res struct { 2843 A string `json:"a"` 2844 B [][]*string `json:"b"` 2845 } 2846 reader := strings.NewReader(payload) 2847 err := UnmarshalJsonReader(reader, &res) 2848 assert.Nil(t, err) 2849 assert.Equal(t, 2, len(res.B)) 2850 assert.Equal(t, 2, len(res.B[0])) 2851 } 2852 2853 func TestUnmarshalJsonReaderPtrMultiArrayInt(t *testing.T) { 2854 payload := `{"a": "133", "b": [[11, 22], [33]]}` 2855 var res struct { 2856 A string `json:"a"` 2857 B [][]*int `json:"b"` 2858 } 2859 reader := strings.NewReader(payload) 2860 err := UnmarshalJsonReader(reader, &res) 2861 assert.Nil(t, err) 2862 assert.Equal(t, 2, len(res.B)) 2863 assert.Equal(t, 2, len(res.B[0])) 2864 } 2865 2866 func TestUnmarshalJsonReaderPtrArray(t *testing.T) { 2867 payload := `{"a": "133", "b": ["add", "cccd", "eeee"]}` 2868 var res struct { 2869 A string `json:"a"` 2870 B []*string `json:"b"` 2871 } 2872 reader := strings.NewReader(payload) 2873 err := UnmarshalJsonReader(reader, &res) 2874 assert.Nil(t, err) 2875 assert.Equal(t, 3, len(res.B)) 2876 } 2877 2878 func TestUnmarshalJsonReaderPtrArray_Int(t *testing.T) { 2879 payload := `{"a": "133", "b": [11, 22, 33]}` 2880 var res struct { 2881 A string `json:"a"` 2882 B []*string `json:"b"` 2883 } 2884 reader := strings.NewReader(payload) 2885 err := UnmarshalJsonReader(reader, &res) 2886 assert.Nil(t, err) 2887 assert.Equal(t, 3, len(res.B)) 2888 } 2889 2890 func TestUnmarshalJsonReaderPtrInt(t *testing.T) { 2891 payload := `{"a": "133", "b": [11, 22, 33]}` 2892 var res struct { 2893 A string `json:"a"` 2894 B []*string `json:"b"` 2895 } 2896 reader := strings.NewReader(payload) 2897 err := UnmarshalJsonReader(reader, &res) 2898 assert.Nil(t, err) 2899 assert.Equal(t, 3, len(res.B)) 2900 } 2901 2902 func TestUnmarshalJsonWithoutKey(t *testing.T) { 2903 payload := `{"A": "1", "B": "2"}` 2904 var res struct { 2905 A string `json:""` 2906 B string `json:","` 2907 } 2908 reader := strings.NewReader(payload) 2909 err := UnmarshalJsonReader(reader, &res) 2910 assert.Nil(t, err) 2911 assert.Equal(t, "1", res.A) 2912 assert.Equal(t, "2", res.B) 2913 } 2914 2915 func TestUnmarshalJsonUintNegative(t *testing.T) { 2916 payload := `{"a": -1}` 2917 var res struct { 2918 A uint `json:"a"` 2919 } 2920 reader := strings.NewReader(payload) 2921 err := UnmarshalJsonReader(reader, &res) 2922 assert.NotNil(t, err) 2923 } 2924 2925 func TestUnmarshalJsonDefinedInt(t *testing.T) { 2926 type Int int 2927 var res struct { 2928 A Int `json:"a"` 2929 } 2930 payload := `{"a": -1}` 2931 reader := strings.NewReader(payload) 2932 err := UnmarshalJsonReader(reader, &res) 2933 assert.Nil(t, err) 2934 assert.Equal(t, Int(-1), res.A) 2935 } 2936 2937 func TestUnmarshalJsonDefinedString(t *testing.T) { 2938 type String string 2939 var res struct { 2940 A String `json:"a"` 2941 } 2942 payload := `{"a": "foo"}` 2943 reader := strings.NewReader(payload) 2944 err := UnmarshalJsonReader(reader, &res) 2945 assert.Nil(t, err) 2946 assert.Equal(t, String("foo"), res.A) 2947 } 2948 2949 func TestUnmarshalJsonDefinedStringPtr(t *testing.T) { 2950 type String string 2951 var res struct { 2952 A *String `json:"a"` 2953 } 2954 payload := `{"a": "foo"}` 2955 reader := strings.NewReader(payload) 2956 err := UnmarshalJsonReader(reader, &res) 2957 assert.Nil(t, err) 2958 assert.Equal(t, String("foo"), *res.A) 2959 } 2960 2961 func TestUnmarshalJsonReaderComplex(t *testing.T) { 2962 type ( 2963 MyInt int 2964 MyTxt string 2965 MyTxtArray []string 2966 2967 Req struct { 2968 MyInt MyInt `json:"my_int"` // int.. ok 2969 MyTxtArray MyTxtArray `json:"my_txt_array"` 2970 MyTxt MyTxt `json:"my_txt"` // but string is not assignable 2971 Int int `json:"int"` 2972 Txt string `json:"txt"` 2973 } 2974 ) 2975 body := `{ 2976 "my_int": 100, 2977 "my_txt_array": [ 2978 "a", 2979 "b" 2980 ], 2981 "my_txt": "my_txt", 2982 "int": 200, 2983 "txt": "txt" 2984 }` 2985 var req Req 2986 err := UnmarshalJsonReader(strings.NewReader(body), &req) 2987 assert.Nil(t, err) 2988 assert.Equal(t, MyInt(100), req.MyInt) 2989 assert.Equal(t, MyTxt("my_txt"), req.MyTxt) 2990 assert.EqualValues(t, MyTxtArray([]string{"a", "b"}), req.MyTxtArray) 2991 assert.Equal(t, 200, req.Int) 2992 assert.Equal(t, "txt", req.Txt) 2993 } 2994 2995 func TestUnmarshalJsonReaderArrayBool(t *testing.T) { 2996 payload := `{"id": false}` 2997 var res struct { 2998 ID []string `json:"id"` 2999 } 3000 reader := strings.NewReader(payload) 3001 err := UnmarshalJsonReader(reader, &res) 3002 assert.NotNil(t, err) 3003 } 3004 3005 func TestUnmarshalJsonReaderArrayInt(t *testing.T) { 3006 payload := `{"id": 123}` 3007 var res struct { 3008 ID []string `json:"id"` 3009 } 3010 reader := strings.NewReader(payload) 3011 err := UnmarshalJsonReader(reader, &res) 3012 assert.NotNil(t, err) 3013 } 3014 3015 func TestUnmarshalJsonReaderArrayString(t *testing.T) { 3016 payload := `{"id": "123"}` 3017 var res struct { 3018 ID []string `json:"id"` 3019 } 3020 reader := strings.NewReader(payload) 3021 err := UnmarshalJsonReader(reader, &res) 3022 assert.NotNil(t, err) 3023 } 3024 3025 func TestGoogleUUID(t *testing.T) { 3026 var val struct { 3027 Uid uuid.UUID `json:"uid,optional"` 3028 Uidp *uuid.UUID `json:"uidp,optional"` 3029 } 3030 assert.NoError(t, UnmarshalJsonBytes([]byte(`{ 3031 "uid": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", 3032 "uidp": "6ba7b810-9dad-11d1-80b4-00c04fd430c9"}`), &val)) 3033 assert.Equal(t, "6ba7b810-9dad-11d1-80b4-00c04fd430c8", val.Uid.String()) 3034 assert.Equal(t, "6ba7b810-9dad-11d1-80b4-00c04fd430c9", val.Uidp.String()) 3035 assert.NoError(t, UnmarshalJsonMap(map[string]interface{}{ 3036 "uid": []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c1"), 3037 "uidp": []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c2"), 3038 }, &val)) 3039 assert.Equal(t, "6ba7b810-9dad-11d1-80b4-00c04fd430c1", val.Uid.String()) 3040 assert.Equal(t, "6ba7b810-9dad-11d1-80b4-00c04fd430c2", val.Uidp.String()) 3041 } 3042 3043 func BenchmarkDefaultValue(b *testing.B) { 3044 for i := 0; i < b.N; i++ { 3045 var a struct { 3046 Ints []int `json:"ints,default=[1,2,3]"` 3047 Strs []string `json:"strs,default=[foo,bar,baz]"` 3048 } 3049 _ = UnmarshalJsonMap(nil, &a) 3050 if len(a.Strs) != 3 || len(a.Ints) != 3 { 3051 b.Fatal("failed") 3052 } 3053 } 3054 }