OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [encoding/] [xml/] [marshal_test.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2011 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
package xml
6
 
7
import (
8
        "reflect"
9
        "strconv"
10
        "strings"
11
        "testing"
12
)
13
 
14
type DriveType int
15
 
16
const (
17
        HyperDrive DriveType = iota
18
        ImprobabilityDrive
19
)
20
 
21
type Passenger struct {
22
        Name   []string `xml:"name"`
23
        Weight float32  `xml:"weight"`
24
}
25
 
26
type Ship struct {
27
        XMLName struct{} `xml:"spaceship"`
28
 
29
        Name      string       `xml:"name,attr"`
30
        Pilot     string       `xml:"pilot,attr"`
31
        Drive     DriveType    `xml:"drive"`
32
        Age       uint         `xml:"age"`
33
        Passenger []*Passenger `xml:"passenger"`
34
        secret    string
35
}
36
 
37
type NamedType string
38
 
39
type Port struct {
40
        XMLName struct{} `xml:"port"`
41
        Type    string   `xml:"type,attr"`
42
        Comment string   `xml:",comment"`
43
        Number  string   `xml:",chardata"`
44
}
45
 
46
type Domain struct {
47
        XMLName struct{} `xml:"domain"`
48
        Country string   `xml:",attr"`
49
        Name    []byte   `xml:",chardata"`
50
        Comment []byte   `xml:",comment"`
51
}
52
 
53
type Book struct {
54
        XMLName struct{} `xml:"book"`
55
        Title   string   `xml:",chardata"`
56
}
57
 
58
type SecretAgent struct {
59
        XMLName   struct{} `xml:"agent"`
60
        Handle    string   `xml:"handle,attr"`
61
        Identity  string
62
        Obfuscate string `xml:",innerxml"`
63
}
64
 
65
type NestedItems struct {
66
        XMLName struct{} `xml:"result"`
67
        Items   []string `xml:">item"`
68
        Item1   []string `xml:"Items>item1"`
69
}
70
 
71
type NestedOrder struct {
72
        XMLName struct{} `xml:"result"`
73
        Field1  string   `xml:"parent>c"`
74
        Field2  string   `xml:"parent>b"`
75
        Field3  string   `xml:"parent>a"`
76
}
77
 
78
type MixedNested struct {
79
        XMLName struct{} `xml:"result"`
80
        A       string   `xml:"parent1>a"`
81
        B       string   `xml:"b"`
82
        C       string   `xml:"parent1>parent2>c"`
83
        D       string   `xml:"parent1>d"`
84
}
85
 
86
type NilTest struct {
87
        A interface{} `xml:"parent1>parent2>a"`
88
        B interface{} `xml:"parent1>b"`
89
        C interface{} `xml:"parent1>parent2>c"`
90
}
91
 
92
type Service struct {
93
        XMLName struct{} `xml:"service"`
94
        Domain  *Domain  `xml:"host>domain"`
95
        Port    *Port    `xml:"host>port"`
96
        Extra1  interface{}
97
        Extra2  interface{} `xml:"host>extra2"`
98
}
99
 
100
var nilStruct *Ship
101
 
102
type EmbedA struct {
103
        EmbedC
104
        EmbedB EmbedB
105
        FieldA string
106
}
107
 
108
type EmbedB struct {
109
        FieldB string
110
        EmbedC
111
}
112
 
113
type EmbedC struct {
114
        FieldA1 string `xml:"FieldA>A1"`
115
        FieldA2 string `xml:"FieldA>A2"`
116
        FieldB  string
117
        FieldC  string
118
}
119
 
120
type NameCasing struct {
121
        XMLName struct{} `xml:"casing"`
122
        Xy      string
123
        XY      string
124
        XyA     string `xml:"Xy,attr"`
125
        XYA     string `xml:"XY,attr"`
126
}
127
 
128
type NamePrecedence struct {
129
        XMLName     Name              `xml:"Parent"`
130
        FromTag     XMLNameWithoutTag `xml:"InTag"`
131
        FromNameVal XMLNameWithoutTag
132
        FromNameTag XMLNameWithTag
133
        InFieldName string
134
}
135
 
136
type XMLNameWithTag struct {
137
        XMLName Name   `xml:"InXMLNameTag"`
138
        Value   string ",chardata"
139
}
140
 
141
type XMLNameWithoutTag struct {
142
        XMLName Name
143
        Value   string ",chardata"
144
}
145
 
146
type NameInField struct {
147
        Foo Name `xml:"ns foo"`
148
}
149
 
150
type AttrTest struct {
151
        Int   int     `xml:",attr"`
152
        Lower int     `xml:"int,attr"`
153
        Float float64 `xml:",attr"`
154
        Uint8 uint8   `xml:",attr"`
155
        Bool  bool    `xml:",attr"`
156
        Str   string  `xml:",attr"`
157
}
158
 
159
type AnyTest struct {
160
        XMLName  struct{}  `xml:"a"`
161
        Nested   string    `xml:"nested>value"`
162
        AnyField AnyHolder `xml:",any"`
163
}
164
 
165
type AnyHolder struct {
166
        XMLName Name
167
        XML     string `xml:",innerxml"`
168
}
169
 
170
type RecurseA struct {
171
        A string
172
        B *RecurseB
173
}
174
 
175
type RecurseB struct {
176
        A *RecurseA
177
        B string
178
}
179
 
180
type PresenceTest struct {
181
        Exists *struct{}
182
}
183
 
184
type IgnoreTest struct {
185
        PublicSecret string `xml:"-"`
186
}
187
 
188
type MyBytes []byte
189
 
190
type Data struct {
191
        Bytes  []byte
192
        Attr   []byte `xml:",attr"`
193
        Custom MyBytes
194
}
195
 
196
type Plain struct {
197
        V interface{}
198
}
199
 
200
// Unless explicitly stated as such (or *Plain), all of the
201
// tests below are two-way tests. When introducing new tests,
202
// please try to make them two-way as well to ensure that
203
// marshalling and unmarshalling are as symmetrical as feasible.
204
var marshalTests = []struct {
205
        Value         interface{}
206
        ExpectXML     string
207
        MarshalOnly   bool
208
        UnmarshalOnly bool
209
}{
210
        // Test nil marshals to nothing
211
        {Value: nil, ExpectXML: ``, MarshalOnly: true},
212
        {Value: nilStruct, ExpectXML: ``, MarshalOnly: true},
213
 
214
        // Test value types
215
        {Value: &Plain{true}, ExpectXML: `true`},
216
        {Value: &Plain{false}, ExpectXML: `false`},
217
        {Value: &Plain{int(42)}, ExpectXML: `42`},
218
        {Value: &Plain{int8(42)}, ExpectXML: `42`},
219
        {Value: &Plain{int16(42)}, ExpectXML: `42`},
220
        {Value: &Plain{int32(42)}, ExpectXML: `42`},
221
        {Value: &Plain{uint(42)}, ExpectXML: `42`},
222
        {Value: &Plain{uint8(42)}, ExpectXML: `42`},
223
        {Value: &Plain{uint16(42)}, ExpectXML: `42`},
224
        {Value: &Plain{uint32(42)}, ExpectXML: `42`},
225
        {Value: &Plain{float32(1.25)}, ExpectXML: `1.25`},
226
        {Value: &Plain{float64(1.25)}, ExpectXML: `1.25`},
227
        {Value: &Plain{uintptr(0xFFDD)}, ExpectXML: `65501`},
228
        {Value: &Plain{"gopher"}, ExpectXML: `gopher`},
229
        {Value: &Plain{[]byte("gopher")}, ExpectXML: `gopher`},
230
        {Value: &Plain{""}, ExpectXML: `</>`},
231
        {Value: &Plain{[]byte("")}, ExpectXML: `</>`},
232
        {Value: &Plain{[3]byte{'<', '/', '>'}}, ExpectXML: `</>`},
233
        {Value: &Plain{NamedType("potato")}, ExpectXML: `potato`},
234
        {Value: &Plain{[]int{1, 2, 3}}, ExpectXML: `123`},
235
        {Value: &Plain{[3]int{1, 2, 3}}, ExpectXML: `123`},
236
 
237
        // A pointer to struct{} may be used to test for an element's presence.
238
        {
239
                Value:     &PresenceTest{new(struct{})},
240
                ExpectXML: ``,
241
        },
242
        {
243
                Value:     &PresenceTest{},
244
                ExpectXML: ``,
245
        },
246
 
247
        // A pointer to struct{} may be used to test for an element's presence.
248
        {
249
                Value:     &PresenceTest{new(struct{})},
250
                ExpectXML: ``,
251
        },
252
        {
253
                Value:     &PresenceTest{},
254
                ExpectXML: ``,
255
        },
256
 
257
        // A []byte field is only nil if the element was not found.
258
        {
259
                Value:         &Data{},
260
                ExpectXML:     ``,
261
                UnmarshalOnly: true,
262
        },
263
        {
264
                Value:         &Data{Bytes: []byte{}, Custom: MyBytes{}, Attr: []byte{}},
265
                ExpectXML:     ``,
266
                UnmarshalOnly: true,
267
        },
268
 
269
        // Check that []byte works, including named []byte types.
270
        {
271
                Value:     &Data{Bytes: []byte("ab"), Custom: MyBytes("cd"), Attr: []byte{'v'}},
272
                ExpectXML: `abcd`,
273
        },
274
 
275
        // Test innerxml
276
        {
277
                Value: &SecretAgent{
278
                        Handle:    "007",
279
                        Identity:  "James Bond",
280
                        Obfuscate: "",
281
                },
282
                ExpectXML:   `James Bond`,
283
                MarshalOnly: true,
284
        },
285
        {
286
                Value: &SecretAgent{
287
                        Handle:    "007",
288
                        Identity:  "James Bond",
289
                        Obfuscate: "James Bond",
290
                },
291
                ExpectXML:     `James Bond`,
292
                UnmarshalOnly: true,
293
        },
294
 
295
        // Test structs
296
        {Value: &Port{Type: "ssl", Number: "443"}, ExpectXML: `443`},
297
        {Value: &Port{Number: "443"}, ExpectXML: `443`},
298
        {Value: &Port{Type: ""}, ExpectXML: ``},
299
        {Value: &Port{Number: "443", Comment: "https"}, ExpectXML: `443`},
300
        {Value: &Port{Number: "443", Comment: "add space-"}, ExpectXML: `443`, MarshalOnly: true},
301
        {Value: &Domain{Name: []byte("google.com&friends")}, ExpectXML: `google.com&friends`},
302
        {Value: &Domain{Name: []byte("google.com"), Comment: []byte(" &friends ")}, ExpectXML: `google.com`},
303
        {Value: &Book{Title: "Pride & Prejudice"}, ExpectXML: `Pride & Prejudice`},
304
        {Value: atomValue, ExpectXML: atomXml},
305
        {
306
                Value: &Ship{
307
                        Name:  "Heart of Gold",
308
                        Pilot: "Computer",
309
                        Age:   1,
310
                        Drive: ImprobabilityDrive,
311
                        Passenger: []*Passenger{
312
                                {
313
                                        Name:   []string{"Zaphod", "Beeblebrox"},
314
                                        Weight: 7.25,
315
                                },
316
                                {
317
                                        Name:   []string{"Trisha", "McMillen"},
318
                                        Weight: 5.5,
319
                                },
320
                                {
321
                                        Name:   []string{"Ford", "Prefect"},
322
                                        Weight: 7,
323
                                },
324
                                {
325
                                        Name:   []string{"Arthur", "Dent"},
326
                                        Weight: 6.75,
327
                                },
328
                        },
329
                },
330
                ExpectXML: `` +
331
                        `` + strconv.Itoa(int(ImprobabilityDrive)) + `` +
332
                        `1` +
333
                        `` +
334
                        `Zaphod` +
335
                        `Beeblebrox` +
336
                        `7.25` +
337
                        `` +
338
                        `` +
339
                        `Trisha` +
340
                        `McMillen` +
341
                        `5.5` +
342
                        `` +
343
                        `` +
344
                        `Ford` +
345
                        `Prefect` +
346
                        `7` +
347
                        `` +
348
                        `` +
349
                        `Arthur` +
350
                        `Dent` +
351
                        `6.75` +
352
                        `` +
353
                        ``,
354
        },
355
 
356
        // Test a>b
357
        {
358
                Value: &NestedItems{Items: nil, Item1: nil},
359
                ExpectXML: `` +
360
                        `` +
361
                        `` +
362
                        ``,
363
        },
364
        {
365
                Value: &NestedItems{Items: []string{}, Item1: []string{}},
366
                ExpectXML: `` +
367
                        `` +
368
                        `` +
369
                        ``,
370
                MarshalOnly: true,
371
        },
372
        {
373
                Value: &NestedItems{Items: nil, Item1: []string{"A"}},
374
                ExpectXML: `` +
375
                        `` +
376
                        `A` +
377
                        `` +
378
                        ``,
379
        },
380
        {
381
                Value: &NestedItems{Items: []string{"A", "B"}, Item1: nil},
382
                ExpectXML: `` +
383
                        `` +
384
                        `A` +
385
                        `B` +
386
                        `` +
387
                        ``,
388
        },
389
        {
390
                Value: &NestedItems{Items: []string{"A", "B"}, Item1: []string{"C"}},
391
                ExpectXML: `` +
392
                        `` +
393
                        `A` +
394
                        `B` +
395
                        `C` +
396
                        `` +
397
                        ``,
398
        },
399
        {
400
                Value: &NestedOrder{Field1: "C", Field2: "B", Field3: "A"},
401
                ExpectXML: `` +
402
                        `` +
403
                        `C` +
404
                        `B` +
405
                        `A` +
406
                        `` +
407
                        ``,
408
        },
409
        {
410
                Value: &NilTest{A: "A", B: nil, C: "C"},
411
                ExpectXML: `` +
412
                        `` +
413
                        `A` +
414
                        `C` +
415
                        `` +
416
                        ``,
417
                MarshalOnly: true, // Uses interface{}
418
        },
419
        {
420
                Value: &MixedNested{A: "A", B: "B", C: "C", D: "D"},
421
                ExpectXML: `` +
422
                        `A` +
423
                        `B` +
424
                        `` +
425
                        `C` +
426
                        `D` +
427
                        `` +
428
                        ``,
429
        },
430
        {
431
                Value:     &Service{Port: &Port{Number: "80"}},
432
                ExpectXML: `80`,
433
        },
434
        {
435
                Value:     &Service{},
436
                ExpectXML: ``,
437
        },
438
        {
439
                Value: &Service{Port: &Port{Number: "80"}, Extra1: "A", Extra2: "B"},
440
                ExpectXML: `` +
441
                        `80` +
442
                        `A` +
443
                        `B` +
444
                        ``,
445
                MarshalOnly: true,
446
        },
447
        {
448
                Value: &Service{Port: &Port{Number: "80"}, Extra2: "example"},
449
                ExpectXML: `` +
450
                        `80` +
451
                        `example` +
452
                        ``,
453
                MarshalOnly: true,
454
        },
455
 
456
        // Test struct embedding
457
        {
458
                Value: &EmbedA{
459
                        EmbedC: EmbedC{
460
                                FieldA1: "", // Shadowed by A.A
461
                                FieldA2: "", // Shadowed by A.A
462
                                FieldB:  "A.C.B",
463
                                FieldC:  "A.C.C",
464
                        },
465
                        EmbedB: EmbedB{
466
                                FieldB: "A.B.B",
467
                                EmbedC: EmbedC{
468
                                        FieldA1: "A.B.C.A1",
469
                                        FieldA2: "A.B.C.A2",
470
                                        FieldB:  "", // Shadowed by A.B.B
471
                                        FieldC:  "A.B.C.C",
472
                                },
473
                        },
474
                        FieldA: "A.A",
475
                },
476
                ExpectXML: `` +
477
                        `A.C.B` +
478
                        `A.C.C` +
479
                        `` +
480
                        `A.B.B` +
481
                        `` +
482
                        `A.B.C.A1` +
483
                        `A.B.C.A2` +
484
                        `` +
485
                        `A.B.C.C` +
486
                        `` +
487
                        `A.A` +
488
                        ``,
489
        },
490
 
491
        // Test that name casing matters
492
        {
493
                Value:     &NameCasing{Xy: "mixed", XY: "upper", XyA: "mixedA", XYA: "upperA"},
494
                ExpectXML: `mixedupper`,
495
        },
496
 
497
        // Test the order in which the XML element name is chosen
498
        {
499
                Value: &NamePrecedence{
500
                        FromTag:     XMLNameWithoutTag{Value: "A"},
501
                        FromNameVal: XMLNameWithoutTag{XMLName: Name{Local: "InXMLName"}, Value: "B"},
502
                        FromNameTag: XMLNameWithTag{Value: "C"},
503
                        InFieldName: "D",
504
                },
505
                ExpectXML: `` +
506
                        `A` +
507
                        `B` +
508
                        `C` +
509
                        `D` +
510
                        ``,
511
                MarshalOnly: true,
512
        },
513
        {
514
                Value: &NamePrecedence{
515
                        XMLName:     Name{Local: "Parent"},
516
                        FromTag:     XMLNameWithoutTag{XMLName: Name{Local: "InTag"}, Value: "A"},
517
                        FromNameVal: XMLNameWithoutTag{XMLName: Name{Local: "FromNameVal"}, Value: "B"},
518
                        FromNameTag: XMLNameWithTag{XMLName: Name{Local: "InXMLNameTag"}, Value: "C"},
519
                        InFieldName: "D",
520
                },
521
                ExpectXML: `` +
522
                        `A` +
523
                        `B` +
524
                        `C` +
525
                        `D` +
526
                        ``,
527
                UnmarshalOnly: true,
528
        },
529
 
530
        // xml.Name works in a plain field as well.
531
        {
532
                Value:     &NameInField{Name{Space: "ns", Local: "foo"}},
533
                ExpectXML: ``,
534
        },
535
        {
536
                Value:         &NameInField{Name{Space: "ns", Local: "foo"}},
537
                ExpectXML:     ``,
538
                UnmarshalOnly: true,
539
        },
540
 
541
        // Marshaling zero xml.Name uses the tag or field name.
542
        {
543
                Value:       &NameInField{},
544
                ExpectXML:   ``,
545
                MarshalOnly: true,
546
        },
547
 
548
        // Test attributes
549
        {
550
                Value: &AttrTest{
551
                        Int:   8,
552
                        Lower: 9,
553
                        Float: 23.5,
554
                        Uint8: 255,
555
                        Bool:  true,
556
                        Str:   "s",
557
                },
558
                ExpectXML: ``,
559
        },
560
 
561
        // Test ",any"
562
        {
563
                ExpectXML: `knownunknown`,
564
                Value: &AnyTest{
565
                        Nested: "known",
566
                        AnyField: AnyHolder{
567
                                XMLName: Name{Local: "other"},
568
                                XML:     "unknown",
569
                        },
570
                },
571
                UnmarshalOnly: true,
572
        },
573
        {
574
                Value:       &AnyTest{Nested: "known", AnyField: AnyHolder{XML: ""}},
575
                ExpectXML:   `known`,
576
                MarshalOnly: true,
577
        },
578
 
579
        // Test recursive types.
580
        {
581
                Value: &RecurseA{
582
                        A: "a1",
583
                        B: &RecurseB{
584
                                A: &RecurseA{"a2", nil},
585
                                B: "b1",
586
                        },
587
                },
588
                ExpectXML: `a1a2b1`,
589
        },
590
 
591
        // Test ignoring fields via "-" tag
592
        {
593
                ExpectXML: ``,
594
                Value:     &IgnoreTest{},
595
        },
596
        {
597
                ExpectXML:   ``,
598
                Value:       &IgnoreTest{PublicSecret: "can't tell"},
599
                MarshalOnly: true,
600
        },
601
        {
602
                ExpectXML:     `ignore me`,
603
                Value:         &IgnoreTest{},
604
                UnmarshalOnly: true,
605
        },
606
}
607
 
608
func TestMarshal(t *testing.T) {
609
        for idx, test := range marshalTests {
610
                if test.UnmarshalOnly {
611
                        continue
612
                }
613
                data, err := Marshal(test.Value)
614
                if err != nil {
615
                        t.Errorf("#%d: Error: %s", idx, err)
616
                        continue
617
                }
618
                if got, want := string(data), test.ExpectXML; got != want {
619
                        if strings.Contains(want, "\n") {
620
                                t.Errorf("#%d: marshal(%#v):\nHAVE:\n%s\nWANT:\n%s", idx, test.Value, got, want)
621
                        } else {
622
                                t.Errorf("#%d: marshal(%#v):\nhave %#q\nwant %#q", idx, test.Value, got, want)
623
                        }
624
                }
625
        }
626
}
627
 
628
var marshalErrorTests = []struct {
629
        Value interface{}
630
        Err   string
631
        Kind  reflect.Kind
632
}{
633
        {
634
                Value: make(chan bool),
635
                Err:   "xml: unsupported type: chan bool",
636
                Kind:  reflect.Chan,
637
        },
638
        {
639
                Value: map[string]string{
640
                        "question": "What do you get when you multiply six by nine?",
641
                        "answer":   "42",
642
                },
643
                Err:  "xml: unsupported type: map[string]string",
644
                Kind: reflect.Map,
645
        },
646
        {
647
                Value: map[*Ship]bool{nil: false},
648
                Err:   "xml: unsupported type: map[*xml.Ship]bool",
649
                Kind:  reflect.Map,
650
        },
651
        {
652
                Value: &Domain{Comment: []byte("f--bar")},
653
                Err:   `xml: comments must not contain "--"`,
654
        },
655
}
656
 
657
func TestMarshalErrors(t *testing.T) {
658
        for idx, test := range marshalErrorTests {
659
                _, err := Marshal(test.Value)
660
                if err == nil || err.Error() != test.Err {
661
                        t.Errorf("#%d: marshal(%#v) = [error] %v, want %v", idx, test.Value, err, test.Err)
662
                }
663
                if test.Kind != reflect.Invalid {
664
                        if kind := err.(*UnsupportedTypeError).Type.Kind(); kind != test.Kind {
665
                                t.Errorf("#%d: marshal(%#v) = [error kind] %s, want %s", idx, test.Value, kind, test.Kind)
666
                        }
667
                }
668
        }
669
}
670
 
671
// Do invertibility testing on the various structures that we test
672
func TestUnmarshal(t *testing.T) {
673
        for i, test := range marshalTests {
674
                if test.MarshalOnly {
675
                        continue
676
                }
677
                if _, ok := test.Value.(*Plain); ok {
678
                        continue
679
                }
680
 
681
                vt := reflect.TypeOf(test.Value)
682
                dest := reflect.New(vt.Elem()).Interface()
683
                err := Unmarshal([]byte(test.ExpectXML), dest)
684
 
685
                switch fix := dest.(type) {
686
                case *Feed:
687
                        fix.Author.InnerXML = ""
688
                        for i := range fix.Entry {
689
                                fix.Entry[i].Author.InnerXML = ""
690
                        }
691
                }
692
 
693
                if err != nil {
694
                        t.Errorf("#%d: unexpected error: %#v", i, err)
695
                } else if got, want := dest, test.Value; !reflect.DeepEqual(got, want) {
696
                        t.Errorf("#%d: unmarshal(%q):\nhave %#v\nwant %#v", i, test.ExpectXML, got, want)
697
                }
698
        }
699
}
700
 
701
func BenchmarkMarshal(b *testing.B) {
702
        for i := 0; i < b.N; i++ {
703
                Marshal(atomValue)
704
        }
705
}
706
 
707
func BenchmarkUnmarshal(b *testing.B) {
708
        xml := []byte(atomXml)
709
        for i := 0; i < b.N; i++ {
710
                Unmarshal(xml, &Feed{})
711
        }
712
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.