~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/gopkg.in/yaml.v2/decode_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
        // int
 
271
        {
 
272
                "int_max: 2147483647",
 
273
                map[string]int{"int_max": math.MaxInt32},
 
274
        },
 
275
        {
 
276
                "int_min: -2147483648",
 
277
                map[string]int{"int_min": math.MinInt32},
 
278
        },
 
279
        {
 
280
                "int_overflow: 9223372036854775808", // math.MaxInt64 + 1
 
281
                map[string]int{},
 
282
        },
 
283
 
 
284
        // int64
 
285
        {
 
286
                "int64_max: 9223372036854775807",
 
287
                map[string]int64{"int64_max": math.MaxInt64},
 
288
        },
 
289
        {
 
290
                "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111",
 
291
                map[string]int64{"int64_max_base2": math.MaxInt64},
 
292
        },
 
293
        {
 
294
                "int64_min: -9223372036854775808",
 
295
                map[string]int64{"int64_min": math.MinInt64},
 
296
        },
 
297
        {
 
298
                "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111",
 
299
                map[string]int64{"int64_neg_base2": -math.MaxInt64},
 
300
        },
 
301
        {
 
302
                "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1
 
303
                map[string]int64{},
 
304
        },
 
305
 
 
306
        // uint
 
307
        {
 
308
                "uint_min: 0",
 
309
                map[string]uint{"uint_min": 0},
 
310
        },
 
311
        {
 
312
                "uint_max: 4294967295",
 
313
                map[string]uint{"uint_max": math.MaxUint32},
 
314
        },
 
315
        {
 
316
                "uint_underflow: -1",
 
317
                map[string]uint{},
 
318
        },
 
319
 
 
320
        // uint64
 
321
        {
 
322
                "uint64_min: 0",
 
323
                map[string]uint{"uint64_min": 0},
 
324
        },
 
325
        {
 
326
                "uint64_max: 18446744073709551615",
 
327
                map[string]uint64{"uint64_max": math.MaxUint64},
 
328
        },
 
329
        {
 
330
                "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111",
 
331
                map[string]uint64{"uint64_max_base2": math.MaxUint64},
 
332
        },
 
333
        {
 
334
                "uint64_maxint64: 9223372036854775807",
 
335
                map[string]uint64{"uint64_maxint64": math.MaxInt64},
 
336
        },
 
337
        {
 
338
                "uint64_underflow: -1",
 
339
                map[string]uint64{},
 
340
        },
 
341
 
 
342
        // float32
 
343
        {
 
344
                "float32_max: 3.40282346638528859811704183484516925440e+38",
 
345
                map[string]float32{"float32_max": math.MaxFloat32},
 
346
        },
 
347
        {
 
348
                "float32_nonzero: 1.401298464324817070923729583289916131280e-45",
 
349
                map[string]float32{"float32_nonzero": math.SmallestNonzeroFloat32},
 
350
        },
 
351
        {
 
352
                "float32_maxuint64: 18446744073709551615",
 
353
                map[string]float32{"float32_maxuint64": float32(math.MaxUint64)},
 
354
        },
 
355
        {
 
356
                "float32_maxuint64+1: 18446744073709551616",
 
357
                map[string]float32{"float32_maxuint64+1": float32(math.MaxUint64 + 1)},
 
358
        },
 
359
 
 
360
        // float64
 
361
        {
 
362
                "float64_max: 1.797693134862315708145274237317043567981e+308",
 
363
                map[string]float64{"float64_max": math.MaxFloat64},
 
364
        },
 
365
        {
 
366
                "float64_nonzero: 4.940656458412465441765687928682213723651e-324",
 
367
                map[string]float64{"float64_nonzero": math.SmallestNonzeroFloat64},
 
368
        },
 
369
        {
 
370
                "float64_maxuint64: 18446744073709551615",
 
371
                map[string]float64{"float64_maxuint64": float64(math.MaxUint64)},
 
372
        },
 
373
        {
 
374
                "float64_maxuint64+1: 18446744073709551616",
 
375
                map[string]float64{"float64_maxuint64+1": float64(math.MaxUint64 + 1)},
 
376
        },
 
377
 
 
378
        // Overflow cases.
 
379
        {
 
380
                "v: 4294967297",
 
381
                map[string]int32{},
 
382
        }, {
 
383
                "v: 128",
 
384
                map[string]int8{},
 
385
        },
 
386
 
 
387
        // Quoted values.
 
