github.com/ssube/gitlab-ci-multi-runner@v1.2.1-0.20160607142738-b8d1285632e6/Godeps/_workspace/src/gopkg.in/yaml.v1/decode_test.go (about) 1 package yaml_test 2 3 import ( 4 . "gopkg.in/check.v1" 5 "gopkg.in/yaml.v1" 6 "math" 7 "reflect" 8 "strings" 9 "time" 10 ) 11 12 var unmarshalIntTest = 123 13 14 var unmarshalTests = []struct { 15 data string 16 value interface{} 17 }{ 18 { 19 "", 20 &struct{}{}, 21 }, { 22 "{}", &struct{}{}, 23 }, { 24 "v: hi", 25 map[string]string{"v": "hi"}, 26 }, { 27 "v: hi", map[string]interface{}{"v": "hi"}, 28 }, { 29 "v: true", 30 map[string]string{"v": "true"}, 31 }, { 32 "v: true", 33 map[string]interface{}{"v": true}, 34 }, { 35 "v: 10", 36 map[string]interface{}{"v": 10}, 37 }, { 38 "v: 0b10", 39 map[string]interface{}{"v": 2}, 40 }, { 41 "v: 0xA", 42 map[string]interface{}{"v": 10}, 43 }, { 44 "v: 4294967296", 45 map[string]int64{"v": 4294967296}, 46 }, { 47 "v: 0.1", 48 map[string]interface{}{"v": 0.1}, 49 }, { 50 "v: .1", 51 map[string]interface{}{"v": 0.1}, 52 }, { 53 "v: .Inf", 54 map[string]interface{}{"v": math.Inf(+1)}, 55 }, { 56 "v: -.Inf", 57 map[string]interface{}{"v": math.Inf(-1)}, 58 }, { 59 "v: -10", 60 map[string]interface{}{"v": -10}, 61 }, { 62 "v: -.1", 63 map[string]interface{}{"v": -0.1}, 64 }, 65 66 // Simple values. 67 { 68 "123", 69 &unmarshalIntTest, 70 }, 71 72 // Floats from spec 73 { 74 "canonical: 6.8523e+5", 75 map[string]interface{}{"canonical": 6.8523e+5}, 76 }, { 77 "expo: 685.230_15e+03", 78 map[string]interface{}{"expo": 685.23015e+03}, 79 }, { 80 "fixed: 685_230.15", 81 map[string]interface{}{"fixed": 685230.15}, 82 }, { 83 "neginf: -.inf", 84 map[string]interface{}{"neginf": math.Inf(-1)}, 85 }, { 86 "fixed: 685_230.15", 87 map[string]float64{"fixed": 685230.15}, 88 }, 89 //{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported 90 //{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails. 91 92 // Bools from spec 93 { 94 "canonical: y", 95 map[string]interface{}{"canonical": true}, 96 }, { 97 "answer: NO", 98 map[string]interface{}{"answer": false}, 99 }, { 100 "logical: True", 101 map[string]interface{}{"logical": true}, 102 }, { 103 "option: on", 104 map[string]interface{}{"option": true}, 105 }, { 106 "option: on", 107 map[string]bool{"option": true}, 108 }, 109 // Ints from spec 110 { 111 "canonical: 685230", 112 map[string]interface{}{"canonical": 685230}, 113 }, { 114 "decimal: +685_230", 115 map[string]interface{}{"decimal": 685230}, 116 }, { 117 "octal: 02472256", 118 map[string]interface{}{"octal": 685230}, 119 }, { 120 "hexa: 0x_0A_74_AE", 121 map[string]interface{}{"hexa": 685230}, 122 }, { 123 "bin: 0b1010_0111_0100_1010_1110", 124 map[string]interface{}{"bin": 685230}, 125 }, { 126 "bin: -0b101010", 127 map[string]interface{}{"bin": -42}, 128 }, { 129 "decimal: +685_230", 130 map[string]int{"decimal": 685230}, 131 }, 132 133 //{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported 134 135 // Nulls from spec 136 { 137 "empty:", 138 map[string]interface{}{"empty": nil}, 139 }, { 140 "canonical: ~", 141 map[string]interface{}{"canonical": nil}, 142 }, { 143 "english: null", 144 map[string]interface{}{"english": nil}, 145 }, { 146 "~: null key", 147 map[interface{}]string{nil: "null key"}, 148 }, { 149 "empty:", 150 map[string]*bool{"empty": nil}, 151 }, 152 153 // Flow sequence 154 { 155 "seq: [A,B]", 156 map[string]interface{}{"seq": []interface{}{"A", "B"}}, 157 }, { 158 "seq: [A,B,C,]", 159 map[string][]string{"seq": []string{"A", "B", "C"}}, 160 }, { 161 "seq: [A,1,C]", 162 map[string][]string{"seq": []string{"A", "1", "C"}}, 163 }, { 164 "seq: [A,1,C]", 165 map[string][]int{"seq": []int{1}}, 166 }, { 167 "seq: [A,1,C]", 168 map[string]interface{}{"seq": []interface{}{"A", 1, "C"}}, 169 }, 170 // Block sequence 171 { 172 "seq:\n - A\n - B", 173 map[string]interface{}{"seq": []interface{}{"A", "B"}}, 174 }, { 175 "seq:\n - A\n - B\n - C", 176 map[string][]string{"seq": []string{"A", "B", "C"}}, 177 }, { 178 "seq:\n - A\n - 1\n - C", 179 map[string][]string{"seq": []string{"A", "1", "C"}}, 180 }, { 181 "seq:\n - A\n - 1\n - C", 182 map[string][]int{"seq": []int{1}}, 183 }, { 184 "seq:\n - A\n - 1\n - C", 185 map[string]interface{}{"seq": []interface{}{"A", 1, "C"}}, 186 }, 187 188 // Literal block scalar 189 { 190 "scalar: | # Comment\n\n literal\n\n \ttext\n\n", 191 map[string]string{"scalar": "\nliteral\n\n\ttext\n"}, 192 }, 193 194 // Folded block scalar 195 { 196 "scalar: > # Comment\n\n folded\n line\n \n next\n line\n * one\n * two\n\n last\n line\n\n", 197 map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"}, 198 }, 199 200 // Map inside interface with no type hints. 201 { 202 "a: {b: c}", 203 map[string]interface{}{"a": map[interface{}]interface{}{"b": "c"}}, 204 }, 205 206 // Structs and type conversions. 207 { 208 "hello: world", 209 &struct{ Hello string }{"world"}, 210 }, { 211 "a: {b: c}", 212 &struct{ A struct{ B string } }{struct{ B string }{"c"}}, 213 }, { 214 "a: {b: c}", 215 &struct{ A *struct{ B string } }{&struct{ B string }{"c"}}, 216 }, { 217 "a: {b: c}", 218 &struct{ A map[string]string }{map[string]string{"b": "c"}}, 219 }, { 220 "a: {b: c}", 221 &struct{ A *map[string]string }{&map[string]string{"b": "c"}}, 222 }, { 223 "a:", 224 &struct{ A map[string]string }{}, 225 }, { 226 "a: 1", 227 &struct{ A int }{1}, 228 }, { 229 "a: 1", 230 &struct{ A float64 }{1}, 231 }, { 232 "a: 1.0", 233 &struct{ A int }{1}, 234 }, { 235 "a: 1.0", 236 &struct{ A uint }{1}, 237 }, { 238 "a: [1, 2]", 239 &struct{ A []int }{[]int{1, 2}}, 240 }, { 241 "a: 1", 242 &struct{ B int }{0}, 243 }, { 244 "a: 1", 245 &struct { 246 B int "a" 247 }{1}, 248 }, { 249 "a: y", 250 &struct{ A bool }{true}, 251 }, 252 253 // Some cross type conversions 254 { 255 "v: 42", 256 map[string]uint{"v": 42}, 257 }, { 258 "v: -42", 259 map[string]uint{}, 260 }, { 261 "v: 4294967296", 262 map[string]uint64{"v": 4294967296}, 263 }, { 264 "v: -4294967296", 265 map[string]uint64{}, 266 }, 267 268 // Overflow cases. 269 { 270 "v: 4294967297", 271 map[string]int32{}, 272 }, { 273 "v: 128", 274 map[string]int8{}, 275 }, 276 277 // Quoted values. 278 { 279 "'1': '\"2\"'", 280 map[interface{}]interface{}{"1": "\"2\""}, 281 }, { 282 "v:\n- A\n- 'B\n\n C'\n", 283 map[string][]string{"v": []string{"A", "B\nC"}}, 284 }, 285 286 // Explicit tags. 287 { 288 "v: !!float '1.1'", 289 map[string]interface{}{"v": 1.1}, 290 }, { 291 "v: !!null ''", 292 map[string]interface{}{"v": nil}, 293 }, { 294 "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'", 295 map[string]interface{}{"v": 1}, 296 }, 297 298 // Anchors and aliases. 299 { 300 "a: &x 1\nb: &y 2\nc: *x\nd: *y\n", 301 &struct{ A, B, C, D int }{1, 2, 1, 2}, 302 }, { 303 "a: &a {c: 1}\nb: *a", 304 &struct { 305 A, B struct { 306 C int 307 } 308 }{struct{ C int }{1}, struct{ C int }{1}}, 309 }, { 310 "a: &a [1, 2]\nb: *a", 311 &struct{ B []int }{[]int{1, 2}}, 312 }, 313 314 // Bug #1133337 315 { 316 "foo: ''", 317 map[string]*string{"foo": new(string)}, 318 }, { 319 "foo: null", 320 map[string]string{"foo": ""}, 321 }, { 322 "foo: null", 323 map[string]interface{}{"foo": nil}, 324 }, 325 326 // Ignored field 327 { 328 "a: 1\nb: 2\n", 329 &struct { 330 A int 331 B int "-" 332 }{1, 0}, 333 }, 334 335 // Bug #1191981 336 { 337 "" + 338 "%YAML 1.1\n" + 339 "--- !!str\n" + 340 `"Generic line break (no glyph)\n\` + "\n" + 341 ` Generic line break (glyphed)\n\` + "\n" + 342 ` Line separator\u2028\` + "\n" + 343 ` Paragraph separator\u2029"` + "\n", 344 "" + 345 "Generic line break (no glyph)\n" + 346 "Generic line break (glyphed)\n" + 347 "Line separator\u2028Paragraph separator\u2029", 348 }, 349 350 // Struct inlining 351 { 352 "a: 1\nb: 2\nc: 3\n", 353 &struct { 354 A int 355 C inlineB `yaml:",inline"` 356 }{1, inlineB{2, inlineC{3}}}, 357 }, 358 359 // bug 1243827 360 { 361 "a: -b_c", 362 map[string]interface{}{"a": "-b_c"}, 363 }, 364 { 365 "a: +b_c", 366 map[string]interface{}{"a": "+b_c"}, 367 }, 368 { 369 "a: 50cent_of_dollar", 370 map[string]interface{}{"a": "50cent_of_dollar"}, 371 }, 372 373 // Duration 374 { 375 "a: 3s", 376 map[string]time.Duration{"a": 3 * time.Second}, 377 }, 378 379 // Issue #24. 380 { 381 "a: <foo>", 382 map[string]string{"a": "<foo>"}, 383 }, 384 385 // Base 60 floats are obsolete and unsupported. 386 { 387 "a: 1:1\n", 388 map[string]string{"a": "1:1"}, 389 }, 390 391 // Binary data. 392 { 393 "a: !!binary gIGC\n", 394 map[string]string{"a": "\x80\x81\x82"}, 395 }, { 396 "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n", 397 map[string]string{"a": strings.Repeat("\x90", 54)}, 398 }, { 399 "a: !!binary |\n " + strings.Repeat("A", 70) + "\n ==\n", 400 map[string]string{"a": strings.Repeat("\x00", 52)}, 401 }, 402 } 403 404 type inlineB struct { 405 B int 406 inlineC `yaml:",inline"` 407 } 408 409 type inlineC struct { 410 C int 411 } 412 413 func (s *S) TestUnmarshal(c *C) { 414 for i, item := range unmarshalTests { 415 t := reflect.ValueOf(item.value).Type() 416 var value interface{} 417 switch t.Kind() { 418 case reflect.Map: 419 value = reflect.MakeMap(t).Interface() 420 case reflect.String: 421 t := reflect.ValueOf(item.value).Type() 422 v := reflect.New(t) 423 value = v.Interface() 424 default: 425 pt := reflect.ValueOf(item.value).Type() 426 pv := reflect.New(pt.Elem()) 427 value = pv.Interface() 428 } 429 err := yaml.Unmarshal([]byte(item.data), value) 430 c.Assert(err, IsNil, Commentf("Item #%d", i)) 431 if t.Kind() == reflect.String { 432 c.Assert(*value.(*string), Equals, item.value, Commentf("Item #%d", i)) 433 } else { 434 c.Assert(value, DeepEquals, item.value, Commentf("Item #%d", i)) 435 } 436 } 437 } 438 439 func (s *S) TestUnmarshalNaN(c *C) { 440 value := map[string]interface{}{} 441 err := yaml.Unmarshal([]byte("notanum: .NaN"), &value) 442 c.Assert(err, IsNil) 443 c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true) 444 } 445 446 var unmarshalErrorTests = []struct { 447 data, error string 448 }{ 449 {"v: !!float 'error'", "YAML error: cannot decode !!str `error` as a !!float"}, 450 {"v: [A,", "YAML error: line 1: did not find expected node content"}, 451 {"v:\n- [A,", "YAML error: line 2: did not find expected node content"}, 452 {"a: *b\n", "YAML error: Unknown anchor 'b' referenced"}, 453 {"a: &a\n b: *a\n", "YAML error: Anchor 'a' value contains itself"}, 454 {"value: -", "YAML error: block sequence entries are not allowed in this context"}, 455 {"a: !!binary ==", "YAML error: !!binary value contains invalid base64 data"}, 456 {"{[.]}", `YAML error: invalid map key: \[\]interface \{\}\{"\."\}`}, 457 {"{{.}}", `YAML error: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`}, 458 } 459 460 func (s *S) TestUnmarshalErrors(c *C) { 461 for _, item := range unmarshalErrorTests { 462 var value interface{} 463 err := yaml.Unmarshal([]byte(item.data), &value) 464 c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value)) 465 } 466 } 467 468 var setterTests = []struct { 469 data, tag string 470 value interface{} 471 }{ 472 {"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}}, 473 {"_: [1,A]", "!!seq", []interface{}{1, "A"}}, 474 {"_: 10", "!!int", 10}, 475 {"_: null", "!!null", nil}, 476 {`_: BAR!`, "!!str", "BAR!"}, 477 {`_: "BAR!"`, "!!str", "BAR!"}, 478 {"_: !!foo 'BAR!'", "!!foo", "BAR!"}, 479 } 480 481 var setterResult = map[int]bool{} 482 483 type typeWithSetter struct { 484 tag string 485 value interface{} 486 } 487 488 func (o *typeWithSetter) SetYAML(tag string, value interface{}) (ok bool) { 489 o.tag = tag 490 o.value = value 491 if i, ok := value.(int); ok { 492 if result, ok := setterResult[i]; ok { 493 return result 494 } 495 } 496 return true 497 } 498 499 type setterPointerType struct { 500 Field *typeWithSetter "_" 501 } 502 503 type setterValueType struct { 504 Field typeWithSetter "_" 505 } 506 507 func (s *S) TestUnmarshalWithPointerSetter(c *C) { 508 for _, item := range setterTests { 509 obj := &setterPointerType{} 510 err := yaml.Unmarshal([]byte(item.data), obj) 511 c.Assert(err, IsNil) 512 c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value)) 513 c.Assert(obj.Field.tag, Equals, item.tag) 514 c.Assert(obj.Field.value, DeepEquals, item.value) 515 } 516 } 517 518 func (s *S) TestUnmarshalWithValueSetter(c *C) { 519 for _, item := range setterTests { 520 obj := &setterValueType{} 521 err := yaml.Unmarshal([]byte(item.data), obj) 522 c.Assert(err, IsNil) 523 c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value)) 524 c.Assert(obj.Field.tag, Equals, item.tag) 525 c.Assert(obj.Field.value, DeepEquals, item.value) 526 } 527 } 528 529 func (s *S) TestUnmarshalWholeDocumentWithSetter(c *C) { 530 obj := &typeWithSetter{} 531 err := yaml.Unmarshal([]byte(setterTests[0].data), obj) 532 c.Assert(err, IsNil) 533 c.Assert(obj.tag, Equals, setterTests[0].tag) 534 value, ok := obj.value.(map[interface{}]interface{}) 535 c.Assert(ok, Equals, true) 536 c.Assert(value["_"], DeepEquals, setterTests[0].value) 537 } 538 539 func (s *S) TestUnmarshalWithFalseSetterIgnoresValue(c *C) { 540 setterResult[2] = false 541 setterResult[4] = false 542 defer func() { 543 delete(setterResult, 2) 544 delete(setterResult, 4) 545 }() 546 547 m := map[string]*typeWithSetter{} 548 data := `{abc: 1, def: 2, ghi: 3, jkl: 4}` 549 err := yaml.Unmarshal([]byte(data), m) 550 c.Assert(err, IsNil) 551 c.Assert(m["abc"], NotNil) 552 c.Assert(m["def"], IsNil) 553 c.Assert(m["ghi"], NotNil) 554 c.Assert(m["jkl"], IsNil) 555 556 c.Assert(m["abc"].value, Equals, 1) 557 c.Assert(m["ghi"].value, Equals, 3) 558 } 559 560 // From http://yaml.org/type/merge.html 561 var mergeTests = ` 562 anchors: 563 - &CENTER { "x": 1, "y": 2 } 564 - &LEFT { "x": 0, "y": 2 } 565 - &BIG { "r": 10 } 566 - &SMALL { "r": 1 } 567 568 # All the following maps are equal: 569 570 plain: 571 # Explicit keys 572 "x": 1 573 "y": 2 574 "r": 10 575 label: center/big 576 577 mergeOne: 578 # Merge one map 579 << : *CENTER 580 "r": 10 581 label: center/big 582 583 mergeMultiple: 584 # Merge multiple maps 585 << : [ *CENTER, *BIG ] 586 label: center/big 587 588 override: 589 # Override 590 << : [ *BIG, *LEFT, *SMALL ] 591 "x": 1 592 label: center/big 593 594 shortTag: 595 # Explicit short merge tag 596 !!merge "<<" : [ *CENTER, *BIG ] 597 label: center/big 598 599 longTag: 600 # Explicit merge long tag 601 !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ] 602 label: center/big 603 604 inlineMap: 605 # Inlined map 606 << : {"x": 1, "y": 2, "r": 10} 607 label: center/big 608 609 inlineSequenceMap: 610 # Inlined map in sequence 611 << : [ *CENTER, {"r": 10} ] 612 label: center/big 613 ` 614 615 func (s *S) TestMerge(c *C) { 616 var want = map[interface{}]interface{}{ 617 "x": 1, 618 "y": 2, 619 "r": 10, 620 "label": "center/big", 621 } 622 623 var m map[string]interface{} 624 err := yaml.Unmarshal([]byte(mergeTests), &m) 625 c.Assert(err, IsNil) 626 for name, test := range m { 627 if name == "anchors" { 628 continue 629 } 630 c.Assert(test, DeepEquals, want, Commentf("test %q failed", name)) 631 } 632 } 633 634 func (s *S) TestMergeStruct(c *C) { 635 type Data struct { 636 X, Y, R int 637 Label string 638 } 639 want := Data{1, 2, 10, "center/big"} 640 641 var m map[string]Data 642 err := yaml.Unmarshal([]byte(mergeTests), &m) 643 c.Assert(err, IsNil) 644 for name, test := range m { 645 if name == "anchors" { 646 continue 647 } 648 c.Assert(test, Equals, want, Commentf("test %q failed", name)) 649 } 650 } 651 652 var unmarshalNullTests = []func() interface{}{ 653 func() interface{} { var v interface{}; v = "v"; return &v }, 654 func() interface{} { var s = "s"; return &s }, 655 func() interface{} { var s = "s"; sptr := &s; return &sptr }, 656 func() interface{} { var i = 1; return &i }, 657 func() interface{} { var i = 1; iptr := &i; return &iptr }, 658 func() interface{} { m := map[string]int{"s": 1}; return &m }, 659 func() interface{} { m := map[string]int{"s": 1}; return m }, 660 } 661 662 func (s *S) TestUnmarshalNull(c *C) { 663 for _, test := range unmarshalNullTests { 664 item := test() 665 zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface() 666 err := yaml.Unmarshal([]byte("null"), item) 667 c.Assert(err, IsNil) 668 if reflect.TypeOf(item).Kind() == reflect.Map { 669 c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface()) 670 } else { 671 c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero) 672 } 673 } 674 } 675 676 //var data []byte 677 //func init() { 678 // var err error 679 // data, err = ioutil.ReadFile("/tmp/file.yaml") 680 // if err != nil { 681 // panic(err) 682 // } 683 //} 684 // 685 //func (s *S) BenchmarkUnmarshal(c *C) { 686 // var err error 687 // for i := 0; i < c.N; i++ { 688 // var v map[string]interface{} 689 // err = yaml.Unmarshal(data, &v) 690 // } 691 // if err != nil { 692 // panic(err) 693 // } 694 //} 695 // 696 //func (s *S) BenchmarkMarshal(c *C) { 697 // var v map[string]interface{} 698 // yaml.Unmarshal(data, &v) 699 // c.ResetTimer() 700 // for i := 0; i < c.N; i++ { 701 // yaml.Marshal(&v) 702 // } 703 //}