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 }