388
        {
 
389
                "'1': '\"2\"'",
 
390
                map[interface{}]interface{}{"1": "\"2\""},
 
391
        }, {
 
392
                "v:\n- A\n- 'B\n\n  C'\n",
 
393
                map[string][]string{"v": []string{"A", "B\nC"}},
 
394
        },
 
395
 
 
396
        // Explicit tags.
 
397
        {
 
398
                "v: !!float '1.1'",
 
399
                map[string]interface{}{"v": 1.1},
 
400
        }, {
 
401
                "v: !!null ''",
 
402
                map[string]interface{}{"v": nil},
 
403
        }, {
 
404
                "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
 
405
                map[string]interface{}{"v": 1},
 
406
        },
 
407
 
 
408
        // Anchors and aliases.
 
409
        {
 
410
                "a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
 
411
                &struct{ A, B, C, D int }{1, 2, 1, 2},
 
412
        }, {
 
413
                "a: &a {c: 1}\nb: *a",
 
414
                &struct {
 
415
                        A, B struct {
 
416
                                C int
 
417
                        }
 
418
                }{struct{ C int }{1}, struct{ C int }{1}},
 
419
        }, {
 
420
                "a: &a [1, 2]\nb: *a",
 
421
                &struct{ B []int }{[]int{1, 2}},
 
422
        }, {
 
423
                "b: *a\na: &a {c: 1}",
 
424
                &struct {
 
425
                        A, B struct {
 
426
                                C int
 
427
                        }
 
428
                }{struct{ C int }{1}, struct{ C int }{1}},
 
429
        },
 
430
 
 
431
        // Bug #1133337
 
432
        {
 
433
                "foo: ''",
 
434
                map[string]*string{"foo": new(string)},
 
435
        }, {
 
436
                "foo: null",
 
437
                map[string]string{"foo": ""},
 
438
        }, {
 
439
                "foo: null",
 
440
                map[string]interface{}{"foo": nil},
 
441
        },
 
442
 
 
443
        // Ignored field
 
444
        {
 
445
                "a: 1\nb: 2\n",
 
446
                &struct {
 
447
                        A int
 
448
                        B int "-"
 
449
                }{1, 0},
 
450
        },
 
451
 
 
452
        // Bug #1191981
 
453
        {
 
454
                "" +
 
455
                        "%YAML 1.1\n" +
 
456
                        "--- !!str\n" +
 
457
                        `"Generic line break (no glyph)\n\` + "\n" +
 
458
                        ` Generic line break (glyphed)\n\` + "\n" +
 
459
                        ` Line separator\u2028\` + "\n" +
 
460
                        ` Paragraph separator\u2029"` + "\n",
 
461
                "" +
 
462
                        "Generic line break (no glyph)\n" +
 
463
                        "Generic line break (glyphed)\n" +
 
464
                        "Line separator\u2028Paragraph separator\u2029",
 
465
        },
 
466
 
 
467
        // Struct inlining
 
468
        {
 
469
                "a: 1\nb: 2\nc: 3\n",
 
470
                &struct {
 
471
                        A int
 
472
                        C inlineB `yaml:",inline"`
 
473
                }{1, inlineB{2, inlineC{3}}},
 
474
        },
 
475
 
 
476
        // Map inlining
 
477
        {
 
478
                "a: 1\nb: 2\nc: 3\n",
 
479
                &struct {
 
480
                        A int
 
481
                        C map[string]int `yaml:",inline"`
 
482
                }{1, map[string]int{"b": 2, "c": 3}},
 
483
        },
 
484
 
 
485
        // bug 1243827
 
486
        {
 
487
                "a: -b_c",
 
488
                map[string]interface{}{"a": "-b_c"},
 
489
        },
 
490
        {
 
491
                "a: +b_c",
 
492
                map[string]interface{}{"a": "+b_c"},
 
493
        },
 
494
        {
 
495
                "a: 50cent_of_dollar",
 
496
                map[string]interface{}{"a": "50cent_of_dollar"},
 
497
        },
 
498
 
 
499
        // Duration
 
500
        {
 
501
                "a: 3s",
 
502
                map[string]time.Duration{"a": 3 * time.Second},
 
503
        },
 
504
 
 
505
        // Issue #24.
 
506
        {
 
507
                "a: <foo>",
 
508
                map[string]string{"a": "<foo>"},
 
509
        },
 
510
 
 
511
        // Base 60 floats are obsolete and unsupported.
 
512
        {
 
513
                "a: 1:1\n",
 
514
                map[string]string{"a": "1:1"},
 
515
        },
 
