github.com/trevoraustin/hub@v2.2.0-preview1.0.20141105230840-96d8bfc654cc+incompatible/Godeps/_workspace/src/gopkg.in/yaml.v1/encode_test.go (about)

     1  package yaml_test
     2  
     3  import (
     4  	"fmt"
     5  	"gopkg.in/yaml.v1"
     6  	. "gopkg.in/check.v1"
     7  	"math"
     8  	"strconv"
     9  	"strings"
    10  	"time"
    11  )
    12  
    13  var marshalIntTest = 123
    14  
    15  var marshalTests = []struct {
    16  	value interface{}
    17  	data  string
    18  }{
    19  	{
    20  		&struct{}{},
    21  		"{}\n",
    22  	}, {
    23  		map[string]string{"v": "hi"},
    24  		"v: hi\n",
    25  	}, {
    26  		map[string]interface{}{"v": "hi"},
    27  		"v: hi\n",
    28  	}, {
    29  		map[string]string{"v": "true"},
    30  		"v: \"true\"\n",
    31  	}, {
    32  		map[string]string{"v": "false"},
    33  		"v: \"false\"\n",
    34  	}, {
    35  		map[string]interface{}{"v": true},
    36  		"v: true\n",
    37  	}, {
    38  		map[string]interface{}{"v": false},
    39  		"v: false\n",
    40  	}, {
    41  		map[string]interface{}{"v": 10},
    42  		"v: 10\n",
    43  	}, {
    44  		map[string]interface{}{"v": -10},
    45  		"v: -10\n",
    46  	}, {
    47  		map[string]uint{"v": 42},
    48  		"v: 42\n",
    49  	}, {
    50  		map[string]interface{}{"v": int64(4294967296)},
    51  		"v: 4294967296\n",
    52  	}, {
    53  		map[string]int64{"v": int64(4294967296)},
    54  		"v: 4294967296\n",
    55  	}, {
    56  		map[string]uint64{"v": 4294967296},
    57  		"v: 4294967296\n",
    58  	}, {
    59  		map[string]interface{}{"v": "10"},
    60  		"v: \"10\"\n",
    61  	}, {
    62  		map[string]interface{}{"v": 0.1},
    63  		"v: 0.1\n",
    64  	}, {
    65  		map[string]interface{}{"v": float64(0.1)},
    66  		"v: 0.1\n",
    67  	}, {
    68  		map[string]interface{}{"v": -0.1},
    69  		"v: -0.1\n",
    70  	}, {
    71  		map[string]interface{}{"v": math.Inf(+1)},
    72  		"v: .inf\n",
    73  	}, {
    74  		map[string]interface{}{"v": math.Inf(-1)},
    75  		"v: -.inf\n",
    76  	}, {
    77  		map[string]interface{}{"v": math.NaN()},
    78  		"v: .nan\n",
    79  	}, {
    80  		map[string]interface{}{"v": nil},
    81  		"v: null\n",
    82  	}, {
    83  		map[string]interface{}{"v": ""},
    84  		"v: \"\"\n",
    85  	}, {
    86  		map[string][]string{"v": []string{"A", "B"}},
    87  		"v:\n- A\n- B\n",
    88  	}, {
    89  		map[string][]string{"v": []string{"A", "B\nC"}},
    90  		"v:\n- A\n- 'B\n\n  C'\n",
    91  	}, {
    92  		map[string][]interface{}{"v": []interface{}{"A", 1, map[string][]int{"B": []int{2, 3}}}},
    93  		"v:\n- A\n- 1\n- B:\n  - 2\n  - 3\n",
    94  	}, {
    95  		map[string]interface{}{"a": map[interface{}]interface{}{"b": "c"}},
    96  		"a:\n  b: c\n",
    97  	}, {
    98  		map[string]interface{}{"a": "-"},
    99  		"a: '-'\n",
   100  	},
   101  
   102  	// Simple values.
   103  	{
   104  		&marshalIntTest,
   105  		"123\n",
   106  	},
   107  
   108  	// Structures
   109  	{
   110  		&struct{ Hello string }{"world"},
   111  		"hello: world\n",
   112  	}, {
   113  		&struct {
   114  			A struct {
   115  				B string
   116  			}
   117  		}{struct{ B string }{"c"}},
   118  		"a:\n  b: c\n",
   119  	}, {
   120  		&struct {
   121  			A *struct {
   122  				B string
   123  			}
   124  		}{&struct{ B string }{"c"}},
   125  		"a:\n  b: c\n",
   126  	}, {
   127  		&struct {
   128  			A *struct {
   129  				B string
   130  			}
   131  		}{},
   132  		"a: null\n",
   133  	}, {
   134  		&struct{ A int }{1},
   135  		"a: 1\n",
   136  	}, {
   137  		&struct{ A []int }{[]int{1, 2}},
   138  		"a:\n- 1\n- 2\n",
   139  	}, {
   140  		&struct {
   141  			B int "a"
   142  		}{1},
   143  		"a: 1\n",
   144  	}, {
   145  		&struct{ A bool }{true},
   146  		"a: true\n",
   147  	},
   148  
   149  	// Conditional flag
   150  	{
   151  		&struct {
   152  			A int "a,omitempty"
   153  			B int "b,omitempty"
   154  		}{1, 0},
   155  		"a: 1\n",
   156  	}, {
   157  		&struct {
   158  			A int "a,omitempty"
   159  			B int "b,omitempty"
   160  		}{0, 0},
   161  		"{}\n",
   162  	}, {
   163  		&struct {
   164  			A *struct{ X int } "a,omitempty"
   165  			B int              "b,omitempty"
   166  		}{nil, 0},
   167  		"{}\n",
   168  	},
   169  
   170  	// Flow flag
   171  	{
   172  		&struct {
   173  			A []int "a,flow"
   174  		}{[]int{1, 2}},
   175  		"a: [1, 2]\n",
   176  	}, {
   177  		&struct {
   178  			A map[string]string "a,flow"
   179  		}{map[string]string{"b": "c", "d": "e"}},
   180  		"a: {b: c, d: e}\n",
   181  	}, {
   182  		&struct {
   183  			A struct {
   184  				B, D string
   185  			} "a,flow"
   186  		}{struct{ B, D string }{"c", "e"}},
   187  		"a: {b: c, d: e}\n",
   188  	},
   189  
   190  	// Unexported field
   191  	{
   192  		&struct {
   193  			u int
   194  			A int
   195  		}{0, 1},
   196  		"a: 1\n",
   197  	},
   198  
   199  	// Ignored field
   200  	{
   201  		&struct {
   202  			A int
   203  			B int "-"
   204  		}{1, 2},
   205  		"a: 1\n",
   206  	},
   207  
   208  	// Struct inlining
   209  	{
   210  		&struct {
   211  			A int
   212  			C inlineB `yaml:",inline"`
   213  		}{1, inlineB{2, inlineC{3}}},
   214  		"a: 1\nb: 2\nc: 3\n",
   215  	},
   216  
   217  	// Duration
   218  	{
   219  		map[string]time.Duration{"a": 3 * time.Second},
   220  		"a: 3s\n",
   221  	},
   222  
   223  	// Issue #24. 
   224  	{
   225  		map[string]string{"a": "<foo>"},
   226  		"a: <foo>\n",
   227  	},
   228  }
   229  
   230  func (s *S) TestMarshal(c *C) {
   231  	for _, item := range marshalTests {
   232  		data, err := yaml.Marshal(item.value)
   233  		c.Assert(err, IsNil)
   234  		c.Assert(string(data), Equals, item.data)
   235  	}
   236  }
   237  
   238  var marshalErrorTests = []struct {
   239  	value interface{}
   240  	error string
   241  }{
   242  	{
   243  		&struct {
   244  			B       int
   245  			inlineB ",inline"
   246  		}{1, inlineB{2, inlineC{3}}},
   247  		`Duplicated key 'b' in struct struct \{ B int; .*`,
   248  	},
   249  }
   250  
   251  func (s *S) TestMarshalErrors(c *C) {
   252  	for _, item := range marshalErrorTests {
   253  		_, err := yaml.Marshal(item.value)
   254  		c.Assert(err, ErrorMatches, item.error)
   255  	}
   256  }
   257  
   258  var marshalTaggedIfaceTest interface{} = &struct{ A string }{"B"}
   259  
   260  var getterTests = []struct {
   261  	data, tag string
   262  	value     interface{}
   263  }{
   264  	{"_:\n  hi: there\n", "", map[interface{}]interface{}{"hi": "there"}},
   265  	{"_:\n- 1\n- A\n", "", []interface{}{1, "A"}},
   266  	{"_: 10\n", "", 10},
   267  	{"_: null\n", "", nil},
   268  	{"_: !foo BAR!\n", "!foo", "BAR!"},
   269  	{"_: !foo 1\n", "!foo", "1"},
   270  	{"_: !foo '\"1\"'\n", "!foo", "\"1\""},
   271  	{"_: !foo 1.1\n", "!foo", 1.1},
   272  	{"_: !foo 1\n", "!foo", 1},
   273  	{"_: !foo 1\n", "!foo", uint(1)},
   274  	{"_: !foo true\n", "!foo", true},
   275  	{"_: !foo\n- A\n- B\n", "!foo", []string{"A", "B"}},
   276  	{"_: !foo\n  A: B\n", "!foo", map[string]string{"A": "B"}},
   277  	{"_: !foo\n  a: B\n", "!foo", &marshalTaggedIfaceTest},
   278  }
   279  
   280  func (s *S) TestMarshalTypeCache(c *C) {
   281  	var data []byte
   282  	var err error
   283  	func() {
   284  		type T struct{ A int }
   285  		data, err = yaml.Marshal(&T{})
   286  		c.Assert(err, IsNil)
   287  	}()
   288  	func() {
   289  		type T struct{ B int }
   290  		data, err = yaml.Marshal(&T{})
   291  		c.Assert(err, IsNil)
   292  	}()
   293  	c.Assert(string(data), Equals, "b: 0\n")
   294  }
   295  
   296  type typeWithGetter struct {
   297  	tag   string
   298  	value interface{}
   299  }
   300  
   301  func (o typeWithGetter) GetYAML() (tag string, value interface{}) {
   302  	return o.tag, o.value
   303  }
   304  
   305  type typeWithGetterField struct {
   306  	Field typeWithGetter "_"
   307  }
   308  
   309  func (s *S) TestMashalWithGetter(c *C) {
   310  	for _, item := range getterTests {
   311  		obj := &typeWithGetterField{}
   312  		obj.Field.tag = item.tag
   313  		obj.Field.value = item.value
   314  		data, err := yaml.Marshal(obj)
   315  		c.Assert(err, IsNil)
   316  		c.Assert(string(data), Equals, string(item.data))
   317  	}
   318  }
   319  
   320  func (s *S) TestUnmarshalWholeDocumentWithGetter(c *C) {
   321  	obj := &typeWithGetter{}
   322  	obj.tag = ""
   323  	obj.value = map[string]string{"hello": "world!"}
   324  	data, err := yaml.Marshal(obj)
   325  	c.Assert(err, IsNil)
   326  	c.Assert(string(data), Equals, "hello: world!\n")
   327  }
   328  
   329  func (s *S) TestSortedOutput(c *C) {
   330  	order := []interface{}{
   331  		false,
   332  		true,
   333  		1,
   334  		uint(1),
   335  		1.0,
   336  		1.1,
   337  		1.2,
   338  		2,
   339  		uint(2),
   340  		2.0,
   341  		2.1,
   342  		"",
   343  		".1",
   344  		".2",
   345  		".a",
   346  		"1",
   347  		"2",
   348  		"a!10",
   349  		"a/2",
   350  		"a/10",
   351  		"a~10",
   352  		"ab/1",
   353  		"b/1",
   354  		"b/01",
   355  		"b/2",
   356  		"b/02",
   357  		"b/3",
   358  		"b/03",
   359  		"b1",
   360  		"b01",
   361  		"b3",
   362  		"c2.10",
   363  		"c10.2",
   364  		"d1",
   365  		"d12",
   366  		"d12a",
   367  	}
   368  	m := make(map[interface{}]int)
   369  	for _, k := range order {
   370  		m[k] = 1
   371  	}
   372  	data, err := yaml.Marshal(m)
   373  	c.Assert(err, IsNil)
   374  	out := "\n" + string(data)
   375  	last := 0
   376  	for i, k := range order {
   377  		repr := fmt.Sprint(k)
   378  		if s, ok := k.(string); ok {
   379  			if _, err = strconv.ParseFloat(repr, 32); s == "" || err == nil {
   380  				repr = `"` + repr + `"`
   381  			}
   382  		}
   383  		index := strings.Index(out, "\n"+repr+":")
   384  		if index == -1 {
   385  			c.Fatalf("%#v is not in the output: %#v", k, out)
   386  		}
   387  		if index < last {
   388  			c.Fatalf("%#v was generated before %#v: %q", k, order[i-1], out)
   389  		}
   390  		last = index
   391  	}
   392  }