github.com/mfpierre/corectl@v0.5.6/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  	// UTF-16-LE
   564  	{
   565  		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00",
   566  		M{"ñoño": "very yes"},
   567  	},
   568  	// UTF-16-LE with surrogate.
   569  	{
   570  		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00",
   571  		M{"ñoño": "very yes 🟔"},
   572  	},
   573  
   574  	// UTF-16-BE
   575  	{
   576  		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n",
   577  		M{"ñoño": "very yes"},
   578  	},
   579  	// UTF-16-BE with surrogate.
   580  	{
   581  		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n",
   582  		M{"ñoño": "very yes 🟔"},
   583  	},
   584  }
   585  
   586  type M map[interface{}]interface{}
   587  
   588  type inlineB struct {
   589  	B       int
   590  	inlineC `yaml:",inline"`
   591  }
   592  
   593  type inlineC struct {
   594  	C int
   595  }
   596  
   597  func (s *S) TestUnmarshal(c *C) {
   598  	for _, item := range unmarshalTests {
   599  		t := reflect.ValueOf(item.value).Type()
   600  		var value interface{}
   601  		switch t.Kind() {
   602  		case reflect.Map:
   603  			value = reflect.MakeMap(t).Interface()
   604  		case reflect.String:
   605  			value = reflect.New(t).Interface()
   606  		case reflect.Ptr:
   607  			value = reflect.New(t.Elem()).Interface()
   608  		default:
   609  			c.Fatalf("missing case for %s", t)
   610  		}
   611  		err := yaml.Unmarshal([]byte(item.data), value)
   612  		if _, ok := err.(*yaml.TypeError); !ok {
   613  			c.Assert(err, IsNil)
   614  		}
   615  		if t.Kind() == reflect.String {
   616  			c.Assert(*value.(*string), Equals, item.value)
   617  		} else {
   618  			c.Assert(value, DeepEquals, item.value)
   619  		}
   620  	}
   621  }
   622  
   623  func (s *S) TestUnmarshalNaN(c *C) {
   624  	value := map[string]interface{}{}
   625  	err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
   626  	c.Assert(err, IsNil)
   627  	c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
   628  }
   629  
   630  var unmarshalErrorTests = []struct {
   631  	data, error string
   632  }{
   633  	{"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"},
   634  	{"v: [A,", "yaml: line 1: did not find expected node content"},
   635  	{"v:\n- [A,", "yaml: line 2: did not find expected node content"},
   636  	{"a: *b\n", "yaml: unknown anchor 'b' referenced"},
   637  	{"a: &a\n  b: *a\n", "yaml: anchor 'a' value contains itself"},
   638  	{"value: -", "yaml: block sequence entries are not allowed in this context"},
   639  	{"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
   640  	{"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
   641  	{"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
   642  }
   643  
   644  func (s *S) TestUnmarshalErrors(c *C) {
   645  	for _, item := range unmarshalErrorTests {
   646  		var value interface{}
   647  		err := yaml.Unmarshal([]byte(item.data), &value)
   648  		c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
   649  	}
   650  }
   651  
   652  var unmarshalerTests = []struct {
   653  	data, tag string
   654  	value     interface{}
   655  }{
   656  	{"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}},
   657  	{"_: [1,A]", "!!seq", []interface{}{1, "A"}},
   658  	{"_: 10", "!!int", 10},
   659  	{"_: null", "!!null", nil},
   660  	{`_: BAR!`, "!!str", "BAR!"},
   661  	{`_: "BAR!"`, "!!str", "BAR!"},
   662  	{"_: !!foo 'BAR!'", "!!foo", "BAR!"},
   663  }
   664  
   665  var unmarshalerResult = map[int]error{}
   666  
   667  type unmarshalerType struct {
   668  	value interface{}
   669  }
   670  
   671  func (o *unmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error {
   672  	if err := unmarshal(&o.value); err != nil {
   673  		return err
   674  	}
   675  	if i, ok := o.value.(int); ok {
   676  		if result, ok := unmarshalerResult[i]; ok {
   677  			return result
   678  		}
   679  	}
   680  	return nil
   681  }
   682  
   683  type unmarshalerPointer struct {
   684  	Field *unmarshalerType "_"
   685  }
   686  
   687  type unmarshalerValue struct {
   688  	Field unmarshalerType "_"
   689  }
   690  
   691  func (s *S) TestUnmarshalerPointerField(c *C) {
   692  	for _, item := range unmarshalerTests {
   693  		obj := &unmarshalerPointer{}
   694  		err := yaml.Unmarshal([]byte(item.data), obj)
   695  		c.Assert(err, IsNil)
   696  		if item.value == nil {
   697  			c.Assert(obj.Field, IsNil)
   698  		} else {
   699  			c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
   700  			c.Assert(obj.Field.value, DeepEquals, item.value)
   701  		}
   702  	}
   703  }
   704  
   705  func (s *S) TestUnmarshalerValueField(c *C) {
   706  	for _, item := range unmarshalerTests {
   707  		obj := &unmarshalerValue{}
   708  		err := yaml.Unmarshal([]byte(item.data), obj)
   709  		c.Assert(err, IsNil)
   710  		c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
   711  		c.Assert(obj.Field.value, DeepEquals, item.value)
   712  	}
   713  }
   714  
   715  func (s *S) TestUnmarshalerWholeDocument(c *C) {
   716  	obj := &unmarshalerType{}
   717  	err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj)
   718  	c.Assert(err, IsNil)
   719  	value, ok := obj.value.(map[interface{}]interface{})
   720  	c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value))
   721  	c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value)
   722  }
   723  
   724  func (s *S) TestUnmarshalerTypeError(c *C) {
   725  	unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
   726  	unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
   727  	defer func() {
   728  		delete(unmarshalerResult, 2)
   729  		delete(unmarshalerResult, 4)
   730  	}()
   731  
   732  	type T struct {
   733  		Before int
   734  		After  int
   735  		M      map[string]*unmarshalerType
   736  	}
   737  	var v T
   738  	data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
   739  	err := yaml.Unmarshal([]byte(data), &v)
   740  	c.Assert(err, ErrorMatches, ""+
   741  		"yaml: unmarshal errors:\n"+
   742  		"  line 1: cannot unmarshal !!str `A` into int\n"+
   743  		"  foo\n"+
   744  		"  bar\n"+
   745  		"  line 1: cannot unmarshal !!str `B` into int")
   746  	c.Assert(v.M["abc"], NotNil)
   747  	c.Assert(v.M["def"], IsNil)
   748  	c.Assert(v.M["ghi"], NotNil)
   749  	c.Assert(v.M["jkl"], IsNil)
   750  
   751  	c.Assert(v.M["abc"].value, Equals, 1)
   752  	c.Assert(v.M["ghi"].value, Equals, 3)
   753  }
   754  
   755  type proxyTypeError struct{}
   756  
   757  func (v *proxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error {
   758  	var s string
   759  	var a int32
   760  	var b int64
   761  	if err := unmarshal(&s); err != nil {
   762  		panic(err)
   763  	}
   764  	if s == "a" {
   765  		if err := unmarshal(&b); err == nil {
   766  			panic("should have failed")
   767  		}
   768  		return unmarshal(&a)
   769  	}
   770  	if err := unmarshal(&a); err == nil {
   771  		panic("should have failed")
   772  	}
   773  	return unmarshal(&b)
   774  }
   775  
   776  func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
   777  	type T struct {
   778  		Before int
   779  		After  int
   780  		M      map[string]*proxyTypeError
   781  	}
   782  	var v T
   783  	data := `{before: A, m: {abc: a, def: b}, after: B}`
   784  	err := yaml.Unmarshal([]byte(data), &v)
   785  	c.Assert(err, ErrorMatches, ""+
   786  		"yaml: unmarshal errors:\n"+
   787  		"  line 1: cannot unmarshal !!str `A` into int\n"+
   788  		"  line 1: cannot unmarshal !!str `a` into int32\n"+
   789  		"  line 1: cannot unmarshal !!str `b` into int64\n"+
   790  		"  line 1: cannot unmarshal !!str `B` into int")
   791  }
   792  
   793  type failingUnmarshaler struct{}
   794  
   795  var failingErr = errors.New("failingErr")
   796  
   797  func (ft *failingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
   798  	return failingErr
   799  }
   800  
   801  func (s *S) TestUnmarshalerError(c *C) {
   802  	err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{})
   803  	c.Assert(err, Equals, failingErr)
   804  }
   805  
   806  type sliceUnmarshaler []int
   807  
   808  func (su *sliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
   809  	var slice []int
   810  	err := unmarshal(&slice)
   811  	if err == nil {
   812  		*su = slice
   813  		return nil
   814  	}
   815  
   816  	var intVal int
   817  	err = unmarshal(&intVal)
   818  	if err == nil {
   819  		*su = []int{intVal}
   820  		return nil
   821  	}
   822  
   823  	return err
   824  }
   825  
   826  func (s *S) TestUnmarshalerRetry(c *C) {
   827  	var su sliceUnmarshaler
   828  	err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
   829  	c.Assert(err, IsNil)
   830  	c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3}))
   831  
   832  	err = yaml.Unmarshal([]byte("1"), &su)
   833  	c.Assert(err, IsNil)
   834  	c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1}))
   835  }
   836  
   837  // From http://yaml.org/type/merge.html
   838  var mergeTests = `
   839  anchors:
   840    list:
   841      - &CENTER { "x": 1, "y": 2 }
   842      - &LEFT   { "x": 0, "y": 2 }
   843      - &BIG    { "r": 10 }
   844      - &SMALL  { "r": 1 }
   845  
   846  # All the following maps are equal:
   847  
   848  plain:
   849    # Explicit keys
   850    "x": 1
   851    "y": 2
   852    "r": 10
   853    label: center/big
   854  
   855  mergeOne:
   856    # Merge one map
   857    << : *CENTER
   858    "r": 10
   859    label: center/big
   860  
   861  mergeMultiple:
   862    # Merge multiple maps
   863    << : [ *CENTER, *BIG ]
   864    label: center/big
   865  
   866  override:
   867    # Override
   868    << : [ *BIG, *LEFT, *SMALL ]
   869    "x": 1
   870    label: center/big
   871  
   872  shortTag:
   873    # Explicit short merge tag
   874    !!merge "<<" : [ *CENTER, *BIG ]
   875    label: center/big
   876  
   877  longTag:
   878    # Explicit merge long tag
   879    !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ]
   880    label: center/big
   881  
   882  inlineMap:
   883    # Inlined map 
   884    << : {"x": 1, "y": 2, "r": 10}
   885    label: center/big
   886  
   887  inlineSequenceMap:
   888    # Inlined map in sequence
   889    << : [ *CENTER, {"r": 10} ]
   890    label: center/big
   891  `
   892  
   893  func (s *S) TestMerge(c *C) {
   894  	var want = map[interface{}]interface{}{
   895  		"x":     1,
   896  		"y":     2,
   897  		"r":     10,
   898  		"label": "center/big",
   899  	}
   900  
   901  	var m map[interface{}]interface{}
   902  	err := yaml.Unmarshal([]byte(mergeTests), &m)
   903  	c.Assert(err, IsNil)
   904  	for name, test := range m {
   905  		if name == "anchors" {
   906  			continue
   907  		}
   908  		c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
   909  	}
   910  }
   911  
   912  func (s *S) TestMergeStruct(c *C) {
   913  	type Data struct {
   914  		X, Y, R int
   915  		Label   string
   916  	}
   917  	want := Data{1, 2, 10, "center/big"}
   918  
   919  	var m map[string]Data
   920  	err := yaml.Unmarshal([]byte(mergeTests), &m)
   921  	c.Assert(err, IsNil)
   922  	for name, test := range m {
   923  		if name == "anchors" {
   924  			continue
   925  		}
   926  		c.Assert(test, Equals, want, Commentf("test %q failed", name))
   927  	}
   928  }
   929  
   930  var unmarshalNullTests = []func() interface{}{
   931  	func() interface{} { var v interface{}; v = "v"; return &v },
   932  	func() interface{} { var s = "s"; return &s },
   933  	func() interface{} { var s = "s"; sptr := &s; return &sptr },
   934  	func() interface{} { var i = 1; return &i },
   935  	func() interface{} { var i = 1; iptr := &i; return &iptr },
   936  	func() interface{} { m := map[string]int{"s": 1}; return &m },
   937  	func() interface{} { m := map[string]int{"s": 1}; return m },
   938  }
   939  
   940  func (s *S) TestUnmarshalNull(c *C) {
   941  	for _, test := range unmarshalNullTests {
   942  		item := test()
   943  		zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface()
   944  		err := yaml.Unmarshal([]byte("null"), item)
   945  		c.Assert(err, IsNil)
   946  		if reflect.TypeOf(item).Kind() == reflect.Map {
   947  			c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface())
   948  		} else {
   949  			c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero)
   950  		}
   951  	}
   952  }
   953  
   954  func (s *S) TestUnmarshalSliceOnPreset(c *C) {
   955  	// Issue #48.
   956  	v := struct{ A []int }{[]int{1}}
   957  	yaml.Unmarshal([]byte("a: [2]"), &v)
   958  	c.Assert(v.A, DeepEquals, []int{2})
   959  }
   960  
   961  //var data []byte
   962  //func init() {
   963  //	var err error
   964  //	data, err = ioutil.ReadFile("/tmp/file.yaml")
   965  //	if err != nil {
   966  //		panic(err)
   967  //	}
   968  //}
   969  //
   970  //func (s *S) BenchmarkUnmarshal(c *C) {
   971  //	var err error
   972  //	for i := 0; i < c.N; i++ {
   973  //		var v map[string]interface{}
   974  //		err = yaml.Unmarshal(data, &v)
   975  //	}
   976  //	if err != nil {
   977  //		panic(err)
   978  //	}
   979  //}
   980  //
   981  //func (s *S) BenchmarkMarshal(c *C) {
   982  //	var v map[string]interface{}
   983  //	yaml.Unmarshal(data, &v)
   984  //	c.ResetTimer()
   985  //	for i := 0; i < c.N; i++ {
   986  //		yaml.Marshal(&v)
   987  //	}
   988  //}