github.com/nibnait/go-learn@v0.0.0-20220227013611-dfa47ea6d2da/src/pkg/mod/gopkg.in/yaml.v3@v3.0.0-20200313102051-9f266ea9e77c/decode_test.go (about) 1 // 2 // Copyright (c) 2011-2019 Canonical Ltd 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package yaml_test 17 18 import ( 19 "bytes" 20 "errors" 21 "fmt" 22 "io" 23 "math" 24 "reflect" 25 "strings" 26 "time" 27 28 . "gopkg.in/check.v1" 29 "gopkg.in/yaml.v3" 30 ) 31 32 var unmarshalIntTest = 123 33 34 var unmarshalTests = []struct { 35 data string 36 value interface{} 37 }{ 38 { 39 "", 40 (*struct{})(nil), 41 }, 42 { 43 "{}", &struct{}{}, 44 }, { 45 "v: hi", 46 map[string]string{"v": "hi"}, 47 }, { 48 "v: hi", map[string]interface{}{"v": "hi"}, 49 }, { 50 "v: true", 51 map[string]string{"v": "true"}, 52 }, { 53 "v: true", 54 map[string]interface{}{"v": true}, 55 }, { 56 "v: 10", 57 map[string]interface{}{"v": 10}, 58 }, { 59 "v: 0b10", 60 map[string]interface{}{"v": 2}, 61 }, { 62 "v: 0xA", 63 map[string]interface{}{"v": 10}, 64 }, { 65 "v: 4294967296", 66 map[string]int64{"v": 4294967296}, 67 }, { 68 "v: 0.1", 69 map[string]interface{}{"v": 0.1}, 70 }, { 71 "v: .1", 72 map[string]interface{}{"v": 0.1}, 73 }, { 74 "v: .Inf", 75 map[string]interface{}{"v": math.Inf(+1)}, 76 }, { 77 "v: -.Inf", 78 map[string]interface{}{"v": math.Inf(-1)}, 79 }, { 80 "v: -10", 81 map[string]interface{}{"v": -10}, 82 }, { 83 "v: -.1", 84 map[string]interface{}{"v": -0.1}, 85 }, 86 87 // Simple values. 88 { 89 "123", 90 &unmarshalIntTest, 91 }, 92 93 // Floats from spec 94 { 95 "canonical: 6.8523e+5", 96 map[string]interface{}{"canonical": 6.8523e+5}, 97 }, { 98 "expo: 685.230_15e+03", 99 map[string]interface{}{"expo": 685.23015e+03}, 100 }, { 101 "fixed: 685_230.15", 102 map[string]interface{}{"fixed": 685230.15}, 103 }, { 104 "neginf: -.inf", 105 map[string]interface{}{"neginf": math.Inf(-1)}, 106 }, { 107 "fixed: 685_230.15", 108 map[string]float64{"fixed": 685230.15}, 109 }, 110 //{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported 111 //{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails. 112 113 // Bools are per 1.2 spec. 114 { 115 "canonical: true", 116 map[string]interface{}{"canonical": true}, 117 }, { 118 "canonical: false", 119 map[string]interface{}{"canonical": false}, 120 }, { 121 "bool: True", 122 map[string]interface{}{"bool": true}, 123 }, { 124 "bool: False", 125 map[string]interface{}{"bool": false}, 126 }, { 127 "bool: TRUE", 128 map[string]interface{}{"bool": true}, 129 }, { 130 "bool: FALSE", 131 map[string]interface{}{"bool": false}, 132 }, 133 // For backwards compatibility with 1.1, decoding old strings into typed values still works. 134 { 135 "option: on", 136 map[string]bool{"option": true}, 137 }, { 138 "option: y", 139 map[string]bool{"option": true}, 140 }, { 141 "option: Off", 142 map[string]bool{"option": false}, 143 }, { 144 "option: No", 145 map[string]bool{"option": false}, 146 }, { 147 "option: other", 148 map[string]bool{}, 149 }, 150 // Ints from spec 151 { 152 "canonical: 685230", 153 map[string]interface{}{"canonical": 685230}, 154 }, { 155 "decimal: +685_230", 156 map[string]interface{}{"decimal": 685230}, 157 }, { 158 "octal: 02472256", 159 map[string]interface{}{"octal": 685230}, 160 }, { 161 "octal: -02472256", 162 map[string]interface{}{"octal": -685230}, 163 }, { 164 "octal: 0o2472256", 165 map[string]interface{}{"octal": 685230}, 166 }, { 167 "octal: -0o2472256", 168 map[string]interface{}{"octal": -685230}, 169 }, { 170 "hexa: 0x_0A_74_AE", 171 map[string]interface{}{"hexa": 685230}, 172 }, { 173 "bin: 0b1010_0111_0100_1010_1110", 174 map[string]interface{}{"bin": 685230}, 175 }, { 176 "bin: -0b101010", 177 map[string]interface{}{"bin": -42}, 178 }, { 179 "bin: -0b1000000000000000000000000000000000000000000000000000000000000000", 180 map[string]interface{}{"bin": -9223372036854775808}, 181 }, { 182 "decimal: +685_230", 183 map[string]int{"decimal": 685230}, 184 }, 185 186 //{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported 187 188 // Nulls from spec 189 { 190 "empty:", 191 map[string]interface{}{"empty": nil}, 192 }, { 193 "canonical: ~", 194 map[string]interface{}{"canonical": nil}, 195 }, { 196 "english: null", 197 map[string]interface{}{"english": nil}, 198 }, { 199 "~: null key", 200 map[interface{}]string{nil: "null key"}, 201 }, { 202 "empty:", 203 map[string]*bool{"empty": nil}, 204 }, 205 206 // Flow sequence 207 { 208 "seq: [A,B]", 209 map[string]interface{}{"seq": []interface{}{"A", "B"}}, 210 }, { 211 "seq: [A,B,C,]", 212 map[string][]string{"seq": []string{"A", "B", "C"}}, 213 }, { 214 "seq: [A,1,C]", 215 map[string][]string{"seq": []string{"A", "1", "C"}}, 216 }, { 217 "seq: [A,1,C]", 218 map[string][]int{"seq": []int{1}}, 219 }, { 220 "seq: [A,1,C]", 221 map[string]interface{}{"seq": []interface{}{"A", 1, "C"}}, 222 }, 223 // Block sequence 224 { 225 "seq:\n - A\n - B", 226 map[string]interface{}{"seq": []interface{}{"A", "B"}}, 227 }, { 228 "seq:\n - A\n - B\n - C", 229 map[string][]string{"seq": []string{"A", "B", "C"}}, 230 }, { 231 "seq:\n - A\n - 1\n - C", 232 map[string][]string{"seq": []string{"A", "1", "C"}}, 233 }, { 234 "seq:\n - A\n - 1\n - C", 235 map[string][]int{"seq": []int{1}}, 236 }, { 237 "seq:\n - A\n - 1\n - C", 238 map[string]interface{}{"seq": []interface{}{"A", 1, "C"}}, 239 }, 240 241 // Literal block scalar 242 { 243 "scalar: | # Comment\n\n literal\n\n \ttext\n\n", 244 map[string]string{"scalar": "\nliteral\n\n\ttext\n"}, 245 }, 246 247 // Folded block scalar 248 { 249 "scalar: > # Comment\n\n folded\n line\n \n next\n line\n * one\n * two\n\n last\n line\n\n", 250 map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"}, 251 }, 252 253 // Map inside interface with no type hints. 254 { 255 "a: {b: c}", 256 map[interface{}]interface{}{"a": map[string]interface{}{"b": "c"}}, 257 }, 258 // Non-string map inside interface with no type hints. 259 { 260 "a: {b: c, 1: d}", 261 map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": "c", 1: "d"}}, 262 }, 263 264 // Structs and type conversions. 265 { 266 "hello: world", 267 &struct{ Hello string }{"world"}, 268 }, { 269 "a: {b: c}", 270 &struct{ A struct{ B string } }{struct{ B string }{"c"}}, 271 }, { 272 "a: {b: c}", 273 &struct{ A *struct{ B string } }{&struct{ B string }{"c"}}, 274 }, { 275 "a: 'null'", 276 &struct{ A *unmarshalerType }{&unmarshalerType{"null"}}, 277 }, { 278 "a: {b: c}", 279 &struct{ A map[string]string }{map[string]string{"b": "c"}}, 280 }, { 281 "a: {b: c}", 282 &struct{ A *map[string]string }{&map[string]string{"b": "c"}}, 283 }, { 284 "a:", 285 &struct{ A map[string]string }{}, 286 }, { 287 "a: 1", 288 &struct{ A int }{1}, 289 }, { 290 "a: 1", 291 &struct{ A float64 }{1}, 292 }, { 293 "a: 1.0", 294 &struct{ A int }{1}, 295 }, { 296 "a: 1.0", 297 &struct{ A uint }{1}, 298 }, { 299 "a: [1, 2]", 300 &struct{ A []int }{[]int{1, 2}}, 301 }, { 302 "a: [1, 2]", 303 &struct{ A [2]int }{[2]int{1, 2}}, 304 }, { 305 "a: 1", 306 &struct{ B int }{0}, 307 }, { 308 "a: 1", 309 &struct { 310 B int "a" 311 }{1}, 312 }, { 313 // Some limited backwards compatibility with the 1.1 spec. 314 "a: YES", 315 &struct{ A bool }{true}, 316 }, 317 318 // Some cross type conversions 319 { 320 "v: 42", 321 map[string]uint{"v": 42}, 322 }, { 323 "v: -42", 324 map[string]uint{}, 325 }, { 326 "v: 4294967296", 327 map[string]uint64{"v": 4294967296}, 328 }, { 329 "v: -4294967296", 330 map[string]uint64{}, 331 }, 332 333 // int 334 { 335 "int_max: 2147483647", 336 map[string]int{"int_max": math.MaxInt32}, 337 }, 338 { 339 "int_min: -2147483648", 340 map[string]int{"int_min": math.MinInt32}, 341 }, 342 { 343 "int_overflow: 9223372036854775808", // math.MaxInt64 + 1 344 map[string]int{}, 345 }, 346 347 // int64 348 { 349 "int64_max: 9223372036854775807", 350 map[string]int64{"int64_max": math.MaxInt64}, 351 }, 352 { 353 "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111", 354 map[string]int64{"int64_max_base2": math.MaxInt64}, 355 }, 356 { 357 "int64_min: -9223372036854775808", 358 map[string]int64{"int64_min": math.MinInt64}, 359 }, 360 { 361 "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111", 362 map[string]int64{"int64_neg_base2": -math.MaxInt64}, 363 }, 364 { 365 "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1 366 map[string]int64{}, 367 }, 368 369 // uint 370 { 371 "uint_min: 0", 372 map[string]uint{"uint_min": 0}, 373 }, 374 { 375 "uint_max: 4294967295", 376 map[string]uint{"uint_max": math.MaxUint32}, 377 }, 378 { 379 "uint_underflow: -1", 380 map[string]uint{}, 381 }, 382 383 // uint64 384 { 385 "uint64_min: 0", 386 map[string]uint{"uint64_min": 0}, 387 }, 388 { 389 "uint64_max: 18446744073709551615", 390 map[string]uint64{"uint64_max": math.MaxUint64}, 391 }, 392 { 393 "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111", 394 map[string]uint64{"uint64_max_base2": math.MaxUint64}, 395 }, 396 { 397 "uint64_maxint64: 9223372036854775807", 398 map[string]uint64{"uint64_maxint64": math.MaxInt64}, 399 }, 400 { 401 "uint64_underflow: -1", 402 map[string]uint64{}, 403 }, 404 405 // float32 406 { 407 "float32_max: 3.40282346638528859811704183484516925440e+38", 408 map[string]float32{"float32_max": math.MaxFloat32}, 409 }, 410 { 411 "float32_nonzero: 1.401298464324817070923729583289916131280e-45", 412 map[string]float32{"float32_nonzero": math.SmallestNonzeroFloat32}, 413 }, 414 { 415 "float32_maxuint64: 18446744073709551615", 416 map[string]float32{"float32_maxuint64": float32(math.MaxUint64)}, 417 }, 418 { 419 "float32_maxuint64+1: 18446744073709551616", 420 map[string]float32{"float32_maxuint64+1": float32(math.MaxUint64 + 1)}, 421 }, 422 423 // float64 424 { 425 "float64_max: 1.797693134862315708145274237317043567981e+308", 426 map[string]float64{"float64_max": math.MaxFloat64}, 427 }, 428 { 429 "float64_nonzero: 4.940656458412465441765687928682213723651e-324", 430 map[string]float64{"float64_nonzero": math.SmallestNonzeroFloat64}, 431 }, 432 { 433 "float64_maxuint64: 18446744073709551615", 434 map[string]float64{"float64_maxuint64": float64(math.MaxUint64)}, 435 }, 436 { 437 "float64_maxuint64+1: 18446744073709551616", 438 map[string]float64{"float64_maxuint64+1": float64(math.MaxUint64 + 1)}, 439 }, 440 441 // Overflow cases. 442 { 443 "v: 4294967297", 444 map[string]int32{}, 445 }, { 446 "v: 128", 447 map[string]int8{}, 448 }, 449 450 // Quoted values. 451 { 452 "'1': '\"2\"'", 453 map[interface{}]interface{}{"1": "\"2\""}, 454 }, { 455 "v:\n- A\n- 'B\n\n C'\n", 456 map[string][]string{"v": []string{"A", "B\nC"}}, 457 }, 458 459 // Explicit tags. 460 { 461 "v: !!float '1.1'", 462 map[string]interface{}{"v": 1.1}, 463 }, { 464 "v: !!float 0", 465 map[string]interface{}{"v": float64(0)}, 466 }, { 467 "v: !!float -1", 468 map[string]interface{}{"v": float64(-1)}, 469 }, { 470 "v: !!null ''", 471 map[string]interface{}{"v": nil}, 472 }, { 473 "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'", 474 map[string]interface{}{"v": 1}, 475 }, 476 477 // Non-specific tag (Issue #75) 478 { 479 "v: ! test", 480 map[string]interface{}{"v": "test"}, 481 }, 482 483 // Anchors and aliases. 484 { 485 "a: &x 1\nb: &y 2\nc: *x\nd: *y\n", 486 &struct{ A, B, C, D int }{1, 2, 1, 2}, 487 }, { 488 "a: &a {c: 1}\nb: *a", 489 &struct { 490 A, B struct { 491 C int 492 } 493 }{struct{ C int }{1}, struct{ C int }{1}}, 494 }, { 495 "a: &a [1, 2]\nb: *a", 496 &struct{ B []int }{[]int{1, 2}}, 497 }, 498 499 // Bug #1133337 500 { 501 "foo: ''", 502 map[string]*string{"foo": new(string)}, 503 }, { 504 "foo: null", 505 map[string]*string{"foo": nil}, 506 }, { 507 "foo: null", 508 map[string]string{}, 509 }, { 510 "foo: null", 511 map[string]interface{}{"foo": nil}, 512 }, 513 514 // Support for ~ 515 { 516 "foo: ~", 517 map[string]*string{"foo": nil}, 518 }, { 519 "foo: ~", 520 map[string]string{}, 521 }, { 522 "foo: ~", 523 map[string]interface{}{"foo": nil}, 524 }, 525 526 // Ignored field 527 { 528 "a: 1\nb: 2\n", 529 &struct { 530 A int 531 B int "-" 532 }{1, 0}, 533 }, 534 535 // Bug #1191981 536 { 537 "" + 538 "%YAML 1.1\n" + 539 "--- !!str\n" + 540 `"Generic line break (no glyph)\n\` + "\n" + 541 ` Generic line break (glyphed)\n\` + "\n" + 542 ` Line separator\u2028\` + "\n" + 543 ` Paragraph separator\u2029"` + "\n", 544 "" + 545 "Generic line break (no glyph)\n" + 546 "Generic line break (glyphed)\n" + 547 "Line separator\u2028Paragraph separator\u2029", 548 }, 549 550 // Struct inlining 551 { 552 "a: 1\nb: 2\nc: 3\n", 553 &struct { 554 A int 555 C inlineB `yaml:",inline"` 556 }{1, inlineB{2, inlineC{3}}}, 557 }, 558 559 // Struct inlining as a pointer. 560 { 561 "a: 1\nb: 2\nc: 3\n", 562 &struct { 563 A int 564 C *inlineB `yaml:",inline"` 565 }{1, &inlineB{2, inlineC{3}}}, 566 }, { 567 "a: 1\n", 568 &struct { 569 A int 570 C *inlineB `yaml:",inline"` 571 }{1, nil}, 572 }, { 573 "a: 1\nc: 3\nd: 4\n", 574 &struct { 575 A int 576 C *inlineD `yaml:",inline"` 577 }{1, &inlineD{&inlineC{3}, 4}}, 578 }, 579 580 // Map inlining 581 { 582 "a: 1\nb: 2\nc: 3\n", 583 &struct { 584 A int 585 C map[string]int `yaml:",inline"` 586 }{1, map[string]int{"b": 2, "c": 3}}, 587 }, 588 589 // bug 1243827 590 { 591 "a: -b_c", 592 map[string]interface{}{"a": "-b_c"}, 593 }, 594 { 595 "a: +b_c", 596 map[string]interface{}{"a": "+b_c"}, 597 }, 598 { 599 "a: 50cent_of_dollar", 600 map[string]interface{}{"a": "50cent_of_dollar"}, 601 }, 602 603 // issue #295 (allow scalars with colons in flow mappings and sequences) 604 { 605 "a: {b: https://github.com/go-yaml/yaml}", 606 map[string]interface{}{"a": map[string]interface{}{ 607 "b": "https://github.com/go-yaml/yaml", 608 }}, 609 }, 610 { 611 "a: [https://github.com/go-yaml/yaml]", 612 map[string]interface{}{"a": []interface{}{"https://github.com/go-yaml/yaml"}}, 613 }, 614 615 // Duration 616 { 617 "a: 3s", 618 map[string]time.Duration{"a": 3 * time.Second}, 619 }, 620 621 // Issue #24. 622 { 623 "a: <foo>", 624 map[string]string{"a": "<foo>"}, 625 }, 626 627 // Base 60 floats are obsolete and unsupported. 628 { 629 "a: 1:1\n", 630 map[string]string{"a": "1:1"}, 631 }, 632 633 // Binary data. 634 { 635 "a: !!binary gIGC\n", 636 map[string]string{"a": "\x80\x81\x82"}, 637 }, { 638 "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n", 639 map[string]string{"a": strings.Repeat("\x90", 54)}, 640 }, { 641 "a: !!binary |\n " + strings.Repeat("A", 70) + "\n ==\n", 642 map[string]string{"a": strings.Repeat("\x00", 52)}, 643 }, 644 645 // Issue #39. 646 { 647 "a:\n b:\n c: d\n", 648 map[string]struct{ B interface{} }{"a": {map[string]interface{}{"c": "d"}}}, 649 }, 650 651 // Custom map type. 652 { 653 "a: {b: c}", 654 M{"a": M{"b": "c"}}, 655 }, 656 657 // Support encoding.TextUnmarshaler. 658 { 659 "a: 1.2.3.4\n", 660 map[string]textUnmarshaler{"a": textUnmarshaler{S: "1.2.3.4"}}, 661 }, 662 { 663 "a: 2015-02-24T18:19:39Z\n", 664 map[string]textUnmarshaler{"a": textUnmarshaler{"2015-02-24T18:19:39Z"}}, 665 }, 666 667 // Timestamps 668 { 669 // Date only. 670 "a: 2015-01-01\n", 671 map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 672 }, 673 { 674 // RFC3339 675 "a: 2015-02-24T18:19:39.12Z\n", 676 map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, .12e9, time.UTC)}, 677 }, 678 { 679 // RFC3339 with short dates. 680 "a: 2015-2-3T3:4:5Z", 681 map[string]time.Time{"a": time.Date(2015, 2, 3, 3, 4, 5, 0, time.UTC)}, 682 }, 683 { 684 // ISO8601 lower case t 685 "a: 2015-02-24t18:19:39Z\n", 686 map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)}, 687 }, 688 { 689 // space separate, no time zone 690 "a: 2015-02-24 18:19:39\n", 691 map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)}, 692 }, 693 // Some cases not currently handled. Uncomment these when 694 // the code is fixed. 695 // { 696 // // space separated with time zone 697 // "a: 2001-12-14 21:59:43.10 -5", 698 // map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)}, 699 // }, 700 // { 701 // // arbitrary whitespace between fields 702 // "a: 2001-12-14 \t\t \t21:59:43.10 \t Z", 703 // map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)}, 704 // }, 705 { 706 // explicit string tag 707 "a: !!str 2015-01-01", 708 map[string]interface{}{"a": "2015-01-01"}, 709 }, 710 { 711 // explicit timestamp tag on quoted string 712 "a: !!timestamp \"2015-01-01\"", 713 map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 714 }, 715 { 716 // explicit timestamp tag on unquoted string 717 "a: !!timestamp 2015-01-01", 718 map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 719 }, 720 { 721 // quoted string that's a valid timestamp 722 "a: \"2015-01-01\"", 723 map[string]interface{}{"a": "2015-01-01"}, 724 }, 725 { 726 // explicit timestamp tag into interface. 727 "a: !!timestamp \"2015-01-01\"", 728 map[string]interface{}{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 729 }, 730 { 731 // implicit timestamp tag into interface. 732 "a: 2015-01-01", 733 map[string]interface{}{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 734 }, 735 736 // Encode empty lists as zero-length slices. 737 { 738 "a: []", 739 &struct{ A []int }{[]int{}}, 740 }, 741 742 // UTF-16-LE 743 { 744 "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00", 745 M{"ñoño": "very yes"}, 746 }, 747 // UTF-16-LE with surrogate. 748 { 749 "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00", 750 M{"ñoño": "very yes 🟔"}, 751 }, 752 753 // UTF-16-BE 754 { 755 "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n", 756 M{"ñoño": "very yes"}, 757 }, 758 // UTF-16-BE with surrogate. 759 { 760 "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n", 761 M{"ñoño": "very yes 🟔"}, 762 }, 763 764 // This *is* in fact a float number, per the spec. #171 was a mistake. 765 { 766 "a: 123456e1\n", 767 M{"a": 123456e1}, 768 }, { 769 "a: 123456E1\n", 770 M{"a": 123456E1}, 771 }, 772 // yaml-test-suite 3GZX: Spec Example 7.1. Alias Nodes 773 { 774 "First occurrence: &anchor Foo\nSecond occurrence: *anchor\nOverride anchor: &anchor Bar\nReuse anchor: *anchor\n", 775 map[string]interface{}{ 776 "First occurrence": "Foo", 777 "Second occurrence": "Foo", 778 "Override anchor": "Bar", 779 "Reuse anchor": "Bar", 780 }, 781 }, 782 // Single document with garbage following it. 783 { 784 "---\nhello\n...\n}not yaml", 785 "hello", 786 }, 787 788 // Comment scan exhausting the input buffer (issue #469). 789 { 790 "true\n#" + strings.Repeat(" ", 512*3), 791 "true", 792 }, { 793 "true #" + strings.Repeat(" ", 512*3), 794 "true", 795 }, 796 797 // CRLF 798 { 799 "a: b\r\nc:\r\n- d\r\n- e\r\n", 800 map[string]interface{}{ 801 "a": "b", 802 "c": []interface{}{"d", "e"}, 803 }, 804 }, 805 806 } 807 808 type M map[string]interface{} 809 810 type inlineB struct { 811 B int 812 inlineC `yaml:",inline"` 813 } 814 815 type inlineC struct { 816 C int 817 } 818 819 type inlineD struct { 820 C *inlineC `yaml:",inline"` 821 D int 822 } 823 824 func (s *S) TestUnmarshal(c *C) { 825 for i, item := range unmarshalTests { 826 c.Logf("test %d: %q", i, item.data) 827 t := reflect.ValueOf(item.value).Type() 828 value := reflect.New(t) 829 err := yaml.Unmarshal([]byte(item.data), value.Interface()) 830 if _, ok := err.(*yaml.TypeError); !ok { 831 c.Assert(err, IsNil) 832 } 833 c.Assert(value.Elem().Interface(), DeepEquals, item.value, Commentf("error: %v", err)) 834 } 835 } 836 837 func (s *S) TestUnmarshalFullTimestamp(c *C) { 838 // Full timestamp in same format as encoded. This is confirmed to be 839 // properly decoded by Python as a timestamp as well. 840 var str = "2015-02-24T18:19:39.123456789-03:00" 841 var t interface{} 842 err := yaml.Unmarshal([]byte(str), &t) 843 c.Assert(err, IsNil) 844 c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.(time.Time).Location())) 845 c.Assert(t.(time.Time).In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC)) 846 } 847 848 func (s *S) TestDecoderSingleDocument(c *C) { 849 // Test that Decoder.Decode works as expected on 850 // all the unmarshal tests. 851 for i, item := range unmarshalTests { 852 c.Logf("test %d: %q", i, item.data) 853 if item.data == "" { 854 // Behaviour differs when there's no YAML. 855 continue 856 } 857 t := reflect.ValueOf(item.value).Type() 858 value := reflect.New(t) 859 err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(value.Interface()) 860 if _, ok := err.(*yaml.TypeError); !ok { 861 c.Assert(err, IsNil) 862 } 863 c.Assert(value.Elem().Interface(), DeepEquals, item.value) 864 } 865 } 866 867 var decoderTests = []struct { 868 data string 869 values []interface{} 870 }{{ 871 "", 872 nil, 873 }, { 874 "a: b", 875 []interface{}{ 876 map[string]interface{}{"a": "b"}, 877 }, 878 }, { 879 "---\na: b\n...\n", 880 []interface{}{ 881 map[string]interface{}{"a": "b"}, 882 }, 883 }, { 884 "---\n'hello'\n...\n---\ngoodbye\n...\n", 885 []interface{}{ 886 "hello", 887 "goodbye", 888 }, 889 }} 890 891 func (s *S) TestDecoder(c *C) { 892 for i, item := range decoderTests { 893 c.Logf("test %d: %q", i, item.data) 894 var values []interface{} 895 dec := yaml.NewDecoder(strings.NewReader(item.data)) 896 for { 897 var value interface{} 898 err := dec.Decode(&value) 899 if err == io.EOF { 900 break 901 } 902 c.Assert(err, IsNil) 903 values = append(values, value) 904 } 905 c.Assert(values, DeepEquals, item.values) 906 } 907 } 908 909 type errReader struct{} 910 911 func (errReader) Read([]byte) (int, error) { 912 return 0, errors.New("some read error") 913 } 914 915 func (s *S) TestDecoderReadError(c *C) { 916 err := yaml.NewDecoder(errReader{}).Decode(&struct{}{}) 917 c.Assert(err, ErrorMatches, `yaml: input error: some read error`) 918 } 919 920 func (s *S) TestUnmarshalNaN(c *C) { 921 value := map[string]interface{}{} 922 err := yaml.Unmarshal([]byte("notanum: .NaN"), &value) 923 c.Assert(err, IsNil) 924 c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true) 925 } 926 927 func (s *S) TestUnmarshalDurationInt(c *C) { 928 // Don't accept plain ints as durations as it's unclear (issue #200). 929 var d time.Duration 930 err := yaml.Unmarshal([]byte("123"), &d) 931 c.Assert(err, ErrorMatches, "(?s).* line 1: cannot unmarshal !!int `123` into time.Duration") 932 } 933 934 var unmarshalErrorTests = []struct { 935 data, error string 936 }{ 937 {"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"}, 938 {"v: [A,", "yaml: line 1: did not find expected node content"}, 939 {"v:\n- [A,", "yaml: line 2: did not find expected node content"}, 940 {"a:\n- b: *,", "yaml: line 2: did not find expected alphabetic or numeric character"}, 941 {"a: *b\n", "yaml: unknown anchor 'b' referenced"}, 942 {"a: &a\n b: *a\n", "yaml: anchor 'a' value contains itself"}, 943 {"value: -", "yaml: block sequence entries are not allowed in this context"}, 944 {"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"}, 945 {"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`}, 946 {"{{.}}", `yaml: invalid map key: map\[string]interface \{\}\{".":interface \{\}\(nil\)\}`}, 947 {"b: *a\na: &a {c: 1}", `yaml: unknown anchor 'a' referenced`}, 948 {"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"}, 949 {"a:\n 1:\nb\n 2:", ".*could not find expected ':'"}, 950 { 951 "a: &a [00,00,00,00,00,00,00,00,00]\n" + 952 "b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]\n" + 953 "c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]\n" + 954 "d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]\n" + 955 "e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]\n" + 956 "f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]\n" + 957 "g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]\n" + 958 "h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]\n" + 959 "i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]\n", 960 "yaml: document contains excessive aliasing", 961 }, 962 } 963 964 func (s *S) TestUnmarshalErrors(c *C) { 965 for i, item := range unmarshalErrorTests { 966 c.Logf("test %d: %q", i, item.data) 967 var value interface{} 968 err := yaml.Unmarshal([]byte(item.data), &value) 969 c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value)) 970 } 971 } 972 973 func (s *S) TestDecoderErrors(c *C) { 974 for _, item := range unmarshalErrorTests { 975 var value interface{} 976 err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(&value) 977 c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value)) 978 } 979 } 980 981 var unmarshalerTests = []struct { 982 data, tag string 983 value interface{} 984 }{ 985 {"_: {hi: there}", "!!map", map[string]interface{}{"hi": "there"}}, 986 {"_: [1,A]", "!!seq", []interface{}{1, "A"}}, 987 {"_: 10", "!!int", 10}, 988 {"_: null", "!!null", nil}, 989 {`_: BAR!`, "!!str", "BAR!"}, 990 {`_: "BAR!"`, "!!str", "BAR!"}, 991 {"_: !!foo 'BAR!'", "!!foo", "BAR!"}, 992 {`_: ""`, "!!str", ""}, 993 } 994 995 var unmarshalerResult = map[int]error{} 996 997 type unmarshalerType struct { 998 value interface{} 999 } 1000 1001 func (o *unmarshalerType) UnmarshalYAML(value *yaml.Node) error { 1002 if err := value.Decode(&o.value); err != nil { 1003 return err 1004 } 1005 if i, ok := o.value.(int); ok { 1006 if result, ok := unmarshalerResult[i]; ok { 1007 return result 1008 } 1009 } 1010 return nil 1011 } 1012 1013 type unmarshalerPointer struct { 1014 Field *unmarshalerType "_" 1015 } 1016 1017 type unmarshalerValue struct { 1018 Field unmarshalerType "_" 1019 } 1020 1021 type unmarshalerInlined struct { 1022 Field *unmarshalerType "_" 1023 Inlined unmarshalerType `yaml:",inline"` 1024 } 1025 1026 type unmarshalerInlinedTwice struct { 1027 InlinedTwice unmarshalerInlined `yaml:",inline"` 1028 } 1029 1030 type obsoleteUnmarshalerType struct { 1031 value interface{} 1032 } 1033 1034 func (o *obsoleteUnmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error { 1035 if err := unmarshal(&o.value); err != nil { 1036 return err 1037 } 1038 if i, ok := o.value.(int); ok { 1039 if result, ok := unmarshalerResult[i]; ok { 1040 return result 1041 } 1042 } 1043 return nil 1044 } 1045 1046 type obsoleteUnmarshalerPointer struct { 1047 Field *obsoleteUnmarshalerType "_" 1048 } 1049 1050 type obsoleteUnmarshalerValue struct { 1051 Field obsoleteUnmarshalerType "_" 1052 } 1053 1054 func (s *S) TestUnmarshalerPointerField(c *C) { 1055 for _, item := range unmarshalerTests { 1056 obj := &unmarshalerPointer{} 1057 err := yaml.Unmarshal([]byte(item.data), obj) 1058 c.Assert(err, IsNil) 1059 if item.value == nil { 1060 c.Assert(obj.Field, IsNil) 1061 } else { 1062 c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value)) 1063 c.Assert(obj.Field.value, DeepEquals, item.value) 1064 } 1065 } 1066 for _, item := range unmarshalerTests { 1067 obj := &obsoleteUnmarshalerPointer{} 1068 err := yaml.Unmarshal([]byte(item.data), obj) 1069 c.Assert(err, IsNil) 1070 if item.value == nil { 1071 c.Assert(obj.Field, IsNil) 1072 } else { 1073 c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value)) 1074 c.Assert(obj.Field.value, DeepEquals, item.value) 1075 } 1076 } 1077 } 1078 1079 func (s *S) TestUnmarshalerValueField(c *C) { 1080 for _, item := range unmarshalerTests { 1081 obj := &obsoleteUnmarshalerValue{} 1082 err := yaml.Unmarshal([]byte(item.data), obj) 1083 c.Assert(err, IsNil) 1084 c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value)) 1085 c.Assert(obj.Field.value, DeepEquals, item.value) 1086 } 1087 } 1088 1089 func (s *S) TestUnmarshalerInlinedField(c *C) { 1090 obj := &unmarshalerInlined{} 1091 err := yaml.Unmarshal([]byte("_: a\ninlined: b\n"), obj) 1092 c.Assert(err, IsNil) 1093 c.Assert(obj.Field, DeepEquals, &unmarshalerType{"a"}) 1094 c.Assert(obj.Inlined, DeepEquals, unmarshalerType{map[string]interface{}{"_": "a", "inlined": "b"}}) 1095 1096 twc := &unmarshalerInlinedTwice{} 1097 err = yaml.Unmarshal([]byte("_: a\ninlined: b\n"), twc) 1098 c.Assert(err, IsNil) 1099 c.Assert(twc.InlinedTwice.Field, DeepEquals, &unmarshalerType{"a"}) 1100 c.Assert(twc.InlinedTwice.Inlined, DeepEquals, unmarshalerType{map[string]interface{}{"_": "a", "inlined": "b"}}) 1101 } 1102 1103 func (s *S) TestUnmarshalerWholeDocument(c *C) { 1104 obj := &obsoleteUnmarshalerType{} 1105 err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj) 1106 c.Assert(err, IsNil) 1107 value, ok := obj.value.(map[string]interface{}) 1108 c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value)) 1109 c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value) 1110 } 1111 1112 func (s *S) TestUnmarshalerTypeError(c *C) { 1113 unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}} 1114 unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}} 1115 defer func() { 1116 delete(unmarshalerResult, 2) 1117 delete(unmarshalerResult, 4) 1118 }() 1119 1120 type T struct { 1121 Before int 1122 After int 1123 M map[string]*unmarshalerType 1124 } 1125 var v T 1126 data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}` 1127 err := yaml.Unmarshal([]byte(data), &v) 1128 c.Assert(err, ErrorMatches, ""+ 1129 "yaml: unmarshal errors:\n"+ 1130 " line 1: cannot unmarshal !!str `A` into int\n"+ 1131 " foo\n"+ 1132 " bar\n"+ 1133 " line 1: cannot unmarshal !!str `B` into int") 1134 c.Assert(v.M["abc"], NotNil) 1135 c.Assert(v.M["def"], IsNil) 1136 c.Assert(v.M["ghi"], NotNil) 1137 c.Assert(v.M["jkl"], IsNil) 1138 1139 c.Assert(v.M["abc"].value, Equals, 1) 1140 c.Assert(v.M["ghi"].value, Equals, 3) 1141 } 1142 1143 func (s *S) TestObsoleteUnmarshalerTypeError(c *C) { 1144 unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}} 1145 unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}} 1146 defer func() { 1147 delete(unmarshalerResult, 2) 1148 delete(unmarshalerResult, 4) 1149 }() 1150 1151 type T struct { 1152 Before int 1153 After int 1154 M map[string]*obsoleteUnmarshalerType 1155 } 1156 var v T 1157 data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}` 1158 err := yaml.Unmarshal([]byte(data), &v) 1159 c.Assert(err, ErrorMatches, ""+ 1160 "yaml: unmarshal errors:\n"+ 1161 " line 1: cannot unmarshal !!str `A` into int\n"+ 1162 " foo\n"+ 1163 " bar\n"+ 1164 " line 1: cannot unmarshal !!str `B` into int") 1165 c.Assert(v.M["abc"], NotNil) 1166 c.Assert(v.M["def"], IsNil) 1167 c.Assert(v.M["ghi"], NotNil) 1168 c.Assert(v.M["jkl"], IsNil) 1169 1170 c.Assert(v.M["abc"].value, Equals, 1) 1171 c.Assert(v.M["ghi"].value, Equals, 3) 1172 } 1173 1174 type proxyTypeError struct{} 1175 1176 func (v *proxyTypeError) UnmarshalYAML(node *yaml.Node) error { 1177 var s string 1178 var a int32 1179 var b int64 1180 if err := node.Decode(&s); err != nil { 1181 panic(err) 1182 } 1183 if s == "a" { 1184 if err := node.Decode(&b); err == nil { 1185 panic("should have failed") 1186 } 1187 return node.Decode(&a) 1188 } 1189 if err := node.Decode(&a); err == nil { 1190 panic("should have failed") 1191 } 1192 return node.Decode(&b) 1193 } 1194 1195 func (s *S) TestUnmarshalerTypeErrorProxying(c *C) { 1196 type T struct { 1197 Before int 1198 After int 1199 M map[string]*proxyTypeError 1200 } 1201 var v T 1202 data := `{before: A, m: {abc: a, def: b}, after: B}` 1203 err := yaml.Unmarshal([]byte(data), &v) 1204 c.Assert(err, ErrorMatches, ""+ 1205 "yaml: unmarshal errors:\n"+ 1206 " line 1: cannot unmarshal !!str `A` into int\n"+ 1207 " line 1: cannot unmarshal !!str `a` into int32\n"+ 1208 " line 1: cannot unmarshal !!str `b` into int64\n"+ 1209 " line 1: cannot unmarshal !!str `B` into int") 1210 } 1211 1212 type obsoleteProxyTypeError struct{} 1213 1214 func (v *obsoleteProxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error { 1215 var s string 1216 var a int32 1217 var b int64 1218 if err := unmarshal(&s); err != nil { 1219 panic(err) 1220 } 1221 if s == "a" { 1222 if err := unmarshal(&b); err == nil { 1223 panic("should have failed") 1224 } 1225 return unmarshal(&a) 1226 } 1227 if err := unmarshal(&a); err == nil { 1228 panic("should have failed") 1229 } 1230 return unmarshal(&b) 1231 } 1232 1233 func (s *S) TestObsoleteUnmarshalerTypeErrorProxying(c *C) { 1234 type T struct { 1235 Before int 1236 After int 1237 M map[string]*obsoleteProxyTypeError 1238 } 1239 var v T 1240 data := `{before: A, m: {abc: a, def: b}, after: B}` 1241 err := yaml.Unmarshal([]byte(data), &v) 1242 c.Assert(err, ErrorMatches, ""+ 1243 "yaml: unmarshal errors:\n"+ 1244 " line 1: cannot unmarshal !!str `A` into int\n"+ 1245 " line 1: cannot unmarshal !!str `a` into int32\n"+ 1246 " line 1: cannot unmarshal !!str `b` into int64\n"+ 1247 " line 1: cannot unmarshal !!str `B` into int") 1248 } 1249 1250 var failingErr = errors.New("failingErr") 1251 1252 type failingUnmarshaler struct{} 1253 1254 func (ft *failingUnmarshaler) UnmarshalYAML(node *yaml.Node) error { 1255 return failingErr 1256 } 1257 1258 func (s *S) TestUnmarshalerError(c *C) { 1259 err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{}) 1260 c.Assert(err, Equals, failingErr) 1261 } 1262 1263 type obsoleteFailingUnmarshaler struct{} 1264 1265 func (ft *obsoleteFailingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error { 1266 return failingErr 1267 } 1268 1269 func (s *S) TestObsoleteUnmarshalerError(c *C) { 1270 err := yaml.Unmarshal([]byte("a: b"), &obsoleteFailingUnmarshaler{}) 1271 c.Assert(err, Equals, failingErr) 1272 } 1273 1274 type sliceUnmarshaler []int 1275 1276 func (su *sliceUnmarshaler) UnmarshalYAML(node *yaml.Node) error { 1277 var slice []int 1278 err := node.Decode(&slice) 1279 if err == nil { 1280 *su = slice 1281 return nil 1282 } 1283 1284 var intVal int 1285 err = node.Decode(&intVal) 1286 if err == nil { 1287 *su = []int{intVal} 1288 return nil 1289 } 1290 1291 return err 1292 } 1293 1294 func (s *S) TestUnmarshalerRetry(c *C) { 1295 var su sliceUnmarshaler 1296 err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su) 1297 c.Assert(err, IsNil) 1298 c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3})) 1299 1300 err = yaml.Unmarshal([]byte("1"), &su) 1301 c.Assert(err, IsNil) 1302 c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1})) 1303 } 1304 1305 type obsoleteSliceUnmarshaler []int 1306 1307 func (su *obsoleteSliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error { 1308 var slice []int 1309 err := unmarshal(&slice) 1310 if err == nil { 1311 *su = slice 1312 return nil 1313 } 1314 1315 var intVal int 1316 err = unmarshal(&intVal) 1317 if err == nil { 1318 *su = []int{intVal} 1319 return nil 1320 } 1321 1322 return err 1323 } 1324 1325 func (s *S) TestObsoleteUnmarshalerRetry(c *C) { 1326 var su obsoleteSliceUnmarshaler 1327 err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su) 1328 c.Assert(err, IsNil) 1329 c.Assert(su, DeepEquals, obsoleteSliceUnmarshaler([]int{1, 2, 3})) 1330 1331 err = yaml.Unmarshal([]byte("1"), &su) 1332 c.Assert(err, IsNil) 1333 c.Assert(su, DeepEquals, obsoleteSliceUnmarshaler([]int{1})) 1334 } 1335 1336 // From http://yaml.org/type/merge.html 1337 var mergeTests = ` 1338 anchors: 1339 list: 1340 - &CENTER { "x": 1, "y": 2 } 1341 - &LEFT { "x": 0, "y": 2 } 1342 - &BIG { "r": 10 } 1343 - &SMALL { "r": 1 } 1344 1345 # All the following maps are equal: 1346 1347 plain: 1348 # Explicit keys 1349 "x": 1 1350 "y": 2 1351 "r": 10 1352 label: center/big 1353 1354 mergeOne: 1355 # Merge one map 1356 << : *CENTER 1357 "r": 10 1358 label: center/big 1359 1360 mergeMultiple: 1361 # Merge multiple maps 1362 << : [ *CENTER, *BIG ] 1363 label: center/big 1364 1365 override: 1366 # Override 1367 << : [ *BIG, *LEFT, *SMALL ] 1368 "x": 1 1369 label: center/big 1370 1371 shortTag: 1372 # Explicit short merge tag 1373 !!merge "<<" : [ *CENTER, *BIG ] 1374 label: center/big 1375 1376 longTag: 1377 # Explicit merge long tag 1378 !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ] 1379 label: center/big 1380 1381 inlineMap: 1382 # Inlined map 1383 << : {"x": 1, "y": 2, "r": 10} 1384 label: center/big 1385 1386 inlineSequenceMap: 1387 # Inlined map in sequence 1388 << : [ *CENTER, {"r": 10} ] 1389 label: center/big 1390 ` 1391 1392 func (s *S) TestMerge(c *C) { 1393 var want = map[interface{}]interface{}{ 1394 "x": 1, 1395 "y": 2, 1396 "r": 10, 1397 "label": "center/big", 1398 } 1399 1400 wantStringMap := make(map[string]interface{}) 1401 for k, v := range want { 1402 wantStringMap[fmt.Sprintf("%v", k)] = v 1403 } 1404 1405 var m map[interface{}]interface{} 1406 err := yaml.Unmarshal([]byte(mergeTests), &m) 1407 c.Assert(err, IsNil) 1408 for name, test := range m { 1409 if name == "anchors" { 1410 continue 1411 } 1412 if name == "plain" { 1413 c.Assert(test, DeepEquals, wantStringMap, Commentf("test %q failed", name)) 1414 continue 1415 } 1416 c.Assert(test, DeepEquals, want, Commentf("test %q failed", name)) 1417 } 1418 } 1419 1420 func (s *S) TestMergeStruct(c *C) { 1421 type Data struct { 1422 X, Y, R int 1423 Label string 1424 } 1425 want := Data{1, 2, 10, "center/big"} 1426 1427 var m map[string]Data 1428 err := yaml.Unmarshal([]byte(mergeTests), &m) 1429 c.Assert(err, IsNil) 1430 for name, test := range m { 1431 if name == "anchors" { 1432 continue 1433 } 1434 c.Assert(test, Equals, want, Commentf("test %q failed", name)) 1435 } 1436 } 1437 1438 var unmarshalNullTests = []func() interface{}{ 1439 func() interface{} { var v interface{}; v = "v"; return &v }, 1440 func() interface{} { var s = "s"; return &s }, 1441 func() interface{} { var s = "s"; sptr := &s; return &sptr }, 1442 func() interface{} { var i = 1; return &i }, 1443 func() interface{} { var i = 1; iptr := &i; return &iptr }, 1444 func() interface{} { m := map[string]int{"s": 1}; return &m }, 1445 func() interface{} { m := map[string]int{"s": 1}; return m }, 1446 } 1447 1448 func (s *S) TestUnmarshalNull(c *C) { 1449 for _, test := range unmarshalNullTests { 1450 pristine := test() 1451 decoded := test() 1452 zero := reflect.Zero(reflect.TypeOf(decoded).Elem()).Interface() 1453 err := yaml.Unmarshal([]byte("null"), decoded) 1454 c.Assert(err, IsNil) 1455 switch pristine.(type) { 1456 case *interface{}, **string, **int, *map[string]int: 1457 c.Assert(reflect.ValueOf(decoded).Elem().Interface(), DeepEquals, zero) 1458 default: 1459 c.Assert(reflect.ValueOf(decoded).Interface(), DeepEquals, pristine) 1460 } 1461 } 1462 } 1463 1464 func (s *S) TestUnmarshalPreservesData(c *C) { 1465 var v struct { 1466 A, B int 1467 C int `yaml:"-"` 1468 } 1469 v.A = 42 1470 v.C = 88 1471 err := yaml.Unmarshal([]byte("---"), &v) 1472 c.Assert(err, IsNil) 1473 c.Assert(v.A, Equals, 42) 1474 c.Assert(v.B, Equals, 0) 1475 c.Assert(v.C, Equals, 88) 1476 1477 err = yaml.Unmarshal([]byte("b: 21\nc: 99"), &v) 1478 c.Assert(err, IsNil) 1479 c.Assert(v.A, Equals, 42) 1480 c.Assert(v.B, Equals, 21) 1481 c.Assert(v.C, Equals, 88) 1482 } 1483 1484 func (s *S) TestUnmarshalSliceOnPreset(c *C) { 1485 // Issue #48. 1486 v := struct{ A []int }{[]int{1}} 1487 yaml.Unmarshal([]byte("a: [2]"), &v) 1488 c.Assert(v.A, DeepEquals, []int{2}) 1489 } 1490 1491 var unmarshalStrictTests = []struct { 1492 known bool 1493 unique bool 1494 data string 1495 value interface{} 1496 error string 1497 }{{ 1498 known: true, 1499 data: "a: 1\nc: 2\n", 1500 value: struct{ A, B int }{A: 1}, 1501 error: `yaml: unmarshal errors:\n line 2: field c not found in type struct { A int; B int }`, 1502 }, { 1503 unique: true, 1504 data: "a: 1\nb: 2\na: 3\n", 1505 value: struct{ A, B int }{A: 3, B: 2}, 1506 error: `yaml: unmarshal errors:\n line 3: mapping key "a" already defined at line 1`, 1507 }, { 1508 unique: true, 1509 data: "c: 3\na: 1\nb: 2\nc: 4\n", 1510 value: struct { 1511 A int 1512 inlineB `yaml:",inline"` 1513 }{ 1514 A: 1, 1515 inlineB: inlineB{ 1516 B: 2, 1517 inlineC: inlineC{ 1518 C: 4, 1519 }, 1520 }, 1521 }, 1522 error: `yaml: unmarshal errors:\n line 4: mapping key "c" already defined at line 1`, 1523 }, { 1524 unique: true, 1525 data: "c: 0\na: 1\nb: 2\nc: 1\n", 1526 value: struct { 1527 A int 1528 inlineB `yaml:",inline"` 1529 }{ 1530 A: 1, 1531 inlineB: inlineB{ 1532 B: 2, 1533 inlineC: inlineC{ 1534 C: 1, 1535 }, 1536 }, 1537 }, 1538 error: `yaml: unmarshal errors:\n line 4: mapping key "c" already defined at line 1`, 1539 }, { 1540 unique: true, 1541 data: "c: 1\na: 1\nb: 2\nc: 3\n", 1542 value: struct { 1543 A int 1544 M map[string]interface{} `yaml:",inline"` 1545 }{ 1546 A: 1, 1547 M: map[string]interface{}{ 1548 "b": 2, 1549 "c": 3, 1550 }, 1551 }, 1552 error: `yaml: unmarshal errors:\n line 4: mapping key "c" already defined at line 1`, 1553 }, { 1554 unique: true, 1555 data: "a: 1\n9: 2\nnull: 3\n9: 4", 1556 value: map[interface{}]interface{}{ 1557 "a": 1, 1558 nil: 3, 1559 9: 4, 1560 }, 1561 error: `yaml: unmarshal errors:\n line 4: mapping key "9" already defined at line 2`, 1562 }} 1563 1564 func (s *S) TestUnmarshalKnownFields(c *C) { 1565 for i, item := range unmarshalStrictTests { 1566 c.Logf("test %d: %q", i, item.data) 1567 // First test that normal Unmarshal unmarshals to the expected value. 1568 if !item.unique { 1569 t := reflect.ValueOf(item.value).Type() 1570 value := reflect.New(t) 1571 err := yaml.Unmarshal([]byte(item.data), value.Interface()) 1572 c.Assert(err, Equals, nil) 1573 c.Assert(value.Elem().Interface(), DeepEquals, item.value) 1574 } 1575 1576 // Then test that it fails on the same thing with KnownFields on. 1577 t := reflect.ValueOf(item.value).Type() 1578 value := reflect.New(t) 1579 dec := yaml.NewDecoder(bytes.NewBuffer([]byte(item.data))) 1580 dec.KnownFields(item.known) 1581 err := dec.Decode(value.Interface()) 1582 c.Assert(err, ErrorMatches, item.error) 1583 } 1584 } 1585 1586 type textUnmarshaler struct { 1587 S string 1588 } 1589 1590 func (t *textUnmarshaler) UnmarshalText(s []byte) error { 1591 t.S = string(s) 1592 return nil 1593 } 1594 1595 func (s *S) TestFuzzCrashers(c *C) { 1596 cases := []string{ 1597 // runtime error: index out of range 1598 "\"\\0\\\r\n", 1599 1600 // should not happen 1601 " 0: [\n] 0", 1602 "? ? \"\n\" 0", 1603 " - {\n000}0", 1604 "0:\n 0: [0\n] 0", 1605 " - \"\n000\"0", 1606 " - \"\n000\"\"", 1607 "0:\n - {\n000}0", 1608 "0:\n - \"\n000\"0", 1609 "0:\n - \"\n000\"\"", 1610 1611 // runtime error: index out of range 1612 " \ufeff\n", 1613 "? \ufeff\n", 1614 "? \ufeff:\n", 1615 "0: \ufeff\n", 1616 "? \ufeff: \ufeff\n", 1617 } 1618 for _, data := range cases { 1619 var v interface{} 1620 _ = yaml.Unmarshal([]byte(data), &v) 1621 } 1622 } 1623 1624 //var data []byte 1625 //func init() { 1626 // var err error 1627 // data, err = ioutil.ReadFile("/tmp/file.yaml") 1628 // if err != nil { 1629 // panic(err) 1630 // } 1631 //} 1632 // 1633 //func (s *S) BenchmarkUnmarshal(c *C) { 1634 // var err error 1635 // for i := 0; i < c.N; i++ { 1636 // var v map[string]interface{} 1637 // err = yaml.Unmarshal(data, &v) 1638 // } 1639 // if err != nil { 1640 // panic(err) 1641 // } 1642 //} 1643 // 1644 //func (s *S) BenchmarkMarshal(c *C) { 1645 // var v map[string]interface{} 1646 // yaml.Unmarshal(data, &v) 1647 // c.ResetTimer() 1648 // for i := 0; i < c.N; i++ { 1649 // yaml.Marshal(&v) 1650 // } 1651 //}