github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/Godeps/_workspace/src/gopkg.in/yaml.v2/decode_test.go (about) 1 package yaml_test 2 3 import ( 4 "errors" 5 . "gopkg.in/check.v1" 6 "gopkg.in/yaml.v2" 7 "math" 8 "net" 9 "reflect" 10 "strings" 11 "time" 12 ) 13 14 var unmarshalIntTest = 123 15 16 var unmarshalTests = []struct { 17 data string 18 value interface{} 19 }{ 20 { 21 "", 22 &struct{}{}, 23 }, { 24 "{}", &struct{}{}, 25 }, { 26 "v: hi", 27 map[string]string{"v": "hi"}, 28 }, { 29 "v: hi", map[string]interface{}{"v": "hi"}, 30 }, { 31 "v: true", 32 map[string]string{"v": "true"}, 33 }, { 34 "v: true", 35 map[string]interface{}{"v": true}, 36 }, { 37 "v: 10", 38 map[string]interface{}{"v": 10}, 39 }, { 40 "v: 0b10", 41 map[string]interface{}{"v": 2}, 42 }, { 43 "v: 0xA", 44 map[string]interface{}{"v": 10}, 45 }, { 46 "v: 4294967296", 47 map[string]int64{"v": 4294967296}, 48 }, { 49 "v: 0.1", 50 map[string]interface{}{"v": 0.1}, 51 }, { 52 "v: .1", 53 map[string]interface{}{"v": 0.1}, 54 }, { 55 "v: .Inf", 56 map[string]interface{}{"v": math.Inf(+1)}, 57 }, { 58 "v: -.Inf", 59 map[string]interface{}{"v": math.Inf(-1)}, 60 }, { 61 "v: -10", 62 map[string]interface{}{"v": -10}, 63 }, { 64 "v: -.1", 65 map[string]interface{}{"v": -0.1}, 66 }, 67 68 // Simple values. 69 { 70 "123", 71 &unmarshalIntTest, 72 }, 73 74 // Floats from spec 75 { 76 "canonical: 6.8523e+5", 77 map[string]interface{}{"canonical": 6.8523e+5}, 78 }, { 79 "expo: 685.230_15e+03", 80 map[string]interface{}{"expo": 685.23015e+03}, 81 }, { 82 "fixed: 685_230.15", 83 map[string]interface{}{"fixed": 685230.15}, 84 }, { 85 "neginf: -.inf", 86 map[string]interface{}{"neginf": math.Inf(-1)}, 87 }, { 88 "fixed: 685_230.15", 89 map[string]float64{"fixed": 685230.15}, 90 }, 91 //{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported 92 //{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails. 93 94 // Bools from spec 95 { 96 "canonical: y", 97 map[string]interface{}{"canonical": true}, 98 }, { 99 "answer: NO", 100 map[string]interface{}{"answer": false}, 101 }, { 102 "logical: True", 103 map[string]interface{}{"logical": true}, 104 }, { 105 "option: on", 106 map[string]interface{}{"option": true}, 107 }, { 108 "option: on", 109 map[string]bool{"option": true}, 110 }, 111 // Ints from spec 112 { 113 "canonical: 685230", 114 map[string]interface{}{"canonical": 685230}, 115 }, { 116 "decimal: +685_230", 117 map[string]interface{}{"decimal": 685230}, 118 }, { 119 "octal: 02472256", 120 map[string]interface{}{"octal": 685230}, 121 }, { 122 "hexa: 0x_0A_74_AE", 123 map[string]interface{}{"hexa": 685230}, 124 }, { 125 "bin: 0b1010_0111_0100_1010_1110", 126 map[string]interface{}{"bin": 685230}, 127 }, { 128 "bin: -0b101010", 129 map[string]interface{}{"bin": -42}, 130 }, { 131 "decimal: +685_230", 132 map[string]int{"decimal": 685230}, 133 }, 134 135 //{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported 136 137 // Nulls from spec 138 { 139 "empty:", 140 map[string]interface{}{"empty": nil}, 141 }, { 142 "canonical: ~", 143 map[string]interface{}{"canonical": nil}, 144 }, { 145 "english: null", 146 map[string]interface{}{"english": nil}, 147 }, { 148 "~: null key", 149 map[interface{}]string{nil: "null key"}, 150 }, { 151 "empty:", 152 map[string]*bool{"empty": nil}, 153 }, 154 155 // Flow sequence 156 { 157 "seq: [A,B]", 158 map[string]interface{}{"seq": []interface{}{"A", "B"}}, 159 }, { 160 "seq: [A,B,C,]", 161 map[string][]string{"seq": []string{"A", "B", "C"}}, 162 }, { 163 "seq: [A,1,C]", 164 map[string][]string{"seq": []string{"A", "1", "C"}}, 165 }, { 166 "seq: [A,1,C]", 167 map[string][]int{"seq": []int{1}}, 168 }, { 169 "seq: [A,1,C]", 170 map[string]interface{}{"seq": []interface{}{"A", 1, "C"}}, 171 }, 172 // Block sequence 173 { 174 "seq:\n - A\n - B", 175 map[string]interface{}{"seq": []interface{}{"A", "B"}}, 176 }, { 177 "seq:\n - A\n - B\n - C", 178 map[string][]string{"seq": []string{"A", "B", "C"}}, 179 }, { 180 "seq:\n - A\n - 1\n - C", 181 map[string][]string{"seq": []string{"A", "1", "C"}}, 182 }, { 183 "seq:\n - A\n - 1\n - C", 184 map[string][]int{"seq": []int{1}}, 185 }, { 186 "seq:\n - A\n - 1\n - C", 187 map[string]interface{}{"seq": []interface{}{"A", 1, "C"}}, 188 }, 189 190 // Literal block scalar 191 { 192 "scalar: | # Comment\n\n literal\n\n \ttext\n\n", 193 map[string]string{"scalar": "\nliteral\n\n\ttext\n"}, 194 }, 195 196 // Folded block scalar 197 { 198 "scalar: > # Comment\n\n folded\n line\n \n next\n line\n * one\n * two\n\n last\n line\n\n", 199 map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"}, 200 }, 201 202 // Map inside interface with no type hints. 203 { 204 "a: {b: c}", 205 map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": "c"}}, 206 }, 207 208 // Structs and type conversions. 209 { 210 "hello: world", 211 &struct{ Hello string }{"world"}, 212 }, { 213 "a: {b: c}", 214 &struct{ A struct{ B string } }{struct{ B string }{"c"}}, 215 }, { 216 "a: {b: c}", 217 &struct{ A *struct{ B string } }{&struct{ B string }{"c"}}, 218 }, { 219 "a: {b: c}", 220 &struct{ A map[string]string }{map[string]string{"b": "c"}}, 221 }, { 222 "a: {b: c}", 223 &struct{ A *map[string]string }{&map[string]string{"b": "c"}}, 224 }, { 225 "a:", 226 &struct{ A map[string]string }{}, 227 }, { 228 "a: 1", 229 &struct{ A int }{1}, 230 }, { 231 "a: 1", 232 &struct{ A float64 }{1}, 233 }, { 234 "a: 1.0", 235 &struct{ A int }{1}, 236 }, { 237 "a: 1.0", 238 &struct{ A uint }{1}, 239 }, { 240 "a: [1, 2]", 241 &struct{ A []int }{[]int{1, 2}}, 242 }, { 243 "a: 1", 244 &struct{ B int }{0}, 245 }, { 246 "a: 1", 247 &struct { 248 B int "a" 249 }{1}, 250 }, { 251 "a: y", 252 &struct{ A bool }{true}, 253 }, 254 255 // Some cross type conversions 256 { 257 "v: 42", 258 map[string]uint{"v": 42}, 259 }, { 260 "v: -42", 261 map[string]uint{}, 262 }, { 263 "v: 4294967296", 264 map[string]uint64{"v": 4294967296}, 265 }, { 266 "v: -4294967296", 267 map[string]uint64{}, 268 }, 269 270 // int 271 { 272 "int_max: 2147483647", 273 map[string]int{"int_max": math.MaxInt32}, 274 }, 275 { 276 "int_min: -2147483648", 277 map[string]int{"int_min": math.MinInt32}, 278 }, 279 { 280 "int_overflow: 9223372036854775808", // math.MaxInt64 + 1 281 map[string]int{}, 282 }, 283 284 // int64 285 { 286 "int64_max: 9223372036854775807", 287 map[string]int64{"int64_max": math.MaxInt64}, 288 }, 289 { 290 "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111", 291 map[string]int64{"int64_max_base2": math.MaxInt64}, 292 }, 293 { 294 "int64_min: -9223372036854775808", 295 map[string]int64{"int64_min": math.MinInt64}, 296 }, 297 { 298 "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111", 299 map[string]int64{"int64_neg_base2": -math.MaxInt64}, 300 }, 301 { 302 "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1 303 map[string]int64{}, 304 }, 305 306 // uint 307 { 308 "uint_min: 0", 309 map[string]uint{"uint_min": 0}, 310 }, 311 { 312 "uint_max: 4294967295", 313 map[string]uint{"uint_max": math.MaxUint32}, 314 }, 315 { 316 "uint_underflow: -1", 317 map[string]uint{}, 318 }, 319 320 // uint64 321 { 322 "uint64_min: 0", 323 map[string]uint{"uint64_min": 0}, 324 }, 325 { 326 "uint64_max: 18446744073709551615", 327 map[string]uint64{"uint64_max": math.MaxUint64}, 328 }, 329 { 330 "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111", 331 map[string]uint64{"uint64_max_base2": math.MaxUint64}, 332 }, 333 { 334 "uint64_maxint64: 9223372036854775807", 335 map[string]uint64{"uint64_maxint64": math.MaxInt64}, 336 }, 337 { 338 "uint64_underflow: -1", 339 map[string]uint64{}, 340 }, 341 342 // float32 343 { 344 "float32_max: 3.40282346638528859811704183484516925440e+38", 345 map[string]float32{"float32_max": math.MaxFloat32}, 346 }, 347 { 348 "float32_nonzero: 1.401298464324817070923729583289916131280e-45", 349 map[string]float32{"float32_nonzero": math.SmallestNonzeroFloat32}, 350 }, 351 { 352 "float32_maxuint64: 18446744073709551615", 353 map[string]float32{"float32_maxuint64": float32(math.MaxUint64)}, 354 }, 355 { 356 "float32_maxuint64+1: 18446744073709551616", 357 map[string]float32{"float32_maxuint64+1": float32(math.MaxUint64 + 1)}, 358 }, 359 360 // float64 361 { 362 "float64_max: 1.797693134862315708145274237317043567981e+308", 363 map[string]float64{"float64_max": math.MaxFloat64}, 364 }, 365 { 366 "float64_nonzero: 4.940656458412465441765687928682213723651e-324", 367 map[string]float64{"float64_nonzero": math.SmallestNonzeroFloat64}, 368 }, 369 { 370 "float64_maxuint64: 18446744073709551615", 371 map[string]float64{"float64_maxuint64": float64(math.MaxUint64)}, 372 }, 373 { 374 "float64_maxuint64+1: 18446744073709551616", 375 map[string]float64{"float64_maxuint64+1": float64(math.MaxUint64 + 1)}, 376 }, 377 378 // Overflow cases. 379 { 380 "v: 4294967297", 381 map[string]int32{}, 382 }, { 383 "v: 128", 384 map[string]int8{}, 385 }, 386 387 // Quoted values. 388 { 389 "'1': '\"2\"'", 390 map[interface{}]interface{}{"1": "\"2\""}, 391 }, { 392 "v:\n- A\n- 'B\n\n C'\n", 393 map[string][]string{"v": []string{"A", "B\nC"}}, 394 }, 395 396 // Explicit tags. 397 { 398 "v: !!float '1.1'", 399 map[string]interface{}{"v": 1.1}, 400 }, { 401 "v: !!null ''", 402 map[string]interface{}{"v": nil}, 403 }, { 404 "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'", 405 map[string]interface{}{"v": 1}, 406 }, 407 408 // Anchors and aliases. 409 { 410 "a: &x 1\nb: &y 2\nc: *x\nd: *y\n", 411 &struct{ A, B, C, D int }{1, 2, 1, 2}, 412 }, { 413 "a: &a {c: 1}\nb: *a", 414 &struct { 415 A, B struct { 416 C int 417 } 418 }{struct{ C int }{1}, struct{ C int }{1}}, 419 }, { 420 "a: &a [1, 2]\nb: *a", 421 &struct{ B []int }{[]int{1, 2}}, 422 }, { 423 "b: *a\na: &a {c: 1}", 424 &struct { 425 A, B struct { 426 C int 427 } 428 }{struct{ C int }{1}, struct{ C int }{1}}, 429 }, 430 431 // Bug #1133337 432 { 433 "foo: ''", 434 map[string]*string{"foo": new(string)}, 435 }, { 436 "foo: null", 437 map[string]string{"foo": ""}, 438 }, { 439 "foo: null", 440 map[string]interface{}{"foo": nil}, 441 }, 442 443 // Ignored field 444 { 445 "a: 1\nb: 2\n", 446 &struct { 447 A int 448 B int "-" 449 }{1, 0}, 450 }, 451 452 // Bug #1191981 453 { 454 "" + 455 "%YAML 1.1\n" + 456 "--- !!str\n" + 457 `"Generic line break (no glyph)\n\` + "\n" + 458 ` Generic line break (glyphed)\n\` + "\n" + 459 ` Line separator\u2028\` + "\n" + 460 ` Paragraph separator\u2029"` + "\n", 461 "" + 462 "Generic line break (no glyph)\n" + 463 "Generic line break (glyphed)\n" + 464 "Line separator\u2028Paragraph separator\u2029", 465 }, 466 467 // Struct inlining 468 { 469 "a: 1\nb: 2\nc: 3\n", 470 &struct { 471 A int 472 C inlineB `yaml:",inline"` 473 }{1, inlineB{2, inlineC{3}}}, 474 }, 475 476 // Map inlining 477 { 478 "a: 1\nb: 2\nc: 3\n", 479 &struct { 480 A int 481 C map[string]int `yaml:",inline"` 482 }{1, map[string]int{"b": 2, "c": 3}}, 483 }, 484 485 // bug 1243827 486 { 487 "a: -b_c", 488 map[string]interface{}{"a": "-b_c"}, 489 }, 490 { 491 "a: +b_c", 492 map[string]interface{}{"a": "+b_c"}, 493 }, 494 { 495 "a: 50cent_of_dollar", 496 map[string]interface{}{"a": "50cent_of_dollar"}, 497 }, 498 499 // Duration 500 { 501 "a: 3s", 502 map[string]time.Duration{"a": 3 * time.Second}, 503 }, 504 505 // Issue #24. 506 { 507 "a: <foo>", 508 map[string]string{"a": "<foo>"}, 509 }, 510 511 // Base 60 floats are obsolete and unsupported. 512 { 513 "a: 1:1\n", 514 map[string]string{"a": "1:1"}, 515 }, 516 517 // Binary data. 518 { 519 "a: !!binary gIGC\n", 520 map[string]string{"a": "\x80\x81\x82"}, 521 }, { 522 "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n", 523 map[string]string{"a": strings.Repeat("\x90", 54)}, 524 }, { 525 "a: !!binary |\n " + strings.Repeat("A", 70) + "\n ==\n", 526 map[string]string{"a": strings.Repeat("\x00", 52)}, 527 }, 528 529 // Ordered maps. 530 { 531 "{b: 2, a: 1, d: 4, c: 3, sub: {e: 5}}", 532 &yaml.MapSlice{{"b", 2}, {"a", 1}, {"d", 4}, {"c", 3}, {"sub", yaml.MapSlice{{"e", 5}}}}, 533 }, 534 535 // Issue #39. 536 { 537 "a:\n b:\n c: d\n", 538 map[string]struct{ B interface{} }{"a": {map[interface{}]interface{}{"c": "d"}}}, 539 }, 540 541 // Custom map type. 542 { 543 "a: {b: c}", 544 M{"a": M{"b": "c"}}, 545 }, 546 547 // Support encoding.TextUnmarshaler. 548 { 549 "a: 1.2.3.4\n", 550 map[string]net.IP{"a": net.IPv4(1, 2, 3, 4)}, 551 }, 552 { 553 "a: 2015-02-24T18:19:39Z\n", 554 map[string]time.Time{"a": time.Unix(1424801979, 0)}, 555 }, 556 557 // Encode empty lists as zero-length slices. 558 { 559 "a: []", 560 &struct{ A []int }{[]int{}}, 561 }, 562 } 563 564 type M map[interface{}]interface{} 565 566 type inlineB struct { 567 B int 568 inlineC `yaml:",inline"` 569 } 570 571 type inlineC struct { 572 C int 573 } 574 575 func (s *S) TestUnmarshal(c *C) { 576 for _, item := range unmarshalTests { 577 t := reflect.ValueOf(item.value).Type() 578 var value interface{} 579 switch t.Kind() { 580 case reflect.Map: 581 value = reflect.MakeMap(t).Interface() 582 case reflect.String: 583 value = reflect.New(t).Interface() 584 case reflect.Ptr: 585 value = reflect.New(t.Elem()).Interface() 586 default: 587 c.Fatalf("missing case for %s", t) 588 } 589 err := yaml.Unmarshal([]byte(item.data), value) 590 if _, ok := err.(*yaml.TypeError); !ok { 591 c.Assert(err, IsNil) 592 } 593 if t.Kind() == reflect.String { 594 c.Assert(*value.(*string), Equals, item.value) 595 } else { 596 c.Assert(value, DeepEquals, item.value) 597 } 598 } 599 } 600 601 func (s *S) TestUnmarshalNaN(c *C) { 602 value := map[string]interface{}{} 603 err := yaml.Unmarshal([]byte("notanum: .NaN"), &value) 604 c.Assert(err, IsNil) 605 c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true) 606 } 607 608 var unmarshalErrorTests = []struct { 609 data, error string 610 }{ 611 {"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"}, 612 {"v: [A,", "yaml: line 1: did not find expected node content"}, 613 {"v:\n- [A,", "yaml: line 2: did not find expected node content"}, 614 {"a: *b\n", "yaml: unknown anchor 'b' referenced"}, 615 {"a: &a\n b: *a\n", "yaml: anchor 'a' value contains itself"}, 616 {"value: -", "yaml: block sequence entries are not allowed in this context"}, 617 {"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"}, 618 {"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`}, 619 {"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`}, 620 } 621 622 func (s *S) TestUnmarshalErrors(c *C) { 623 for _, item := range unmarshalErrorTests { 624 var value interface{} 625 err := yaml.Unmarshal([]byte(item.data), &value) 626 c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value)) 627 } 628 } 629 630 var unmarshalerTests = []struct { 631 data, tag string 632 value interface{} 633 }{ 634 {"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}}, 635 {"_: [1,A]", "!!seq", []interface{}{1, "A"}}, 636 {"_: 10", "!!int", 10}, 637 {"_: null", "!!null", nil}, 638 {`_: BAR!`, "!!str", "BAR!"}, 639 {`_: "BAR!"`, "!!str", "BAR!"}, 640 {"_: !!foo 'BAR!'", "!!foo", "BAR!"}, 641 } 642 643 var unmarshalerResult = map[int]error{} 644 645 type unmarshalerType struct { 646 value interface{} 647 } 648 649 func (o *unmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error { 650 if err := unmarshal(&o.value); err != nil { 651 return err 652 } 653 if i, ok := o.value.(int); ok { 654 if result, ok := unmarshalerResult[i]; ok { 655 return result 656 } 657 } 658 return nil 659 } 660 661 type unmarshalerPointer struct { 662 Field *unmarshalerType "_" 663 } 664 665 type unmarshalerValue struct { 666 Field unmarshalerType "_" 667 } 668 669 func (s *S) TestUnmarshalerPointerField(c *C) { 670 for _, item := range unmarshalerTests { 671 obj := &unmarshalerPointer{} 672 err := yaml.Unmarshal([]byte(item.data), obj) 673 c.Assert(err, IsNil) 674 if item.value == nil { 675 c.Assert(obj.Field, IsNil) 676 } else { 677 c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value)) 678 c.Assert(obj.Field.value, DeepEquals, item.value) 679 } 680 } 681 } 682 683 func (s *S) TestUnmarshalerValueField(c *C) { 684 for _, item := range unmarshalerTests { 685 obj := &unmarshalerValue{} 686 err := yaml.Unmarshal([]byte(item.data), obj) 687 c.Assert(err, IsNil) 688 c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value)) 689 c.Assert(obj.Field.value, DeepEquals, item.value) 690 } 691 } 692 693 func (s *S) TestUnmarshalerWholeDocument(c *C) { 694 obj := &unmarshalerType{} 695 err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj) 696 c.Assert(err, IsNil) 697 value, ok := obj.value.(map[interface{}]interface{}) 698 c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value)) 699 c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value) 700 } 701 702 func (s *S) TestUnmarshalerTypeError(c *C) { 703 unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}} 704 unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}} 705 defer func() { 706 delete(unmarshalerResult, 2) 707 delete(unmarshalerResult, 4) 708 }() 709 710 type T struct { 711 Before int 712 After int 713 M map[string]*unmarshalerType 714 } 715 var v T 716 data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}` 717 err := yaml.Unmarshal([]byte(data), &v) 718 c.Assert(err, ErrorMatches, ""+ 719 "yaml: unmarshal errors:\n"+ 720 " line 1: cannot unmarshal !!str `A` into int\n"+ 721 " foo\n"+ 722 " bar\n"+ 723 " line 1: cannot unmarshal !!str `B` into int") 724 c.Assert(v.M["abc"], NotNil) 725 c.Assert(v.M["def"], IsNil) 726 c.Assert(v.M["ghi"], NotNil) 727 c.Assert(v.M["jkl"], IsNil) 728 729 c.Assert(v.M["abc"].value, Equals, 1) 730 c.Assert(v.M["ghi"].value, Equals, 3) 731 } 732 733 type proxyTypeError struct{} 734 735 func (v *proxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error { 736 var s string 737 var a int32 738 var b int64 739 if err := unmarshal(&s); err != nil { 740 panic(err) 741 } 742 if s == "a" { 743 if err := unmarshal(&b); err == nil { 744 panic("should have failed") 745 } 746 return unmarshal(&a) 747 } 748 if err := unmarshal(&a); err == nil { 749 panic("should have failed") 750 } 751 return unmarshal(&b) 752 } 753 754 func (s *S) TestUnmarshalerTypeErrorProxying(c *C) { 755 type T struct { 756 Before int 757 After int 758 M map[string]*proxyTypeError 759 } 760 var v T 761 data := `{before: A, m: {abc: a, def: b}, after: B}` 762 err := yaml.Unmarshal([]byte(data), &v) 763 c.Assert(err, ErrorMatches, ""+ 764 "yaml: unmarshal errors:\n"+ 765 " line 1: cannot unmarshal !!str `A` into int\n"+ 766 " line 1: cannot unmarshal !!str `a` into int32\n"+ 767 " line 1: cannot unmarshal !!str `b` into int64\n"+ 768 " line 1: cannot unmarshal !!str `B` into int") 769 } 770 771 type failingUnmarshaler struct{} 772 773 var failingErr = errors.New("failingErr") 774 775 func (ft *failingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error { 776 return failingErr 777 } 778 779 func (s *S) TestUnmarshalerError(c *C) { 780 err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{}) 781 c.Assert(err, Equals, failingErr) 782 } 783 784 type sliceUnmarshaler []int 785 786 func (su *sliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error { 787 var slice []int 788 err := unmarshal(&slice) 789 if err == nil { 790 *su = slice 791 return nil 792 } 793 794 var intVal int 795 err = unmarshal(&intVal) 796 if err == nil { 797 *su = []int{intVal} 798 return nil 799 } 800 801 return err 802 } 803 804 func (s *S) TestUnmarshalerRetry(c *C) { 805 var su sliceUnmarshaler 806 err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su) 807 c.Assert(err, IsNil) 808 c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3})) 809 810 err = yaml.Unmarshal([]byte("1"), &su) 811 c.Assert(err, IsNil) 812 c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1})) 813 } 814 815 // From http://yaml.org/type/merge.html 816 var mergeTests = ` 817 anchors: 818 list: 819 - &CENTER { "x": 1, "y": 2 } 820 - &LEFT { "x": 0, "y": 2 } 821 - &BIG { "r": 10 } 822 - &SMALL { "r": 1 } 823 824 # All the following maps are equal: 825 826 plain: 827 # Explicit keys 828 "x": 1 829 "y": 2 830 "r": 10 831 label: center/big 832 833 mergeOne: 834 # Merge one map 835 << : *CENTER 836 "r": 10 837 label: center/big 838 839 mergeMultiple: 840 # Merge multiple maps 841 << : [ *CENTER, *BIG ] 842 label: center/big 843 844 override: 845 # Override 846 << : [ *BIG, *LEFT, *SMALL ] 847 "x": 1 848 label: center/big 849 850 shortTag: 851 # Explicit short merge tag 852 !!merge "<<" : [ *CENTER, *BIG ] 853 label: center/big 854 855 longTag: 856 # Explicit merge long tag 857 !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ] 858 label: center/big 859 860 inlineMap: 861 # Inlined map 862 << : {"x": 1, "y": 2, "r": 10} 863 label: center/big 864 865 inlineSequenceMap: 866 # Inlined map in sequence 867 << : [ *CENTER, {"r": 10} ] 868 label: center/big 869 ` 870 871 func (s *S) TestMerge(c *C) { 872 var want = map[interface{}]interface{}{ 873 "x": 1, 874 "y": 2, 875 "r": 10, 876 "label": "center/big", 877 } 878 879 var m map[interface{}]interface{} 880 err := yaml.Unmarshal([]byte(mergeTests), &m) 881 c.Assert(err, IsNil) 882 for name, test := range m { 883 if name == "anchors" { 884 continue 885 } 886 c.Assert(test, DeepEquals, want, Commentf("test %q failed", name)) 887 } 888 } 889 890 func (s *S) TestMergeStruct(c *C) { 891 type Data struct { 892 X, Y, R int 893 Label string 894 } 895 want := Data{1, 2, 10, "center/big"} 896 897 var m map[string]Data 898 err := yaml.Unmarshal([]byte(mergeTests), &m) 899 c.Assert(err, IsNil) 900 for name, test := range m { 901 if name == "anchors" { 902 continue 903 } 904 c.Assert(test, Equals, want, Commentf("test %q failed", name)) 905 } 906 } 907 908 var unmarshalNullTests = []func() interface{}{ 909 func() interface{} { var v interface{}; v = "v"; return &v }, 910 func() interface{} { var s = "s"; return &s }, 911 func() interface{} { var s = "s"; sptr := &s; return &sptr }, 912 func() interface{} { var i = 1; return &i }, 913 func() interface{} { var i = 1; iptr := &i; return &iptr }, 914 func() interface{} { m := map[string]int{"s": 1}; return &m }, 915 func() interface{} { m := map[string]int{"s": 1}; return m }, 916 } 917 918 func (s *S) TestUnmarshalNull(c *C) { 919 for _, test := range unmarshalNullTests { 920 item := test() 921 zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface() 922 err := yaml.Unmarshal([]byte("null"), item) 923 c.Assert(err, IsNil) 924 if reflect.TypeOf(item).Kind() == reflect.Map { 925 c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface()) 926 } else { 927 c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero) 928 } 929 } 930 } 931 932 func (s *S) TestUnmarshalSliceOnPreset(c *C) { 933 // Issue #48. 934 v := struct{ A []int }{[]int{1}} 935 yaml.Unmarshal([]byte("a: [2]"), &v) 936 c.Assert(v.A, DeepEquals, []int{2}) 937 } 938 939 //var data []byte 940 //func init() { 941 // var err error 942 // data, err = ioutil.ReadFile("/tmp/file.yaml") 943 // if err != nil { 944 // panic(err) 945 // } 946 //} 947 // 948 //func (s *S) BenchmarkUnmarshal(c *C) { 949 // var err error 950 // for i := 0; i < c.N; i++ { 951 // var v map[string]interface{} 952 // err = yaml.Unmarshal(data, &v) 953 // } 954 // if err != nil { 955 // panic(err) 956 // } 957 //} 958 // 959 //func (s *S) BenchmarkMarshal(c *C) { 960 // var v map[string]interface{} 961 // yaml.Unmarshal(data, &v) 962 // c.ResetTimer() 963 // for i := 0; i < c.N; i++ { 964 // yaml.Marshal(&v) 965 // } 966 //}