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  //}