516
 
 
517
        // Binary data.
 
518
        {
 
519
                "a: !!binary gIGC\n",
 
520
                map[string]string{"a": "\x80\x81\x82"},
 
521
        }, {
 
522
                "a: !!binary |\n  " + strings.Repeat("kJCQ", 17) + "kJ\n  CQ\n",
 
523
                map[string]string{"a": strings.Repeat("\x90", 54)},
 
524
        }, {
 
525
                "a: !!binary |\n  " + strings.Repeat("A", 70) + "\n  ==\n",
 
526
                map[string]string{"a": strings.Repeat("\x00", 52)},
 
527
        },
 
528
 
 
529
        // Ordered maps.
 
530
        {
 
531
                "{b: 2, a: 1, d: 4, c: 3, sub: {e: 5}}",
 
532
                &yaml.MapSlice{{"b", 2}, {"a", 1}, {"d", 4}, {"c", 3}, {"sub", yaml.MapSlice{{"e", 5}}}},
 
533
        },
 
534
 
 
535
        // Issue #39.
 
536
        {
 
537
                "a:\n b:\n  c: d\n",
 
538
                map[string]struct{ B interface{} }{"a": {map[interface{}]interface{}{"c": "d"}}},
 
539
        },
 
540
 
 
541
        // Custom map type.
 
542
        {
 
543
                "a: {b: c}",
 
544
                M{"a": M{"b": "c"}},
 
545
        },
 
546
 
 
547
        // Support encoding.TextUnmarshaler.
 
548
        {
 
549
                "a: 1.2.3.4\n",
 
550
                map[string]net.IP{"a": net.IPv4(1, 2, 3, 4)},
 
551
        },
 
552
        {
 
553
                "a: 2015-02-24T18:19:39Z\n",
 
554
                map[string]time.Time{"a": time.Unix(1424801979, 0)},
 
555
        },
 
556
 
 
557
        // Encode empty lists as zero-length slices.
 
558
        {
 
559
                "a: []",
 
560
                &struct{ A []int }{[]int{}},
 
561
        },
 
562
 
 
563
        // UTF-16-LE
 
564
        {
 
565
                "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00",
 
566
                M{"ñoño": "very yes"},
 
567
        },
 
568
        // UTF-16-LE with surrogate.
 
569
        {
 
570
                "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00",
 
571
                M{"ñoño": "very yes 🟔"},
 
572
        },
 
573
 
 
574
        // UTF-16-BE
 
575
        {
 
576
                "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n",
 
577
                M{"ñoño": "very yes"},
 
578
        },
 
579
        // UTF-16-BE with surrogate.
 
580
        {
 
581
                "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n",
 
582
                M{"ñoño": "very yes 🟔"},
 
583
        },
 
584
}
 
585
 
 
586
type M map[interface{}]interface{}
 
587
 
 
588
type inlineB struct {
 
589
        B       int
 
590
        inlineC `yaml:",inline"`
 
591
}
 
592
 
 
593
type inlineC struct {
 
594
        C int
 
595
}
 
596
 
 
597
func (s *S) TestUnmarshal(c *C) {
 
598
        for _, item := range unmarshalTests {
 
599
                t := reflect.ValueOf(item.value).Type()
 
600
                var value interface{}
 
601
                switch t.Kind() {
 
602
                case reflect.Map:
 
603
                        value = reflect.MakeMap(t).Interface()
 
604
                case reflect.String:
 
605
                        value = reflect.New(t).Interface()
 
606
                case reflect.Ptr:
 
607
                        value = reflect.New(t.Elem()).Interface()
 
608
                default:
 
609
                        c.Fatalf("missing case for %s", t)
 
610
                }
 
611
                err := yaml.Unmarshal([]byte(item.data), value)
 
612
                if _, ok := err.(*yaml.TypeError); !ok {
 
613
                        c.Assert(err, IsNil)
 
614
                }
 
615
                if t.Kind() == reflect.String {
 
616
                        c.Assert(*value.(*string), Equals, item.value)
 
617
                } else {
 
618
                        c.Assert(value, DeepEquals, item.value)
 
619
                }
 
620
        }
 
621
}
 
622
 
 
623
func (s *S) TestUnmarshalNaN(c *C) {
 
624
        value := map[string]interface{}{}
 
625
        err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
 
626
        c.Assert(err, IsNil)
 
627
        c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
 
628
}
 
