github.com/nibnait/go-learn@v0.0.0-20220227013611-dfa47ea6d2da/src/pkg/mod/gopkg.in/yaml.v3@v3.0.0-20200313102051-9f266ea9e77c/decode_test.go (about)

     1  //
     2  // Copyright (c) 2011-2019 Canonical Ltd
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package yaml_test
    17  
    18  import (
    19  	"bytes"
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  	"math"
    24  	"reflect"
    25  	"strings"
    26  	"time"
    27  
    28  	. "gopkg.in/check.v1"
    29  	"gopkg.in/yaml.v3"
    30  )
    31  
    32  var unmarshalIntTest = 123
    33  
    34  var unmarshalTests = []struct {
    35  	data  string
    36  	value interface{}
    37  }{
    38  	{
    39  		"",
    40  		(*struct{})(nil),
    41  	},
    42  	{
    43  		"{}", &struct{}{},
    44  	}, {
    45  		"v: hi",
    46  		map[string]string{"v": "hi"},
    47  	}, {
    48  		"v: hi", map[string]interface{}{"v": "hi"},
    49  	}, {
    50  		"v: true",
    51  		map[string]string{"v": "true"},
    52  	}, {
    53  		"v: true",
    54  		map[string]interface{}{"v": true},
    55  	}, {
    56  		"v: 10",
    57  		map[string]interface{}{"v": 10},
    58  	}, {
    59  		"v: 0b10",
    60  		map[string]interface{}{"v": 2},
    61  	}, {
    62  		"v: 0xA",
    63  		map[string]interface{}{"v": 10},
    64  	}, {
    65  		"v: 4294967296",
    66  		map[string]int64{"v": 4294967296},
    67  	}, {
    68  		"v: 0.1",
    69  		map[string]interface{}{"v": 0.1},
    70  	}, {
    71  		"v: .1",
    72  		map[string]interface{}{"v": 0.1},
    73  	}, {
    74  		"v: .Inf",
    75  		map[string]interface{}{"v": math.Inf(+1)},
    76  	}, {
    77  		"v: -.Inf",
    78  		map[string]interface{}{"v": math.Inf(-1)},
    79  	}, {
    80  		"v: -10",
    81  		map[string]interface{}{"v": -10},
    82  	}, {
    83  		"v: -.1",
    84  		map[string]interface{}{"v": -0.1},
    85  	},
    86  
    87  	// Simple values.
    88  	{
    89  		"123",
    90  		&unmarshalIntTest,
    91  	},
    92  
    93  	// Floats from spec
    94  	{
    95  		"canonical: 6.8523e+5",
    96  		map[string]interface{}{"canonical": 6.8523e+5},
    97  	}, {
    98  		"expo: 685.230_15e+03",
    99  		map[string]interface{}{"expo": 685.23015e+03},
   100  	}, {
   101  		"fixed: 685_230.15",
   102  		map[string]interface{}{"fixed": 685230.15},
   103  	}, {
   104  		"neginf: -.inf",
   105  		map[string]interface{}{"neginf": math.Inf(-1)},
   106  	}, {
   107  		"fixed: 685_230.15",
   108  		map[string]float64{"fixed": 685230.15},
   109  	},
   110  	//{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported
   111  	//{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails.
   112  
   113  	// Bools are per 1.2 spec.
   114  	{
   115  		"canonical: true",
   116  		map[string]interface{}{"canonical": true},
   117  	}, {
   118  		"canonical: false",
   119  		map[string]interface{}{"canonical": false},
   120  	}, {
   121  		"bool: True",
   122  		map[string]interface{}{"bool": true},
   123  	}, {
   124  		"bool: False",
   125  		map[string]interface{}{"bool": false},
   126  	}, {
   127  		"bool: TRUE",
   128  		map[string]interface{}{"bool": true},
   129  	}, {
   130  		"bool: FALSE",
   131  		map[string]interface{}{"bool": false},
   132  	},
   133  	// For backwards compatibility with 1.1, decoding old strings into typed values still works.
   134  	{
   135  		"option: on",
   136  		map[string]bool{"option": true},
   137  	}, {
   138  		"option: y",
   139  		map[string]bool{"option": true},
   140  	}, {
   141  		"option: Off",
   142  		map[string]bool{"option": false},
   143  	}, {
   144  		"option: No",
   145  		map[string]bool{"option": false},
   146  	}, {
   147  		"option: other",
   148  		map[string]bool{},
   149  	},
   150  	// Ints from spec
   151  	{
   152  		"canonical: 685230",
   153  		map[string]interface{}{"canonical": 685230},
   154  	}, {
   155  		"decimal: +685_230",
   156  		map[string]interface{}{"decimal": 685230},
   157  	}, {
   158  		"octal: 02472256",
   159  		map[string]interface{}{"octal": 685230},
   160  	}, {
   161  		"octal: -02472256",
   162  		map[string]interface{}{"octal": -685230},
   163  	}, {
   164  		"octal: 0o2472256",
   165  		map[string]interface{}{"octal": 685230},
   166  	}, {
   167  		"octal: -0o2472256",
   168  		map[string]interface{}{"octal": -685230},
   169  	}, {
   170  		"hexa: 0x_0A_74_AE",
   171  		map[string]interface{}{"hexa": 685230},
   172  	}, {
   173  		"bin: 0b1010_0111_0100_1010_1110",
   174  		map[string]interface{}{"bin": 685230},
   175  	}, {
   176  		"bin: -0b101010",
   177  		map[string]interface{}{"bin": -42},
   178  	}, {
   179  		"bin: -0b1000000000000000000000000000000000000000000000000000000000000000",
   180  		map[string]interface{}{"bin": -9223372036854775808},
   181  	}, {
   182  		"decimal: +685_230",
   183  		map[string]int{"decimal": 685230},
   184  	},
   185  
   186  	//{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported
   187  
   188  	// Nulls from spec
   189  	{
   190  		"empty:",
   191  		map[string]interface{}{"empty": nil},
   192  	}, {
   193  		"canonical: ~",
   194  		map[string]interface{}{"canonical": nil},
   195  	}, {
   196  		"english: null",
   197  		map[string]interface{}{"english": nil},
   198  	}, {
   199  		"~: null key",
   200  		map[interface{}]string{nil: "null key"},
   201  	}, {
   202  		"empty:",
   203  		map[string]*bool{"empty": nil},
   204  	},
   205  
   206  	// Flow sequence
   207  	{
   208  		"seq: [A,B]",
   209  		map[string]interface{}{"seq": []interface{}{"A", "B"}},
   210  	}, {
   211  		"seq: [A,B,C,]",
   212  		map[string][]string{"seq": []string{"A", "B", "C"}},
   213  	}, {
   214  		"seq: [A,1,C]",
   215  		map[string][]string{"seq": []string{"A", "1", "C"}},
   216  	}, {
   217  		"seq: [A,1,C]",
   218  		map[string][]int{"seq": []int{1}},
   219  	}, {
   220  		"seq: [A,1,C]",
   221  		map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
   222  	},
   223  	// Block sequence
   224  	{
   225  		"seq:\n - A\n - B",
   226  		map[string]interface{}{"seq": []interface{}{"A", "B"}},
   227  	}, {
   228  		"seq:\n - A\n - B\n - C",
   229  		map[string][]string{"seq": []string{"A", "B", "C"}},
   230  	}, {
   231  		"seq:\n - A\n - 1\n - C",
   232  		map[string][]string{"seq": []string{"A", "1", "C"}},
   233  	}, {
   234  		"seq:\n - A\n - 1\n - C",
   235  		map[string][]int{"seq": []int{1}},
   236  	}, {
   237  		"seq:\n - A\n - 1\n - C",
   238  		map[string]interface{}{"seq": []interface{}{"A", 1, "C"}},
   239  	},
   240  
   241  	// Literal block scalar
   242  	{
   243  		"scalar: | # Comment\n\n literal\n\n \ttext\n\n",
   244  		map[string]string{"scalar": "\nliteral\n\n\ttext\n"},
   245  	},
   246  
   247  	// Folded block scalar
   248  	{
   249  		"scalar: > # Comment\n\n folded\n line\n \n next\n line\n  * one\n  * two\n\n last\n line\n\n",
   250  		map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"},
   251  	},
   252  
   253  	// Map inside interface with no type hints.
   254  	{
   255  		"a: {b: c}",
   256  		map[interface{}]interface{}{"a": map[string]interface{}{"b": "c"}},
   257  	},
   258  	// Non-string map inside interface with no type hints.
   259  	{
   260  		"a: {b: c, 1: d}",
   261  		map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": "c", 1: "d"}},
   262  	},
   263  
   264  	// Structs and type conversions.
   265  	{
   266  		"hello: world",
   267  		&struct{ Hello string }{"world"},
   268  	}, {
   269  		"a: {b: c}",
   270  		&struct{ A struct{ B string } }{struct{ B string }{"c"}},
   271  	}, {
   272  		"a: {b: c}",
   273  		&struct{ A *struct{ B string } }{&struct{ B string }{"c"}},
   274  	}, {
   275  		"a: 'null'",
   276  		&struct{ A *unmarshalerType }{&unmarshalerType{"null"}},
   277  	}, {
   278  		"a: {b: c}",
   279  		&struct{ A map[string]string }{map[string]string{"b": "c"}},
   280  	}, {
   281  		"a: {b: c}",
   282  		&struct{ A *map[string]string }{&map[string]string{"b": "c"}},
   283  	}, {
   284  		"a:",
   285  		&struct{ A map[string]string }{},
   286  	}, {
   287  		"a: 1",
   288  		&struct{ A int }{1},
   289  	}, {
   290  		"a: 1",
   291  		&struct{ A float64 }{1},
   292  	}, {
   293  		"a: 1.0",
   294  		&struct{ A int }{1},
   295  	}, {
   296  		"a: 1.0",
   297  		&struct{ A uint }{1},
   298  	}, {
   299  		"a: [1, 2]",
   300  		&struct{ A []int }{[]int{1, 2}},
   301  	}, {
   302  		"a: [1, 2]",
   303  		&struct{ A [2]int }{[2]int{1, 2}},
   304  	}, {
   305  		"a: 1",
   306  		&struct{ B int }{0},
   307  	}, {
   308  		"a: 1",
   309  		&struct {
   310  			B int "a"
   311  		}{1},
   312  	}, {
   313  		// Some limited backwards compatibility with the 1.1 spec.
   314  		"a: YES",
   315  		&struct{ A bool }{true},
   316  	},
   317  
   318  	// Some cross type conversions
   319  	{
   320  		"v: 42",
   321  		map[string]uint{"v": 42},
   322  	}, {
   323  		"v: -42",
   324  		map[string]uint{},
   325  	}, {
   326  		"v: 4294967296",
   327  		map[string]uint64{"v": 4294967296},
   328  	}, {
   329  		"v: -4294967296",
   330  		map[string]uint64{},
   331  	},
   332  
   333  	// int
   334  	{
   335  		"int_max: 2147483647",
   336  		map[string]int{"int_max": math.MaxInt32},
   337  	},
   338  	{
   339  		"int_min: -2147483648",
   340  		map[string]int{"int_min": math.MinInt32},
   341  	},
   342  	{
   343  		"int_overflow: 9223372036854775808", // math.MaxInt64 + 1
   344  		map[string]int{},
   345  	},
   346  
   347  	// int64
   348  	{
   349  		"int64_max: 9223372036854775807",
   350  		map[string]int64{"int64_max": math.MaxInt64},
   351  	},
   352  	{
   353  		"int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111",
   354  		map[string]int64{"int64_max_base2": math.MaxInt64},
   355  	},
   356  	{
   357  		"int64_min: -9223372036854775808",
   358  		map[string]int64{"int64_min": math.MinInt64},
   359  	},
   360  	{
   361  		"int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111",
   362  		map[string]int64{"int64_neg_base2": -math.MaxInt64},
   363  	},
   364  	{
   365  		"int64_overflow: 9223372036854775808", // math.MaxInt64 + 1
   366  		map[string]int64{},
   367  	},
   368  
   369  	// uint
   370  	{
   371  		"uint_min: 0",
   372  		map[string]uint{"uint_min": 0},
   373  	},
   374  	{
   375  		"uint_max: 4294967295",
   376  		map[string]uint{"uint_max": math.MaxUint32},
   377  	},
   378  	{
   379  		"uint_underflow: -1",
   380  		map[string]uint{},
   381  	},
   382  
   383  	// uint64
   384  	{
   385  		"uint64_min: 0",
   386  		map[string]uint{"uint64_min": 0},
   387  	},
   388  	{
   389  		"uint64_max: 18446744073709551615",
   390  		map[string]uint64{"uint64_max": math.MaxUint64},
   391  	},
   392  	{
   393  		"uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111",
   394  		map[string]uint64{"uint64_max_base2": math.MaxUint64},
   395  	},
   396  	{
   397  		"uint64_maxint64: 9223372036854775807",
   398  		map[string]uint64{"uint64_maxint64": math.MaxInt64},
   399  	},
   400  	{
   401  		"uint64_underflow: -1",
   402  		map[string]uint64{},
   403  	},
   404  
   405  	// float32
   406  	{
   407  		"float32_max: 3.40282346638528859811704183484516925440e+38",
   408  		map[string]float32{"float32_max": math.MaxFloat32},
   409  	},
   410  	{
   411  		"float32_nonzero: 1.401298464324817070923729583289916131280e-45",
   412  		map[string]float32{"float32_nonzero": math.SmallestNonzeroFloat32},
   413  	},
   414  	{
   415  		"float32_maxuint64: 18446744073709551615",
   416  		map[string]float32{"float32_maxuint64": float32(math.MaxUint64)},
   417  	},
   418  	{
   419  		"float32_maxuint64+1: 18446744073709551616",
   420  		map[string]float32{"float32_maxuint64+1": float32(math.MaxUint64 + 1)},
   421  	},
   422  
   423  	// float64
   424  	{
   425  		"float64_max: 1.797693134862315708145274237317043567981e+308",
   426  		map[string]float64{"float64_max": math.MaxFloat64},
   427  	},
   428  	{
   429  		"float64_nonzero: 4.940656458412465441765687928682213723651e-324",
   430  		map[string]float64{"float64_nonzero": math.SmallestNonzeroFloat64},
   431  	},
   432  	{
   433  		"float64_maxuint64: 18446744073709551615",
   434  		map[string]float64{"float64_maxuint64": float64(math.MaxUint64)},
   435  	},
   436  	{
   437  		"float64_maxuint64+1: 18446744073709551616",
   438  		map[string]float64{"float64_maxuint64+1": float64(math.MaxUint64 + 1)},
   439  	},
   440  
   441  	// Overflow cases.
   442  	{
   443  		"v: 4294967297",
   444  		map[string]int32{},
   445  	}, {
   446  		"v: 128",
   447  		map[string]int8{},
   448  	},
   449  
   450  	// Quoted values.
   451  	{
   452  		"'1': '\"2\"'",
   453  		map[interface{}]interface{}{"1": "\"2\""},
   454  	}, {
   455  		"v:\n- A\n- 'B\n\n  C'\n",
   456  		map[string][]string{"v": []string{"A", "B\nC"}},
   457  	},
   458  
   459  	// Explicit tags.
   460  	{
   461  		"v: !!float '1.1'",
   462  		map[string]interface{}{"v": 1.1},
   463  	}, {
   464  		"v: !!float 0",
   465  		map[string]interface{}{"v": float64(0)},
   466  	}, {
   467  		"v: !!float -1",
   468  		map[string]interface{}{"v": float64(-1)},
   469  	}, {
   470  		"v: !!null ''",
   471  		map[string]interface{}{"v": nil},
   472  	}, {
   473  		"%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
   474  		map[string]interface{}{"v": 1},
   475  	},
   476  
   477  	// Non-specific tag (Issue #75)
   478  	{
   479  		"v: ! test",
   480  		map[string]interface{}{"v": "test"},
   481  	},
   482  
   483  	// Anchors and aliases.
   484  	{
   485  		"a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
   486  		&struct{ A, B, C, D int }{1, 2, 1, 2},
   487  	}, {
   488  		"a: &a {c: 1}\nb: *a",
   489  		&struct {
   490  			A, B struct {
   491  				C int
   492  			}
   493  		}{struct{ C int }{1}, struct{ C int }{1}},
   494  	}, {
   495  		"a: &a [1, 2]\nb: *a",
   496  		&struct{ B []int }{[]int{1, 2}},
   497  	},
   498  
   499  	// Bug #1133337
   500  	{
   501  		"foo: ''",
   502  		map[string]*string{"foo": new(string)},
   503  	}, {
   504  		"foo: null",
   505  		map[string]*string{"foo": nil},
   506  	}, {
   507  		"foo: null",
   508  		map[string]string{},
   509  	}, {
   510  		"foo: null",
   511  		map[string]interface{}{"foo": nil},
   512  	},
   513  
   514  	// Support for ~
   515  	{
   516  		"foo: ~",
   517  		map[string]*string{"foo": nil},
   518  	}, {
   519  		"foo: ~",
   520  		map[string]string{},
   521  	}, {
   522  		"foo: ~",
   523  		map[string]interface{}{"foo": nil},
   524  	},
   525  
   526  	// Ignored field
   527  	{
   528  		"a: 1\nb: 2\n",
   529  		&struct {
   530  			A int
   531  			B int "-"
   532  		}{1, 0},
   533  	},
   534  
   535  	// Bug #1191981
   536  	{
   537  		"" +
   538  			"%YAML 1.1\n" +
   539  			"--- !!str\n" +
   540  			`"Generic line break (no glyph)\n\` + "\n" +
   541  			` Generic line break (glyphed)\n\` + "\n" +
   542  			` Line separator\u2028\` + "\n" +
   543  			` Paragraph separator\u2029"` + "\n",
   544  		"" +
   545  			"Generic line break (no glyph)\n" +
   546  			"Generic line break (glyphed)\n" +
   547  			"Line separator\u2028Paragraph separator\u2029",
   548  	},
   549  
   550  	// Struct inlining
   551  	{
   552  		"a: 1\nb: 2\nc: 3\n",
   553  		&struct {
   554  			A int
   555  			C inlineB `yaml:",inline"`
   556  		}{1, inlineB{2, inlineC{3}}},
   557  	},
   558  
   559  	// Struct inlining as a pointer.
   560  	{
   561  		"a: 1\nb: 2\nc: 3\n",
   562  		&struct {
   563  			A int
   564  			C *inlineB `yaml:",inline"`
   565  		}{1, &inlineB{2, inlineC{3}}},
   566  	}, {
   567  		"a: 1\n",
   568  		&struct {
   569  			A int
   570  			C *inlineB `yaml:",inline"`
   571  		}{1, nil},
   572  	}, {
   573  		"a: 1\nc: 3\nd: 4\n",
   574  		&struct {
   575  			A int
   576  			C *inlineD `yaml:",inline"`
   577  		}{1, &inlineD{&inlineC{3}, 4}},
   578  	},
   579  
   580  	// Map inlining
   581  	{
   582  		"a: 1\nb: 2\nc: 3\n",
   583  		&struct {
   584  			A int
   585  			C map[string]int `yaml:",inline"`
   586  		}{1, map[string]int{"b": 2, "c": 3}},
   587  	},
   588  
   589  	// bug 1243827
   590  	{
   591  		"a: -b_c",
   592  		map[string]interface{}{"a": "-b_c"},
   593  	},
   594  	{
   595  		"a: +b_c",
   596  		map[string]interface{}{"a": "+b_c"},
   597  	},
   598  	{
   599  		"a: 50cent_of_dollar",
   600  		map[string]interface{}{"a": "50cent_of_dollar"},
   601  	},
   602  
   603  	// issue #295 (allow scalars with colons in flow mappings and sequences)
   604  	{
   605  		"a: {b: https://github.com/go-yaml/yaml}",
   606  		map[string]interface{}{"a": map[string]interface{}{
   607  			"b": "https://github.com/go-yaml/yaml",
   608  		}},
   609  	},
   610  	{
   611  		"a: [https://github.com/go-yaml/yaml]",
   612  		map[string]interface{}{"a": []interface{}{"https://github.com/go-yaml/yaml"}},
   613  	},
   614  
   615  	// Duration
   616  	{
   617  		"a: 3s",
   618  		map[string]time.Duration{"a": 3 * time.Second},
   619  	},
   620  
   621  	// Issue #24.
   622  	{
   623  		"a: <foo>",
   624  		map[string]string{"a": "<foo>"},
   625  	},
   626  
   627  	// Base 60 floats are obsolete and unsupported.
   628  	{
   629  		"a: 1:1\n",
   630  		map[string]string{"a": "1:1"},
   631  	},
   632  
   633  	// Binary data.
   634  	{
   635  		"a: !!binary gIGC\n",
   636  		map[string]string{"a": "\x80\x81\x82"},
   637  	}, {
   638  		"a: !!binary |\n  " + strings.Repeat("kJCQ", 17) + "kJ\n  CQ\n",
   639  		map[string]string{"a": strings.Repeat("\x90", 54)},
   640  	}, {
   641  		"a: !!binary |\n  " + strings.Repeat("A", 70) + "\n  ==\n",
   642  		map[string]string{"a": strings.Repeat("\x00", 52)},
   643  	},
   644  
   645  	// Issue #39.
   646  	{
   647  		"a:\n b:\n  c: d\n",
   648  		map[string]struct{ B interface{} }{"a": {map[string]interface{}{"c": "d"}}},
   649  	},
   650  
   651  	// Custom map type.
   652  	{
   653  		"a: {b: c}",
   654  		M{"a": M{"b": "c"}},
   655  	},
   656  
   657  	// Support encoding.TextUnmarshaler.
   658  	{
   659  		"a: 1.2.3.4\n",
   660  		map[string]textUnmarshaler{"a": textUnmarshaler{S: "1.2.3.4"}},
   661  	},
   662  	{
   663  		"a: 2015-02-24T18:19:39Z\n",
   664  		map[string]textUnmarshaler{"a": textUnmarshaler{"2015-02-24T18:19:39Z"}},
   665  	},
   666  
   667  	// Timestamps
   668  	{
   669  		// Date only.
   670  		"a: 2015-01-01\n",
   671  		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   672  	},
   673  	{
   674  		// RFC3339
   675  		"a: 2015-02-24T18:19:39.12Z\n",
   676  		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, .12e9, time.UTC)},
   677  	},
   678  	{
   679  		// RFC3339 with short dates.
   680  		"a: 2015-2-3T3:4:5Z",
   681  		map[string]time.Time{"a": time.Date(2015, 2, 3, 3, 4, 5, 0, time.UTC)},
   682  	},
   683  	{
   684  		// ISO8601 lower case t
   685  		"a: 2015-02-24t18:19:39Z\n",
   686  		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
   687  	},
   688  	{
   689  		// space separate, no time zone
   690  		"a: 2015-02-24 18:19:39\n",
   691  		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
   692  	},
   693  	// Some cases not currently handled. Uncomment these when
   694  	// the code is fixed.
   695  	//	{
   696  	//		// space separated with time zone
   697  	//		"a: 2001-12-14 21:59:43.10 -5",
   698  	//		map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
   699  	//	},
   700  	//	{
   701  	//		// arbitrary whitespace between fields
   702  	//		"a: 2001-12-14 \t\t \t21:59:43.10 \t Z",
   703  	//		map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
   704  	//	},
   705  	{
   706  		// explicit string tag
   707  		"a: !!str 2015-01-01",
   708  		map[string]interface{}{"a": "2015-01-01"},
   709  	},
   710  	{
   711  		// explicit timestamp tag on quoted string
   712  		"a: !!timestamp \"2015-01-01\"",
   713  		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   714  	},
   715  	{
   716  		// explicit timestamp tag on unquoted string
   717  		"a: !!timestamp 2015-01-01",
   718  		map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   719  	},
   720  	{
   721  		// quoted string that's a valid timestamp
   722  		"a: \"2015-01-01\"",
   723  		map[string]interface{}{"a": "2015-01-01"},
   724  	},
   725  	{
   726  		// explicit timestamp tag into interface.
   727  		"a: !!timestamp \"2015-01-01\"",
   728  		map[string]interface{}{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   729  	},
   730  	{
   731  		// implicit timestamp tag into interface.
   732  		"a: 2015-01-01",
   733  		map[string]interface{}{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
   734  	},
   735  
   736  	// Encode empty lists as zero-length slices.
   737  	{
   738  		"a: []",
   739  		&struct{ A []int }{[]int{}},
   740  	},
   741  
   742  	// UTF-16-LE
   743  	{
   744  		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00",
   745  		M{"ñoño": "very yes"},
   746  	},
   747  	// UTF-16-LE with surrogate.
   748  	{
   749  		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00",
   750  		M{"ñoño": "very yes 🟔"},
   751  	},
   752  
   753  	// UTF-16-BE
   754  	{
   755  		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n",
   756  		M{"ñoño": "very yes"},
   757  	},
   758  	// UTF-16-BE with surrogate.
   759  	{
   760  		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n",
   761  		M{"ñoño": "very yes 🟔"},
   762  	},
   763  
   764  	// This *is* in fact a float number, per the spec. #171 was a mistake.
   765  	{
   766  		"a: 123456e1\n",
   767  		M{"a": 123456e1},
   768  	}, {
   769  		"a: 123456E1\n",
   770  		M{"a": 123456E1},
   771  	},
   772  	// yaml-test-suite 3GZX: Spec Example 7.1. Alias Nodes
   773  	{
   774  		"First occurrence: &anchor Foo\nSecond occurrence: *anchor\nOverride anchor: &anchor Bar\nReuse anchor: *anchor\n",
   775  		map[string]interface{}{
   776  			"First occurrence":  "Foo",
   777  			"Second occurrence": "Foo",
   778  			"Override anchor":   "Bar",
   779  			"Reuse anchor":      "Bar",
   780  		},
   781  	},
   782  	// Single document with garbage following it.
   783  	{
   784  		"---\nhello\n...\n}not yaml",
   785  		"hello",
   786  	},
   787  
   788  	// Comment scan exhausting the input buffer (issue #469).
   789  	{
   790  		"true\n#" + strings.Repeat(" ", 512*3),
   791  		"true",
   792  	}, {
   793  		"true #" + strings.Repeat(" ", 512*3),
   794  		"true",
   795  	},
   796  
   797  	// CRLF
   798  	{
   799  		"a: b\r\nc:\r\n- d\r\n- e\r\n",
   800  		map[string]interface{}{
   801  			"a": "b",
   802  			"c": []interface{}{"d", "e"},
   803  		},
   804  	},
   805  
   806  }
   807  
   808  type M map[string]interface{}
   809  
   810  type inlineB struct {
   811  	B       int
   812  	inlineC `yaml:",inline"`
   813  }
   814  
   815  type inlineC struct {
   816  	C int
   817  }
   818  
   819  type inlineD struct {
   820  	C *inlineC `yaml:",inline"`
   821  	D int
   822  }
   823  
   824  func (s *S) TestUnmarshal(c *C) {
   825  	for i, item := range unmarshalTests {
   826  		c.Logf("test %d: %q", i, item.data)
   827  		t := reflect.ValueOf(item.value).Type()
   828  		value := reflect.New(t)
   829  		err := yaml.Unmarshal([]byte(item.data), value.Interface())
   830  		if _, ok := err.(*yaml.TypeError); !ok {
   831  			c.Assert(err, IsNil)
   832  		}
   833  		c.Assert(value.Elem().Interface(), DeepEquals, item.value, Commentf("error: %v", err))
   834  	}
   835  }
   836  
   837  func (s *S) TestUnmarshalFullTimestamp(c *C) {
   838  	// Full timestamp in same format as encoded. This is confirmed to be
   839  	// properly decoded by Python as a timestamp as well.
   840  	var str = "2015-02-24T18:19:39.123456789-03:00"
   841  	var t interface{}
   842  	err := yaml.Unmarshal([]byte(str), &t)
   843  	c.Assert(err, IsNil)
   844  	c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.(time.Time).Location()))
   845  	c.Assert(t.(time.Time).In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC))
   846  }
   847  
   848  func (s *S) TestDecoderSingleDocument(c *C) {
   849  	// Test that Decoder.Decode works as expected on
   850  	// all the unmarshal tests.
   851  	for i, item := range unmarshalTests {
   852  		c.Logf("test %d: %q", i, item.data)
   853  		if item.data == "" {
   854  			// Behaviour differs when there's no YAML.
   855  			continue
   856  		}
   857  		t := reflect.ValueOf(item.value).Type()
   858  		value := reflect.New(t)
   859  		err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(value.Interface())
   860  		if _, ok := err.(*yaml.TypeError); !ok {
   861  			c.Assert(err, IsNil)
   862  		}
   863  		c.Assert(value.Elem().Interface(), DeepEquals, item.value)
   864  	}
   865  }
   866  
   867  var decoderTests = []struct {
   868  	data   string
   869  	values []interface{}
   870  }{{
   871  	"",
   872  	nil,
   873  }, {
   874  	"a: b",
   875  	[]interface{}{
   876  		map[string]interface{}{"a": "b"},
   877  	},
   878  }, {
   879  	"---\na: b\n...\n",
   880  	[]interface{}{
   881  		map[string]interface{}{"a": "b"},
   882  	},
   883  }, {
   884  	"---\n'hello'\n...\n---\ngoodbye\n...\n",
   885  	[]interface{}{
   886  		"hello",
   887  		"goodbye",
   888  	},
   889  }}
   890  
   891  func (s *S) TestDecoder(c *C) {
   892  	for i, item := range decoderTests {
   893  		c.Logf("test %d: %q", i, item.data)
   894  		var values []interface{}
   895  		dec := yaml.NewDecoder(strings.NewReader(item.data))
   896  		for {
   897  			var value interface{}
   898  			err := dec.Decode(&value)
   899  			if err == io.EOF {
   900  				break
   901  			}
   902  			c.Assert(err, IsNil)
   903  			values = append(values, value)
   904  		}
   905  		c.Assert(values, DeepEquals, item.values)
   906  	}
   907  }
   908  
   909  type errReader struct{}
   910  
   911  func (errReader) Read([]byte) (int, error) {
   912  	return 0, errors.New("some read error")
   913  }
   914  
   915  func (s *S) TestDecoderReadError(c *C) {
   916  	err := yaml.NewDecoder(errReader{}).Decode(&struct{}{})
   917  	c.Assert(err, ErrorMatches, `yaml: input error: some read error`)
   918  }
   919  
   920  func (s *S) TestUnmarshalNaN(c *C) {
   921  	value := map[string]interface{}{}
   922  	err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
   923  	c.Assert(err, IsNil)
   924  	c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
   925  }
   926  
   927  func (s *S) TestUnmarshalDurationInt(c *C) {
   928  	// Don't accept plain ints as durations as it's unclear (issue #200).
   929  	var d time.Duration
   930  	err := yaml.Unmarshal([]byte("123"), &d)
   931  	c.Assert(err, ErrorMatches, "(?s).* line 1: cannot unmarshal !!int `123` into time.Duration")
   932  }
   933  
   934  var unmarshalErrorTests = []struct {
   935  	data, error string
   936  }{
   937  	{"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"},
   938  	{"v: [A,", "yaml: line 1: did not find expected node content"},
   939  	{"v:\n- [A,", "yaml: line 2: did not find expected node content"},
   940  	{"a:\n- b: *,", "yaml: line 2: did not find expected alphabetic or numeric character"},
   941  	{"a: *b\n", "yaml: unknown anchor 'b' referenced"},
   942  	{"a: &a\n  b: *a\n", "yaml: anchor 'a' value contains itself"},
   943  	{"value: -", "yaml: block sequence entries are not allowed in this context"},
   944  	{"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
   945  	{"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
   946  	{"{{.}}", `yaml: invalid map key: map\[string]interface \{\}\{".":interface \{\}\(nil\)\}`},
   947  	{"b: *a\na: &a {c: 1}", `yaml: unknown anchor 'a' referenced`},
   948  	{"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
   949  	{"a:\n  1:\nb\n  2:", ".*could not find expected ':'"},
   950  	{
   951  		"a: &a [00,00,00,00,00,00,00,00,00]\n" +
   952  		"b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]\n" +
   953  		"c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]\n" +
   954  		"d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]\n" +
   955  		"e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]\n" +
   956  		"f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]\n" +
   957  		"g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]\n" +
   958  		"h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]\n" +
   959  		"i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]\n",
   960  		"yaml: document contains excessive aliasing",
   961  	},
   962  }
   963  
   964  func (s *S) TestUnmarshalErrors(c *C) {
   965  	for i, item := range unmarshalErrorTests {
   966  		c.Logf("test %d: %q", i, item.data)
   967  		var value interface{}
   968  		err := yaml.Unmarshal([]byte(item.data), &value)
   969  		c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
   970  	}
   971  }
   972  
   973  func (s *S) TestDecoderErrors(c *C) {
   974  	for _, item := range unmarshalErrorTests {
   975  		var value interface{}
   976  		err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(&value)
   977  		c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
   978  	}
   979  }
   980  
   981  var unmarshalerTests = []struct {
   982  	data, tag string
   983  	value     interface{}
   984  }{
   985  	{"_: {hi: there}", "!!map", map[string]interface{}{"hi": "there"}},
   986  	{"_: [1,A]", "!!seq", []interface{}{1, "A"}},
   987  	{"_: 10", "!!int", 10},
   988  	{"_: null", "!!null", nil},
   989  	{`_: BAR!`, "!!str", "BAR!"},
   990  	{`_: "BAR!"`, "!!str", "BAR!"},
   991  	{"_: !!foo 'BAR!'", "!!foo", "BAR!"},
   992  	{`_: ""`, "!!str", ""},
   993  }
   994  
   995  var unmarshalerResult = map[int]error{}
   996  
   997  type unmarshalerType struct {
   998  	value interface{}
   999  }
  1000  
  1001  func (o *unmarshalerType) UnmarshalYAML(value *yaml.Node) error {
  1002  	if err := value.Decode(&o.value); err != nil {
  1003  		return err
  1004  	}
  1005  	if i, ok := o.value.(int); ok {
  1006  		if result, ok := unmarshalerResult[i]; ok {
  1007  			return result
  1008  		}
  1009  	}
  1010  	return nil
  1011  }
  1012  
  1013  type unmarshalerPointer struct {
  1014  	Field *unmarshalerType "_"
  1015  }
  1016  
  1017  type unmarshalerValue struct {
  1018  	Field unmarshalerType "_"
  1019  }
  1020  
  1021  type unmarshalerInlined struct {
  1022  	Field   *unmarshalerType "_"
  1023  	Inlined unmarshalerType  `yaml:",inline"`
  1024  }
  1025  
  1026  type unmarshalerInlinedTwice struct {
  1027  	InlinedTwice unmarshalerInlined `yaml:",inline"`
  1028  }
  1029  
  1030  type obsoleteUnmarshalerType struct {
  1031  	value interface{}
  1032  }
  1033  
  1034  func (o *obsoleteUnmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error {
  1035  	if err := unmarshal(&o.value); err != nil {
  1036  		return err
  1037  	}
  1038  	if i, ok := o.value.(int); ok {
  1039  		if result, ok := unmarshalerResult[i]; ok {
  1040  			return result
  1041  		}
  1042  	}
  1043  	return nil
  1044  }
  1045  
  1046  type obsoleteUnmarshalerPointer struct {
  1047  	Field *obsoleteUnmarshalerType "_"
  1048  }
  1049  
  1050  type obsoleteUnmarshalerValue struct {
  1051  	Field obsoleteUnmarshalerType "_"
  1052  }
  1053  
  1054  func (s *S) TestUnmarshalerPointerField(c *C) {
  1055  	for _, item := range unmarshalerTests {
  1056  		obj := &unmarshalerPointer{}
  1057  		err := yaml.Unmarshal([]byte(item.data), obj)
  1058  		c.Assert(err, IsNil)
  1059  		if item.value == nil {
  1060  			c.Assert(obj.Field, IsNil)
  1061  		} else {
  1062  			c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
  1063  			c.Assert(obj.Field.value, DeepEquals, item.value)
  1064  		}
  1065  	}
  1066  	for _, item := range unmarshalerTests {
  1067  		obj := &obsoleteUnmarshalerPointer{}
  1068  		err := yaml.Unmarshal([]byte(item.data), obj)
  1069  		c.Assert(err, IsNil)
  1070  		if item.value == nil {
  1071  			c.Assert(obj.Field, IsNil)
  1072  		} else {
  1073  			c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
  1074  			c.Assert(obj.Field.value, DeepEquals, item.value)
  1075  		}
  1076  	}
  1077  }
  1078  
  1079  func (s *S) TestUnmarshalerValueField(c *C) {
  1080  	for _, item := range unmarshalerTests {
  1081  		obj := &obsoleteUnmarshalerValue{}
  1082  		err := yaml.Unmarshal([]byte(item.data), obj)
  1083  		c.Assert(err, IsNil)
  1084  		c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
  1085  		c.Assert(obj.Field.value, DeepEquals, item.value)
  1086  	}
  1087  }
  1088  
  1089  func (s *S) TestUnmarshalerInlinedField(c *C) {
  1090  	obj := &unmarshalerInlined{}
  1091  	err := yaml.Unmarshal([]byte("_: a\ninlined: b\n"), obj)
  1092  	c.Assert(err, IsNil)
  1093  	c.Assert(obj.Field, DeepEquals, &unmarshalerType{"a"})
  1094  	c.Assert(obj.Inlined, DeepEquals, unmarshalerType{map[string]interface{}{"_": "a", "inlined": "b"}})
  1095  
  1096  	twc := &unmarshalerInlinedTwice{}
  1097  	err = yaml.Unmarshal([]byte("_: a\ninlined: b\n"), twc)
  1098  	c.Assert(err, IsNil)
  1099  	c.Assert(twc.InlinedTwice.Field, DeepEquals, &unmarshalerType{"a"})
  1100  	c.Assert(twc.InlinedTwice.Inlined, DeepEquals, unmarshalerType{map[string]interface{}{"_": "a", "inlined": "b"}})
  1101  }
  1102  
  1103  func (s *S) TestUnmarshalerWholeDocument(c *C) {
  1104  	obj := &obsoleteUnmarshalerType{}
  1105  	err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj)
  1106  	c.Assert(err, IsNil)
  1107  	value, ok := obj.value.(map[string]interface{})
  1108  	c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value))
  1109  	c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value)
  1110  }
  1111  
  1112  func (s *S) TestUnmarshalerTypeError(c *C) {
  1113  	unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
  1114  	unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
  1115  	defer func() {
  1116  		delete(unmarshalerResult, 2)
  1117  		delete(unmarshalerResult, 4)
  1118  	}()
  1119  
  1120  	type T struct {
  1121  		Before int
  1122  		After  int
  1123  		M      map[string]*unmarshalerType
  1124  	}
  1125  	var v T
  1126  	data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
  1127  	err := yaml.Unmarshal([]byte(data), &v)
  1128  	c.Assert(err, ErrorMatches, ""+
  1129  		"yaml: unmarshal errors:\n"+
  1130  		"  line 1: cannot unmarshal !!str `A` into int\n"+
  1131  		"  foo\n"+
  1132  		"  bar\n"+
  1133  		"  line 1: cannot unmarshal !!str `B` into int")
  1134  	c.Assert(v.M["abc"], NotNil)
  1135  	c.Assert(v.M["def"], IsNil)
  1136  	c.Assert(v.M["ghi"], NotNil)
  1137  	c.Assert(v.M["jkl"], IsNil)
  1138  
  1139  	c.Assert(v.M["abc"].value, Equals, 1)
  1140  	c.Assert(v.M["ghi"].value, Equals, 3)
  1141  }
  1142  
  1143  func (s *S) TestObsoleteUnmarshalerTypeError(c *C) {
  1144  	unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
  1145  	unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
  1146  	defer func() {
  1147  		delete(unmarshalerResult, 2)
  1148  		delete(unmarshalerResult, 4)
  1149  	}()
  1150  
  1151  	type T struct {
  1152  		Before int
  1153  		After  int
  1154  		M      map[string]*obsoleteUnmarshalerType
  1155  	}
  1156  	var v T
  1157  	data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
  1158  	err := yaml.Unmarshal([]byte(data), &v)
  1159  	c.Assert(err, ErrorMatches, ""+
  1160  		"yaml: unmarshal errors:\n"+
  1161  		"  line 1: cannot unmarshal !!str `A` into int\n"+
  1162  		"  foo\n"+
  1163  		"  bar\n"+
  1164  		"  line 1: cannot unmarshal !!str `B` into int")
  1165  	c.Assert(v.M["abc"], NotNil)
  1166  	c.Assert(v.M["def"], IsNil)
  1167  	c.Assert(v.M["ghi"], NotNil)
  1168  	c.Assert(v.M["jkl"], IsNil)
  1169  
  1170  	c.Assert(v.M["abc"].value, Equals, 1)
  1171  	c.Assert(v.M["ghi"].value, Equals, 3)
  1172  }
  1173  
  1174  type proxyTypeError struct{}
  1175  
  1176  func (v *proxyTypeError) UnmarshalYAML(node *yaml.Node) error {
  1177  	var s string
  1178  	var a int32
  1179  	var b int64
  1180  	if err := node.Decode(&s); err != nil {
  1181  		panic(err)
  1182  	}
  1183  	if s == "a" {
  1184  		if err := node.Decode(&b); err == nil {
  1185  			panic("should have failed")
  1186  		}
  1187  		return node.Decode(&a)
  1188  	}
  1189  	if err := node.Decode(&a); err == nil {
  1190  		panic("should have failed")
  1191  	}
  1192  	return node.Decode(&b)
  1193  }
  1194  
  1195  func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
  1196  	type T struct {
  1197  		Before int
  1198  		After  int
  1199  		M      map[string]*proxyTypeError
  1200  	}
  1201  	var v T
  1202  	data := `{before: A, m: {abc: a, def: b}, after: B}`
  1203  	err := yaml.Unmarshal([]byte(data), &v)
  1204  	c.Assert(err, ErrorMatches, ""+
  1205  		"yaml: unmarshal errors:\n"+
  1206  		"  line 1: cannot unmarshal !!str `A` into int\n"+
  1207  		"  line 1: cannot unmarshal !!str `a` into int32\n"+
  1208  		"  line 1: cannot unmarshal !!str `b` into int64\n"+
  1209  		"  line 1: cannot unmarshal !!str `B` into int")
  1210  }
  1211  
  1212  type obsoleteProxyTypeError struct{}
  1213  
  1214  func (v *obsoleteProxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error {
  1215  	var s string
  1216  	var a int32
  1217  	var b int64
  1218  	if err := unmarshal(&s); err != nil {
  1219  		panic(err)
  1220  	}
  1221  	if s == "a" {
  1222  		if err := unmarshal(&b); err == nil {
  1223  			panic("should have failed")
  1224  		}
  1225  		return unmarshal(&a)
  1226  	}
  1227  	if err := unmarshal(&a); err == nil {
  1228  		panic("should have failed")
  1229  	}
  1230  	return unmarshal(&b)
  1231  }
  1232  
  1233  func (s *S) TestObsoleteUnmarshalerTypeErrorProxying(c *C) {
  1234  	type T struct {
  1235  		Before int
  1236  		After  int
  1237  		M      map[string]*obsoleteProxyTypeError
  1238  	}
  1239  	var v T
  1240  	data := `{before: A, m: {abc: a, def: b}, after: B}`
  1241  	err := yaml.Unmarshal([]byte(data), &v)
  1242  	c.Assert(err, ErrorMatches, ""+
  1243  		"yaml: unmarshal errors:\n"+
  1244  		"  line 1: cannot unmarshal !!str `A` into int\n"+
  1245  		"  line 1: cannot unmarshal !!str `a` into int32\n"+
  1246  		"  line 1: cannot unmarshal !!str `b` into int64\n"+
  1247  		"  line 1: cannot unmarshal !!str `B` into int")
  1248  }
  1249  
  1250  var failingErr = errors.New("failingErr")
  1251  
  1252  type failingUnmarshaler struct{}
  1253  
  1254  func (ft *failingUnmarshaler) UnmarshalYAML(node *yaml.Node) error {
  1255  	return failingErr
  1256  }
  1257  
  1258  func (s *S) TestUnmarshalerError(c *C) {
  1259  	err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{})
  1260  	c.Assert(err, Equals, failingErr)
  1261  }
  1262  
  1263  type obsoleteFailingUnmarshaler struct{}
  1264  
  1265  func (ft *obsoleteFailingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
  1266  	return failingErr
  1267  }
  1268  
  1269  func (s *S) TestObsoleteUnmarshalerError(c *C) {
  1270  	err := yaml.Unmarshal([]byte("a: b"), &obsoleteFailingUnmarshaler{})
  1271  	c.Assert(err, Equals, failingErr)
  1272  }
  1273  
  1274  type sliceUnmarshaler []int
  1275  
  1276  func (su *sliceUnmarshaler) UnmarshalYAML(node *yaml.Node) error {
  1277  	var slice []int
  1278  	err := node.Decode(&slice)
  1279  	if err == nil {
  1280  		*su = slice
  1281  		return nil
  1282  	}
  1283  
  1284  	var intVal int
  1285  	err = node.Decode(&intVal)
  1286  	if err == nil {
  1287  		*su = []int{intVal}
  1288  		return nil
  1289  	}
  1290  
  1291  	return err
  1292  }
  1293  
  1294  func (s *S) TestUnmarshalerRetry(c *C) {
  1295  	var su sliceUnmarshaler
  1296  	err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
  1297  	c.Assert(err, IsNil)
  1298  	c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3}))
  1299  
  1300  	err = yaml.Unmarshal([]byte("1"), &su)
  1301  	c.Assert(err, IsNil)
  1302  	c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1}))
  1303  }
  1304  
  1305  type obsoleteSliceUnmarshaler []int
  1306  
  1307  func (su *obsoleteSliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
  1308  	var slice []int
  1309  	err := unmarshal(&slice)
  1310  	if err == nil {
  1311  		*su = slice
  1312  		return nil
  1313  	}
  1314  
  1315  	var intVal int
  1316  	err = unmarshal(&intVal)
  1317  	if err == nil {
  1318  		*su = []int{intVal}
  1319  		return nil
  1320  	}
  1321  
  1322  	return err
  1323  }
  1324  
  1325  func (s *S) TestObsoleteUnmarshalerRetry(c *C) {
  1326  	var su obsoleteSliceUnmarshaler
  1327  	err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
  1328  	c.Assert(err, IsNil)
  1329  	c.Assert(su, DeepEquals, obsoleteSliceUnmarshaler([]int{1, 2, 3}))
  1330  
  1331  	err = yaml.Unmarshal([]byte("1"), &su)
  1332  	c.Assert(err, IsNil)
  1333  	c.Assert(su, DeepEquals, obsoleteSliceUnmarshaler([]int{1}))
  1334  }
  1335  
  1336  // From http://yaml.org/type/merge.html
  1337  var mergeTests = `
  1338  anchors:
  1339    list:
  1340      - &CENTER { "x": 1, "y": 2 }
  1341      - &LEFT   { "x": 0, "y": 2 }
  1342      - &BIG    { "r": 10 }
  1343      - &SMALL  { "r": 1 }
  1344  
  1345  # All the following maps are equal:
  1346  
  1347  plain:
  1348    # Explicit keys
  1349    "x": 1
  1350    "y": 2
  1351    "r": 10
  1352    label: center/big
  1353  
  1354  mergeOne:
  1355    # Merge one map
  1356    << : *CENTER
  1357    "r": 10
  1358    label: center/big
  1359  
  1360  mergeMultiple:
  1361    # Merge multiple maps
  1362    << : [ *CENTER, *BIG ]
  1363    label: center/big
  1364  
  1365  override:
  1366    # Override
  1367    << : [ *BIG, *LEFT, *SMALL ]
  1368    "x": 1
  1369    label: center/big
  1370  
  1371  shortTag:
  1372    # Explicit short merge tag
  1373    !!merge "<<" : [ *CENTER, *BIG ]
  1374    label: center/big
  1375  
  1376  longTag:
  1377    # Explicit merge long tag
  1378    !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ]
  1379    label: center/big
  1380  
  1381  inlineMap:
  1382    # Inlined map 
  1383    << : {"x": 1, "y": 2, "r": 10}
  1384    label: center/big
  1385  
  1386  inlineSequenceMap:
  1387    # Inlined map in sequence
  1388    << : [ *CENTER, {"r": 10} ]
  1389    label: center/big
  1390  `
  1391  
  1392  func (s *S) TestMerge(c *C) {
  1393  	var want = map[interface{}]interface{}{
  1394  		"x":     1,
  1395  		"y":     2,
  1396  		"r":     10,
  1397  		"label": "center/big",
  1398  	}
  1399  
  1400  	wantStringMap := make(map[string]interface{})
  1401  	for k, v := range want {
  1402  		wantStringMap[fmt.Sprintf("%v", k)] = v
  1403  	}
  1404  
  1405  	var m map[interface{}]interface{}
  1406  	err := yaml.Unmarshal([]byte(mergeTests), &m)
  1407  	c.Assert(err, IsNil)
  1408  	for name, test := range m {
  1409  		if name == "anchors" {
  1410  			continue
  1411  		}
  1412  		if name == "plain" {
  1413  			c.Assert(test, DeepEquals, wantStringMap, Commentf("test %q failed", name))
  1414  			continue
  1415  		}
  1416  		c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
  1417  	}
  1418  }
  1419  
  1420  func (s *S) TestMergeStruct(c *C) {
  1421  	type Data struct {
  1422  		X, Y, R int
  1423  		Label   string
  1424  	}
  1425  	want := Data{1, 2, 10, "center/big"}
  1426  
  1427  	var m map[string]Data
  1428  	err := yaml.Unmarshal([]byte(mergeTests), &m)
  1429  	c.Assert(err, IsNil)
  1430  	for name, test := range m {
  1431  		if name == "anchors" {
  1432  			continue
  1433  		}
  1434  		c.Assert(test, Equals, want, Commentf("test %q failed", name))
  1435  	}
  1436  }
  1437  
  1438  var unmarshalNullTests = []func() interface{}{
  1439  	func() interface{} { var v interface{}; v = "v"; return &v },
  1440  	func() interface{} { var s = "s"; return &s },
  1441  	func() interface{} { var s = "s"; sptr := &s; return &sptr },
  1442  	func() interface{} { var i = 1; return &i },
  1443  	func() interface{} { var i = 1; iptr := &i; return &iptr },
  1444  	func() interface{} { m := map[string]int{"s": 1}; return &m },
  1445  	func() interface{} { m := map[string]int{"s": 1}; return m },
  1446  }
  1447  
  1448  func (s *S) TestUnmarshalNull(c *C) {
  1449  	for _, test := range unmarshalNullTests {
  1450  		pristine := test()
  1451  		decoded := test()
  1452  		zero := reflect.Zero(reflect.TypeOf(decoded).Elem()).Interface()
  1453  		err := yaml.Unmarshal([]byte("null"), decoded)
  1454  		c.Assert(err, IsNil)
  1455  		switch pristine.(type) {
  1456  		case *interface{}, **string, **int, *map[string]int:
  1457  			c.Assert(reflect.ValueOf(decoded).Elem().Interface(), DeepEquals, zero)
  1458  		default:
  1459  			c.Assert(reflect.ValueOf(decoded).Interface(), DeepEquals, pristine)
  1460  		}
  1461  	}
  1462  }
  1463  
  1464  func (s *S) TestUnmarshalPreservesData(c *C) {
  1465  	var v struct {
  1466  		A, B int
  1467  		C int `yaml:"-"`
  1468  	}
  1469  	v.A = 42
  1470  	v.C = 88
  1471  	err := yaml.Unmarshal([]byte("---"), &v)
  1472  	c.Assert(err, IsNil)
  1473  	c.Assert(v.A, Equals, 42)
  1474  	c.Assert(v.B, Equals, 0)
  1475  	c.Assert(v.C, Equals, 88)
  1476  
  1477  	err = yaml.Unmarshal([]byte("b: 21\nc: 99"), &v)
  1478  	c.Assert(err, IsNil)
  1479  	c.Assert(v.A, Equals, 42)
  1480  	c.Assert(v.B, Equals, 21)
  1481  	c.Assert(v.C, Equals, 88)
  1482  }
  1483  
  1484  func (s *S) TestUnmarshalSliceOnPreset(c *C) {
  1485  	// Issue #48.
  1486  	v := struct{ A []int }{[]int{1}}
  1487  	yaml.Unmarshal([]byte("a: [2]"), &v)
  1488  	c.Assert(v.A, DeepEquals, []int{2})
  1489  }
  1490  
  1491  var unmarshalStrictTests = []struct {
  1492  	known  bool
  1493  	unique bool
  1494  	data   string
  1495  	value  interface{}
  1496  	error  string
  1497  }{{
  1498  	known: true,
  1499  	data:  "a: 1\nc: 2\n",
  1500  	value: struct{ A, B int }{A: 1},
  1501  	error: `yaml: unmarshal errors:\n  line 2: field c not found in type struct { A int; B int }`,
  1502  }, {
  1503  	unique: true,
  1504  	data:   "a: 1\nb: 2\na: 3\n",
  1505  	value:  struct{ A, B int }{A: 3, B: 2},
  1506  	error:  `yaml: unmarshal errors:\n  line 3: mapping key "a" already defined at line 1`,
  1507  }, {
  1508  	unique: true,
  1509  	data:   "c: 3\na: 1\nb: 2\nc: 4\n",
  1510  	value: struct {
  1511  		A       int
  1512  		inlineB `yaml:",inline"`
  1513  	}{
  1514  		A: 1,
  1515  		inlineB: inlineB{
  1516  			B: 2,
  1517  			inlineC: inlineC{
  1518  				C: 4,
  1519  			},
  1520  		},
  1521  	},
  1522  	error: `yaml: unmarshal errors:\n  line 4: mapping key "c" already defined at line 1`,
  1523  }, {
  1524  	unique: true,
  1525  	data:   "c: 0\na: 1\nb: 2\nc: 1\n",
  1526  	value: struct {
  1527  		A       int
  1528  		inlineB `yaml:",inline"`
  1529  	}{
  1530  		A: 1,
  1531  		inlineB: inlineB{
  1532  			B: 2,
  1533  			inlineC: inlineC{
  1534  				C: 1,
  1535  			},
  1536  		},
  1537  	},
  1538  	error: `yaml: unmarshal errors:\n  line 4: mapping key "c" already defined at line 1`,
  1539  }, {
  1540  	unique: true,
  1541  	data:   "c: 1\na: 1\nb: 2\nc: 3\n",
  1542  	value: struct {
  1543  		A int
  1544  		M map[string]interface{} `yaml:",inline"`
  1545  	}{
  1546  		A: 1,
  1547  		M: map[string]interface{}{
  1548  			"b": 2,
  1549  			"c": 3,
  1550  		},
  1551  	},
  1552  	error: `yaml: unmarshal errors:\n  line 4: mapping key "c" already defined at line 1`,
  1553  }, {
  1554  	unique: true,
  1555  	data:   "a: 1\n9: 2\nnull: 3\n9: 4",
  1556  	value: map[interface{}]interface{}{
  1557  		"a": 1,
  1558  		nil: 3,
  1559  		9:   4,
  1560  	},
  1561  	error: `yaml: unmarshal errors:\n  line 4: mapping key "9" already defined at line 2`,
  1562  }}
  1563  
  1564  func (s *S) TestUnmarshalKnownFields(c *C) {
  1565  	for i, item := range unmarshalStrictTests {
  1566  		c.Logf("test %d: %q", i, item.data)
  1567  		// First test that normal Unmarshal unmarshals to the expected value.
  1568  		if !item.unique {
  1569  			t := reflect.ValueOf(item.value).Type()
  1570  			value := reflect.New(t)
  1571  			err := yaml.Unmarshal([]byte(item.data), value.Interface())
  1572  			c.Assert(err, Equals, nil)
  1573  			c.Assert(value.Elem().Interface(), DeepEquals, item.value)
  1574  		}
  1575  
  1576  		// Then test that it fails on the same thing with KnownFields on.
  1577  		t := reflect.ValueOf(item.value).Type()
  1578  		value := reflect.New(t)
  1579  		dec := yaml.NewDecoder(bytes.NewBuffer([]byte(item.data)))
  1580  		dec.KnownFields(item.known)
  1581  		err := dec.Decode(value.Interface())
  1582  		c.Assert(err, ErrorMatches, item.error)
  1583  	}
  1584  }
  1585  
  1586  type textUnmarshaler struct {
  1587  	S string
  1588  }
  1589  
  1590  func (t *textUnmarshaler) UnmarshalText(s []byte) error {
  1591  	t.S = string(s)
  1592  	return nil
  1593  }
  1594  
  1595  func (s *S) TestFuzzCrashers(c *C) {
  1596  	cases := []string{
  1597  		// runtime error: index out of range
  1598  		"\"\\0\\\r\n",
  1599  
  1600  		// should not happen
  1601  		"  0: [\n] 0",
  1602  		"? ? \"\n\" 0",
  1603  		"    - {\n000}0",
  1604  		"0:\n  0: [0\n] 0",
  1605  		"    - \"\n000\"0",
  1606  		"    - \"\n000\"\"",
  1607  		"0:\n    - {\n000}0",
  1608  		"0:\n    - \"\n000\"0",
  1609  		"0:\n    - \"\n000\"\"",
  1610  
  1611  		// runtime error: index out of range
  1612  		" \ufeff\n",
  1613  		"? \ufeff\n",
  1614  		"? \ufeff:\n",
  1615  		"0: \ufeff\n",
  1616  		"? \ufeff: \ufeff\n",
  1617  	}
  1618  	for _, data := range cases {
  1619  		var v interface{}
  1620  		_ = yaml.Unmarshal([]byte(data), &v)
  1621  	}
  1622  }
  1623  
  1624  //var data []byte
  1625  //func init() {
  1626  //	var err error
  1627  //	data, err = ioutil.ReadFile("/tmp/file.yaml")
  1628  //	if err != nil {
  1629  //		panic(err)
  1630  //	}
  1631  //}
  1632  //
  1633  //func (s *S) BenchmarkUnmarshal(c *C) {
  1634  //	var err error
  1635  //	for i := 0; i < c.N; i++ {
  1636  //		var v map[string]interface{}
  1637  //		err = yaml.Unmarshal(data, &v)
  1638  //	}
  1639  //	if err != nil {
  1640  //		panic(err)
  1641  //	}
  1642  //}
  1643  //
  1644  //func (s *S) BenchmarkMarshal(c *C) {
  1645  //	var v map[string]interface{}
  1646  //	yaml.Unmarshal(data, &v)
  1647  //	c.ResetTimer()
  1648  //	for i := 0; i < c.N; i++ {
  1649  //		yaml.Marshal(&v)
  1650  //	}
  1651  //}