github.com/solo-io/cue@v0.4.7/internal/third_party/yaml/decode_test.go (about) 1 package yaml_test 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "strconv" 9 "strings" 10 "testing" 11 12 "github.com/solo-io/cue/cue/ast" 13 "github.com/solo-io/cue/cue/format" 14 "github.com/solo-io/cue/internal/cuetest" 15 "github.com/solo-io/cue/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 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 // Some cross type conversions 266 { 267 "v: 42", 268 "v: 42", 269 }, { 270 "v: -42", 271 "v: -42", 272 }, { 273 "v: 4294967296", 274 "v: 4294967296", 275 }, { 276 "v: -4294967296", 277 "v: -4294967296", 278 }, 279 280 // int 281 { 282 "int_max: 2147483647", 283 "int_max: 2147483647", 284 }, 285 { 286 "int_min: -2147483648", 287 "int_min: -2147483648", 288 }, 289 { 290 "int_overflow: 9223372036854775808", // math.MaxInt64 + 1 291 "int_overflow: 9223372036854775808", // math.MaxInt64 + 1 292 }, 293 294 // int64 295 { 296 "int64_max: 9223372036854775807", 297 "int64_max: 9223372036854775807", 298 }, 299 { 300 "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111", 301 "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111", 302 }, 303 { 304 "int64_min: -9223372036854775808", 305 "int64_min: -9223372036854775808", 306 }, 307 { 308 "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111", 309 "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111", 310 }, 311 { 312 "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1 313 "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1 314 }, 315 316 // uint 317 { 318 "uint_max: 4294967295", 319 "uint_max: 4294967295", 320 }, 321 322 // uint64 323 { 324 "uint64_max: 18446744073709551615", 325 "uint64_max: 18446744073709551615", 326 }, 327 { 328 "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111", 329 "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111", 330 }, 331 { 332 "uint64_maxint64: 9223372036854775807", 333 "uint64_maxint64: 9223372036854775807", 334 }, 335 336 // float32 337 { 338 "float32_max: 3.40282346638528859811704183484516925440e+38", 339 "float32_max: 3.40282346638528859811704183484516925440e+38", 340 }, 341 { 342 "float32_nonzero: 1.401298464324817070923729583289916131280e-45", 343 "float32_nonzero: 1.401298464324817070923729583289916131280e-45", 344 }, 345 { 346 "float32_maxuint64: 18446744073709551615", 347 "float32_maxuint64: 18446744073709551615", 348 }, 349 { 350 "float32_maxuint64+1: 18446744073709551616", 351 `"float32_maxuint64+1": 18446744073709551616`, 352 }, 353 354 // float64 355 { 356 "float64_max: 1.797693134862315708145274237317043567981e+308", 357 "float64_max: 1.797693134862315708145274237317043567981e+308", 358 }, 359 { 360 "float64_nonzero: 4.940656458412465441765687928682213723651e-324", 361 "float64_nonzero: 4.940656458412465441765687928682213723651e-324", 362 }, 363 { 364 "float64_maxuint64: 18446744073709551615", 365 "float64_maxuint64: 18446744073709551615", 366 }, 367 { 368 "float64_maxuint64+1: 18446744073709551616", 369 `"float64_maxuint64+1": 18446744073709551616`, 370 }, 371 372 // Overflow cases. 373 { 374 "v: 4294967297", 375 "v: 4294967297", 376 }, { 377 "v: 128", 378 "v: 128", 379 }, 380 381 // Quoted values. 382 { 383 "'1': '\"2\"'", 384 `"1": "\"2\""`, 385 }, { 386 "v:\n- A\n- 'B\n\n C'\n", 387 `v: [ 388 "A", 389 """ 390 B 391 C 392 """, 393 ]`, 394 }, { 395 `"\0"`, 396 `"\u0000"`, 397 }, 398 399 // Explicit tags. 400 { 401 "v: !!float '1.1'", 402 "v: 1.1", 403 }, { 404 "v: !!float 0", 405 "v: float & 0", // Should this be 0.0? 406 }, { 407 "v: !!float -1", 408 "v: float & -1", // Should this be -1.0? 409 }, { 410 "v: !!null ''", 411 "v: null", 412 }, { 413 "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'", 414 "v: 1", 415 }, 416 417 // Non-specific tag (Issue #75) 418 { 419 "v: ! test", 420 // TODO: map[string]interface{}{"v": "test"}, 421 "", 422 }, 423 424 // Anchors and aliases. 425 { 426 "a: &x 1\nb: &y 2\nc: *x\nd: *y\n", 427 `a: 1 428 b: 2 429 c: 1 430 d: 2`, 431 }, { 432 "a: &a {c: 1}\nb: *a", 433 `a: {c: 1} 434 b: { 435 c: 1 436 }`, 437 }, { 438 "a: &a [1, 2]\nb: *a", 439 "a: [1, 2]\nb: [1, 2]", // TODO: a: [1, 2], b: a 440 }, 441 442 { 443 "foo: ''", 444 `foo: ""`, 445 }, { 446 "foo: null", 447 "foo: null", 448 }, 449 450 // Support for ~ 451 { 452 "foo: ~", 453 "foo: null", 454 }, 455 456 // Bug #1191981 457 { 458 "" + 459 "%YAML 1.1\n" + 460 "--- !!str\n" + 461 `"Generic line break (no glyph)\n\` + "\n" + 462 ` Generic line break (glyphed)\n\` + "\n" + 463 ` Line separator\u2028\` + "\n" + 464 ` Paragraph separator\u2029"` + "\n", 465 `""" 466 Generic line break (no glyph) 467 Generic line break (glyphed) 468 Line separator\u2028Paragraph separator\u2029 469 """`, 470 }, 471 472 // bug 1243827 473 { 474 "a: -b_c", 475 `a: "-b_c"`, 476 }, 477 { 478 "a: +b_c", 479 `a: "+b_c"`, 480 }, 481 { 482 "a: 50cent_of_dollar", 483 `a: "50cent_of_dollar"`, 484 }, 485 486 // issue #295 (allow scalars with colons in flow mappings and sequences) 487 { 488 "a: {b: https://github.com/go-yaml/yaml}", 489 `a: {b: "https://github.com/go-yaml/yaml"}`, 490 }, 491 { 492 "a: [https://github.com/go-yaml/yaml]", 493 `a: ["https://github.com/go-yaml/yaml"]`, 494 }, 495 496 // Duration 497 { 498 "a: 3s", 499 `a: "3s"`, // for now 500 }, 501 502 // Issue #24. 503 { 504 "a: <foo>", 505 `a: "<foo>"`, 506 }, 507 508 // Base 60 floats are obsolete and unsupported. 509 { 510 "a: 1:1\n", 511 `a: "1:1"`, 512 }, 513 514 // Binary data. 515 { 516 "a: !!binary gIGC\n", 517 `a: '\x80\x81\x82'`, 518 }, { 519 "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n", 520 "a: '" + strings.Repeat(`\x90`, 54) + "'", 521 }, { 522 "a: !!binary |\n " + strings.Repeat("A", 70) + "\n ==\n", 523 "a: '" + strings.Repeat(`\x00`, 52) + "'", 524 }, 525 526 // Ordered maps. 527 { 528 "{b: 2, a: 1, d: 4, c: 3, sub: {e: 5}}", 529 `b: 2, a: 1, d: 4, c: 3, sub: {e: 5}`, 530 }, 531 532 // Spacing 533 { 534 ` 535 a: {} 536 c: 1 537 d: [ 538 ] 539 e: [] 540 `, 541 `a: {} 542 c: 1 543 d: [ 544 ] 545 e: []`, 546 }, 547 548 { 549 ` 550 a: 551 - { "a": 1, "b": 2 } 552 - { "c": 1, "d": 2 } 553 `, 554 `a: [{ 555 a: 1, b: 2 556 }, { 557 c: 1, d: 2 558 }]`, 559 }, 560 561 { 562 "a:\n b:\n c: d\n e: f\n", 563 `a: { 564 b: { 565 c: "d" 566 e: "f" 567 } 568 }`, 569 }, 570 571 // Issue #39. 572 { 573 "a:\n b:\n c: d\n", 574 `a: { 575 b: { 576 c: "d" 577 } 578 }`, 579 }, 580 581 // Timestamps 582 { 583 // Date only. 584 "a: 2015-01-01\n", 585 `a: "2015-01-01"`, 586 }, 587 { 588 // RFC3339 589 "a: 2015-02-24T18:19:39.12Z\n", 590 `a: "2015-02-24T18:19:39.12Z"`, 591 }, 592 { 593 // RFC3339 with short dates. 594 "a: 2015-2-3T3:4:5Z", 595 `a: "2015-2-3T3:4:5Z"`, 596 }, 597 { 598 // ISO8601 lower case t 599 "a: 2015-02-24t18:19:39Z\n", 600 `a: "2015-02-24t18:19:39Z"`, 601 }, 602 { 603 // space separate, no time zone 604 "a: 2015-02-24 18:19:39\n", 605 `a: "2015-02-24 18:19:39"`, 606 }, 607 // Some cases not currently handled. Uncomment these when 608 // the code is fixed. 609 // { 610 // // space separated with time zone 611 // "a: 2001-12-14 21:59:43.10 -5", 612 // map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)}, 613 // }, 614 // { 615 // // arbitrary whitespace between fields 616 // "a: 2001-12-14 \t\t \t21:59:43.10 \t Z", 617 // map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)}, 618 // }, 619 { 620 // explicit string tag 621 "a: !!str 2015-01-01", 622 `a: "2015-01-01"`, 623 }, 624 { 625 // explicit timestamp tag on quoted string 626 "a: !!timestamp \"2015-01-01\"", 627 `a: "2015-01-01"`, 628 }, 629 { 630 // explicit timestamp tag on unquoted string 631 "a: !!timestamp 2015-01-01", 632 `a: "2015-01-01"`, 633 }, 634 { 635 // quoted string that's a valid timestamp 636 "a: \"2015-01-01\"", 637 "a: \"2015-01-01\"", 638 }, 639 640 // Empty list 641 { 642 "a: []", 643 "a: []", 644 }, 645 646 // UTF-16-LE 647 { 648 "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00", 649 `ñoño: "very yes"`, 650 }, 651 // UTF-16-LE with surrogate. 652 { 653 "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00", 654 `ñoño: "very yes 🟔"`, 655 }, 656 657 // UTF-16-BE 658 { 659 "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n", 660 `ñoño: "very yes"`, 661 }, 662 // UTF-16-BE with surrogate. 663 { 664 "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n", 665 `ñoño: "very yes 🟔"`, 666 }, 667 668 // YAML Float regex shouldn't match this 669 { 670 "a: 123456e1\n", 671 `a: "123456e1"`, 672 }, { 673 "a: 123456E1\n", 674 `a: "123456E1"`, 675 }, 676 // yaml-test-suite 3GZX: Spec Example 7.1. Alias Nodes 677 { 678 "First occurrence: &anchor Foo\nSecond occurrence: *anchor\nOverride anchor: &anchor Bar\nReuse anchor: *anchor\n", 679 `"First occurrence": "Foo" 680 "Second occurrence": "Foo" 681 "Override anchor": "Bar" 682 "Reuse anchor": "Bar"`, 683 }, 684 // Single document with garbage following it. 685 { 686 "---\nhello\n...\n}not yaml", 687 `"hello"`, 688 }, 689 } 690 691 type M map[interface{}]interface{} 692 693 type inlineB struct { 694 B int 695 inlineC `yaml:",inline"` 696 } 697 698 type inlineC struct { 699 C int 700 } 701 702 func cueStr(node ast.Node) string { 703 if s, ok := node.(*ast.StructLit); ok { 704 node = &ast.File{ 705 Decls: s.Elts, 706 } 707 } 708 b, _ := format.Node(node) 709 return strings.TrimSpace(string(b)) 710 } 711 712 func newDecoder(t *testing.T, data string) *yaml.Decoder { 713 dec, err := yaml.NewDecoder("test.yaml", strings.NewReader(data)) 714 if err != nil { 715 t.Fatal(err) 716 } 717 return dec 718 } 719 720 func callUnmarshal(t *testing.T, data string) (ast.Expr, error) { 721 return yaml.Unmarshal("test.yaml", []byte(data)) 722 } 723 724 func TestUnmarshal(t *testing.T) { 725 for i, item := range unmarshalTests { 726 t.Run(strconv.Itoa(i), func(t *testing.T) { 727 t.Logf("test %d: %q", i, item.data) 728 expr, err := callUnmarshal(t, item.data) 729 if _, ok := err.(*yaml.TypeError); !ok && err != nil { 730 t.Fatal("expected error to be nil") 731 } 732 if got := cueStr(expr); got != item.want { 733 t.Errorf("\n got: %v;\nwant: %v", got, item.want) 734 } 735 }) 736 } 737 } 738 739 // // TODO(v3): This test should also work when unmarshaling onto an interface{}. 740 // func (s *S) TestUnmarshalFullTimestamp(c *C) { 741 // // Full timestamp in same format as encoded. This is confirmed to be 742 // // properly decoded by Python as a timestamp as well. 743 // var str = "2015-02-24T18:19:39.123456789-03:00" 744 // expr, err := yaml.Unmarshal([]byte(str)) 745 // c.Assert(err, IsNil) 746 // c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.Location())) 747 // c.Assert(t.In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC)) 748 // } 749 750 func TestDecoderSingleDocument(t *testing.T) { 751 // Test that Decoder.Decode works as expected on 752 // all the unmarshal tests. 753 for i, item := range unmarshalTests { 754 t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 755 if item.data == "" { 756 // Behaviour differs when there's no YAML. 757 return 758 } 759 expr, err := newDecoder(t, item.data).Decode() 760 if _, ok := err.(*yaml.TypeError); !ok && err != nil { 761 t.Errorf("err should be nil, was %v", err) 762 } 763 if got := cueStr(expr); got != item.want { 764 t.Errorf("\n got: %v;\nwant: %v", got, item.want) 765 } 766 }) 767 } 768 } 769 770 var decoderTests = []struct { 771 data string 772 want string 773 }{{ 774 "", 775 "", 776 }, { 777 "a: b", 778 `a: "b"`, 779 }, { 780 "---\na: b\n...\n", 781 `a: "b"`, 782 }, { 783 "---\n'hello'\n...\n---\ngoodbye\n...\n", 784 `"hello"` + "\n" + `"goodbye"`, 785 }} 786 787 func TestDecoder(t *testing.T) { 788 for i, item := range decoderTests { 789 t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 790 var values []string 791 dec := newDecoder(t, item.data) 792 for { 793 expr, err := dec.Decode() 794 if err == io.EOF { 795 break 796 } 797 if err != nil { 798 t.Errorf("err should be nil, was %v", err) 799 } 800 values = append(values, cueStr(expr)) 801 } 802 got := strings.Join(values, "\n") 803 if got != item.want { 804 t.Errorf("\n got: %v;\nwant: %v", got, item.want) 805 } 806 }) 807 } 808 } 809 810 type errReader struct{} 811 812 func (errReader) Read([]byte) (int, error) { 813 return 0, errors.New("some read error") 814 } 815 816 func TestUnmarshalNaN(t *testing.T) { 817 expr, err := callUnmarshal(t, "notanum: .NaN") 818 if err != nil { 819 t.Fatal("unexpected error", err) 820 } 821 got := cueStr(expr) 822 want := "notanum: NaN" 823 if got != want { 824 t.Errorf("got %v; want %v", got, want) 825 } 826 } 827 828 var unmarshalErrorTests = []struct { 829 data, error string 830 }{ 831 {"\nv: !!float 'error'", "test.yaml:2: cannot decode !!str `error` as a !!float"}, 832 {"v: [A,", "test.yaml:1: did not find expected node content"}, 833 {"v:\n- [A,", "test.yaml:2: did not find expected node content"}, 834 {"a:\n- b: *,", "test.yaml:2: did not find expected alphabetic or numeric character"}, 835 {"a: *b\n", "test.yaml:1: unknown anchor 'b' referenced"}, 836 {"a: &a\n b: *a\n", "test.yaml:2: anchor 'a' value contains itself"}, 837 {"value: -", "test.yaml:1: block sequence entries are not allowed in this context"}, 838 {"a: !!binary ==", "test.yaml:1: !!binary value contains invalid base64 data"}, 839 {"{[.]}", `test.yaml:1: invalid map key: sequence`}, 840 {"{{.}}", `test.yaml:1: invalid map key: map`}, 841 {"b: *a\na: &a {c: 1}", `test.yaml:1: unknown anchor 'a' referenced`}, 842 {"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "test.yaml:1: did not find expected whitespace"}, 843 } 844 845 func TestUnmarshalErrors(t *testing.T) { 846 for i, item := range unmarshalErrorTests { 847 t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 848 expr, err := callUnmarshal(t, item.data) 849 val := "" 850 if expr != nil { 851 val = cueStr(expr) 852 } 853 if err == nil || err.Error() != item.error { 854 t.Errorf("got %v; want %v; (value %v)", err, item.error, val) 855 } 856 }) 857 } 858 } 859 860 func TestDecoderErrors(t *testing.T) { 861 for i, item := range unmarshalErrorTests { 862 t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 863 _, err := newDecoder(t, item.data).Decode() 864 if err == nil || err.Error() != item.error { 865 t.Errorf("got %v; want %v", err, item.error) 866 } 867 }) 868 } 869 } 870 871 func TestFiles(t *testing.T) { 872 files := []string{"merge"} 873 for _, test := range files { 874 t.Run(test, func(t *testing.T) { 875 testname := fmt.Sprintf("testdata/%s.test", test) 876 filename := fmt.Sprintf("testdata/%s.out", test) 877 mergeTests, err := ioutil.ReadFile(testname) 878 if err != nil { 879 t.Fatal(err) 880 } 881 expr, err := yaml.Unmarshal("test.yaml", mergeTests) 882 if err != nil { 883 t.Fatal(err) 884 } 885 got := cueStr(expr) 886 if cuetest.UpdateGoldenFiles { 887 ioutil.WriteFile(filename, []byte(got), 0644) 888 return 889 } 890 b, err := ioutil.ReadFile(filename) 891 if err != nil { 892 t.Fatal(err) 893 } 894 if want := string(b); got != want { 895 t.Errorf("\n got: %v;\nwant: %v", got, want) 896 } 897 }) 898 } 899 } 900 901 func TestFuzzCrashers(t *testing.T) { 902 cases := []string{ 903 // runtime error: index out of range 904 "\"\\0\\\r\n", 905 906 // should not happen 907 " 0: [\n] 0", 908 "? ? \"\n\" 0", 909 " - {\n000}0", 910 "0:\n 0: [0\n] 0", 911 " - \"\n000\"0", 912 " - \"\n000\"\"", 913 "0:\n - {\n000}0", 914 "0:\n - \"\n000\"0", 915 "0:\n - \"\n000\"\"", 916 917 // runtime error: index out of range 918 " \ufeff\n", 919 "? \ufeff\n", 920 "? \ufeff:\n", 921 "0: \ufeff\n", 922 "? \ufeff: \ufeff\n", 923 } 924 for _, data := range cases { 925 _, _ = callUnmarshal(t, data) 926 } 927 } 928 929 //var data []byte 930 //func init() { 931 // var err error 932 // data, err = ioutil.ReadFile("/tmp/file.yaml") 933 // if err != nil { 934 // panic(err) 935 // } 936 //} 937 // 938 //func (s *S) BenchmarkUnmarshal(c *C) { 939 // var err error 940 // for i := 0; i < c.N; i++ { 941 // var v map[string]interface{} 942 // err = yaml.Unmarshal(data, &v) 943 // } 944 // if err != nil { 945 // panic(err) 946 // } 947 //} 948 // 949 //func (s *S) BenchmarkMarshal(c *C) { 950 // var v map[string]interface{} 951 // yaml.Unmarshal(data, &v) 952 // c.ResetTimer() 953 // for i := 0; i < c.N; i++ { 954 // yaml.Marshal(&v) 955 // } 956 //}