14 var unmarshalIntTest = 123
16 var unmarshalTests = []struct {
27 map[string]string{"v": "hi"},
29 "v: hi", map[string]interface{}{"v": "hi"},
32 map[string]string{"v": "true"},
35 map[string]interface{}{"v": true},
38 map[string]interface{}{"v": 10},
41 map[string]interface{}{"v": 2},
44 map[string]interface{}{"v": 10},
47 map[string]int64{"v": 4294967296},
50 map[string]interface{}{"v": 0.1},
53 map[string]interface{}{"v": 0.1},
56 map[string]interface{}{"v": math.Inf(+1)},
59 map[string]interface{}{"v": math.Inf(-1)},
62 map[string]interface{}{"v": -10},
65 map[string]interface{}{"v": -0.1},
76 "canonical: 6.8523e+5",
77 map[string]interface{}{"canonical": 6.8523e+5},
79 "expo: 685.230_15e+03",
80 map[string]interface{}{"expo": 685.23015e+03},
83 map[string]interface{}{"fixed": 685230.15},
86 map[string]interface{}{"neginf": math.Inf(-1)},
89 map[string]float64{"fixed": 685230.15},
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.
97 map[string]interface{}{"canonical": true},
100 map[string]interface{}{"answer": false},
103 map[string]interface{}{"logical": true},
106 map[string]interface{}{"option": true},
109 map[string]bool{"option": true},
114 map[string]interface{}{"canonical": 685230},
117 map[string]interface{}{"decimal": 685230},
120 map[string]interface{}{"octal": 685230},
123 map[string]interface{}{"hexa": 685230},
125 "bin: 0b1010_0111_0100_1010_1110",
126 map[string]interface{}{"bin": 685230},
129 map[string]interface{}{"bin": -42},
132 map[string]int{"decimal": 685230},
135 //{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported
140 map[string]interface{}{"empty": nil},
143 map[string]interface{}{"canonical": nil},
146 map[string]interface{}{"english": nil},
149 map[interface{}]string{nil: "null key"},
152 map[string]*bool{"empty": nil},
158 map[string]interface{}{"seq": []interface{}{"A", "B"}},
161 map[string][]string{"seq": []string{"A", "B", "C"}},
164 map[string][]string{"seq": []string{"A", "1", "C"}},
167 map[string][]int{"seq": []int{1}},
170 map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
175 map[string]interface{}{"seq": []interface{}{"A", "B"}},
177 "seq:\n - A\n - B\n - C",
178 map[string][]string{"seq": []string{"A", "B", "C"}},
180 "seq:\n - A\n - 1\n - C",
181 map[string][]string{"seq": []string{"A", "1", "C"}},
183 "seq:\n - A\n - 1\n - C",
184 map[string][]int{"seq": []int{1}},
186 "seq:\n - A\n - 1\n - C",
187 map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
190 // Literal block scalar
192 "scalar: | # Comment\n\n literal\n\n \ttext\n\n",
193 map[string]string{"scalar": "\nliteral\n\n\ttext\n"},
196 // Folded block scalar
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"},
202 // Map inside interface with no type hints.
205 map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": "c"}},
208 // Structs and type conversions.
211 &struct{ Hello string }{"world"},
214 &struct{ A struct{ B string } }{struct{ B string }{"c"}},
217 &struct{ A *struct{ B string } }{&struct{ B string }{"c"}},
220 &struct{ A map[string]string }{map[string]string{"b": "c"}},
223 &struct{ A *map[string]string }{&map[string]string{"b": "c"}},
226 &struct{ A map[string]string }{},
232 &struct{ A float64 }{1},
238 &struct{ A uint }{1},
241 &struct{ A []int }{[]int{1, 2}},
252 &struct{ A bool }{true},
255 // Some cross type conversions
258 map[string]uint{"v": 42},
264 map[string]uint64{"v": 4294967296},
272 "int_max: 2147483647",
273 map[string]int{"int_max": math.MaxInt32},
276 "int_min: -2147483648",
277 map[string]int{"int_min": math.MinInt32},
280 "int_overflow: 9223372036854775808", // math.MaxInt64 + 1
286 "int64_max: 9223372036854775807",
287 map[string]int64{"int64_max": math.MaxInt64},
290 "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111",
291 map[string]int64{"int64_max_base2": math.MaxInt64},
294 "int64_min: -9223372036854775808",
295 map[string]int64{"int64_min": math.MinInt64},
298 "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111",
299 map[string]int64{"int64_neg_base2": -math.MaxInt64},
302 "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1
309 map[string]uint{"uint_min": 0},
312 "uint_max: 4294967295",
313 map[string]uint{"uint_max": math.MaxUint32},
316 "uint_underflow: -1",
323 map[string]uint{"uint64_min": 0},
326 "uint64_max: 18446744073709551615",
327 map[string]uint64{"uint64_max": math.MaxUint64},
330 "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111",
331 map[string]uint64{"uint64_max_base2": math.MaxUint64},
334 "uint64_maxint64: 9223372036854775807",
335 map[string]uint64{"uint64_maxint64": math.MaxInt64},
338 "uint64_underflow: -1",
344 "float32_max: 3.40282346638528859811704183484516925440e+38",
345 map[string]float32{"float32_max": math.MaxFloat32},
348 "float32_nonzero: 1.401298464324817070923729583289916131280e-45",
349 map[string]float32{"float32_nonzero": math.SmallestNonzeroFloat32},
352 "float32_maxuint64: 18446744073709551615",
353 map[string]float32{"float32_maxuint64": float32(math.MaxUint64)},
356 "float32_maxuint64+1: 18446744073709551616",
357 map[string]float32{"float32_maxuint64+1": float32(math.MaxUint64 + 1)},
362 "float64_max: 1.797693134862315708145274237317043567981e+308",
363 map[string]float64{"float64_max": math.MaxFloat64},
366 "float64_nonzero: 4.940656458412465441765687928682213723651e-324",
367 map[string]float64{"float64_nonzero": math.SmallestNonzeroFloat64},
370 "float64_maxuint64: 18446744073709551615",
371 map[string]float64{"float64_maxuint64": float64(math.MaxUint64)},
374 "float64_maxuint64+1: 18446744073709551616",
375 map[string]float64{"float64_maxuint64+1": float64(math.MaxUint64 + 1)},
390 map[interface{}]interface{}{"1": "\"2\""},
392 "v:\n- A\n- 'B\n\n C'\n",
393 map[string][]string{"v": []string{"A", "B\nC"}},
399 map[string]interface{}{"v": 1.1},
402 map[string]interface{}{"v": nil},
404 "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
405 map[string]interface{}{"v": 1},
408 // Non-specific tag (Issue #75)
411 map[string]interface{}{"v": "test"},
414 // Anchors and aliases.
416 "a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
417 &struct{ A, B, C, D int }{1, 2, 1, 2},
419 "a: &a {c: 1}\nb: *a",
424 }{struct{ C int }{1}, struct{ C int }{1}},
426 "a: &a [1, 2]\nb: *a",
427 &struct{ B []int }{[]int{1, 2}},
429 "b: *a\na: &a {c: 1}",
434 }{struct{ C int }{1}, struct{ C int }{1}},
440 map[string]*string{"foo": new(string)},
443 map[string]string{"foo": ""},
446 map[string]interface{}{"foo": nil},
463 `"Generic line break (no glyph)\n\` + "\n" +
464 ` Generic line break (glyphed)\n\` + "\n" +
465 ` Line separator\u2028\` + "\n" +
466 ` Paragraph separator\u2029"` + "\n",
468 "Generic line break (no glyph)\n" +
469 "Generic line break (glyphed)\n" +
470 "Line separator\u2028Paragraph separator\u2029",
475 "a: 1\nb: 2\nc: 3\n",
478 C inlineB `yaml:",inline"`
479 }{1, inlineB{2, inlineC{3}}},
484 "a: 1\nb: 2\nc: 3\n",
487 C map[string]int `yaml:",inline"`
488 }{1, map[string]int{"b": 2, "c": 3}},
494 map[string]interface{}{"a": "-b_c"},
498 map[string]interface{}{"a": "+b_c"},
501 "a: 50cent_of_dollar",
502 map[string]interface{}{"a": "50cent_of_dollar"},
508 map[string]time.Duration{"a": 3 * time.Second},
514 map[string]string{"a": "<foo>"},
517 // Base 60 floats are obsolete and unsupported.
520 map[string]string{"a": "1:1"},
525 "a: !!binary gIGC\n",
526 map[string]string{"a": "\x80\x81\x82"},
528 "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n",
529 map[string]string{"a": strings.Repeat("\x90", 54)},
531 "a: !!binary |\n " + strings.Repeat("A", 70) + "\n ==\n",
532 map[string]string{"a": strings.Repeat("\x00", 52)},
537 "{b: 2, a: 1, d: 4, c: 3, sub: {e: 5}}",
538 &yaml.MapSlice{{"b", 2}, {"a", 1}, {"d", 4}, {"c", 3}, {"sub", yaml.MapSlice{{"e", 5}}}},
544 map[string]struct{ B interface{} }{"a": {map[interface{}]interface{}{"c": "d"}}},
553 // Support encoding.TextUnmarshaler.
556 map[string]net.IP{"a": net.IPv4(1, 2, 3, 4)},
559 "a: 2015-02-24T18:19:39Z\n",
560 map[string]time.Time{"a": time.Unix(1424801979, 0).In(time.UTC)},
563 // Encode empty lists as zero-length slices.
566 &struct{ A []int }{[]int{}},
571 "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00",
572 M{"ñoño": "very yes"},
574 // UTF-16-LE with surrogate.
576 "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00",
577 M{"ñoño": "very yes 🟔"},
582 "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n",
583 M{"ñoño": "very yes"},
585 // UTF-16-BE with surrogate.
587 "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n",
588 M{"ñoño": "very yes 🟔"},
591 // YAML Float regex shouldn't match this
601 type M map[interface{}]interface{}
603 type inlineB struct {
605 inlineC `yaml:",inline"`
608 type inlineC struct {
612 func (s *S) TestUnmarshal(c *C) {
613 for i, item := range unmarshalTests {
614 c.Logf("test %d: %q", i, item.data)
615 t := reflect.ValueOf(item.value).Type()
616 var value interface{}
619 value = reflect.MakeMap(t).Interface()
621 value = reflect.New(t).Interface()
623 value = reflect.New(t.Elem()).Interface()
625 c.Fatalf("missing case for %s", t)
627 err := yaml.Unmarshal([]byte(item.data), value)
628 if _, ok := err.(*yaml.TypeError); !ok {
631 if t.Kind() == reflect.String {
632 c.Assert(*value.(*string), Equals, item.value)
634 c.Assert(value, DeepEquals, item.value)
639 func (s *S) TestUnmarshalNaN(c *C) {
640 value := map[string]interface{}{}
641 err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
643 c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
646 var unmarshalErrorTests = []struct {
649 {"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"},
650 {"v: [A,", "yaml: line 1: did not find expected node content"},
651 {"v:\n- [A,", "yaml: line 2: did not find expected node content"},
652 {"a: *b\n", "yaml: unknown anchor 'b' referenced"},
653 {"a: &a\n b: *a\n", "yaml: anchor 'a' value contains itself"},
654 {"value: -", "yaml: block sequence entries are not allowed in this context"},
655 {"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
656 {"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
657 {"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
658 {"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
661 func (s *S) TestUnmarshalErrors(c *C) {
662 for _, item := range unmarshalErrorTests {
663 var value interface{}
664 err := yaml.Unmarshal([]byte(item.data), &value)
665 c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
669 var unmarshalerTests = []struct {
673 {"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}},
674 {"_: [1,A]", "!!seq", []interface{}{1, "A"}},
675 {"_: 10", "!!int", 10},
676 {"_: null", "!!null", nil},
677 {`_: BAR!`, "!!str", "BAR!"},
678 {`_: "BAR!"`, "!!str", "BAR!"},
679 {"_: !!foo 'BAR!'", "!!foo", "BAR!"},
680 {`_: ""`, "!!str", ""},
683 var unmarshalerResult = map[int]error{}
685 type unmarshalerType struct {
689 func (o *unmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error {
690 if err := unmarshal(&o.value); err != nil {
693 if i, ok := o.value.(int); ok {
694 if result, ok := unmarshalerResult[i]; ok {
701 type unmarshalerPointer struct {
702 Field *unmarshalerType "_"
705 type unmarshalerValue struct {
706 Field unmarshalerType "_"
709 func (s *S) TestUnmarshalerPointerField(c *C) {
710 for _, item := range unmarshalerTests {
711 obj := &unmarshalerPointer{}
712 err := yaml.Unmarshal([]byte(item.data), obj)
714 if item.value == nil {
715 c.Assert(obj.Field, IsNil)
717 c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
718 c.Assert(obj.Field.value, DeepEquals, item.value)
723 func (s *S) TestUnmarshalerValueField(c *C) {
724 for _, item := range unmarshalerTests {
725 obj := &unmarshalerValue{}
726 err := yaml.Unmarshal([]byte(item.data), obj)
728 c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
729 c.Assert(obj.Field.value, DeepEquals, item.value)
733 func (s *S) TestUnmarshalerWholeDocument(c *C) {
734 obj := &unmarshalerType{}
735 err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj)
737 value, ok := obj.value.(map[interface{}]interface{})
738 c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value))
739 c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value)
742 func (s *S) TestUnmarshalerTypeError(c *C) {
743 unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
744 unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
746 delete(unmarshalerResult, 2)
747 delete(unmarshalerResult, 4)
753 M map[string]*unmarshalerType
756 data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
757 err := yaml.Unmarshal([]byte(data), &v)
758 c.Assert(err, ErrorMatches, ""+
759 "yaml: unmarshal errors:\n"+
760 " line 1: cannot unmarshal !!str `A` into int\n"+
763 " line 1: cannot unmarshal !!str `B` into int")
764 c.Assert(v.M["abc"], NotNil)
765 c.Assert(v.M["def"], IsNil)
766 c.Assert(v.M["ghi"], NotNil)
767 c.Assert(v.M["jkl"], IsNil)
769 c.Assert(v.M["abc"].value, Equals, 1)
770 c.Assert(v.M["ghi"].value, Equals, 3)
773 type proxyTypeError struct{}
775 func (v *proxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error {
779 if err := unmarshal(&s); err != nil {
783 if err := unmarshal(&b); err == nil {
784 panic("should have failed")
788 if err := unmarshal(&a); err == nil {
789 panic("should have failed")
794 func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
798 M map[string]*proxyTypeError
801 data := `{before: A, m: {abc: a, def: b}, after: B}`
802 err := yaml.Unmarshal([]byte(data), &v)
803 c.Assert(err, ErrorMatches, ""+
804 "yaml: unmarshal errors:\n"+
805 " line 1: cannot unmarshal !!str `A` into int\n"+
806 " line 1: cannot unmarshal !!str `a` into int32\n"+
807 " line 1: cannot unmarshal !!str `b` into int64\n"+
808 " line 1: cannot unmarshal !!str `B` into int")
811 type failingUnmarshaler struct{}
813 var failingErr = errors.New("failingErr")
815 func (ft *failingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
819 func (s *S) TestUnmarshalerError(c *C) {
820 err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{})
821 c.Assert(err, Equals, failingErr)
824 type sliceUnmarshaler []int
826 func (su *sliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
828 err := unmarshal(&slice)
835 err = unmarshal(&intVal)
844 func (s *S) TestUnmarshalerRetry(c *C) {
845 var su sliceUnmarshaler
846 err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
848 c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3}))
850 err = yaml.Unmarshal([]byte("1"), &su)
852 c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1}))
855 // From http://yaml.org/type/merge.html
859 - &CENTER { "x": 1, "y": 2 }
860 - &LEFT { "x": 0, "y": 2 }
864 # All the following maps are equal:
880 # Merge multiple maps
881 << : [ *CENTER, *BIG ]
886 << : [ *BIG, *LEFT, *SMALL ]
891 # Explicit short merge tag
892 !!merge "<<" : [ *CENTER, *BIG ]
896 # Explicit merge long tag
897 !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ]
902 << : {"x": 1, "y": 2, "r": 10}
906 # Inlined map in sequence
907 << : [ *CENTER, {"r": 10} ]
911 func (s *S) TestMerge(c *C) {
912 var want = map[interface{}]interface{}{
916 "label": "center/big",
919 var m map[interface{}]interface{}
920 err := yaml.Unmarshal([]byte(mergeTests), &m)
922 for name, test := range m {
923 if name == "anchors" {
926 c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
930 func (s *S) TestMergeStruct(c *C) {
935 want := Data{1, 2, 10, "center/big"}
937 var m map[string]Data
938 err := yaml.Unmarshal([]byte(mergeTests), &m)
940 for name, test := range m {
941 if name == "anchors" {
944 c.Assert(test, Equals, want, Commentf("test %q failed", name))
948 var unmarshalNullTests = []func() interface{}{
949 func() interface{} { var v interface{}; v = "v"; return &v },
950 func() interface{} { var s = "s"; return &s },
951 func() interface{} { var s = "s"; sptr := &s; return &sptr },
952 func() interface{} { var i = 1; return &i },
953 func() interface{} { var i = 1; iptr := &i; return &iptr },
954 func() interface{} { m := map[string]int{"s": 1}; return &m },
955 func() interface{} { m := map[string]int{"s": 1}; return m },
958 func (s *S) TestUnmarshalNull(c *C) {
959 for _, test := range unmarshalNullTests {
961 zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface()
962 err := yaml.Unmarshal([]byte("null"), item)
964 if reflect.TypeOf(item).Kind() == reflect.Map {
965 c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface())
967 c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero)
972 func (s *S) TestUnmarshalSliceOnPreset(c *C) {
974 v := struct{ A []int }{[]int{1}}
975 yaml.Unmarshal([]byte("a: [2]"), &v)
976 c.Assert(v.A, DeepEquals, []int{2})
979 func (s *S) TestUnmarshalStrict(c *C) {
980 v := struct{ A, B int }{}
982 err := yaml.UnmarshalStrict([]byte("a: 1\nb: 2"), &v)
984 err = yaml.Unmarshal([]byte("a: 1\nb: 2\nc: 3"), &v)
986 err = yaml.UnmarshalStrict([]byte("a: 1\nb: 2\nc: 3"), &v)
987 c.Check(err, ErrorMatches, "yaml: unmarshal errors:\n line 1: field c not found in struct struct { A int; B int }")
993 // data, err = ioutil.ReadFile("/tmp/file.yaml")
999 //func (s *S) BenchmarkUnmarshal(c *C) {
1001 // for i := 0; i < c.N; i++ {
1002 // var v map[string]interface{}
1003 // err = yaml.Unmarshal(data, &v)
1010 //func (s *S) BenchmarkMarshal(c *C) {
1011 // var v map[string]interface{}
1012 // yaml.Unmarshal(data, &v)
1014 // for i := 0; i < c.N; i++ {