cuelang.org/go@v0.10.1/internal/third_party/yaml/decode_test.go (about) 1 package yaml_test 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "os" 8 "strconv" 9 "strings" 10 "testing" 11 12 "cuelang.org/go/cue/ast" 13 "cuelang.org/go/cue/format" 14 "cuelang.org/go/internal/cuetest" 15 "cuelang.org/go/internal/third_party/yaml" 16 ) 17 18 var unmarshalIntTest = 123 19 20 var unmarshalTests = []struct { 21 data string 22 want string 23 }{ 24 { 25 "", 26 "", 27 }, 28 { 29 "{}", 30 "", 31 }, { 32 "v: hi", 33 `v: "hi"`, 34 }, { 35 "v: hi", 36 `v: "hi"`, 37 }, { 38 "v: true", 39 "v: true", 40 }, { 41 "v: 10", 42 "v: 10", 43 }, { 44 "v: 0b10", 45 "v: 0b10", 46 }, { 47 "v: 0xA", 48 "v: 0xA", 49 }, { 50 "v: 4294967296", 51 "v: 4294967296", 52 }, { 53 "v: 0.1", 54 "v: 0.1", 55 }, { 56 "v: .1", 57 "v: 0.1", 58 }, { 59 "v: .Inf", 60 "v: +Inf", 61 }, { 62 "v: -.Inf", 63 "v: -Inf", 64 }, { 65 "v: -10", 66 "v: -10", 67 }, { 68 "v: -.1", 69 "v: -0.1", 70 }, 71 72 // Simple values. 73 { 74 "123", 75 "123", 76 }, 77 78 // Floats from spec 79 { 80 "canonical: 6.8523e+5", 81 "canonical: 6.8523e+5", 82 }, { 83 "expo: 685.230_15e+03", 84 "expo: 685.230_15e+03", 85 }, { 86 "fixed: 685_230.15", 87 "fixed: 685_230.15", 88 }, { 89 "neginf: -.inf", 90 "neginf: -Inf", 91 }, { 92 "fixed: 685_230.15", 93 "fixed: 685_230.15", 94 }, 95 //{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported 96 //{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails. 97 98 // Bools from spec 99 { 100 "canonical: y", 101 `canonical: "y"`, 102 }, { 103 "answer: n", 104 `answer: "n"`, 105 }, { 106 "answer: NO", 107 `answer: "NO"`, 108 }, { 109 "logical: True", 110 "logical: true", 111 }, { 112 "option: on", 113 `option: "on"`, 114 }, { 115 "answer: off", 116 `answer: "off"`, 117 }, 118 // Ints from spec 119 { 120 "canonical: 685230", 121 "canonical: 685230", 122 }, { 123 "decimal: +685_230", 124 "decimal: +685_230", 125 }, { 126 "octal: 02472256", 127 "octal: 0o2472256", 128 }, { 129 "hexa: 0x_0A_74_AE", 130 "hexa: 0x_0A_74_AE", 131 }, { 132 "bin: 0b1010_0111_0100_1010_1110", 133 "bin: 0b1010_0111_0100_1010_1110", 134 }, { 135 "bin: -0b101010", 136 "bin: -0b101010", 137 }, { 138 "bin: -0b1000000000000000000000000000000000000000000000000000000000000000", 139 "bin: -0b1000000000000000000000000000000000000000000000000000000000000000", 140 }, { 141 "decimal: +685_230", 142 "decimal: +685_230", 143 }, 144 145 //{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported 146 147 // Nulls from spec 148 { 149 "empty:", 150 "empty: null", 151 }, { 152 "canonical: ~", 153 "canonical: null", 154 }, { 155 "english: null", 156 "english: null", 157 }, { 158 "_foo: 1", 159 `"_foo": 1`, 160 }, { 161 `"#foo": 1`, 162 `"#foo": 1`, 163 }, { 164 "_#foo: 1", 165 `"_#foo": 1`, 166 }, { 167 "~: null key", 168 `"null": "null key"`, 169 }, { 170 `empty: 171 apple: "newline"`, 172 `empty: null 173 apple: "newline"`, 174 }, 175 176 // Flow sequence 177 { 178 "seq: [A,B]", 179 `seq: ["A", "B"]`, 180 }, { 181 "seq: [A,B,C,]", 182 `seq: ["A", "B", "C"]`, 183 }, { 184 "seq: [A,1,C]", 185 `seq: ["A", 1, "C"]`, 186 }, 187 // Block sequence 188 { 189 "seq:\n - A\n - B", 190 `seq: [ 191 "A", 192 "B", 193 ]`, 194 }, { 195 "seq:\n - A\n - B\n - C", 196 `seq: [ 197 "A", 198 "B", 199 "C", 200 ]`, 201 }, { 202 "seq:\n - A\n - 1\n - C", 203 `seq: [ 204 "A", 205 1, 206 "C", 207 ]`, 208 }, 209 210 // Literal block scalar 211 { 212 "scalar: | # Comment\n\n literal\n\n \ttext\n\n", 213 `scalar: """ 214 215 literal 216 217 \ttext 218 219 """`, 220 }, 221 222 // Folded block scalar 223 { 224 "scalar: > # Comment\n\n folded\n line\n \n next\n line\n * one\n * two\n\n last\n line\n\n", 225 `scalar: """ 226 227 folded line 228 next line 229 * one 230 * two 231 232 last line 233 234 """`, 235 }, 236 237 // Structs 238 { 239 "a: {b: c}", 240 `a: {b: "c"}`, 241 }, 242 { 243 "hello: world", 244 `hello: "world"`, 245 }, { 246 "a:", 247 "a: null", 248 }, { 249 "a: 1", 250 "a: 1", 251 }, { 252 "a: 1.0", 253 "a: 1.0", 254 }, { 255 "a: [1, 2]", 256 "a: [1, 2]", 257 }, { 258 "a: y", 259 `a: "y"`, 260 }, { 261 "{ a: 1, b: {c: 1} }", 262 `a: 1, b: {c: 1}`, 263 }, { 264 ` 265 True: 1 266 Null: 1 267 .Inf: 2 268 `, 269 `"true": 1 270 "null": 1 271 "+Inf": 2`, 272 }, 273 274 // Some cross type conversions 275 { 276 "v: 42", 277 "v: 42", 278 }, { 279 "v: -42", 280 "v: -42", 281 }, { 282 "v: 4294967296", 283 "v: 4294967296", 284 }, { 285 "v: -4294967296", 286 "v: -4294967296", 287 }, 288 289 // int 290 { 291 "int_max: 2147483647", 292 "int_max: 2147483647", 293 }, 294 { 295 "int_min: -2147483648", 296 "int_min: -2147483648", 297 }, 298 { 299 "int_overflow: 9223372036854775808", // math.MaxInt64 + 1 300 "int_overflow: 9223372036854775808", // math.MaxInt64 + 1 301 }, 302 303 // int64 304 { 305 "int64_max: 9223372036854775807", 306 "int64_max: 9223372036854775807", 307 }, 308 { 309 "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111", 310 "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111", 311 }, 312 { 313 "int64_min: -9223372036854775808", 314 "int64_min: -9223372036854775808", 315 }, 316 { 317 "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111", 318 "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111", 319 }, 320 { 321 "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1 322 "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1 323 }, 324 325 // uint 326 { 327 "uint_max: 4294967295", 328 "uint_max: 4294967295", 329 }, 330 331 // uint64 332 { 333 "uint64_max: 18446744073709551615", 334 "uint64_max: 18446744073709551615", 335 }, 336 { 337 "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111", 338 "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111", 339 }, 340 { 341 "uint64_maxint64: 9223372036854775807", 342 "uint64_maxint64: 9223372036854775807", 343 }, 344 345 // float32 346 { 347 "float32_max: 3.40282346638528859811704183484516925440e+38", 348 "float32_max: 3.40282346638528859811704183484516925440e+38", 349 }, 350 { 351 "float32_nonzero: 1.401298464324817070923729583289916131280e-45", 352 "float32_nonzero: 1.401298464324817070923729583289916131280e-45", 353 }, 354 { 355 "float32_maxuint64: 18446744073709551615", 356 "float32_maxuint64: 18446744073709551615", 357 }, 358 { 359 "float32_maxuint64+1: 18446744073709551616", 360 `"float32_maxuint64+1": 18446744073709551616`, 361 }, 362 363 // float64 364 { 365 "float64_max: 1.797693134862315708145274237317043567981e+308", 366 "float64_max: 1.797693134862315708145274237317043567981e+308", 367 }, 368 { 369 "float64_nonzero: 4.940656458412465441765687928682213723651e-324", 370 "float64_nonzero: 4.940656458412465441765687928682213723651e-324", 371 }, 372 { 373 "float64_maxuint64: 18446744073709551615", 374 "float64_maxuint64: 18446744073709551615", 375 }, 376 { 377 "float64_maxuint64+1: 18446744073709551616", 378 `"float64_maxuint64+1": 18446744073709551616`, 379 }, 380 381 // Overflow cases. 382 { 383 "v: 4294967297", 384 "v: 4294967297", 385 }, { 386 "v: 128", 387 "v: 128", 388 }, 389 390 // Quoted values. 391 { 392 "'1': '\"2\"'", 393 `"1": "\"2\""`, 394 }, { 395 "v:\n- A\n- 'B\n\n C'\n", 396 `v: [ 397 "A", 398 """ 399 B 400 C 401 """, 402 ]`, 403 }, { 404 `"\0"`, 405 `"\u0000"`, 406 }, 407 408 // Explicit tags. 409 { 410 "v: !!float '1.1'", 411 "v: 1.1", 412 }, { 413 "v: !!float 0", 414 "v: float & 0", // Should this be 0.0? 415 }, { 416 "v: !!float -1", 417 "v: float & -1", // Should this be -1.0? 418 }, { 419 "v: !!null ''", 420 "v: null", 421 }, { 422 "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'", 423 "v: 1", 424 }, 425 426 // Non-specific tag (Issue #75) 427 { 428 `v: ! test`, 429 // TODO this should work and produce a string. 430 "", 431 }, 432 433 // Anchors and aliases. 434 { 435 "a: &x 1\nb: &y 2\nc: *x\nd: *y\n", 436 `a: 1 437 b: 2 438 c: 1 439 d: 2`, 440 }, { 441 "a: &a {c: 1}\nb: *a", 442 `a: {c: 1} 443 b: { 444 c: 1 445 }`, 446 }, { 447 "a: &a [1, 2]\nb: *a", 448 "a: [1, 2]\nb: [1, 2]", // TODO: a: [1, 2], b: a 449 }, 450 451 { 452 "foo: ''", 453 `foo: ""`, 454 }, { 455 "foo: null", 456 "foo: null", 457 }, 458 459 // Support for ~ 460 { 461 "foo: ~", 462 "foo: null", 463 }, 464 465 // Bug #1191981 466 { 467 "" + 468 "%YAML 1.1\n" + 469 "--- !!str\n" + 470 `"Generic line break (no glyph)\n\` + "\n" + 471 ` Generic line break (glyphed)\n\` + "\n" + 472 ` Line separator\u2028\` + "\n" + 473 ` Paragraph separator\u2029"` + "\n", 474 `""" 475 Generic line break (no glyph) 476 Generic line break (glyphed) 477 Line separator\u2028Paragraph separator\u2029 478 """`, 479 }, 480 481 // bug 1243827 482 { 483 "a: -b_c", 484 `a: "-b_c"`, 485 }, 486 { 487 "a: +b_c", 488 `a: "+b_c"`, 489 }, 490 { 491 "a: 50cent_of_dollar", 492 `a: "50cent_of_dollar"`, 493 }, 494 495 // issue #295 (allow scalars with colons in flow mappings and sequences) 496 { 497 "a: {b: https://github.com/go-yaml/yaml}", 498 `a: {b: "https://github.com/go-yaml/yaml"}`, 499 }, 500 { 501 "a: [https://github.com/go-yaml/yaml]", 502 `a: ["https://github.com/go-yaml/yaml"]`, 503 }, 504 505 // Duration 506 { 507 "a: 3s", 508 `a: "3s"`, // for now 509 }, 510 511 // Issue #24. 512 { 513 "a: <foo>", 514 `a: "<foo>"`, 515 }, 516 517 // Base 60 floats are obsolete and unsupported. 518 { 519 "a: 1:1\n", 520 `a: "1:1"`, 521 }, 522 523 // Binary data. 524 { 525 "a: !!binary gIGC\n", 526 `a: '\x80\x81\x82'`, 527 }, { 528 "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n", 529 "a: '" + strings.Repeat(`\x90`, 54) + "'", 530 }, { 531 "a: !!binary |\n " + strings.Repeat("A", 70) + "\n ==\n", 532 "a: '" + strings.Repeat(`\x00`, 52) + "'", 533 }, 534 535 // Ordered maps. 536 { 537 "{b: 2, a: 1, d: 4, c: 3, sub: {e: 5}}", 538 `b: 2, a: 1, d: 4, c: 3, sub: {e: 5}`, 539 }, 540 541 // Spacing 542 { 543 ` 544 a: {} 545 c: 1 546 d: [] 547 e: [] 548 `, 549 `a: {} 550 c: 1 551 d: [] 552 e: []`, 553 }, 554 555 { 556 ` 557 a: 558 - { "a": 1, "b": 2 } 559 - { "c": 1, "d": 2 } 560 `, 561 `a: [{ 562 a: 1, b: 2 563 }, { 564 c: 1, d: 2 565 }]`, 566 }, 567 568 { 569 "a:\n b:\n c: d\n e: f\n", 570 `a: { 571 b: { 572 c: "d" 573 e: "f" 574 } 575 }`, 576 }, 577 578 // Issue #39. 579 { 580 "a:\n b:\n c: d\n", 581 `a: { 582 b: { 583 c: "d" 584 } 585 }`, 586 }, 587 588 // Timestamps 589 { 590 // Date only. 591 "a: 2015-01-01\n", 592 `a: "2015-01-01"`, 593 }, 594 { 595 // RFC3339 596 "a: 2015-02-24T18:19:39.12Z\n", 597 `a: "2015-02-24T18:19:39.12Z"`, 598 }, 599 { 600 // RFC3339 with short dates. 601 "a: 2015-2-3T3:4:5Z", 602 `a: "2015-2-3T3:4:5Z"`, 603 }, 604 { 605 // ISO8601 lower case t 606 "a: 2015-02-24t18:19:39Z\n", 607 `a: "2015-02-24t18:19:39Z"`, 608 }, 609 { 610 // space separate, no time zone 611 "a: 2015-02-24 18:19:39\n", 612 `a: "2015-02-24 18:19:39"`, 613 }, 614 // Some cases not currently handled. Uncomment these when 615 // the code is fixed. 616 // { 617 // // space separated with time zone 618 // "a: 2001-12-14 21:59:43.10 -5", 619 // map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)}, 620 // }, 621 // { 622 // // arbitrary whitespace between fields 623 // "a: 2001-12-14 \t\t \t21:59:43.10 \t Z", 624 // map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)}, 625 // }, 626 { 627 // explicit string tag 628 "a: !!str 2015-01-01", 629 `a: "2015-01-01"`, 630 }, 631 { 632 // explicit timestamp tag on quoted string 633 "a: !!timestamp \"2015-01-01\"", 634 `a: "2015-01-01"`, 635 }, 636 { 637 // explicit timestamp tag on unquoted string 638 "a: !!timestamp 2015-01-01", 639 `a: "2015-01-01"`, 640 }, 641 { 642 // quoted string that's a valid timestamp 643 "a: \"2015-01-01\"", 644 "a: \"2015-01-01\"", 645 }, 646 647 // Empty list 648 { 649 "a: []", 650 "a: []", 651 }, 652 653 // UTF-16-LE 654 { 655 "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00", 656 `ñoño: "very yes"`, 657 }, 658 // UTF-16-LE with surrogate. 659 { 660 "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00", 661 `ñoño: "very yes 🟔"`, 662 }, 663 664 // UTF-16-BE 665 { 666 "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n", 667 `ñoño: "very yes"`, 668 }, 669 // UTF-16-BE with surrogate. 670 { 671 "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n", 672 `ñoño: "very yes 🟔"`, 673 }, 674 675 // This *is* in fact a float number, per the spec. #171 was a mistake. 676 { 677 "a: 123456e1\n", 678 `a: 123456e1`, 679 }, { 680 "a: 123456E1\n", 681 `a: 123456e1`, 682 }, 683 // Other float formats: 684 { 685 "x: .1", 686 "x: 0.1", 687 }, 688 { 689 "x: .1e-3", 690 "x: 0.1e-3", 691 }, 692 { 693 "x: 1.2E4", 694 "x: 1.2e4", 695 }, 696 { 697 "x: 1.2E+4", 698 "x: 1.2e+4", 699 }, 700 // yaml-test-suite 3GZX: Spec Example 7.1. Alias Nodes 701 { 702 "First occurrence: &anchor Foo\nSecond occurrence: *anchor\nOverride anchor: &anchor Bar\nReuse anchor: *anchor\n", 703 `"First occurrence": "Foo" 704 "Second occurrence": "Foo" 705 "Override anchor": "Bar" 706 "Reuse anchor": "Bar"`, 707 }, 708 // Single document with garbage following it. 709 { 710 "---\nhello\n...\n}not yaml", 711 `"hello"`, 712 }, 713 } 714 715 type M map[interface{}]interface{} 716 717 type inlineB struct { 718 B int 719 inlineC `yaml:",inline"` 720 } 721 722 type inlineC struct { 723 C int 724 } 725 726 func cueStr(node ast.Node) string { 727 if s, ok := node.(*ast.StructLit); ok { 728 node = &ast.File{ 729 Decls: s.Elts, 730 } 731 } 732 b, _ := format.Node(node) 733 return strings.TrimSpace(string(b)) 734 } 735 736 func newDecoder(t *testing.T, data string) *yaml.Decoder { 737 dec, err := yaml.NewDecoder("test.yaml", strings.NewReader(data)) 738 if err != nil { 739 t.Fatal(err) 740 } 741 return dec 742 } 743 744 func callUnmarshal(t *testing.T, data string) (ast.Expr, error) { 745 return yaml.Unmarshal("test.yaml", []byte(data)) 746 } 747 748 func TestUnmarshal(t *testing.T) { 749 for i, item := range unmarshalTests { 750 t.Run(strconv.Itoa(i), func(t *testing.T) { 751 t.Logf("test %d: %q", i, item.data) 752 expr, err := callUnmarshal(t, item.data) 753 if _, ok := err.(*yaml.TypeError); !ok && err != nil { 754 t.Fatal("expected error to be nil") 755 } 756 if got := cueStr(expr); got != item.want { 757 t.Errorf("\n got:\n%v\nwant:\n%v", got, item.want) 758 } 759 }) 760 } 761 } 762 763 // For debug purposes: do not delete. 764 func TestX(t *testing.T) { 765 y := ` 766 ` 767 y = strings.TrimSpace(y) 768 if len(y) == 0 { 769 t.Skip() 770 } 771 772 expr, err := callUnmarshal(t, y) 773 if _, ok := err.(*yaml.TypeError); !ok && err != nil { 774 t.Fatal(err) 775 } 776 t.Error(cueStr(expr)) 777 } 778 779 // // TODO(v3): This test should also work when unmarshaling onto an interface{}. 780 // func (s *S) TestUnmarshalFullTimestamp(c *C) { 781 // // Full timestamp in same format as encoded. This is confirmed to be 782 // // properly decoded by Python as a timestamp as well. 783 // var str = "2015-02-24T18:19:39.123456789-03:00" 784 // expr, err := yaml.Unmarshal([]byte(str)) 785 // c.Assert(err, IsNil) 786 // c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.Location())) 787 // c.Assert(t.In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC)) 788 // } 789 790 func TestDecoderSingleDocument(t *testing.T) { 791 // Test that Decoder.Decode works as expected on 792 // all the unmarshal tests. 793 for i, item := range unmarshalTests { 794 t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 795 if item.data == "" { 796 // Behaviour differs when there's no YAML. 797 return 798 } 799 expr, err := newDecoder(t, item.data).Decode() 800 if _, ok := err.(*yaml.TypeError); !ok && err != nil { 801 t.Errorf("err should be nil, was %v", err) 802 } 803 if got := cueStr(expr); got != item.want { 804 t.Errorf("\n got: %v;\nwant: %v", got, item.want) 805 } 806 }) 807 } 808 } 809 810 var decoderTests = []struct { 811 data string 812 want string 813 }{{ 814 "", 815 "", 816 }, { 817 "a: b", 818 `a: "b"`, 819 }, { 820 "---\na: b\n...\n", 821 `a: "b"`, 822 }, { 823 "---\n'hello'\n...\n---\ngoodbye\n...\n", 824 `"hello"` + "\n" + `"goodbye"`, 825 }} 826 827 func TestDecoder(t *testing.T) { 828 for i, item := range decoderTests { 829 t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 830 var values []string 831 dec := newDecoder(t, item.data) 832 for { 833 expr, err := dec.Decode() 834 if err == io.EOF { 835 break 836 } 837 if err != nil { 838 t.Errorf("err should be nil, was %v", err) 839 } 840 values = append(values, cueStr(expr)) 841 } 842 got := strings.Join(values, "\n") 843 if got != item.want { 844 t.Errorf("\n got: %v;\nwant: %v", got, item.want) 845 } 846 }) 847 } 848 } 849 850 type errReader struct{} 851 852 func (errReader) Read([]byte) (int, error) { 853 return 0, errors.New("some read error") 854 } 855 856 func TestUnmarshalNaN(t *testing.T) { 857 expr, err := callUnmarshal(t, "notanum: .NaN") 858 if err != nil { 859 t.Fatal("unexpected error", err) 860 } 861 got := cueStr(expr) 862 want := "notanum: NaN" 863 if got != want { 864 t.Errorf("got %v; want %v", got, want) 865 } 866 } 867 868 var unmarshalErrorTests = []struct { 869 data, error string 870 }{ 871 {"\nv: !!float 'error'", "test.yaml:2: cannot decode !!str `error` as a !!float"}, 872 {"v: [A,", "test.yaml:1: did not find expected node content"}, 873 {"v:\n- [A,", "test.yaml:2: did not find expected node content"}, 874 {"a:\n- b: *,", "test.yaml:2: did not find expected alphabetic or numeric character"}, 875 {"a: *b\n", "test.yaml:1: unknown anchor 'b' referenced"}, 876 {"a: &a\n b: *a\n", "test.yaml:2: anchor 'a' value contains itself"}, 877 {"value: -", "test.yaml:1: block sequence entries are not allowed in this context"}, 878 {"a: !!binary ==", "test.yaml:1: !!binary value contains invalid base64 data"}, 879 {"{[.]}", `test.yaml:1: invalid map key: sequence`}, 880 {"{{.}}", `test.yaml:1: invalid map key: map`}, 881 {"b: *a\na: &a {c: 1}", `test.yaml:1: unknown anchor 'a' referenced`}, 882 {"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "test.yaml:1: did not find expected whitespace"}, 883 } 884 885 func TestUnmarshalErrors(t *testing.T) { 886 for i, item := range unmarshalErrorTests { 887 t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 888 expr, err := callUnmarshal(t, item.data) 889 val := "" 890 if expr != nil { 891 val = cueStr(expr) 892 } 893 if err == nil || err.Error() != item.error { 894 t.Errorf("got %v; want %v; (value %v)", err, item.error, val) 895 } 896 }) 897 } 898 } 899 900 func TestDecoderErrors(t *testing.T) { 901 for i, item := range unmarshalErrorTests { 902 t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 903 _, err := newDecoder(t, item.data).Decode() 904 if err == nil || err.Error() != item.error { 905 t.Errorf("got %v; want %v", err, item.error) 906 } 907 }) 908 } 909 } 910 911 func TestFiles(t *testing.T) { 912 files := []string{"merge"} 913 for _, test := range files { 914 t.Run(test, func(t *testing.T) { 915 testname := fmt.Sprintf("testdata/%s.test", test) 916 filename := fmt.Sprintf("testdata/%s.out", test) 917 mergeTests, err := os.ReadFile(testname) 918 if err != nil { 919 t.Fatal(err) 920 } 921 expr, err := yaml.Unmarshal("test.yaml", mergeTests) 922 if err != nil { 923 t.Fatal(err) 924 } 925 got := cueStr(expr) 926 if cuetest.UpdateGoldenFiles { 927 os.WriteFile(filename, []byte(got), 0644) 928 return 929 } 930 b, err := os.ReadFile(filename) 931 if err != nil { 932 t.Fatal(err) 933 } 934 if want := string(b); got != want { 935 t.Errorf("\n got: %v;\nwant: %v", got, want) 936 } 937 }) 938 } 939 } 940 941 func TestFuzzCrashers(t *testing.T) { 942 cases := []string{ 943 // runtime error: index out of range 944 "\"\\0\\\r\n", 945 946 // should not happen 947 " 0: [\n] 0", 948 "? ? \"\n\" 0", 949 " - {\n000}0", 950 "0:\n 0: [0\n] 0", 951 " - \"\n000\"0", 952 " - \"\n000\"\"", 953 "0:\n - {\n000}0", 954 "0:\n - \"\n000\"0", 955 "0:\n - \"\n000\"\"", 956 957 // runtime error: index out of range 958 " \ufeff\n", 959 "? \ufeff\n", 960 "? \ufeff:\n", 961 "0: \ufeff\n", 962 "? \ufeff: \ufeff\n", 963 } 964 for _, data := range cases { 965 _, _ = callUnmarshal(t, data) 966 } 967 } 968 969 //var data []byte 970 //func init() { 971 // var err error 972 // data, err = os.ReadFile("/tmp/file.yaml") 973 // if err != nil { 974 // panic(err) 975 // } 976 //} 977 // 978 //func (s *S) BenchmarkUnmarshal(c *C) { 979 // var err error 980 // for i := 0; i < c.N; i++ { 981 // var v map[string]interface{} 982 // err = yaml.Unmarshal(data, &v) 983 // } 984 // if err != nil { 985 // panic(err) 986 // } 987 //} 988 // 989 //func (s *S) BenchmarkMarshal(c *C) { 990 // var v map[string]interface{} 991 // yaml.Unmarshal(data, &v) 992 // c.ResetTimer() 993 // for i := 0; i < c.N; i++ { 994 // yaml.Marshal(&v) 995 // } 996 //}