629
 
 
630
var unmarshalErrorTests = []struct {
 
631
        data, error string
 
632
}{
 
633
        {"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"},
 
634
        {"v: [A,", "yaml: line 1: did not find expected node content"},
 
635
        {"v:\n- [A,", "yaml: line 2: did not find expected node content"},
 
636
        {"a: *b\n", "yaml: unknown anchor 'b' referenced"},
 
637
        {"a: &a\n  b: *a\n", "yaml: anchor 'a' value contains itself"},
 
638
        {"value: -", "yaml: block sequence entries are not allowed in this context"},
 
639
        {"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
 
640
        {"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
 
641
        {"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
 
642
}
 
643
 
 
644
func (s *S) TestUnmarshalErrors(c *C) {
 
645
        for _, item := range unmarshalErrorTests {
 
646
                var value interface{}
 
647
                err := yaml.Unmarshal([]byte(item.data), &value)
 
648
                c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
 
649
        }
 
650
}
 
651
 
 
652
var unmarshalerTests = []struct {
 
653
        data, tag string
 
654
        value     interface{}
 
655
}{
 
656
        {"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}},
 
657
        {"_: [1,A]", "!!seq", []interface{}{1, "A"}},
 
658
        {"_: 10", "!!int", 10},
 
659
        {"_: null", "!!null", nil},
 
660
        {`_: BAR!`, "!!str", "BAR!"},
 
661
        {`_: "BAR!"`, "!!str", "BAR!"},
 
662
        {"_: !!foo 'BAR!'", "!!foo", "BAR!"},
 
663
}
 
664
 
 
665
var unmarshalerResult = map[int]error{}
 
666
 
 
667
type unmarshalerType struct {
 
668
        value interface{}
 
669
}
 
670
 
 
671
func (o *unmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error {
 
672
        if err := unmarshal(&o.value); err != nil {
 
673
                return err
 
674
        }
 
675
        if i, ok := o.value.(int); ok {
 
676
                if result, ok := unmarshalerResult[i]; ok {
 
677
                        return result
 
678
                }
 
679
        }
 
680
        return nil
 
681
}
 
682
 
 
683
type unmarshalerPointer struct {
 
684
        Field *unmarshalerType "_"
 
685
}
 
686
 
 
687
type unmarshalerValue struct {
 
688
        Field unmarshalerType "_"
 
689
}
 
690
 
 
691
func (s *S) TestUnmarshalerPointerField(c *C) {
 
692
        for _, item := range unmarshalerTests {
 
693
                obj := &unmarshalerPointer{}
 
694
                err := yaml.Unmarshal([]byte(item.data), obj)
 
695
                c.Assert(err, IsNil)
 
696
                if item.value == nil {
 
697
                        c.Assert(obj.Field, IsNil)
 
698
                } else {
 
699
                        c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
 
700
                        c.Assert(obj.Field.value, DeepEquals, item.value)
 
701
                }
 
702
        }
 
703
}
 
704
 
 
705
func (s *S) TestUnmarshalerValueField(c *C) {
 
706
        for _, item := range unmarshalerTests {
 
707
                obj := &unmarshalerValue{}
 
708
                err := yaml.Unmarshal([]byte(item.data), obj)
 
709
                c.Assert(err, IsNil)
 
710
                c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
 
711
                c.Assert(obj.Field.value, DeepEquals, item.value)
 
712
        }
 
713
}
 
714
 
 
715
func (s *S) TestUnmarshalerWholeDocument(c *C) {
 
716
        obj := &unmarshalerType{}
 
717
        err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj)
 
718
        c.Assert(err, IsNil)
 
719
        value, ok := obj.value.(map[interface{}]interface{})
 
720
        c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value))
 
721
        c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value)
 
722
}
 
723
 
 
724
func (s *S) TestUnmarshalerTypeError(c *C) {
 
725
        unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}}
 
726
        unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}}
 
727
        defer func() {
 
728
                delete(unmarshalerResult, 2)
 
729
                delete(unmarshalerResult, 4)
 
730
        }()
 
731
 
 
732
        type T struct {
 
733
                Before int
 
734
                After  int
 
735
                M      map[string]*unmarshalerType
 
736
        }
 
737
        var v T
 
