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 }