github.com/marinho/drone@v0.2.1-0.20140504195434-d3ba962e89a7/Godeps/_workspace/src/launchpad.net/goyaml/encode_test.go (about)

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