738
        data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}`
 
739
        err := yaml.Unmarshal([]byte(data), &v)
 
740
        c.Assert(err, ErrorMatches, ""+
 
741
                "yaml: unmarshal errors:\n"+
 
742
                "  line 1: cannot unmarshal !!str `A` into int\n"+
 
743
                "  foo\n"+
 
744
                "  bar\n"+
 
745
                "  line 1: cannot unmarshal !!str `B` into int")
 
746
        c.Assert(v.M["abc"], NotNil)
 
747
        c.Assert(v.M["def"], IsNil)
 
748
        c.Assert(v.M["ghi"], NotNil)
 
749
        c.Assert(v.M["jkl"], IsNil)
 
750
 
 
751
        c.Assert(v.M["abc"].value, Equals, 1)
 
752
        c.Assert(v.M["ghi"].value, Equals, 3)
 
753
}
 
754
 
 
755
type proxyTypeError struct{}
 
756
 
 
757
func (v *proxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error {
 
758
        var s string
 
759
        var a int32
 
760
        var b int64
 
761
        if err := unmarshal(&s); err != nil {
 
762
                panic(err)
 
763
        }
 
764
        if s == "a" {
 
765
                if err := unmarshal(&b); err == nil {
 
766
                        panic("should have failed")
 
767
                }
 
768
                return unmarshal(&a)
 
769
        }
 
770
        if err := unmarshal(&a); err == nil {
 
771
                panic("should have failed")
 
772
        }
 
773
        return unmarshal(&b)
 
774
}
 
775
 
 
776
func (s *S) TestUnmarshalerTypeErrorProxying(c *C) {
 
777
        type T struct {
 
778
                Before int
 
779
                After  int
 
780
                M      map[string]*proxyTypeError
 
781
        }
 
782
        var v T
 
783
        data := `{before: A, m: {abc: a, def: b}, after: B}`
 
784
        err := yaml.Unmarshal([]byte(data), &v)
 
785
        c.Assert(err, ErrorMatches, ""+
 
786
                "yaml: unmarshal errors:\n"+
 
787
                "  line 1: cannot unmarshal !!str `A` into int\n"+
 
788
                "  line 1: cannot unmarshal !!str `a` into int32\n"+
 
789
                "  line 1: cannot unmarshal !!str `b` into int64\n"+
 
790
                "  line 1: cannot unmarshal !!str `B` into int")
 
791
}
 
792
 
 
793
type failingUnmarshaler struct{}
 
794
 
 
795
var failingErr = errors.New("failingErr")
 
796
 
 
797
func (ft *failingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
 
798
        return failingErr
 
799
}
 
800
 
 
801
func (s *S) TestUnmarshalerError(c *C) {
 
802
        err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{})
 
803
        c.Assert(err, Equals, failingErr)
 
804
}
 
805
 
 
806
type sliceUnmarshaler []int
 
807
 
 
808
func (su *sliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error {
 
809
        var slice []int
 
810
        err := unmarshal(&slice)
 
811
        if err == nil {
 
812
                *su = slice
 
813
                return nil
 
814
        }
 
815
 
 
816
        var intVal int
 
817
        err = unmarshal(&intVal)
 
818
        if err == nil {
 
819
                *su = []int{intVal}
 
820
                return nil
 
821
        }
 
822
 
 
823
        return err
 
824
}
 
825
 
 
826
func (s *S) TestUnmarshalerRetry(c *C) {
 
827
        var su sliceUnmarshaler
 
828
        err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su)
 
829
        c.Assert(err, IsNil)
 
830
        c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3}))
 
831
 
 
832
        err = yaml.Unmarshal([]byte("1"), &su)
 
833
        c.Assert(err, IsNil)
 
834
        c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1}))
 
835
}
 
836
 
 
837
// From http://yaml.org/type/merge.html
 
838
var mergeTests = `
 
839
anchors:
 
840
  list:
 
841
    - &CENTER { "x": 1, "y": 2 }
 
842
    - &LEFT   { "x": 0, "y": 2 }
 
843
    - &BIG    { "r": 10 }
 
844
    - &SMALL  { "r": 1 }
 
845
 
 
846
# All the following maps are equal:
 
847
 
 
848
plain:
 
849
  # Explicit keys
 
850
  "x": 1
 
851
  "y": 2
 
852
  "r": 10
 
853
  label: center/big
 
854
 
 
855
mergeOne:
 
856
  # Merge one map
 
857
  << : *CENTER
 
858
  "r": 10
 
859
  label: center/big
 
860
 
 
861
mergeMultiple:
 
862
  # Merge multiple maps
 
863
  << : [ *CENTER, *BIG ]
 
864
  label: center/big
 
865
 
 
866
override:
 
867
  # Override
 
868
  << : [ *BIG, *LEFT, *SMALL ]
 
869
  "x": 1
 
