github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/yaml/decode_test.go (about) 1 package yaml_test 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "io" 8 "log" 9 "math" 10 "net" 11 "reflect" 12 "strconv" 13 "strings" 14 "testing" 15 "time" 16 17 "github.com/bingoohuang/gg/pkg/man" 18 "github.com/bingoohuang/gg/pkg/yaml" 19 "github.com/bingoohuang/gg/pkg/yaml/ast" 20 "github.com/bingoohuang/gg/pkg/yaml/internal/errors" 21 "github.com/bingoohuang/gg/pkg/yaml/parser" 22 "github.com/stretchr/testify/assert" 23 "golang.org/x/xerrors" 24 ) 25 26 type UseFieldName struct { 27 Size int64 28 } 29 30 func TestUseFieldName(t *testing.T) { 31 c := UseFieldName{} 32 decoder := yaml.NewDecoder(strings.NewReader(`Size: 10`)) 33 err := decoder.Decode(&c) 34 assert.Nil(t, err) 35 assert.Equal(t, UseFieldName{Size: 10}, c) 36 37 var buf bytes.Buffer 38 err = yaml.NewEncoder(&buf, yaml.KeyNaming(yaml.KeyNamingRaw)).Encode(c) 39 assert.Nil(t, err) 40 assert.Equal(t, "Size: 10\n", buf.String()) 41 } 42 43 type Duration struct { 44 Dur time.Duration 45 } 46 47 func decodeDuration(node ast.Node, typ reflect.Type) (reflect.Value, error) { 48 if v, ok := node.(*ast.StringNode); ok { 49 d, err := time.ParseDuration(v.Value) 50 return reflect.ValueOf(d), err 51 } 52 if v, ok := node.(*ast.IntegerNode); ok { 53 if i, ok1 := v.Value.(int64); ok1 { 54 return reflect.ValueOf(time.Duration(i)), nil 55 } else if u, ok2 := v.Value.(uint64); ok2 { 56 return reflect.ValueOf(time.Duration(u)), nil 57 } 58 } 59 return reflect.Value{}, yaml.ErrContinue 60 } 61 62 func TestDecoderDuration(t *testing.T) { 63 c := Duration{} 64 decodeOption := yaml.TypeDecoder(reflect.TypeOf((*time.Duration)(nil)).Elem(), decodeDuration) 65 decoder := yaml.NewDecoder(strings.NewReader(`dur: 10s`), decodeOption) 66 err := decoder.Decode(&c) 67 assert.Nil(t, err) 68 assert.Equal(t, Duration{Dur: 10 * time.Second}, c) 69 70 decoder = yaml.NewDecoder(strings.NewReader(`dur: 111`), decodeOption) 71 err = decoder.Decode(&c) 72 assert.Nil(t, err) 73 assert.Equal(t, Duration{Dur: 111}, c) 74 } 75 76 type Config struct { 77 Size int64 `yaml:",label=size"` 78 } 79 80 func decodeSize(node ast.Node, typ reflect.Type) (reflect.Value, error) { 81 if v, ok := node.(*ast.StringNode); ok { 82 if v, err := man.ParseBytes(v.Value); err != nil { 83 return reflect.Value{}, err 84 } else { 85 return yaml.CastUint64(v, typ) 86 } 87 } 88 return reflect.Value{}, yaml.ErrContinue 89 } 90 91 func TestDecoderLabel(t *testing.T) { 92 c := Config{} 93 decodeOption := yaml.LabelDecoder("size", decodeSize) 94 decoder := yaml.NewDecoder(strings.NewReader(`size: 10MiB`), decodeOption) 95 err := decoder.Decode(&c) 96 assert.Nil(t, err) 97 assert.Equal(t, Config{Size: 10 * 1024 * 1024}, c) 98 99 decoder = yaml.NewDecoder(strings.NewReader(`size: 10,485,761`), decodeOption) 100 c.Size = 0 101 err = decoder.Decode(&c) 102 assert.Nil(t, err) 103 assert.Equal(t, Config{Size: 10485761}, c) 104 } 105 106 type Child struct { 107 B int 108 C int `yaml:"-"` 109 } 110 111 func TestDecoder(t *testing.T) { 112 tests := []struct { 113 source string 114 value interface{} 115 }{ 116 { 117 "null\n", 118 (*struct{})(nil), 119 }, 120 { 121 "v: hi\n", 122 map[string]string{"v": "hi"}, 123 }, 124 { 125 "v: \"true\"\n", 126 map[string]string{"v": "true"}, 127 }, 128 { 129 "v: \"false\"\n", 130 map[string]string{"v": "false"}, 131 }, 132 { 133 "v: true\n", 134 map[string]interface{}{"v": true}, 135 }, 136 { 137 "v: true\n", 138 map[string]string{"v": "true"}, 139 }, 140 { 141 "v: 10\n", 142 map[string]string{"v": "10"}, 143 }, 144 { 145 "v: -10\n", 146 map[string]string{"v": "-10"}, 147 }, 148 { 149 "v: 1.234\n", 150 map[string]string{"v": "1.234"}, 151 }, 152 { 153 "v: false\n", 154 map[string]bool{"v": false}, 155 }, 156 { 157 "v: 10\n", 158 map[string]int{"v": 10}, 159 }, 160 { 161 "v: 10", 162 map[string]interface{}{"v": 10}, 163 }, 164 { 165 "v: 0b10", 166 map[string]interface{}{"v": 2}, 167 }, 168 { 169 "v: -0b101010", 170 map[string]interface{}{"v": -42}, 171 }, 172 { 173 "v: -0b1000000000000000000000000000000000000000000000000000000000000000", 174 map[string]interface{}{"v": -9223372036854775808}, 175 }, 176 { 177 "v: 0xA", 178 map[string]interface{}{"v": 10}, 179 }, 180 { 181 "v: .1", 182 map[string]interface{}{"v": 0.1}, 183 }, 184 { 185 "v: -.1", 186 map[string]interface{}{"v": -0.1}, 187 }, 188 { 189 "v: -10\n", 190 map[string]int{"v": -10}, 191 }, 192 { 193 "v: 4294967296\n", 194 map[string]int{"v": 4294967296}, 195 }, 196 { 197 "v: 0.1\n", 198 map[string]interface{}{"v": 0.1}, 199 }, 200 { 201 "v: 0.99\n", 202 map[string]float32{"v": 0.99}, 203 }, 204 { 205 "v: -0.1\n", 206 map[string]float64{"v": -0.1}, 207 }, 208 { 209 "v: 6.8523e+5", 210 map[string]interface{}{"v": 6.8523e+5}, 211 }, 212 { 213 "v: 685.230_15e+03", 214 map[string]interface{}{"v": 685.23015e+03}, 215 }, 216 { 217 "v: 685_230.15", 218 map[string]interface{}{"v": 685230.15}, 219 }, 220 { 221 "v: 685_230.15", 222 map[string]float64{"v": 685230.15}, 223 }, 224 { 225 "v: 685230", 226 map[string]interface{}{"v": 685230}, 227 }, 228 { 229 "v: +685_230", 230 map[string]interface{}{"v": 685230}, 231 }, 232 { 233 "v: 02472256", 234 map[string]interface{}{"v": 685230}, 235 }, 236 { 237 "v: 0x_0A_74_AE", 238 map[string]interface{}{"v": 685230}, 239 }, 240 { 241 "v: 0b1010_0111_0100_1010_1110", 242 map[string]interface{}{"v": 685230}, 243 }, 244 { 245 "v: +685_230", 246 map[string]int{"v": 685230}, 247 }, 248 249 // Bools from spec 250 { 251 "v: True", 252 map[string]interface{}{"v": true}, 253 }, 254 { 255 "v: TRUE", 256 map[string]interface{}{"v": true}, 257 }, 258 { 259 "v: False", 260 map[string]interface{}{"v": false}, 261 }, 262 { 263 "v: FALSE", 264 map[string]interface{}{"v": false}, 265 }, 266 { 267 "v: y", 268 map[string]interface{}{"v": "y"}, // y or yes or Yes is string 269 }, 270 { 271 "v: NO", 272 map[string]interface{}{"v": "NO"}, // no or No or NO is string 273 }, 274 { 275 "v: on", 276 map[string]interface{}{"v": "on"}, // on is string 277 }, 278 279 // Some cross type conversions 280 { 281 "v: 42", 282 map[string]uint{"v": 42}, 283 }, 284 { 285 "v: 4294967296", 286 map[string]uint64{"v": 4294967296}, 287 }, 288 289 // int 290 { 291 "v: 2147483647", 292 map[string]int{"v": math.MaxInt32}, 293 }, 294 { 295 "v: -2147483648", 296 map[string]int{"v": math.MinInt32}, 297 }, 298 299 // int64 300 { 301 "v: 9223372036854775807", 302 map[string]int64{"v": math.MaxInt64}, 303 }, 304 { 305 "v: 0b111111111111111111111111111111111111111111111111111111111111111", 306 map[string]int64{"v": math.MaxInt64}, 307 }, 308 { 309 "v: -9223372036854775808", 310 map[string]int64{"v": math.MinInt64}, 311 }, 312 { 313 "v: -0b111111111111111111111111111111111111111111111111111111111111111", 314 map[string]int64{"v": -math.MaxInt64}, 315 }, 316 317 // uint 318 { 319 "v: 0", 320 map[string]uint{"v": 0}, 321 }, 322 { 323 "v: 4294967295", 324 map[string]uint{"v": math.MaxUint32}, 325 }, 326 327 // uint64 328 { 329 "v: 0", 330 map[string]uint{"v": 0}, 331 }, 332 { 333 "v: 18446744073709551615", 334 map[string]uint64{"v": math.MaxUint64}, 335 }, 336 { 337 "v: 0b1111111111111111111111111111111111111111111111111111111111111111", 338 map[string]uint64{"v": math.MaxUint64}, 339 }, 340 { 341 "v: 9223372036854775807", 342 map[string]uint64{"v": math.MaxInt64}, 343 }, 344 345 // float32 346 { 347 "v: 3.40282346638528859811704183484516925440e+38", 348 map[string]float32{"v": math.MaxFloat32}, 349 }, 350 { 351 "v: 1.401298464324817070923729583289916131280e-45", 352 map[string]float32{"v": math.SmallestNonzeroFloat32}, 353 }, 354 { 355 "v: 18446744073709551615", 356 map[string]float32{"v": float32(math.MaxUint64)}, 357 }, 358 { 359 "v: 18446744073709551616", 360 map[string]float32{"v": float32(math.MaxUint64 + 1)}, 361 }, 362 363 // float64 364 { 365 "v: 1.797693134862315708145274237317043567981e+308", 366 map[string]float64{"v": math.MaxFloat64}, 367 }, 368 { 369 "v: 4.940656458412465441765687928682213723651e-324", 370 map[string]float64{"v": math.SmallestNonzeroFloat64}, 371 }, 372 { 373 "v: 18446744073709551615", 374 map[string]float64{"v": float64(math.MaxUint64)}, 375 }, 376 { 377 "v: 18446744073709551616", 378 map[string]float64{"v": float64(math.MaxUint64 + 1)}, 379 }, 380 381 // Timestamps 382 { 383 // Date only. 384 "v: 2015-01-01\n", 385 map[string]time.Time{"v": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 386 }, 387 { 388 // RFC3339 389 "v: 2015-02-24T18:19:39.12Z\n", 390 map[string]time.Time{"v": time.Date(2015, 2, 24, 18, 19, 39, .12e9, time.UTC)}, 391 }, 392 { 393 // RFC3339 with short dates. 394 "v: 2015-2-3T3:4:5Z", 395 map[string]time.Time{"v": time.Date(2015, 2, 3, 3, 4, 5, 0, time.UTC)}, 396 }, 397 { 398 // ISO8601 lower case t 399 "v: 2015-02-24t18:19:39Z\n", 400 map[string]time.Time{"v": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)}, 401 }, 402 { 403 // space separate, no time zone 404 "v: 2015-02-24 18:19:39\n", 405 map[string]time.Time{"v": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)}, 406 }, 407 408 { 409 "v: 60s\n", 410 map[string]time.Duration{"v": time.Minute}, 411 }, 412 { 413 "v: -0.5h\n", 414 map[string]time.Duration{"v": -30 * time.Minute}, 415 }, 416 417 // Single Quoted values. 418 { 419 `'1': '2'`, 420 map[interface{}]interface{}{"1": `2`}, 421 }, 422 { 423 `'1': '"2"'`, 424 map[interface{}]interface{}{"1": `"2"`}, 425 }, 426 { 427 `'1': ''''`, 428 map[interface{}]interface{}{"1": `'`}, 429 }, 430 { 431 `'1': '''2'''`, 432 map[interface{}]interface{}{"1": `'2'`}, 433 }, 434 { 435 `'1': 'B''z'`, 436 map[interface{}]interface{}{"1": `B'z`}, 437 }, 438 { 439 `'1': '\'`, 440 map[interface{}]interface{}{"1": `\`}, 441 }, 442 { 443 `'1': '\\'`, 444 map[interface{}]interface{}{"1": `\\`}, 445 }, 446 { 447 `'1': '\"2\"'`, 448 map[interface{}]interface{}{"1": `\"2\"`}, 449 }, 450 { 451 `'1': '\\"2\\"'`, 452 map[interface{}]interface{}{"1": `\\"2\\"`}, 453 }, 454 { 455 "'1': ' 1\n 2\n 3'", 456 map[interface{}]interface{}{"1": " 1 2 3"}, 457 }, 458 { 459 "'1': '\n 2\n 3'", 460 map[interface{}]interface{}{"1": " 2 3"}, 461 }, 462 463 // Double Quoted values. 464 { 465 `"1": "2"`, 466 map[interface{}]interface{}{"1": `2`}, 467 }, 468 { 469 `"1": "\"2\""`, 470 map[interface{}]interface{}{"1": `"2"`}, 471 }, 472 { 473 `"1": "\""`, 474 map[interface{}]interface{}{"1": `"`}, 475 }, 476 { 477 `"1": "X\"z"`, 478 map[interface{}]interface{}{"1": `X"z`}, 479 }, 480 { 481 `"1": "\\"`, 482 map[interface{}]interface{}{"1": `\`}, 483 }, 484 { 485 `"1": "\\\\"`, 486 map[interface{}]interface{}{"1": `\\`}, 487 }, 488 { 489 `"1": "\\\"2\\\""`, 490 map[interface{}]interface{}{"1": `\"2\"`}, 491 }, 492 { 493 "'1': \" 1\n 2\n 3\"", 494 map[interface{}]interface{}{"1": " 1 2 3"}, 495 }, 496 { 497 "'1': \"\n 2\n 3\"", 498 map[interface{}]interface{}{"1": " 2 3"}, 499 }, 500 { 501 `"1": "a\x2Fb"`, 502 map[interface{}]interface{}{"1": `a/b`}, 503 }, 504 { 505 `"1": "a\u002Fb"`, 506 map[interface{}]interface{}{"1": `a/b`}, 507 }, 508 { 509 `"1": "a\x2Fb\u002Fc\U0000002Fd"`, 510 map[interface{}]interface{}{"1": `a/b/c/d`}, 511 }, 512 513 { 514 "a: -b_c", 515 map[string]interface{}{"a": "-b_c"}, 516 }, 517 { 518 "a: +b_c", 519 map[string]interface{}{"a": "+b_c"}, 520 }, 521 { 522 "a: 50cent_of_dollar", 523 map[string]interface{}{"a": "50cent_of_dollar"}, 524 }, 525 526 // Nulls 527 { 528 "v:", 529 map[string]interface{}{"v": nil}, 530 }, 531 { 532 "v: ~", 533 map[string]interface{}{"v": nil}, 534 }, 535 { 536 "~: null key", 537 map[interface{}]string{nil: "null key"}, 538 }, 539 { 540 "v:", 541 map[string]*bool{"v": nil}, 542 }, 543 { 544 "v: null", 545 map[string]*string{"v": nil}, 546 }, 547 { 548 "v: null", 549 map[string]string{"v": ""}, 550 }, 551 { 552 "v: null", 553 map[string]interface{}{"v": nil}, 554 }, 555 { 556 "v: Null", 557 map[string]interface{}{"v": nil}, 558 }, 559 { 560 "v: NULL", 561 map[string]interface{}{"v": nil}, 562 }, 563 { 564 "v: ~", 565 map[string]*string{"v": nil}, 566 }, 567 { 568 "v: ~", 569 map[string]string{"v": ""}, 570 }, 571 572 { 573 "v: .inf\n", 574 map[string]interface{}{"v": math.Inf(0)}, 575 }, 576 { 577 "v: .Inf\n", 578 map[string]interface{}{"v": math.Inf(0)}, 579 }, 580 { 581 "v: .INF\n", 582 map[string]interface{}{"v": math.Inf(0)}, 583 }, 584 { 585 "v: -.inf\n", 586 map[string]interface{}{"v": math.Inf(-1)}, 587 }, 588 { 589 "v: -.Inf\n", 590 map[string]interface{}{"v": math.Inf(-1)}, 591 }, 592 { 593 "v: -.INF\n", 594 map[string]interface{}{"v": math.Inf(-1)}, 595 }, 596 { 597 "v: .nan\n", 598 map[string]interface{}{"v": math.NaN()}, 599 }, 600 { 601 "v: .NaN\n", 602 map[string]interface{}{"v": math.NaN()}, 603 }, 604 { 605 "v: .NAN\n", 606 map[string]interface{}{"v": math.NaN()}, 607 }, 608 609 // Explicit tags. 610 { 611 "v: !!float '1.1'", 612 map[string]interface{}{"v": 1.1}, 613 }, 614 { 615 "v: !!float 0", 616 map[string]interface{}{"v": float64(0)}, 617 }, 618 { 619 "v: !!float -1", 620 map[string]interface{}{"v": float64(-1)}, 621 }, 622 { 623 "v: !!null ''", 624 map[string]interface{}{"v": nil}, 625 }, 626 { 627 "v: !!timestamp \"2015-01-01\"", 628 map[string]time.Time{"v": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 629 }, 630 { 631 "v: !!timestamp 2015-01-01", 632 map[string]time.Time{"v": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 633 }, 634 635 // Flow sequence 636 { 637 "v: [A,B]", 638 map[string]interface{}{"v": []interface{}{"A", "B"}}, 639 }, 640 { 641 "v: [A,B,C,]", 642 map[string][]string{"v": {"A", "B", "C"}}, 643 }, 644 { 645 "v: [A,1,C]", 646 map[string][]string{"v": {"A", "1", "C"}}, 647 }, 648 { 649 "v: [A,1,C]", 650 map[string]interface{}{"v": []interface{}{"A", 1, "C"}}, 651 }, 652 653 // Block sequence 654 { 655 "v:\n - A\n - B", 656 map[string]interface{}{"v": []interface{}{"A", "B"}}, 657 }, 658 { 659 "v:\n - A\n - B\n - C", 660 map[string][]string{"v": {"A", "B", "C"}}, 661 }, 662 { 663 "v:\n - A\n - 1\n - C", 664 map[string][]string{"v": {"A", "1", "C"}}, 665 }, 666 { 667 "v:\n - A\n - 1\n - C", 668 map[string]interface{}{"v": []interface{}{"A", 1, "C"}}, 669 }, 670 671 // Map inside interface with no type hints. 672 { 673 "a: {b: c}", 674 map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": "c"}}, 675 }, 676 677 { 678 "v: \"\"\n", 679 map[string]string{"v": ""}, 680 }, 681 { 682 "v:\n- A\n- B\n", 683 map[string][]string{"v": {"A", "B"}}, 684 }, 685 { 686 "a: '-'\n", 687 map[string]string{"a": "-"}, 688 }, 689 { 690 "123\n", 691 123, 692 }, 693 { 694 "hello: world\n", 695 map[string]string{"hello": "world"}, 696 }, 697 { 698 "hello: world\r\n", 699 map[string]string{"hello": "world"}, 700 }, 701 { 702 "hello: world\rGo: Gopher", 703 map[string]string{"hello": "world", "Go": "Gopher"}, 704 }, 705 706 // Structs and type conversions. 707 { 708 "hello: world", 709 struct{ Hello string }{"world"}, 710 }, 711 { 712 "a: {b: c}", 713 struct{ A struct{ B string } }{struct{ B string }{"c"}}, 714 }, 715 { 716 "a: {b: c}", 717 struct{ A map[string]string }{map[string]string{"b": "c"}}, 718 }, 719 { 720 "a:", 721 struct{ A map[string]string }{}, 722 }, 723 { 724 "a: 1", 725 struct{ A int }{1}, 726 }, 727 { 728 "a: 1", 729 struct{ A float64 }{1}, 730 }, 731 { 732 "a: 1.0", 733 struct{ A int }{1}, 734 }, 735 { 736 "a: 1.0", 737 struct{ A uint }{1}, 738 }, 739 { 740 "a: [1, 2]", 741 struct{ A []int }{[]int{1, 2}}, 742 }, 743 { 744 "a: [1, 2]", 745 struct{ A [2]int }{[2]int{1, 2}}, 746 }, 747 { 748 "a: 1", 749 struct{ B int }{0}, 750 }, 751 { 752 "a: 1", 753 struct { 754 B int `yaml:"a"` 755 }{1}, 756 }, 757 758 { 759 "a: 1\n", 760 yaml.MapItem{Key: "a", Value: 1}, 761 }, 762 { 763 "a: 1\nb: 2\nc: 3\n", 764 yaml.MapSlice{ 765 {Key: "a", Value: 1}, 766 {Key: "b", Value: 2}, 767 {Key: "c", Value: 3}, 768 }, 769 }, 770 { 771 "v:\n- A\n- 1\n- B:\n - 2\n - 3\n", 772 map[string]interface{}{ 773 "v": []interface{}{ 774 "A", 775 1, 776 map[string][]int{ 777 "B": {2, 3}, 778 }, 779 }, 780 }, 781 }, 782 { 783 "a:\n b: c\n", 784 map[string]interface{}{ 785 "a": map[string]string{ 786 "b": "c", 787 }, 788 }, 789 }, 790 { 791 "a: {x: 1}\n", 792 map[string]map[string]int{ 793 "a": { 794 "x": 1, 795 }, 796 }, 797 }, 798 { 799 "t2: 2018-01-09T10:40:47Z\nt4: 2098-01-09T10:40:47Z\n", 800 map[string]string{ 801 "t2": "2018-01-09T10:40:47Z", 802 "t4": "2098-01-09T10:40:47Z", 803 }, 804 }, 805 { 806 "a: [1, 2]\n", 807 map[string][]int{ 808 "a": {1, 2}, 809 }, 810 }, 811 { 812 "a: {b: c, d: e}\n", 813 map[string]interface{}{ 814 "a": map[string]string{ 815 "b": "c", 816 "d": "e", 817 }, 818 }, 819 }, 820 { 821 "a: 3s\n", 822 map[string]string{ 823 "a": "3s", 824 }, 825 }, 826 { 827 "a: <foo>\n", 828 map[string]string{"a": "<foo>"}, 829 }, 830 { 831 "a: \"1:1\"\n", 832 map[string]string{"a": "1:1"}, 833 }, 834 { 835 "a: 1.2.3.4\n", 836 map[string]string{"a": "1.2.3.4"}, 837 }, 838 { 839 "a: 'b: c'\n", 840 map[string]string{"a": "b: c"}, 841 }, 842 { 843 "a: 'Hello #comment'\n", 844 map[string]string{"a": "Hello #comment"}, 845 }, 846 { 847 "a: 100.5\n", 848 map[string]interface{}{ 849 "a": 100.5, 850 }, 851 }, 852 { 853 "a: \"\\0\"\n", 854 map[string]string{"a": "\\0"}, 855 }, 856 { 857 "b: 2\na: 1\nd: 4\nc: 3\nsub:\n e: 5\n", 858 map[string]interface{}{ 859 "b": 2, 860 "a": 1, 861 "d": 4, 862 "c": 3, 863 "sub": map[string]int{ 864 "e": 5, 865 }, 866 }, 867 }, 868 { 869 " a : b \n", 870 map[string]string{"a": "b"}, 871 }, 872 { 873 "a: b # comment\nb: c\n", 874 map[string]string{ 875 "a": "b", 876 "b": "c", 877 }, 878 }, 879 { 880 "---\na: b\n", 881 map[string]string{"a": "b"}, 882 }, 883 { 884 "a: b\n...\n", 885 map[string]string{"a": "b"}, 886 }, 887 { 888 "%YAML 1.2\n---\n", 889 (*struct{})(nil), 890 }, 891 { 892 "---\n", 893 (*struct{})(nil), 894 }, 895 { 896 "...", 897 (*struct{})(nil), 898 }, 899 { 900 "v: go test ./...", 901 map[string]string{"v": "go test ./..."}, 902 }, 903 { 904 "v: echo ---", 905 map[string]string{"v": "echo ---"}, 906 }, 907 { 908 "v: |\n hello\n ...\n world\n", 909 map[string]string{"v": "hello\n...\nworld\n"}, 910 }, 911 { 912 "a: !!binary gIGC\n", 913 map[string]string{"a": "\x80\x81\x82"}, 914 }, 915 { 916 "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n", 917 map[string]string{"a": strings.Repeat("\x90", 54)}, 918 }, 919 { 920 "v:\n- A\n- |-\n B\n C\n", 921 map[string][]string{ 922 "v": { 923 "A", "B\nC", 924 }, 925 }, 926 }, 927 { 928 "v:\n- A\n- >-\n B\n C\n", 929 map[string][]string{ 930 "v": { 931 "A", "B C", 932 }, 933 }, 934 }, 935 { 936 "a: b\nc: d\n", 937 struct { 938 A string 939 C string `yaml:"c"` 940 }{ 941 "b", "d", 942 }, 943 }, 944 { 945 "a: 1\nb: 2\n", 946 struct { 947 A int 948 B int `yaml:"-"` 949 }{ 950 1, 0, 951 }, 952 }, 953 { 954 "a: 1\nb: 2\n", 955 struct { 956 A int 957 Child `yaml:",inline"` 958 }{ 959 1, 960 Child{ 961 B: 2, 962 C: 0, 963 }, 964 }, 965 }, 966 967 // Anchors and aliases. 968 { 969 "a: &x 1\nb: &y 2\nc: *x\nd: *y\n", 970 struct{ A, B, C, D int }{1, 2, 1, 2}, 971 }, 972 { 973 "a: &a {c: 1}\nb: *a\n", 974 struct { 975 A, B struct { 976 C int 977 } 978 }{struct{ C int }{1}, struct{ C int }{1}}, 979 }, 980 { 981 "a: &a [1, 2]\nb: *a\n", 982 struct{ B []int }{[]int{1, 2}}, 983 }, 984 985 { 986 "tags:\n- hello-world\na: foo", 987 struct { 988 Tags []string 989 A string 990 }{Tags: []string{"hello-world"}, A: "foo"}, 991 }, 992 { 993 "", 994 (*struct{})(nil), 995 }, 996 { 997 "{}", struct{}{}, 998 }, 999 { 1000 "v: /a/{b}", 1001 map[string]string{"v": "/a/{b}"}, 1002 }, 1003 { 1004 "v: 1[]{},!%?&*", 1005 map[string]string{"v": "1[]{},!%?&*"}, 1006 }, 1007 { 1008 "v: user's item", 1009 map[string]string{"v": "user's item"}, 1010 }, 1011 { 1012 "v: [1,[2,[3,[4,5],6],7],8]", 1013 map[string]interface{}{ 1014 "v": []interface{}{ 1015 1, 1016 []interface{}{ 1017 2, 1018 []interface{}{ 1019 3, 1020 []int{4, 5}, 1021 6, 1022 }, 1023 7, 1024 }, 1025 8, 1026 }, 1027 }, 1028 }, 1029 { 1030 "v: {a: {b: {c: {d: e},f: g},h: i},j: k}", 1031 map[string]interface{}{ 1032 "v": map[string]interface{}{ 1033 "a": map[string]interface{}{ 1034 "b": map[string]interface{}{ 1035 "c": map[string]string{ 1036 "d": "e", 1037 }, 1038 "f": "g", 1039 }, 1040 "h": "i", 1041 }, 1042 "j": "k", 1043 }, 1044 }, 1045 }, 1046 { 1047 `--- 1048 - a: 1049 b: 1050 - c: d 1051 `, 1052 []map[string]interface{}{ 1053 { 1054 "a": map[string]interface{}{ 1055 "b": nil, 1056 }, 1057 }, 1058 { 1059 "c": "d", 1060 }, 1061 }, 1062 }, 1063 { 1064 `--- 1065 a: 1066 b: 1067 c: d 1068 `, 1069 map[string]interface{}{ 1070 "a": map[string]interface{}{ 1071 "b": nil, 1072 }, 1073 "c": "d", 1074 }, 1075 }, 1076 { 1077 `--- 1078 a: 1079 b: 1080 c: 1081 `, 1082 map[string]interface{}{ 1083 "a": nil, 1084 "b": nil, 1085 "c": nil, 1086 }, 1087 }, 1088 { 1089 `--- 1090 a: go test ./... 1091 b: 1092 c: 1093 `, 1094 map[string]interface{}{ 1095 "a": "go test ./...", 1096 "b": nil, 1097 "c": nil, 1098 }, 1099 }, 1100 { 1101 `--- 1102 a: | 1103 hello 1104 ... 1105 world 1106 b: 1107 c: 1108 `, 1109 map[string]interface{}{ 1110 "a": "hello\n...\nworld\n", 1111 "b": nil, 1112 "c": nil, 1113 }, 1114 }, 1115 1116 // Multi bytes 1117 { 1118 "v: あいうえお\nv2: かきくけこ", 1119 map[string]string{"v": "あいうえお", "v2": "かきくけこ"}, 1120 }, 1121 } 1122 for _, test := range tests { 1123 t.Run(test.source, func(t *testing.T) { 1124 buf := bytes.NewBufferString(test.source) 1125 dec := yaml.NewDecoder(buf) 1126 typ := reflect.ValueOf(test.value).Type() 1127 value := reflect.New(typ) 1128 if err := dec.Decode(value.Interface()); err != nil { 1129 if err == io.EOF { 1130 return 1131 } 1132 t.Fatalf("%s: %+v", test.source, err) 1133 } 1134 actual := fmt.Sprintf("%+v", value.Elem().Interface()) 1135 expect := fmt.Sprintf("%+v", test.value) 1136 if actual != expect { 1137 t.Fatalf("failed to test [%s], actual=[%s], expect=[%s]", test.source, actual, expect) 1138 } 1139 }) 1140 } 1141 } 1142 1143 func TestDecoder_TypeConversionError(t *testing.T) { 1144 t.Run("type conversion for struct", func(t *testing.T) { 1145 type T struct { 1146 A int 1147 B uint 1148 C float32 1149 D bool 1150 } 1151 type U struct { 1152 *T `yaml:",inline"` 1153 } 1154 t.Run("string to int", func(t *testing.T) { 1155 var v T 1156 err := yaml.Unmarshal([]byte(`a: str`), &v) 1157 if err == nil { 1158 t.Fatal("expected to error") 1159 } 1160 msg := "cannot unmarshal string into Go struct field T.A of type int" 1161 if err.Error() != msg { 1162 t.Fatalf("unexpected error message: %s. expect: %s", err.Error(), msg) 1163 } 1164 }) 1165 t.Run("string to bool", func(t *testing.T) { 1166 var v T 1167 err := yaml.Unmarshal([]byte(`d: str`), &v) 1168 if err == nil { 1169 t.Fatal("expected to error") 1170 } 1171 msg := "cannot unmarshal string into Go struct field T.D of type bool" 1172 if err.Error() != msg { 1173 t.Fatalf("unexpected error message: %s. expect: %s", err.Error(), msg) 1174 } 1175 }) 1176 t.Run("string to int at inline", func(t *testing.T) { 1177 var v U 1178 err := yaml.Unmarshal([]byte(`a: str`), &v) 1179 if err == nil { 1180 t.Fatal("expected to error") 1181 } 1182 msg := "cannot unmarshal string into Go struct field U.T.A of type int" 1183 if err.Error() != msg { 1184 t.Fatalf("unexpected error message: %s. expect: %s", err.Error(), msg) 1185 } 1186 }) 1187 }) 1188 t.Run("type conversion for array", func(t *testing.T) { 1189 t.Run("string to int", func(t *testing.T) { 1190 var v map[string][]int 1191 err := yaml.Unmarshal([]byte(`v: [A,1,C]`), &v) 1192 if err == nil { 1193 t.Fatal("expected to error") 1194 } 1195 msg := "cannot unmarshal string into Go value of type int" 1196 if err.Error() != msg { 1197 t.Fatalf("unexpected error message: %s. expect: %s", err.Error(), msg) 1198 } 1199 if len(v) == 0 || len(v["v"]) == 0 { 1200 t.Fatal("failed to decode value") 1201 } 1202 if v["v"][0] != 1 { 1203 t.Fatal("failed to decode value") 1204 } 1205 }) 1206 t.Run("string to int", func(t *testing.T) { 1207 var v map[string][]int 1208 err := yaml.Unmarshal([]byte("v:\n - A\n - 1\n - C"), &v) 1209 if err == nil { 1210 t.Fatal("expected to error") 1211 } 1212 msg := "cannot unmarshal string into Go value of type int" 1213 if err.Error() != msg { 1214 t.Fatalf("unexpected error message: %s. expect: %s", err.Error(), msg) 1215 } 1216 if len(v) == 0 || len(v["v"]) == 0 { 1217 t.Fatal("failed to decode value") 1218 } 1219 if v["v"][0] != 1 { 1220 t.Fatal("failed to decode value") 1221 } 1222 }) 1223 }) 1224 t.Run("overflow error", func(t *testing.T) { 1225 t.Run("negative number to uint", func(t *testing.T) { 1226 var v map[string]uint 1227 err := yaml.Unmarshal([]byte("v: -42"), &v) 1228 if err == nil { 1229 t.Fatal("expected to error") 1230 } 1231 msg := "cannot unmarshal -42 into Go value of type uint ( overflow )" 1232 if err.Error() != msg { 1233 t.Fatalf("unexpected error message: %s. expect: %s", err.Error(), msg) 1234 } 1235 if v["v"] != 0 { 1236 t.Fatal("failed to decode value") 1237 } 1238 }) 1239 t.Run("negative number to uint64", func(t *testing.T) { 1240 var v map[string]uint64 1241 err := yaml.Unmarshal([]byte("v: -4294967296"), &v) 1242 if err == nil { 1243 t.Fatal("expected to error") 1244 } 1245 msg := "cannot unmarshal -4294967296 into Go value of type uint64 ( overflow )" 1246 if err.Error() != msg { 1247 t.Fatalf("unexpected error message: %s. expect: %s", err.Error(), msg) 1248 } 1249 if v["v"] != 0 { 1250 t.Fatal("failed to decode value") 1251 } 1252 }) 1253 t.Run("larger number for int32", func(t *testing.T) { 1254 var v map[string]int32 1255 err := yaml.Unmarshal([]byte("v: 4294967297"), &v) 1256 if err == nil { 1257 t.Fatal("expected to error") 1258 } 1259 msg := "cannot unmarshal 4294967297 into Go value of type int32 ( overflow )" 1260 if err.Error() != msg { 1261 t.Fatalf("unexpected error message: %s. expect: %s", err.Error(), msg) 1262 } 1263 if v["v"] != 0 { 1264 t.Fatal("failed to decode value") 1265 } 1266 }) 1267 t.Run("larger number for int8", func(t *testing.T) { 1268 var v map[string]int8 1269 err := yaml.Unmarshal([]byte("v: 128"), &v) 1270 if err == nil { 1271 t.Fatal("expected to error") 1272 } 1273 msg := "cannot unmarshal 128 into Go value of type int8 ( overflow )" 1274 if err.Error() != msg { 1275 t.Fatalf("unexpected error message: %s. expect: %s", err.Error(), msg) 1276 } 1277 if v["v"] != 0 { 1278 t.Fatal("failed to decode value") 1279 } 1280 }) 1281 }) 1282 t.Run("type conversion for time", func(t *testing.T) { 1283 type T struct { 1284 A time.Time 1285 B time.Duration 1286 } 1287 t.Run("int to time", func(t *testing.T) { 1288 var v T 1289 err := yaml.Unmarshal([]byte(`a: 123`), &v) 1290 if err == nil { 1291 t.Fatal("expected to error") 1292 } 1293 msg := "cannot unmarshal uint64 into Go struct field T.A of type time.Time" 1294 if err.Error() != msg { 1295 t.Fatalf("unexpected error message: %s. expect: %s", err.Error(), msg) 1296 } 1297 }) 1298 t.Run("string to duration", func(t *testing.T) { 1299 var v T 1300 err := yaml.Unmarshal([]byte(`b: str`), &v) 1301 if err == nil { 1302 t.Fatal("expected to error") 1303 } 1304 msg := `time: invalid duration "str"` 1305 if err.Error() != msg { 1306 t.Fatalf("unexpected error message: %s. expect: %s", err.Error(), msg) 1307 } 1308 }) 1309 }) 1310 } 1311 1312 func TestDecoder_AnchorReferenceDirs(t *testing.T) { 1313 buf := bytes.NewBufferString("a: *a\n") 1314 dec := yaml.NewDecoder(buf, yaml.ReferenceDirs("testdata")) 1315 var v struct { 1316 A struct { 1317 B int 1318 C string 1319 } 1320 } 1321 if err := dec.Decode(&v); err != nil { 1322 t.Fatalf("%+v", err) 1323 } 1324 if v.A.B != 1 { 1325 t.Fatal("failed to decode by reference dirs") 1326 } 1327 if v.A.C != "hello" { 1328 t.Fatal("failed to decode by reference dirs") 1329 } 1330 } 1331 1332 func TestDecoder_AnchorReferenceDirsRecursive(t *testing.T) { 1333 buf := bytes.NewBufferString("a: *a\n") 1334 dec := yaml.NewDecoder( 1335 buf, 1336 yaml.RecursiveDir(true), 1337 yaml.ReferenceDirs("testdata"), 1338 ) 1339 var v struct { 1340 A struct { 1341 B int 1342 C string 1343 } 1344 } 1345 if err := dec.Decode(&v); err != nil { 1346 t.Fatalf("%+v", err) 1347 } 1348 if v.A.B != 1 { 1349 t.Fatal("failed to decode by reference dirs") 1350 } 1351 if v.A.C != "hello" { 1352 t.Fatal("failed to decode by reference dirs") 1353 } 1354 } 1355 1356 func TestDecoder_AnchorFiles(t *testing.T) { 1357 buf := bytes.NewBufferString("a: *a\n") 1358 dec := yaml.NewDecoder(buf, yaml.ReferenceFiles("testdata/anchor.yml")) 1359 var v struct { 1360 A struct { 1361 B int 1362 C string 1363 } 1364 } 1365 if err := dec.Decode(&v); err != nil { 1366 t.Fatalf("%+v", err) 1367 } 1368 if v.A.B != 1 { 1369 t.Fatal("failed to decode by reference dirs") 1370 } 1371 if v.A.C != "hello" { 1372 t.Fatal("failed to decode by reference dirs") 1373 } 1374 } 1375 1376 func TestDecodeWithMergeKey(t *testing.T) { 1377 yml := ` 1378 a: &a 1379 b: 1 1380 c: hello 1381 items: 1382 - <<: *a 1383 - <<: *a 1384 c: world 1385 ` 1386 type Item struct { 1387 B int 1388 C string 1389 } 1390 type T struct { 1391 Items []*Item 1392 } 1393 buf := bytes.NewBufferString(yml) 1394 dec := yaml.NewDecoder(buf) 1395 var v T 1396 if err := dec.Decode(&v); err != nil { 1397 t.Fatalf("%+v", err) 1398 } 1399 if len(v.Items) != 2 { 1400 t.Fatal("failed to decode with merge key") 1401 } 1402 if v.Items[0].B != 1 || v.Items[0].C != "hello" { 1403 t.Fatal("failed to decode with merge key") 1404 } 1405 if v.Items[1].B != 1 || v.Items[1].C != "world" { 1406 t.Fatal("failed to decode with merge key") 1407 } 1408 t.Run("decode with interface{}", func(t *testing.T) { 1409 buf := bytes.NewBufferString(yml) 1410 dec := yaml.NewDecoder(buf) 1411 var v interface{} 1412 if err := dec.Decode(&v); err != nil { 1413 t.Fatalf("%+v", err) 1414 } 1415 items := v.(map[string]interface{})["items"].([]interface{}) 1416 if len(items) != 2 { 1417 t.Fatal("failed to decode with merge key") 1418 } 1419 b0 := items[0].(map[string]interface{})["b"] 1420 if _, ok := b0.(uint64); !ok { 1421 t.Fatal("failed to decode with merge key") 1422 } 1423 if b0.(uint64) != 1 { 1424 t.Fatal("failed to decode with merge key") 1425 } 1426 c0 := items[0].(map[string]interface{})["c"] 1427 if _, ok := c0.(string); !ok { 1428 t.Fatal("failed to decode with merge key") 1429 } 1430 if c0.(string) != "hello" { 1431 t.Fatal("failed to decode with merge key") 1432 } 1433 b1 := items[1].(map[string]interface{})["b"] 1434 if _, ok := b1.(uint64); !ok { 1435 t.Fatal("failed to decode with merge key") 1436 } 1437 if b1.(uint64) != 1 { 1438 t.Fatal("failed to decode with merge key") 1439 } 1440 c1 := items[1].(map[string]interface{})["c"] 1441 if _, ok := c1.(string); !ok { 1442 t.Fatal("failed to decode with merge key") 1443 } 1444 if c1.(string) != "world" { 1445 t.Fatal("failed to decode with merge key") 1446 } 1447 }) 1448 t.Run("decode with map", func(t *testing.T) { 1449 var v struct { 1450 Items []map[string]interface{} 1451 } 1452 buf := bytes.NewBufferString(yml) 1453 dec := yaml.NewDecoder(buf) 1454 if err := dec.Decode(&v); err != nil { 1455 t.Fatalf("%+v", err) 1456 } 1457 if len(v.Items) != 2 { 1458 t.Fatal("failed to decode with merge key") 1459 } 1460 b0 := v.Items[0]["b"] 1461 if _, ok := b0.(uint64); !ok { 1462 t.Fatal("failed to decode with merge key") 1463 } 1464 if b0.(uint64) != 1 { 1465 t.Fatal("failed to decode with merge key") 1466 } 1467 c0 := v.Items[0]["c"] 1468 if _, ok := c0.(string); !ok { 1469 t.Fatal("failed to decode with merge key") 1470 } 1471 if c0.(string) != "hello" { 1472 t.Fatal("failed to decode with merge key") 1473 } 1474 b1 := v.Items[1]["b"] 1475 if _, ok := b1.(uint64); !ok { 1476 t.Fatal("failed to decode with merge key") 1477 } 1478 if b1.(uint64) != 1 { 1479 t.Fatal("failed to decode with merge key") 1480 } 1481 c1 := v.Items[1]["c"] 1482 if _, ok := c1.(string); !ok { 1483 t.Fatal("failed to decode with merge key") 1484 } 1485 if c1.(string) != "world" { 1486 t.Fatal("failed to decode with merge key") 1487 } 1488 }) 1489 } 1490 1491 func TestDecoder_Inline(t *testing.T) { 1492 type Base struct { 1493 A int 1494 B string 1495 } 1496 yml := `--- 1497 a: 1 1498 b: hello 1499 c: true 1500 ` 1501 var v struct { 1502 *Base `yaml:",inline"` 1503 C bool 1504 } 1505 if err := yaml.NewDecoder(strings.NewReader(yml)).Decode(&v); err != nil { 1506 t.Fatalf("%+v", err) 1507 } 1508 if v.A != 1 { 1509 t.Fatal("failed to decode with inline key") 1510 } 1511 if v.B != "hello" { 1512 t.Fatal("failed to decode with inline key") 1513 } 1514 if !v.C { 1515 t.Fatal("failed to decode with inline key") 1516 } 1517 1518 t.Run("multiple inline with strict", func(t *testing.T) { 1519 type Base struct { 1520 A int 1521 B string 1522 } 1523 type Base2 struct { 1524 Base *Base `yaml:",inline"` 1525 } 1526 yml := `--- 1527 a: 1 1528 b: hello 1529 ` 1530 var v struct { 1531 Base2 *Base2 `yaml:",inline"` 1532 } 1533 if err := yaml.NewDecoder(strings.NewReader(yml), yaml.Strict()).Decode(&v); err != nil { 1534 t.Fatalf("%+v", err) 1535 } 1536 if v.Base2.Base.A != 1 { 1537 t.Fatal("failed to decode with inline key") 1538 } 1539 if v.Base2.Base.B != "hello" { 1540 t.Fatal("failed to decode with inline key") 1541 } 1542 }) 1543 } 1544 1545 func TestDecoder_InlineAndConflictKey(t *testing.T) { 1546 type Base struct { 1547 A int 1548 B string 1549 } 1550 yml := `--- 1551 a: 1 1552 b: hello 1553 c: true 1554 ` 1555 var v struct { 1556 *Base `yaml:",inline"` 1557 A int 1558 C bool 1559 } 1560 if err := yaml.NewDecoder(strings.NewReader(yml)).Decode(&v); err != nil { 1561 t.Fatalf("%+v", err) 1562 } 1563 if v.A != 1 { 1564 t.Fatal("failed to decode with inline key") 1565 } 1566 if v.B != "hello" { 1567 t.Fatal("failed to decode with inline key") 1568 } 1569 if !v.C { 1570 t.Fatal("failed to decode with inline key") 1571 } 1572 if v.Base.A != 0 { 1573 t.Fatal("failed to decode with inline key") 1574 } 1575 } 1576 1577 func TestDecoder_InlineAndWrongTypeStrict(t *testing.T) { 1578 type Base struct { 1579 A int 1580 B string 1581 } 1582 yml := `--- 1583 a: notanint 1584 b: hello 1585 c: true 1586 ` 1587 var v struct { 1588 *Base `yaml:",inline"` 1589 C bool 1590 } 1591 err := yaml.NewDecoder(strings.NewReader(yml), yaml.Strict()).Decode(&v) 1592 if err == nil { 1593 t.Fatalf("expected error") 1594 } 1595 1596 // TODO: properly check if errors are colored/have source 1597 t.Logf("%s", err) 1598 t.Logf("%s", yaml.FormatError(err, true, false)) 1599 t.Logf("%s", yaml.FormatError(err, false, true)) 1600 t.Logf("%s", yaml.FormatError(err, true, true)) 1601 } 1602 1603 func TestDecoder_InvalidCases(t *testing.T) { 1604 const src = `--- 1605 a: 1606 - b 1607 c: d 1608 ` 1609 var v struct { 1610 A []string 1611 } 1612 err := yaml.NewDecoder(strings.NewReader(src)).Decode(&v) 1613 if err == nil { 1614 t.Fatalf("expected error") 1615 } 1616 1617 if err.Error() != yaml.FormatError(err, false, true) { 1618 t.Logf("err.Error() = %s", err.Error()) 1619 t.Logf("yaml.FormatError(err, false, true) = %s", yaml.FormatError(err, false, true)) 1620 t.Fatal(`err.Error() should match yaml.FormatError(err, false, true)`) 1621 } 1622 1623 // TODO: properly check if errors are colored/have source 1624 t.Logf("%s", err) 1625 t.Logf("%s", yaml.FormatError(err, true, false)) 1626 t.Logf("%s", yaml.FormatError(err, false, true)) 1627 t.Logf("%s", yaml.FormatError(err, true, true)) 1628 } 1629 1630 func TestDecoder_JSONTags(t *testing.T) { 1631 var v struct { 1632 A string `json:"a_json"` // no YAML tag 1633 B string `json:"b_json" yaml:"b_yaml"` // both tags 1634 } 1635 1636 const src = `--- 1637 a_json: a_json_value 1638 b_json: b_json_value 1639 b_yaml: b_yaml_value 1640 ` 1641 if err := yaml.NewDecoder(strings.NewReader(src)).Decode(&v); err != nil { 1642 t.Fatalf(`parsing should succeed: %s`, err) 1643 } 1644 1645 if v.A != "a_json_value" { 1646 t.Fatalf("v.A should be `a_json_value`, got `%s`", v.A) 1647 } 1648 1649 if v.B != "b_yaml_value" { 1650 t.Fatalf("v.B should be `b_yaml_value`, got `%s`", v.B) 1651 } 1652 } 1653 1654 func TestDecoder_DisallowUnknownField(t *testing.T) { 1655 t.Run("different level keys with same name", func(t *testing.T) { 1656 var v struct { 1657 C Child `yaml:"c"` 1658 } 1659 yml := `--- 1660 b: 1 1661 c: 1662 b: 1 1663 ` 1664 1665 err := yaml.NewDecoder(strings.NewReader(yml), yaml.DisallowUnknownField()).Decode(&v) 1666 if err == nil { 1667 t.Fatalf("error expected") 1668 } 1669 }) 1670 t.Run("inline", func(t *testing.T) { 1671 var v struct { 1672 *Child `yaml:",inline"` 1673 A string `yaml:"a"` 1674 } 1675 yml := `--- 1676 a: a 1677 b: 1 1678 ` 1679 1680 if err := yaml.NewDecoder(strings.NewReader(yml), yaml.DisallowUnknownField()).Decode(&v); err != nil { 1681 t.Fatalf(`parsing should succeed: %s`, err) 1682 } 1683 if v.A != "a" { 1684 t.Fatalf("v.A should be `a`, got `%s`", v.A) 1685 } 1686 if v.B != 1 { 1687 t.Fatalf("v.B should be 1, got %d", v.B) 1688 } 1689 if v.C != 0 { 1690 t.Fatalf("v.C should be 0, got %d", v.C) 1691 } 1692 }) 1693 t.Run("list", func(t *testing.T) { 1694 type C struct { 1695 Child `yaml:",inline"` 1696 } 1697 1698 var v struct { 1699 Children []C `yaml:"children"` 1700 } 1701 1702 yml := `--- 1703 children: 1704 - b: 1 1705 - b: 2 1706 ` 1707 1708 if err := yaml.NewDecoder(strings.NewReader(yml), yaml.DisallowUnknownField()).Decode(&v); err != nil { 1709 t.Fatalf(`parsing should succeed: %s`, err) 1710 } 1711 1712 if len(v.Children) != 2 { 1713 t.Fatalf(`len(v.Children) should be 2, got %d`, len(v.Children)) 1714 } 1715 1716 if v.Children[0].B != 1 { 1717 t.Fatalf(`v.Children[0].B should be 1, got %d`, v.Children[0].B) 1718 } 1719 1720 if v.Children[1].B != 2 { 1721 t.Fatalf(`v.Children[1].B should be 2, got %d`, v.Children[1].B) 1722 } 1723 }) 1724 } 1725 1726 func TestDecoder_DisallowDuplicateKey(t *testing.T) { 1727 yml := ` 1728 a: b 1729 a: c 1730 ` 1731 expected := ` 1732 [3:1] duplicate key "a" 1733 2 | a: b 1734 > 3 | a: c 1735 ^ 1736 ` 1737 t.Run("map", func(t *testing.T) { 1738 var v map[string]string 1739 err := yaml.NewDecoder(strings.NewReader(yml), yaml.DisallowDuplicateKey()).Decode(&v) 1740 if err == nil { 1741 t.Fatal("decoding should fail") 1742 } 1743 actual := "\n" + err.Error() 1744 if expected != actual { 1745 t.Fatalf("expected:[%s] actual:[%s]", expected, actual) 1746 } 1747 }) 1748 t.Run("struct", func(t *testing.T) { 1749 var v struct { 1750 A string 1751 } 1752 err := yaml.NewDecoder(strings.NewReader(yml), yaml.DisallowDuplicateKey()).Decode(&v) 1753 if err == nil { 1754 t.Fatal("decoding should fail") 1755 } 1756 actual := "\n" + err.Error() 1757 if expected != actual { 1758 t.Fatalf("expected:[%s] actual:[%s]", expected, actual) 1759 } 1760 }) 1761 } 1762 1763 func TestDecoder_DefaultValues(t *testing.T) { 1764 v := struct { 1765 A string `yaml:"a"` 1766 B string `yaml:"b"` 1767 c string // private 1768 }{ 1769 B: "defaultBValue", 1770 c: "defaultCValue", 1771 } 1772 1773 const src = `--- 1774 a: a_value 1775 ` 1776 if err := yaml.NewDecoder(strings.NewReader(src)).Decode(&v); err != nil { 1777 t.Fatalf(`parsing should succeed: %s`, err) 1778 } 1779 if v.A != "a_value" { 1780 t.Fatalf("v.A should be `a_value`, got `%s`", v.A) 1781 } 1782 1783 if v.B != "defaultBValue" { 1784 t.Fatalf("v.B should be `defaultValue`, got `%s`", v.B) 1785 } 1786 1787 if v.c != "defaultCValue" { 1788 t.Fatalf("v.c should be `defaultCValue`, got `%s`", v.c) 1789 } 1790 } 1791 1792 func Example_YAMLTags() { 1793 yml := `--- 1794 foo: 1 1795 bar: c 1796 A: 2 1797 B: d 1798 ` 1799 var v struct { 1800 A int `yaml:"foo" json:"A"` 1801 B string `yaml:"bar" json:"B"` 1802 } 1803 if err := yaml.Unmarshal([]byte(yml), &v); err != nil { 1804 log.Fatal(err) 1805 } 1806 fmt.Println(v.A) 1807 fmt.Println(v.B) 1808 // OUTPUT: 1809 // 1 1810 // c 1811 } 1812 1813 type useJSONUnmarshalerTest struct { 1814 s string 1815 } 1816 1817 func (t *useJSONUnmarshalerTest) UnmarshalJSON(b []byte) error { 1818 s, err := strconv.Unquote(string(b)) 1819 if err != nil { 1820 return err 1821 } 1822 t.s = s 1823 return nil 1824 } 1825 1826 func TestDecoder_UseJSONUnmarshaler(t *testing.T) { 1827 var v useJSONUnmarshalerTest 1828 if err := yaml.UnmarshalWithOptions([]byte(`"a"`), &v, yaml.UseJSONUnmarshaler()); err != nil { 1829 t.Fatal(err) 1830 } 1831 if v.s != "a" { 1832 t.Fatalf("unexpected decoded value: %s", v.s) 1833 } 1834 } 1835 1836 type unmarshalContext struct { 1837 v int 1838 } 1839 1840 func (c *unmarshalContext) UnmarshalYAML(ctx context.Context, b []byte) error { 1841 v, ok := ctx.Value("k").(int) 1842 if !ok { 1843 return fmt.Errorf("cannot get valid context") 1844 } 1845 if v != 1 { 1846 return fmt.Errorf("cannot get valid context") 1847 } 1848 if string(b) != "1" { 1849 return fmt.Errorf("cannot get valid bytes") 1850 } 1851 c.v = v 1852 return nil 1853 } 1854 1855 func Test_UnmarshalerWithContext(t *testing.T) { 1856 ctx := context.WithValue(context.Background(), "k", 1) 1857 var v unmarshalContext 1858 if err := yaml.UnmarshalContext(ctx, []byte(`1`), &v); err != nil { 1859 t.Fatalf("%+v", err) 1860 } 1861 if v.v != 1 { 1862 t.Fatal("cannot call UnmarshalYAML") 1863 } 1864 } 1865 1866 func TestDecoder_DecodeFromNode(t *testing.T) { 1867 t.Run("has reference", func(t *testing.T) { 1868 str := ` 1869 anchor: &map 1870 text: hello 1871 map: *map` 1872 var buf bytes.Buffer 1873 dec := yaml.NewDecoder(&buf) 1874 f, err := parser.ParseBytes([]byte(str), 0) 1875 if err != nil { 1876 t.Fatalf("failed to parse: %s", err) 1877 } 1878 type T struct { 1879 Map map[string]string 1880 } 1881 var v T 1882 if err := dec.DecodeFromNode(f.Docs[0].Body, &v); err != nil { 1883 t.Fatalf("failed to decode: %s", err) 1884 } 1885 actual := fmt.Sprintf("%+v", v) 1886 expect := fmt.Sprintf("%+v", T{map[string]string{"text": "hello"}}) 1887 if actual != expect { 1888 t.Fatalf("actual=[%s], expect=[%s]", actual, expect) 1889 } 1890 }) 1891 t.Run("with reference option", func(t *testing.T) { 1892 anchor := strings.NewReader(` 1893 map: &map 1894 text: hello`) 1895 var buf bytes.Buffer 1896 dec := yaml.NewDecoder(&buf, yaml.ReferenceReaders(anchor)) 1897 f, err := parser.ParseBytes([]byte("map: *map"), 0) 1898 if err != nil { 1899 t.Fatalf("failed to parse: %s", err) 1900 } 1901 type T struct { 1902 Map map[string]string 1903 } 1904 var v T 1905 if err := dec.DecodeFromNode(f.Docs[0].Body, &v); err != nil { 1906 t.Fatalf("failed to decode: %s", err) 1907 } 1908 actual := fmt.Sprintf("%+v", v) 1909 expect := fmt.Sprintf("%+v", T{map[string]string{"text": "hello"}}) 1910 if actual != expect { 1911 t.Fatalf("actual=[%s], expect=[%s]", actual, expect) 1912 } 1913 }) 1914 t.Run("value is not pointer", func(t *testing.T) { 1915 var buf bytes.Buffer 1916 var v bool 1917 err := yaml.NewDecoder(&buf).DecodeFromNode(nil, v) 1918 if !xerrors.Is(err, errors.ErrDecodeRequiredPointerType) { 1919 t.Fatalf("unexpected error: %s", err) 1920 } 1921 }) 1922 } 1923 1924 func Example_JSONTags() { 1925 yml := `--- 1926 foo: 1 1927 bar: c 1928 ` 1929 var v struct { 1930 A int `json:"foo"` 1931 B string `json:"bar"` 1932 } 1933 if err := yaml.Unmarshal([]byte(yml), &v); err != nil { 1934 log.Fatal(err) 1935 } 1936 fmt.Println(v.A) 1937 fmt.Println(v.B) 1938 // OUTPUT: 1939 // 1 1940 // c 1941 } 1942 1943 func Example_DisallowUnknownField() { 1944 var v struct { 1945 A string `yaml:"simple"` 1946 C string `yaml:"complicated"` 1947 } 1948 1949 const src = `--- 1950 simple: string 1951 complecated: string 1952 ` 1953 err := yaml.NewDecoder(strings.NewReader(src), yaml.DisallowUnknownField()).Decode(&v) 1954 fmt.Printf("%v\n", err) 1955 1956 // OUTPUT: 1957 // [3:1] unknown field "complecated" 1958 // 1 | --- 1959 // 2 | simple: string 1960 // > 3 | complecated: string 1961 // ^ 1962 } 1963 1964 func Example_Unmarshal_Node() { 1965 f, err := parser.ParseBytes([]byte("text: node example"), 0) 1966 if err != nil { 1967 panic(err) 1968 } 1969 var v struct { 1970 Text string `yaml:"text"` 1971 } 1972 if err := yaml.NodeToValue(f.Docs[0].Body, &v); err != nil { 1973 panic(err) 1974 } 1975 fmt.Println(v.Text) 1976 // OUTPUT: 1977 // node example 1978 } 1979 1980 type unmarshalableYAMLStringValue string 1981 1982 func (v *unmarshalableYAMLStringValue) UnmarshalYAML(b []byte) error { 1983 var s string 1984 if err := yaml.Unmarshal(b, &s); err != nil { 1985 return err 1986 } 1987 *v = unmarshalableYAMLStringValue(s) 1988 return nil 1989 } 1990 1991 type unmarshalableTextStringValue string 1992 1993 func (v *unmarshalableTextStringValue) UnmarshalText(b []byte) error { 1994 *v = unmarshalableTextStringValue(string(b)) 1995 return nil 1996 } 1997 1998 type unmarshalableStringContainer struct { 1999 A unmarshalableYAMLStringValue `yaml:"a"` 2000 B unmarshalableTextStringValue `yaml:"b"` 2001 } 2002 2003 func TestUnmarshalableString(t *testing.T) { 2004 t.Run("empty string", func(t *testing.T) { 2005 t.Parallel() 2006 yml := ` 2007 a: "" 2008 b: "" 2009 ` 2010 var container unmarshalableStringContainer 2011 if err := yaml.Unmarshal([]byte(yml), &container); err != nil { 2012 t.Fatalf("failed to unmarshal %v", err) 2013 } 2014 if container.A != "" { 2015 t.Fatalf("expected empty string, but %q is set", container.A) 2016 } 2017 if container.B != "" { 2018 t.Fatalf("expected empty string, but %q is set", container.B) 2019 } 2020 }) 2021 t.Run("filled string", func(t *testing.T) { 2022 t.Parallel() 2023 yml := ` 2024 a: "aaa" 2025 b: "bbb" 2026 ` 2027 var container unmarshalableStringContainer 2028 if err := yaml.Unmarshal([]byte(yml), &container); err != nil { 2029 t.Fatalf("failed to unmarshal %v", err) 2030 } 2031 if container.A != "aaa" { 2032 t.Fatalf("expected \"aaa\", but %q is set", container.A) 2033 } 2034 if container.B != "bbb" { 2035 t.Fatalf("expected \"bbb\", but %q is set", container.B) 2036 } 2037 }) 2038 t.Run("single-quoted string", func(t *testing.T) { 2039 t.Parallel() 2040 yml := ` 2041 a: 'aaa' 2042 b: 'bbb' 2043 ` 2044 var container unmarshalableStringContainer 2045 if err := yaml.Unmarshal([]byte(yml), &container); err != nil { 2046 t.Fatalf("failed to unmarshal %v", err) 2047 } 2048 if container.A != "aaa" { 2049 t.Fatalf("expected \"aaa\", but %q is set", container.A) 2050 } 2051 if container.B != "bbb" { 2052 t.Fatalf("expected \"aaa\", but %q is set", container.B) 2053 } 2054 }) 2055 t.Run("literal", func(t *testing.T) { 2056 t.Parallel() 2057 yml := ` 2058 a: | 2059 a 2060 b 2061 c 2062 b: | 2063 a 2064 b 2065 c 2066 ` 2067 var container unmarshalableStringContainer 2068 if err := yaml.Unmarshal([]byte(yml), &container); err != nil { 2069 t.Fatalf("failed to unmarshal %v", err) 2070 } 2071 if container.A != "a\nb\nc\n" { 2072 t.Fatalf("expected \"a\nb\nc\n\", but %q is set", container.A) 2073 } 2074 if container.B != "a\nb\nc\n" { 2075 t.Fatalf("expected \"a\nb\nc\n\", but %q is set", container.B) 2076 } 2077 }) 2078 t.Run("anchor/alias", func(t *testing.T) { 2079 yml := ` 2080 a: &x 1 2081 b: *x 2082 c: &y hello 2083 d: *y 2084 ` 2085 var v struct { 2086 A, B, C, D unmarshalableTextStringValue 2087 } 2088 if err := yaml.Unmarshal([]byte(yml), &v); err != nil { 2089 t.Fatal(err) 2090 } 2091 if v.A != "1" { 2092 t.Fatal("failed to unmarshal") 2093 } 2094 if v.B != "1" { 2095 t.Fatal("failed to unmarshal") 2096 } 2097 if v.C != "hello" { 2098 t.Fatal("failed to unmarshal") 2099 } 2100 if v.D != "hello" { 2101 t.Fatal("failed to unmarshal") 2102 } 2103 }) 2104 t.Run("net.IP", func(t *testing.T) { 2105 yml := ` 2106 a: &a 127.0.0.1 2107 b: *a 2108 ` 2109 var v struct { 2110 A, B net.IP 2111 } 2112 if err := yaml.Unmarshal([]byte(yml), &v); err != nil { 2113 t.Fatal(err) 2114 } 2115 if v.A.String() != net.IPv4(127, 0, 0, 1).String() { 2116 t.Fatal("failed to unmarshal") 2117 } 2118 if v.B.String() != net.IPv4(127, 0, 0, 1).String() { 2119 t.Fatal("failed to unmarshal") 2120 } 2121 }) 2122 } 2123 2124 type unmarshalablePtrStringContainer struct { 2125 V *string `yaml:"value"` 2126 } 2127 2128 func TestUnmarshalablePtrString(t *testing.T) { 2129 t.Run("empty string", func(t *testing.T) { 2130 t.Parallel() 2131 var container unmarshalablePtrStringContainer 2132 if err := yaml.Unmarshal([]byte(`value: ""`), &container); err != nil { 2133 t.Fatalf("failed to unmarshal %v", err) 2134 } 2135 if container.V == nil || *container.V != "" { 2136 t.Fatalf("expected empty string, but %q is set", *container.V) 2137 } 2138 }) 2139 2140 t.Run("null", func(t *testing.T) { 2141 t.Parallel() 2142 var container unmarshalablePtrStringContainer 2143 if err := yaml.Unmarshal([]byte(`value: null`), &container); err != nil { 2144 t.Fatalf("failed to unmarshal %v", err) 2145 } 2146 if container.V != (*string)(nil) { 2147 t.Fatalf("expected nil, but %q is set", *container.V) 2148 } 2149 }) 2150 } 2151 2152 type unmarshalableIntValue int 2153 2154 func (v *unmarshalableIntValue) UnmarshalYAML(raw []byte) error { 2155 i, err := strconv.Atoi(string(raw)) 2156 if err != nil { 2157 return err 2158 } 2159 *v = unmarshalableIntValue(i) 2160 return nil 2161 } 2162 2163 type unmarshalableIntContainer struct { 2164 V unmarshalableIntValue `yaml:"value"` 2165 } 2166 2167 func TestUnmarshalableInt(t *testing.T) { 2168 t.Run("empty int", func(t *testing.T) { 2169 t.Parallel() 2170 var container unmarshalableIntContainer 2171 if err := yaml.Unmarshal([]byte(``), &container); err != nil { 2172 t.Fatalf("failed to unmarshal %v", err) 2173 } 2174 if container.V != 0 { 2175 t.Fatalf("expected empty int, but %d is set", container.V) 2176 } 2177 }) 2178 t.Run("filled int", func(t *testing.T) { 2179 t.Parallel() 2180 var container unmarshalableIntContainer 2181 if err := yaml.Unmarshal([]byte(`value: 9`), &container); err != nil { 2182 t.Fatalf("failed to unmarshal %v", err) 2183 } 2184 if container.V != 9 { 2185 t.Fatalf("expected 9, but %d is set", container.V) 2186 } 2187 }) 2188 t.Run("filled number", func(t *testing.T) { 2189 t.Parallel() 2190 var container unmarshalableIntContainer 2191 if err := yaml.Unmarshal([]byte(`value: 9`), &container); err != nil { 2192 t.Fatalf("failed to unmarshal %v", err) 2193 } 2194 if container.V != 9 { 2195 t.Fatalf("expected 9, but %d is set", container.V) 2196 } 2197 }) 2198 } 2199 2200 type unmarshalablePtrIntContainer struct { 2201 V *int `yaml:"value"` 2202 } 2203 2204 func TestUnmarshalablePtrInt(t *testing.T) { 2205 t.Run("empty int", func(t *testing.T) { 2206 t.Parallel() 2207 var container unmarshalablePtrIntContainer 2208 if err := yaml.Unmarshal([]byte(`value: 0`), &container); err != nil { 2209 t.Fatalf("failed to unmarshal %v", err) 2210 } 2211 if container.V == nil || *container.V != 0 { 2212 t.Fatalf("expected 0, but %q is set", *container.V) 2213 } 2214 }) 2215 2216 t.Run("null", func(t *testing.T) { 2217 t.Parallel() 2218 var container unmarshalablePtrIntContainer 2219 if err := yaml.Unmarshal([]byte(`value: null`), &container); err != nil { 2220 t.Fatalf("failed to unmarshal %v", err) 2221 } 2222 if container.V != (*int)(nil) { 2223 t.Fatalf("expected nil, but %q is set", *container.V) 2224 } 2225 }) 2226 } 2227 2228 type literalContainer struct { 2229 v string 2230 } 2231 2232 func (c *literalContainer) UnmarshalYAML(v []byte) error { 2233 var lit string 2234 if err := yaml.Unmarshal(v, &lit); err != nil { 2235 return err 2236 } 2237 c.v = lit 2238 return nil 2239 } 2240 2241 func TestDecode_Literal(t *testing.T) { 2242 yml := `--- 2243 value: | 2244 { 2245 "key": "value" 2246 } 2247 ` 2248 var v map[string]*literalContainer 2249 if err := yaml.Unmarshal([]byte(yml), &v); err != nil { 2250 t.Fatalf("failed to unmarshal %+v", err) 2251 } 2252 if v["value"] == nil { 2253 t.Fatal("failed to unmarshal literal with bytes unmarshaler") 2254 } 2255 if v["value"].v == "" { 2256 t.Fatal("failed to unmarshal literal with bytes unmarshaler") 2257 } 2258 } 2259 2260 func TestDecoder_UseOrderedMap(t *testing.T) { 2261 yml := ` 2262 a: b 2263 c: d 2264 e: 2265 f: g 2266 h: i 2267 j: k 2268 ` 2269 var v interface{} 2270 if err := yaml.NewDecoder(strings.NewReader(yml), yaml.UseOrderedMap()).Decode(&v); err != nil { 2271 t.Fatalf("%+v", err) 2272 } 2273 if _, ok := v.(yaml.MapSlice); !ok { 2274 t.Fatalf("failed to convert to ordered map: %T", v) 2275 } 2276 bytes, err := yaml.Marshal(v) 2277 if err != nil { 2278 t.Fatalf("%+v", err) 2279 } 2280 if string(yml) != "\n"+string(bytes) { 2281 t.Fatalf("expected:[%s] actual:[%s]", string(yml), "\n"+string(bytes)) 2282 } 2283 } 2284 2285 func TestDecoder_Stream(t *testing.T) { 2286 yml := ` 2287 --- 2288 a: b 2289 c: d 2290 --- 2291 e: f 2292 g: h 2293 --- 2294 i: j 2295 k: l 2296 ` 2297 dec := yaml.NewDecoder(strings.NewReader(yml)) 2298 values := []map[string]string{} 2299 for { 2300 var v map[string]string 2301 if err := dec.Decode(&v); err != nil { 2302 if err == io.EOF { 2303 break 2304 } 2305 t.Fatalf("%+v", err) 2306 } 2307 values = append(values, v) 2308 } 2309 if len(values) != 3 { 2310 t.Fatal("failed to stream decoding") 2311 } 2312 if values[0]["a"] != "b" { 2313 t.Fatal("failed to stream decoding") 2314 } 2315 if values[1]["e"] != "f" { 2316 t.Fatal("failed to stream decoding") 2317 } 2318 if values[2]["i"] != "j" { 2319 t.Fatal("failed to stream decoding") 2320 } 2321 } 2322 2323 type unmarshalYAMLWithAliasString string 2324 2325 func (v *unmarshalYAMLWithAliasString) UnmarshalYAML(b []byte) error { 2326 var s string 2327 if err := yaml.Unmarshal(b, &s); err != nil { 2328 return err 2329 } 2330 *v = unmarshalYAMLWithAliasString(s) 2331 return nil 2332 } 2333 2334 type unmarshalYAMLWithAliasMap map[string]interface{} 2335 2336 func (v *unmarshalYAMLWithAliasMap) UnmarshalYAML(b []byte) error { 2337 var m map[string]interface{} 2338 if err := yaml.Unmarshal(b, &m); err != nil { 2339 return err 2340 } 2341 *v = unmarshalYAMLWithAliasMap(m) 2342 return nil 2343 } 2344 2345 func TestDecoder_UnmarshalYAMLWithAlias(t *testing.T) { 2346 yml := ` 2347 anchors: 2348 x: &x "\"hello\" \"world\"" 2349 map: &y 2350 a: b 2351 c: d 2352 d: *x 2353 a: *x 2354 b: 2355 <<: *y 2356 e: f 2357 ` 2358 var v struct { 2359 A unmarshalYAMLWithAliasString 2360 B unmarshalYAMLWithAliasMap 2361 } 2362 if err := yaml.Unmarshal([]byte(yml), &v); err != nil { 2363 t.Fatalf("%+v", err) 2364 } 2365 if v.A != `"hello" "world"` { 2366 t.Fatal("failed to unmarshal with alias") 2367 } 2368 if len(v.B) != 4 { 2369 t.Fatal("failed to unmarshal with alias") 2370 } 2371 if v.B["a"] != "b" { 2372 t.Fatal("failed to unmarshal with alias") 2373 } 2374 if v.B["c"] != "d" { 2375 t.Fatal("failed to unmarshal with alias") 2376 } 2377 if v.B["d"] != `"hello" "world"` { 2378 t.Fatal("failed to unmarshal with alias") 2379 } 2380 } 2381 2382 type unmarshalString string 2383 2384 func (u *unmarshalString) UnmarshalYAML(b []byte) error { 2385 *u = unmarshalString(string(b)) 2386 return nil 2387 } 2388 2389 type unmarshalList struct { 2390 v []map[string]unmarshalString 2391 } 2392 2393 func (u *unmarshalList) UnmarshalYAML(b []byte) error { 2394 expected := ` 2395 - b: c 2396 d: | 2397 hello 2398 2399 hello 2400 f: g 2401 - h: i` 2402 actual := "\n" + string(b) 2403 if expected != actual { 2404 return xerrors.Errorf("unexpected bytes: expected [%q] but got [%q]", expected, actual) 2405 } 2406 var v []map[string]unmarshalString 2407 if err := yaml.Unmarshal(b, &v); err != nil { 2408 return err 2409 } 2410 u.v = v 2411 return nil 2412 } 2413 2414 func TestDecoder_UnmarshalBytesWithSeparatedList(t *testing.T) { 2415 yml := ` 2416 a: 2417 - b: c 2418 d: | 2419 hello 2420 2421 hello 2422 f: g 2423 - h: i 2424 ` 2425 var v struct { 2426 A unmarshalList 2427 } 2428 if err := yaml.Unmarshal([]byte(yml), &v); err != nil { 2429 t.Fatal(err) 2430 } 2431 if len(v.A.v) != 2 { 2432 t.Fatalf("failed to unmarshal %+v", v) 2433 } 2434 if len(v.A.v[0]) != 3 { 2435 t.Fatalf("failed to unmarshal %+v", v.A.v[0]) 2436 } 2437 if len(v.A.v[1]) != 1 { 2438 t.Fatalf("failed to unmarshal %+v", v.A.v[1]) 2439 } 2440 } 2441 2442 func TestDecoder_LiteralWithNewLine(t *testing.T) { 2443 type A struct { 2444 Node string `yaml:"b"` 2445 LastNode string `yaml:"last"` 2446 } 2447 tests := []A{ 2448 { 2449 Node: "hello\nworld", 2450 }, 2451 { 2452 Node: "hello\nworld\n", 2453 }, 2454 { 2455 Node: "hello\nworld\n\n", 2456 }, 2457 { 2458 LastNode: "hello\nworld", 2459 }, 2460 { 2461 LastNode: "hello\nworld\n", 2462 }, 2463 { 2464 LastNode: "hello\nworld\n\n", 2465 }, 2466 } 2467 // struct(want) -> Marshal -> Unmarchal -> struct(got) 2468 for _, want := range tests { 2469 bytes, _ := yaml.Marshal(want) 2470 got := A{} 2471 if err := yaml.Unmarshal(bytes, &got); err != nil { 2472 t.Fatal(err) 2473 } 2474 if want.Node != got.Node { 2475 t.Fatalf("expected:%q but got %q", want.Node, got.Node) 2476 } 2477 if want.LastNode != got.LastNode { 2478 t.Fatalf("expected:%q but got %q", want.LastNode, got.LastNode) 2479 } 2480 } 2481 } 2482 2483 func TestDecoder_TabCharacterAtRight(t *testing.T) { 2484 yml := ` 2485 - a: [2 , 2] 2486 b: [2 , 2] 2487 c: [2 , 2]` 2488 var v []map[string][]int 2489 if err := yaml.Unmarshal([]byte(yml), &v); err != nil { 2490 t.Fatal(err) 2491 } 2492 if len(v) != 1 { 2493 t.Fatalf("failed to unmarshal %+v", v) 2494 } 2495 if len(v[0]) != 3 { 2496 t.Fatalf("failed to unmarshal %+v", v) 2497 } 2498 } 2499 2500 func TestDecoder_Canonical(t *testing.T) { 2501 yml := ` 2502 !!map { 2503 ? !!str "explicit":!!str "entry", 2504 ? !!str "implicit" : !!str "entry", 2505 ? !!null "" : !!null "", 2506 } 2507 ` 2508 var v interface{} 2509 if err := yaml.Unmarshal([]byte(yml), &v); err != nil { 2510 t.Fatalf("%+v", err) 2511 } 2512 m, ok := v.(map[string]interface{}) 2513 if !ok { 2514 t.Fatalf("failed to decode canonical yaml: %+v", v) 2515 } 2516 if m["explicit"] != "entry" { 2517 t.Fatalf("failed to decode canonical yaml: %+v", m) 2518 } 2519 if m["implicit"] != "entry" { 2520 t.Fatalf("failed to decode canonical yaml: %+v", m) 2521 } 2522 if m["null"] != nil { 2523 t.Fatalf("failed to decode canonical yaml: %+v", m) 2524 } 2525 } 2526 2527 func TestDecoder_DecodeFromFile(t *testing.T) { 2528 yml := ` 2529 a: b 2530 c: d 2531 ` 2532 file, err := parser.ParseBytes([]byte(yml), 0) 2533 if err != nil { 2534 t.Fatal(err) 2535 } 2536 var v map[string]string 2537 if err := yaml.NewDecoder(file).Decode(&v); err != nil { 2538 t.Fatal(err) 2539 } 2540 if len(v) != 2 { 2541 t.Fatal("failed to decode from ast.File") 2542 } 2543 if v["a"] != "b" { 2544 t.Fatal("failed to decode from ast.File") 2545 } 2546 if v["c"] != "d" { 2547 t.Fatal("failed to decode from ast.File") 2548 } 2549 } 2550 2551 func TestDecoder_DecodeWithNode(t *testing.T) { 2552 t.Run("abstract node", func(t *testing.T) { 2553 type T struct { 2554 Text ast.Node `yaml:"text"` 2555 } 2556 var v T 2557 if err := yaml.Unmarshal([]byte(`text: hello`), &v); err != nil { 2558 t.Fatalf("%+v", err) 2559 } 2560 expected := "hello" 2561 got := v.Text.String() 2562 if expected != got { 2563 t.Fatalf("failed to decode to ast.Node: expected %s but got %s", expected, got) 2564 } 2565 }) 2566 t.Run("concrete node", func(t *testing.T) { 2567 type T struct { 2568 Text *ast.StringNode `yaml:"text"` 2569 } 2570 var v T 2571 if err := yaml.Unmarshal([]byte(`text: hello`), &v); err != nil { 2572 t.Fatalf("%+v", err) 2573 } 2574 expected := "hello" 2575 got := v.Text.String() 2576 if expected != got { 2577 t.Fatalf("failed to decode to ast.Node: expected %s but got %s", expected, got) 2578 } 2579 }) 2580 } 2581 2582 func TestRoundtripAnchorAlias(t *testing.T) { 2583 t.Run("irreversible", func(t *testing.T) { 2584 type foo struct { 2585 K1 string 2586 K2 string 2587 } 2588 2589 type bar struct { 2590 K1 string 2591 K3 string 2592 } 2593 2594 type doc struct { 2595 Foo foo 2596 Bar bar 2597 } 2598 yml := ` 2599 foo: 2600 <<: &test-anchor 2601 k1: "One" 2602 k2: "Two" 2603 2604 bar: 2605 <<: *test-anchor 2606 k3: "Three" 2607 ` 2608 var v doc 2609 if err := yaml.Unmarshal([]byte(yml), &v); err != nil { 2610 t.Fatalf("%+v", err) 2611 } 2612 bytes, err := yaml.Marshal(v) 2613 if err != nil { 2614 t.Fatalf("%+v", err) 2615 } 2616 expected := ` 2617 foo: 2618 k1: One 2619 k2: Two 2620 bar: 2621 k1: One 2622 k3: Three 2623 ` 2624 got := "\n" + string(bytes) 2625 if expected != got { 2626 t.Fatalf("expected:[%s] but got [%s]", expected, got) 2627 } 2628 }) 2629 t.Run("reversible", func(t *testing.T) { 2630 type TestAnchor struct { 2631 K1 string 2632 } 2633 type foo struct { 2634 *TestAnchor `yaml:",inline,alias"` 2635 K2 string 2636 } 2637 type bar struct { 2638 *TestAnchor `yaml:",inline,alias"` 2639 K3 string 2640 } 2641 type doc struct { 2642 TestAnchor *TestAnchor `yaml:"test-anchor,anchor"` 2643 Foo foo 2644 Bar bar 2645 } 2646 yml := ` 2647 test-anchor: &test-anchor 2648 k1: One 2649 foo: 2650 <<: *test-anchor 2651 k2: Two 2652 bar: 2653 <<: *test-anchor 2654 k3: Three 2655 ` 2656 var v doc 2657 if err := yaml.Unmarshal([]byte(yml), &v); err != nil { 2658 t.Fatalf("%+v", err) 2659 } 2660 bytes, err := yaml.Marshal(v) 2661 if err != nil { 2662 t.Fatalf("%+v", err) 2663 } 2664 got := "\n" + string(bytes) 2665 if yml != got { 2666 t.Fatalf("expected:[%s] but got [%s]", yml, got) 2667 } 2668 }) 2669 }