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