870
  label: center/big
 
871
 
 
872
shortTag:
 
873
  # Explicit short merge tag
 
874
  !!merge "<<" : [ *CENTER, *BIG ]
 
875
  label: center/big
 
876
 
 
877
longTag:
 
878
  # Explicit merge long tag
 
879
  !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ]
 
880
  label: center/big
 
881
 
 
882
inlineMap:
 
883
  # Inlined map 
 
884
  << : {"x": 1, "y": 2, "r": 10}
 
885
  label: center/big
 
886
 
 
887
inlineSequenceMap:
 
888
  # Inlined map in sequence
 
889
  << : [ *CENTER, {"r": 10} ]
 
890
  label: center/big
 
891
`
 
892
 
 
893
func (s *S) TestMerge(c *C) {
 
894
        var want = map[interface{}]interface{}{
 
895
                "x":     1,
 
896
                "y":     2,
 
897
                "r":     10,
 
898
                "label": "center/big",
 
899
        }
 
900
 
 
901
        var m map[interface{}]interface{}
 
902
        err := yaml.Unmarshal([]byte(mergeTests), &m)
 
903
        c.Assert(err, IsNil)
 
904
        for name, test := range m {
 
905
                if name == "anchors" {
 
906
                        continue
 
907
                }
 
908
                c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
 
909
        }
 
910
}
 
911
 
 
912
func (s *S) TestMergeStruct(c *C) {
 
913
        type Data struct {
 
914
                X, Y, R int
 
915
                Label   string
 
916
        }
 
917
        want := Data{1, 2, 10, "center/big"}
 
918
 
 
919
        var m map[string]Data
 
920
        err := yaml.Unmarshal([]byte(mergeTests), &m)
 
921
        c.Assert(err, IsNil)
 
922
        for name, test := range m {
 
923
                if name == "anchors" {
 
924
                        continue
 
925
                }
 
926
                c.Assert(test, Equals, want, Commentf("test %q failed", name))
 
927
        }
 
928
}
 
929
 
 
930
var unmarshalNullTests = []func() interface{}{
 
931
        func() interface{} { var v interface{}; v = "v"; return &v },
 
932
        func() interface{} { var s = "s"; return &s },
 
933
        func() interface{} { var s = "s"; sptr := &s; return &sptr },
 
934
        func() interface{} { var i = 1; return &i },
 
935
        func() interface{} { var i = 1; iptr := &i; return &iptr },
 
936
        func() interface{} { m := map[string]int{"s": 1}; return &m },
 
937
        func() interface{} { m := map[string]int{"s": 1}; return m },
 
938
}
 
939
 
 
940
func (s *S) TestUnmarshalNull(c *C) {
 
941
        for _, test := range unmarshalNullTests {
 
942
                item := test()
 
943
                zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface()
 
944
                err := yaml.Unmarshal([]byte("null"), item)
 
945
                c.Assert(err, IsNil)
 
946
                if reflect.TypeOf(item).Kind() == reflect.Map {
 
947
                        c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface())
 
948
                } else {
 
949
                        c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero)
 
950
                }
 
951
        }
 
952
}
 
953
 
 
954
func (s *S) TestUnmarshalSliceOnPreset(c *C) {
 
955
        // Issue #48.
 
956
        v := struct{ A []int }{[]int{1}}
 
957
        yaml.Unmarshal([]byte("a: [2]"), &v)
 
958
        c.Assert(v.A, DeepEquals, []int{2})
 
959
}
 
960
 
 
961
//var data []byte
 
962
//func init() {
 
963
//      var err error
 
964
//      data, err = ioutil.ReadFile("/tmp/file.yaml")
 
965
//      if err != nil {
 
966
//              panic(err)
 
967
//      }
 
968
//}
 
969
//
 
970
//func (s *S) BenchmarkUnmarshal(c *C) {
 
971
//      var err error
 
972
//      for i := 0; i < c.N; i++ {
 
973
//              var v map[string]interface{}
 
974
//              err = yaml.Unmarshal(data, &v)
 
975
//      }
 
976
//      if err != nil {
 
977
//              panic(err)
 
978
//      }
 
979
//}
 
980
//
 
981
//func (s *S) BenchmarkMarshal(c *C) {
 
982
//      var v map[string]interface{}
 
983
//      yaml.Unmarshal(data, &v)
 
984
//      c.ResetTimer()
 
985
//      for i := 0; i < c.N; i++ {
 
986
//              yaml.Marshal(&v)
 
987
//      }
 
988
//}