github.com/rochacon/deis@v1.0.2-0.20150903015341-6839b592a1ff/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  	// Overflow cases.
   271  	{
   272  		"v: 4294967297",
   273  		map[string]int32{},
   274  	}, {
   275  		"v: 128",
   276  		map[string]int8{},
   277  	},
   278  
   279  	// Quoted values.
   280  	{
   281  		"'1': '\"2\"'",
   282  		map[interface{}]interface{}{"1": "\"2\""},
   283  	}, {
   284  		"v:\n- A\n- 'B\n\n  C'\n",
   285  		map[string][]string{"v": []string{"A", "B\nC"}},
   286  	},
   287  
   288  	// Explicit tags.
   289  	{
   290  		"v: !!float '1.1'",
   291  		map[string]interface{}{"v": 1.1},
   292  	}, {
   293  		"v: !!null ''",
   294  		map[string]interface{}{"v": nil},
   295  	}, {
   296  		"%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
   297  		map[string]interface{}{"v": 1},
   298  	},
   299  
   300  	// Anchors and aliases.
   301  	{
   302  		"a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
   303  		&struct{ A, B, C, D int }{1, 2, 1, 2},
   304  	}, {
   305  		"a: &a {c: 1}\nb: *a",
   306  		&struct {
   307  			A, B struct {
   308  				C int
   309  			}
   310  		}{struct{ C int }{1}, struct{ C int }{1}},
   311  	}, {
   312  		"a: &a [1, 2]\nb: *a",
   313  		&struct{ B []int }{[]int{1, 2}},
   314  	},
   315  
   316  	// Bug #1133337
   317  	{
   318  		"foo: ''",
   319  		map[string]*string{"foo": new(string)},
   320  	}, {
   321  		"foo: null",
   322  		map[string]string{"foo": ""},
   323  	}, {
   324  		"foo: null",
   325  		map[string]interface{}{"foo": nil},
   326  	},
   327  
   328  	// Ignored field
   329  	{
   330  		"a: 1\nb: 2\n",
   331  		&struct {
   332  			A int
   333  			B int "-"
   334  		}{1, 0},
   335  	},
   336  
   337  	// Bug #1191981
   338  	{
   339  		"" +
   340  			"%YAML 1.1\n" +
   341  			"--- !!str\n" +
   342  			`"Generic line break (no glyph)\n\` + "\n" +
   343  			` Generic line break (glyphed)\n\` + "\n" +
   344  			` Line separator\u2028\` + "\n" +
   345  			` Paragraph separator\u2029"` + "\n",
   346  		"" +
   347  			"Generic line break (no glyph)\n" +
   348  			"Generic line break (glyphed)\n" +
   349  			"Line separator\u2028Paragraph separator\u2029",
   350  	},
   351  
   352  	// Struct inlining
   353  	{
   354  		"a: 1\nb: 2\nc: 3\n",
   355  		&struct {
   356  			A int
   357  			C inlineB `yaml:",inline"`
   358  		}{1, inlineB{2, inlineC{3}}},
   359  	},
   360  
   361  	// bug 1243827
   362  	{
   363  		"a: -b_c",
   364  		map[string]interface{}{"a": "-b_c"},
   365  	},
   366  	{
   367  		"a: +b_c",
   368  		map[string]interface{}{"a": "+b_c"},
   369  	},
   370  	{
   371  		"a: 50cent_of_dollar",
   372  		map[string]interface{}{"a": "50cent_of_dollar"},
   373  	},
   374  
   375  	// Duration
   376  	{
   377  		"a: 3s",
   378  		map[string]time.Duration{"a": 3 * time.Second},
   379  	},
   380  
   381  	// Issue #24.
   382  	{
   383  		"a: <foo>",
   384  		map[string]string{"a": "<foo>"},
   385  	},
   386  
   387  	// Base 60 floats are obsolete and unsupported.
   388  	{
   389  		"a: 1:1\n",
   390  		map[string]string{"a": "1:1"},
   391  	},
   392  
   393  	// Binary data.
   394  	{
   395  		"a: !!binary gIGC\n",
   396  		map[string]string{"a": "\x80\x81\x82"},
   397  	}, {
   398  		"a: !!binary |\n  " + strings.Repeat("kJCQ", 17) + "kJ\n  CQ\n",
   399  		map[string]string{"a": strings.Repeat("\x90", 54)},
   400  	}, {
   401  		"a: !!binary |\n  " + strings.Repeat("A", 70) + "\n  ==\n",
   402  		map[string]string{"a": strings.Repeat("\x00", 52)},
   403  	},
   404  
   405  	// Ordered maps.
   406  	{
   407  		"{b: 2, a: 1, d: 4, c: 3, sub: {e: 5}}",
   408  		&yaml.MapSlice{{"b", 2}, {"a", 1}, {"d", 4}, {"c", 3}, {"sub", yaml.MapSlice{{"e", 5}}}},
   409  	},
   410  
   411  	// Issue #39.
   412  	{
   413  		"a:\n b:\n  c: d\n",
   414  		map[string]struct{ B interface{} }{"a": {map[interface{}]interface{}{"c": "d"}}},
   415  	},
   416  
   417  	// Custom map type.
   418  	{
   419  		"a: {b: c}",
   420  		M{"a": M{"b": "c"}},
   421  	},
   422  
   423  	// Support encoding.TextUnmarshaler.
   424  	{
   425  		"a: 1.2.3.4\n",
   426  		map[string]net.IP{"a": net.IPv4(1, 2, 3, 4)},
   427  	},
   428  }
   429  
   430  type M map[interface{}]interface{}
   431  
   432  type inlineB struct {
   433  	B       int
   434  	inlineC `yaml:",inline"`
   435  }
   436  
   437  type inlineC struct {
   438  	C int
   439  }
   440  
   441  func (s *S) TestUnmarshal(c *C) {
   442  	for _, item := range unmarshalTests {
   443  		t := reflect.ValueOf(item.value).Type()
   444  		var value interface{}
   445  		switch t.Kind() {
   446  		case reflect.Map:
   447  			value = reflect.MakeMap(t).Interface()
   448  		case reflect.String:
   449  			value = reflect.New(t).Interface()
   450  		case reflect.Ptr:
   451  			value = reflect.New(t.Elem()).Interface()
   452  		default:
   453  			c.Fatalf("missing case for %s", t)
   454  		}
   455  		err := yaml.Unmarshal([]byte(item.data), value)
   456  		if _, ok := err.(*yaml.TypeError); !ok {
   457  			c.Assert(err, IsNil)
   458  		}
   459  		if t.Kind() == reflect.String {
   460  			c.Assert(*value.(*string), Equals, item.value)
   461  		} else {
   462  			c.Assert(value, DeepEquals, item.value)
   463  		}
   464  	}
   465  }
   466  
   467  func (s *S) TestUnmarshalNaN(c *C) {
   468  	value := map[string]interface{}{}
   469  	err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
   470  	c.Assert(err, IsNil)
   471  	c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
   472  }
   473  
   474  var unmarshalErrorTests = []struct {
   475  	data, error string
   476  }{
   477  	{"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"},
   478  	{"v: [A,", "yaml: line 1: did not find expected node content"},
   479  	{"v:\n- [A,", "yaml: line 2: did not find expected node content"},
   480  	{"a: *b\n", "yaml: unknown anchor 'b' referenced"},
   481  	{"a: &a\n  b: *a\n", "yaml: anchor 'a' value contains itself"},
   482  	{"value: -", "yaml: block sequence entries are not allowed in this context"},
   483  	{"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
   484  	{"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
   485  	{"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
   486  }
   487  
   488  func (s *S) TestUnmarshalErrors(c *C) {
   489  	for _, item := range unmarshalErrorTests {
   490  		var value interface{}
   491  		err := yaml.Unmarshal([]byte(item.data), &value)
   492  		c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
   493  	}
   494  }
   495  
   496  var unmarshalerTests = []struct {
   497  	data, tag string
   498  	value     interface{}
   499  }{
   500  	{"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}},
   501  	{"_: [1,A]", "!!seq", []interface{}{1, "A"}},
   502  	{"_: 10", "!!int", 10},
   503  	{"_: null", "!!null", nil},
   504  	{`_: BAR!`, "!!str", "BAR!"},
   505  	{`_: "BAR!"`, "!!str", "BAR!"},
   506  	{"_: !!foo 'BAR!'", "!!foo", "BAR!"},
   507  }
   508  
   509  var unmarshalerResult = map[int]error{}
   510  
   511  type unmarshalerType struct {
   512  	value interface{}
   513  }
   514  
   515  func (o *unmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error {
   516  	if err := unmarshal(&o.value); err != nil {
   517  		return err
   518  	}
   519  	if i, ok := o.value.(int); ok {
   520  		if result, ok := unmarshalerResult[i]; ok {
   521  			return result
   522  		}
   523  	}
   524  	return nil
   525  }
   526  
   527  type unmarshalerPointer struct {
   528  	Field *unmarshalerType "_"
   529  }
   530  
   531  type unmarshalerValue struct {
   532  	Field unmarshalerType "_"
   533  }
   534  
   535  func (s *S) TestUnmarshalerPointerField(c *C) {
   536  	for _, item := range unmarshalerTests {
   537  		obj := &unmarshalerPointer{}
   538  		err := yaml.Unmarshal([]byte(item.data), obj)
   539  		c.Assert(err, IsNil)
   540  		if item.value == nil {
   541  			c.Assert(obj.Field, IsNil)
   542  		} else {
   543  			c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
   544  			c.Assert(obj.Field.value, DeepEquals, item.value)
   545  		}
   546  	}
   547  }
   548  
   549  func (s *S) TestUnmarshalerValueField(c *C) {
   550  	for _, item := range unmarshalerTests {
   551  		obj := &unmarshalerValue{}
   552  		err := yaml.Unmarshal([]byte(item.data), obj)
   553  		c.Assert(err, IsNil)
   554  		c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
   555  		c.Assert(obj.Field.value, DeepEquals, item.value)
   556  	}
   557  }
   558  
   559  func (s *S) TestUnmarshalerWholeDocument(c *C) {
   560  	obj := &unmarshalerType{}
   561  	err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj)
   562  	c.Assert(err, IsNil)
   563  	value, ok := obj.value.(map[interface{}]interface{})
   564  	c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value))
   565  	c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value)
   566  }
   567  
   568  func (s *S) TestUnmarshalerTypeError(c *C) {
   569  	unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
   570  	unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
   571  	defer func() {
   572  		delete(unmarshalerResult, 2)
   573  		delete(unmarshalerResult, 4)
   574  	}()
   575  
   576  	type T struct {
   577  		Before int
   578  		After  int
   579  		M      map[string]*unmarshalerType
   580  	}
   581  	var v T
   582  	data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
   583  	err := yaml.Unmarshal([]byte(data), &v)
   584  	c.Assert(err, ErrorMatches, ""+
   585  		"yaml: unmarshal errors:\n"+
   586  		"  line 1: cannot unmarshal !!str `A` into int\n"+
   587  		"  foo\n"+
   588  		"  bar\n"+
   589  		"  line 1: cannot unmarshal !!str `B` into int")
   590  	c.Assert(v.M["abc"], NotNil)
   591  	c.Assert(v.M["def"], IsNil)
   592  	c.Assert(v.M["ghi"], NotNil)
   593  	c.Assert(v.M["jkl"], IsNil)
   594  
   595  	c.Assert(v.M["abc"].value, Equals, 1)
   596  	c.Assert(v.M["ghi"].value, Equals, 3)
   597  }
   598  
   599  type proxyTypeError struct{}
   600  
   601  func (v *proxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error {
   602  	var s string
   603  	var a int32
   604  	var b int64
   605  	if err := unmarshal(&s); err != nil {
   606  		panic(err)
   607  	}
   608  	if s == "a" {
   609  		if err := unmarshal(&b); err == nil {
   610  			panic("should have failed")
   611  		}
   612  		return unmarshal(&a)
   613  	}
   614  	if err := unmarshal(&a); err == nil {
   615  		panic("should have failed")
   616  	}
   617  	return unmarshal(&b)
   618  }
   619  
   620  func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
   621  	type T struct {
   622  		Before int
   623  		After  int
   624  		M      map[string]*proxyTypeError
   625  	}
   626  	var v T
   627  	data := `{before: A, m: {abc: a, def: b}, after: B}`
   628  	err := yaml.Unmarshal([]byte(data), &v)
   629  	c.Assert(err, ErrorMatches, ""+
   630  		"yaml: unmarshal errors:\n"+
   631  		"  line 1: cannot unmarshal !!str `A` into int\n"+
   632  		"  line 1: cannot unmarshal !!str `a` into int32\n"+
   633  		"  line 1: cannot unmarshal !!str `b` into int64\n"+
   634  		"  line 1: cannot unmarshal !!str `B` into int")
   635  }
   636  
   637  type failingUnmarshaler struct{}
   638  
   639  var failingErr = errors.New("failingErr")
   640  
   641  func (ft *failingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
   642  	return failingErr
   643  }
   644  
   645  func (s *S) TestUnmarshalerError(c *C) {
   646  	err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{})
   647  	c.Assert(err, Equals, failingErr)
   648  }
   649  
   650  // From http://yaml.org/type/merge.html
   651  var mergeTests = `
   652  anchors:
   653    list:
   654      - &CENTER { "x": 1, "y": 2 }
   655      - &LEFT   { "x": 0, "y": 2 }
   656      - &BIG    { "r": 10 }
   657      - &SMALL  { "r": 1 }
   658  
   659  # All the following maps are equal:
   660  
   661  plain:
   662    # Explicit keys
   663    "x": 1
   664    "y": 2
   665    "r": 10
   666    label: center/big
   667  
   668  mergeOne:
   669    # Merge one map
   670    << : *CENTER
   671    "r": 10
   672    label: center/big
   673  
   674  mergeMultiple:
   675    # Merge multiple maps
   676    << : [ *CENTER, *BIG ]
   677    label: center/big
   678  
   679  override:
   680    # Override
   681    << : [ *BIG, *LEFT, *SMALL ]
   682    "x": 1
   683    label: center/big
   684  
   685  shortTag:
   686    # Explicit short merge tag
   687    !!merge "<<" : [ *CENTER, *BIG ]
   688    label: center/big
   689  
   690  longTag:
   691    # Explicit merge long tag
   692    !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ]
   693    label: center/big
   694  
   695  inlineMap:
   696    # Inlined map 
   697    << : {"x": 1, "y": 2, "r": 10}
   698    label: center/big
   699  
   700  inlineSequenceMap:
   701    # Inlined map in sequence
   702    << : [ *CENTER, {"r": 10} ]
   703    label: center/big
   704  `
   705  
   706  func (s *S) TestMerge(c *C) {
   707  	var want = map[interface{}]interface{}{
   708  		"x":     1,
   709  		"y":     2,
   710  		"r":     10,
   711  		"label": "center/big",
   712  	}
   713  
   714  	var m map[interface{}]interface{}
   715  	err := yaml.Unmarshal([]byte(mergeTests), &m)
   716  	c.Assert(err, IsNil)
   717  	for name, test := range m {
   718  		if name == "anchors" {
   719  			continue
   720  		}
   721  		c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
   722  	}
   723  }
   724  
   725  func (s *S) TestMergeStruct(c *C) {
   726  	type Data struct {
   727  		X, Y, R int
   728  		Label   string
   729  	}
   730  	want := Data{1, 2, 10, "center/big"}
   731  
   732  	var m map[string]Data
   733  	err := yaml.Unmarshal([]byte(mergeTests), &m)
   734  	c.Assert(err, IsNil)
   735  	for name, test := range m {
   736  		if name == "anchors" {
   737  			continue
   738  		}
   739  		c.Assert(test, Equals, want, Commentf("test %q failed", name))
   740  	}
   741  }
   742  
   743  var unmarshalNullTests = []func() interface{}{
   744  	func() interface{} { var v interface{}; v = "v"; return &v },
   745  	func() interface{} { var s = "s"; return &s },
   746  	func() interface{} { var s = "s"; sptr := &s; return &sptr },
   747  	func() interface{} { var i = 1; return &i },
   748  	func() interface{} { var i = 1; iptr := &i; return &iptr },
   749  	func() interface{} { m := map[string]int{"s": 1}; return &m },
   750  	func() interface{} { m := map[string]int{"s": 1}; return m },
   751  }
   752  
   753  func (s *S) TestUnmarshalNull(c *C) {
   754  	for _, test := range unmarshalNullTests {
   755  		item := test()
   756  		zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface()
   757  		err := yaml.Unmarshal([]byte("null"), item)
   758  		c.Assert(err, IsNil)
   759  		if reflect.TypeOf(item).Kind() == reflect.Map {
   760  			c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface())
   761  		} else {
   762  			c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero)
   763  		}
   764  	}
   765  }
   766  
   767  //var data []byte
   768  //func init() {
   769  //	var err error
   770  //	data, err = ioutil.ReadFile("/tmp/file.yaml")
   771  //	if err != nil {
   772  //		panic(err)
   773  //	}
   774  //}
   775  //
   776  //func (s *S) BenchmarkUnmarshal(c *C) {
   777  //	var err error
   778  //	for i := 0; i < c.N; i++ {
   779  //		var v map[string]interface{}
   780  //		err = yaml.Unmarshal(data, &v)
   781  //	}
   782  //	if err != nil {
   783  //		panic(err)
   784  //	}
   785  //}
   786  //
   787  //func (s *S) BenchmarkMarshal(c *C) {
   788  //	var v map[string]interface{}
   789  //	yaml.Unmarshal(data, &v)
   790  //	c.ResetTimer()
   791  //	for i := 0; i < c.N; i++ {
   792  //		yaml.Marshal(&v)
   793  //	}
   794  //}