URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [encoding/] [xml/] [marshal_test.go] - Rev 747
Compare with Previous | Blame | View Log
// Copyright 2011 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package xmlimport ("reflect""strconv""strings""testing")type DriveType intconst (HyperDrive DriveType = iotaImprobabilityDrive)type Passenger struct {Name []string `xml:"name"`Weight float32 `xml:"weight"`}type Ship struct {XMLName struct{} `xml:"spaceship"`Name string `xml:"name,attr"`Pilot string `xml:"pilot,attr"`Drive DriveType `xml:"drive"`Age uint `xml:"age"`Passenger []*Passenger `xml:"passenger"`secret string}type NamedType stringtype Port struct {XMLName struct{} `xml:"port"`Type string `xml:"type,attr"`Comment string `xml:",comment"`Number string `xml:",chardata"`}type Domain struct {XMLName struct{} `xml:"domain"`Country string `xml:",attr"`Name []byte `xml:",chardata"`Comment []byte `xml:",comment"`}type Book struct {XMLName struct{} `xml:"book"`Title string `xml:",chardata"`}type SecretAgent struct {XMLName struct{} `xml:"agent"`Handle string `xml:"handle,attr"`Identity stringObfuscate string `xml:",innerxml"`}type NestedItems struct {XMLName struct{} `xml:"result"`Items []string `xml:">item"`Item1 []string `xml:"Items>item1"`}type NestedOrder struct {XMLName struct{} `xml:"result"`Field1 string `xml:"parent>c"`Field2 string `xml:"parent>b"`Field3 string `xml:"parent>a"`}type MixedNested struct {XMLName struct{} `xml:"result"`A string `xml:"parent1>a"`B string `xml:"b"`C string `xml:"parent1>parent2>c"`D string `xml:"parent1>d"`}type NilTest struct {A interface{} `xml:"parent1>parent2>a"`B interface{} `xml:"parent1>b"`C interface{} `xml:"parent1>parent2>c"`}type Service struct {XMLName struct{} `xml:"service"`Domain *Domain `xml:"host>domain"`Port *Port `xml:"host>port"`Extra1 interface{}Extra2 interface{} `xml:"host>extra2"`}var nilStruct *Shiptype EmbedA struct {EmbedCEmbedB EmbedBFieldA string}type EmbedB struct {FieldB stringEmbedC}type EmbedC struct {FieldA1 string `xml:"FieldA>A1"`FieldA2 string `xml:"FieldA>A2"`FieldB stringFieldC string}type NameCasing struct {XMLName struct{} `xml:"casing"`Xy stringXY stringXyA string `xml:"Xy,attr"`XYA string `xml:"XY,attr"`}type NamePrecedence struct {XMLName Name `xml:"Parent"`FromTag XMLNameWithoutTag `xml:"InTag"`FromNameVal XMLNameWithoutTagFromNameTag XMLNameWithTagInFieldName string}type XMLNameWithTag struct {XMLName Name `xml:"InXMLNameTag"`Value string ",chardata"}type XMLNameWithoutTag struct {XMLName NameValue string ",chardata"}type NameInField struct {Foo Name `xml:"ns foo"`}type AttrTest struct {Int int `xml:",attr"`Lower int `xml:"int,attr"`Float float64 `xml:",attr"`Uint8 uint8 `xml:",attr"`Bool bool `xml:",attr"`Str string `xml:",attr"`}type AnyTest struct {XMLName struct{} `xml:"a"`Nested string `xml:"nested>value"`AnyField AnyHolder `xml:",any"`}type AnyHolder struct {XMLName NameXML string `xml:",innerxml"`}type RecurseA struct {A stringB *RecurseB}type RecurseB struct {A *RecurseAB string}type PresenceTest struct {Exists *struct{}}type IgnoreTest struct {PublicSecret string `xml:"-"`}type MyBytes []bytetype Data struct {Bytes []byteAttr []byte `xml:",attr"`Custom MyBytes}type Plain struct {V interface{}}// Unless explicitly stated as such (or *Plain), all of the// tests below are two-way tests. When introducing new tests,// please try to make them two-way as well to ensure that// marshalling and unmarshalling are as symmetrical as feasible.var marshalTests = []struct {Value interface{}ExpectXML stringMarshalOnly boolUnmarshalOnly bool}{// Test nil marshals to nothing{Value: nil, ExpectXML: ``, MarshalOnly: true},{Value: nilStruct, ExpectXML: ``, MarshalOnly: true},// Test value types{Value: &Plain{true}, ExpectXML: `<Plain><V>true</V></Plain>`},{Value: &Plain{false}, ExpectXML: `<Plain><V>false</V></Plain>`},{Value: &Plain{int(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},{Value: &Plain{int8(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},{Value: &Plain{int16(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},{Value: &Plain{int32(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},{Value: &Plain{uint(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},{Value: &Plain{uint8(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},{Value: &Plain{uint16(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},{Value: &Plain{uint32(42)}, ExpectXML: `<Plain><V>42</V></Plain>`},{Value: &Plain{float32(1.25)}, ExpectXML: `<Plain><V>1.25</V></Plain>`},{Value: &Plain{float64(1.25)}, ExpectXML: `<Plain><V>1.25</V></Plain>`},{Value: &Plain{uintptr(0xFFDD)}, ExpectXML: `<Plain><V>65501</V></Plain>`},{Value: &Plain{"gopher"}, ExpectXML: `<Plain><V>gopher</V></Plain>`},{Value: &Plain{[]byte("gopher")}, ExpectXML: `<Plain><V>gopher</V></Plain>`},{Value: &Plain{"</>"}, ExpectXML: `<Plain><V></></V></Plain>`},{Value: &Plain{[]byte("</>")}, ExpectXML: `<Plain><V></></V></Plain>`},{Value: &Plain{[3]byte{'<', '/', '>'}}, ExpectXML: `<Plain><V></></V></Plain>`},{Value: &Plain{NamedType("potato")}, ExpectXML: `<Plain><V>potato</V></Plain>`},{Value: &Plain{[]int{1, 2, 3}}, ExpectXML: `<Plain><V>1</V><V>2</V><V>3</V></Plain>`},{Value: &Plain{[3]int{1, 2, 3}}, ExpectXML: `<Plain><V>1</V><V>2</V><V>3</V></Plain>`},// A pointer to struct{} may be used to test for an element's presence.{Value: &PresenceTest{new(struct{})},ExpectXML: `<PresenceTest><Exists></Exists></PresenceTest>`,},{Value: &PresenceTest{},ExpectXML: `<PresenceTest></PresenceTest>`,},// A pointer to struct{} may be used to test for an element's presence.{Value: &PresenceTest{new(struct{})},ExpectXML: `<PresenceTest><Exists></Exists></PresenceTest>`,},{Value: &PresenceTest{},ExpectXML: `<PresenceTest></PresenceTest>`,},// A []byte field is only nil if the element was not found.{Value: &Data{},ExpectXML: `<Data></Data>`,UnmarshalOnly: true,},{Value: &Data{Bytes: []byte{}, Custom: MyBytes{}, Attr: []byte{}},ExpectXML: `<Data Attr=""><Bytes></Bytes><Custom></Custom></Data>`,UnmarshalOnly: true,},// Check that []byte works, including named []byte types.{Value: &Data{Bytes: []byte("ab"), Custom: MyBytes("cd"), Attr: []byte{'v'}},ExpectXML: `<Data Attr="v"><Bytes>ab</Bytes><Custom>cd</Custom></Data>`,},// Test innerxml{Value: &SecretAgent{Handle: "007",Identity: "James Bond",Obfuscate: "<redacted/>",},ExpectXML: `<agent handle="007"><Identity>James Bond</Identity><redacted/></agent>`,MarshalOnly: true,},{Value: &SecretAgent{Handle: "007",Identity: "James Bond",Obfuscate: "<Identity>James Bond</Identity><redacted/>",},ExpectXML: `<agent handle="007"><Identity>James Bond</Identity><redacted/></agent>`,UnmarshalOnly: true,},// Test structs{Value: &Port{Type: "ssl", Number: "443"}, ExpectXML: `<port type="ssl">443</port>`},{Value: &Port{Number: "443"}, ExpectXML: `<port>443</port>`},{Value: &Port{Type: "<unix>"}, ExpectXML: `<port type="<unix>"></port>`},{Value: &Port{Number: "443", Comment: "https"}, ExpectXML: `<port><!--https-->443</port>`},{Value: &Port{Number: "443", Comment: "add space-"}, ExpectXML: `<port><!--add space- -->443</port>`, MarshalOnly: true},{Value: &Domain{Name: []byte("google.com&friends")}, ExpectXML: `<domain>google.com&friends</domain>`},{Value: &Domain{Name: []byte("google.com"), Comment: []byte(" &friends ")}, ExpectXML: `<domain>google.com<!-- &friends --></domain>`},{Value: &Book{Title: "Pride & Prejudice"}, ExpectXML: `<book>Pride & Prejudice</book>`},{Value: atomValue, ExpectXML: atomXml},{Value: &Ship{Name: "Heart of Gold",Pilot: "Computer",Age: 1,Drive: ImprobabilityDrive,Passenger: []*Passenger{{Name: []string{"Zaphod", "Beeblebrox"},Weight: 7.25,},{Name: []string{"Trisha", "McMillen"},Weight: 5.5,},{Name: []string{"Ford", "Prefect"},Weight: 7,},{Name: []string{"Arthur", "Dent"},Weight: 6.75,},},},ExpectXML: `<spaceship name="Heart of Gold" pilot="Computer">` +`<drive>` + strconv.Itoa(int(ImprobabilityDrive)) + `</drive>` +`<age>1</age>` +`<passenger>` +`<name>Zaphod</name>` +`<name>Beeblebrox</name>` +`<weight>7.25</weight>` +`</passenger>` +`<passenger>` +`<name>Trisha</name>` +`<name>McMillen</name>` +`<weight>5.5</weight>` +`</passenger>` +`<passenger>` +`<name>Ford</name>` +`<name>Prefect</name>` +`<weight>7</weight>` +`</passenger>` +`<passenger>` +`<name>Arthur</name>` +`<name>Dent</name>` +`<weight>6.75</weight>` +`</passenger>` +`</spaceship>`,},// Test a>b{Value: &NestedItems{Items: nil, Item1: nil},ExpectXML: `<result>` +`<Items>` +`</Items>` +`</result>`,},{Value: &NestedItems{Items: []string{}, Item1: []string{}},ExpectXML: `<result>` +`<Items>` +`</Items>` +`</result>`,MarshalOnly: true,},{Value: &NestedItems{Items: nil, Item1: []string{"A"}},ExpectXML: `<result>` +`<Items>` +`<item1>A</item1>` +`</Items>` +`</result>`,},{Value: &NestedItems{Items: []string{"A", "B"}, Item1: nil},ExpectXML: `<result>` +`<Items>` +`<item>A</item>` +`<item>B</item>` +`</Items>` +`</result>`,},{Value: &NestedItems{Items: []string{"A", "B"}, Item1: []string{"C"}},ExpectXML: `<result>` +`<Items>` +`<item>A</item>` +`<item>B</item>` +`<item1>C</item1>` +`</Items>` +`</result>`,},{Value: &NestedOrder{Field1: "C", Field2: "B", Field3: "A"},ExpectXML: `<result>` +`<parent>` +`<c>C</c>` +`<b>B</b>` +`<a>A</a>` +`</parent>` +`</result>`,},{Value: &NilTest{A: "A", B: nil, C: "C"},ExpectXML: `<NilTest>` +`<parent1>` +`<parent2><a>A</a></parent2>` +`<parent2><c>C</c></parent2>` +`</parent1>` +`</NilTest>`,MarshalOnly: true, // Uses interface{}},{Value: &MixedNested{A: "A", B: "B", C: "C", D: "D"},ExpectXML: `<result>` +`<parent1><a>A</a></parent1>` +`<b>B</b>` +`<parent1>` +`<parent2><c>C</c></parent2>` +`<d>D</d>` +`</parent1>` +`</result>`,},{Value: &Service{Port: &Port{Number: "80"}},ExpectXML: `<service><host><port>80</port></host></service>`,},{Value: &Service{},ExpectXML: `<service></service>`,},{Value: &Service{Port: &Port{Number: "80"}, Extra1: "A", Extra2: "B"},ExpectXML: `<service>` +`<host><port>80</port></host>` +`<Extra1>A</Extra1>` +`<host><extra2>B</extra2></host>` +`</service>`,MarshalOnly: true,},{Value: &Service{Port: &Port{Number: "80"}, Extra2: "example"},ExpectXML: `<service>` +`<host><port>80</port></host>` +`<host><extra2>example</extra2></host>` +`</service>`,MarshalOnly: true,},// Test struct embedding{Value: &EmbedA{EmbedC: EmbedC{FieldA1: "", // Shadowed by A.AFieldA2: "", // Shadowed by A.AFieldB: "A.C.B",FieldC: "A.C.C",},EmbedB: EmbedB{FieldB: "A.B.B",EmbedC: EmbedC{FieldA1: "A.B.C.A1",FieldA2: "A.B.C.A2",FieldB: "", // Shadowed by A.B.BFieldC: "A.B.C.C",},},FieldA: "A.A",},ExpectXML: `<EmbedA>` +`<FieldB>A.C.B</FieldB>` +`<FieldC>A.C.C</FieldC>` +`<EmbedB>` +`<FieldB>A.B.B</FieldB>` +`<FieldA>` +`<A1>A.B.C.A1</A1>` +`<A2>A.B.C.A2</A2>` +`</FieldA>` +`<FieldC>A.B.C.C</FieldC>` +`</EmbedB>` +`<FieldA>A.A</FieldA>` +`</EmbedA>`,},// Test that name casing matters{Value: &NameCasing{Xy: "mixed", XY: "upper", XyA: "mixedA", XYA: "upperA"},ExpectXML: `<casing Xy="mixedA" XY="upperA"><Xy>mixed</Xy><XY>upper</XY></casing>`,},// Test the order in which the XML element name is chosen{Value: &NamePrecedence{FromTag: XMLNameWithoutTag{Value: "A"},FromNameVal: XMLNameWithoutTag{XMLName: Name{Local: "InXMLName"}, Value: "B"},FromNameTag: XMLNameWithTag{Value: "C"},InFieldName: "D",},ExpectXML: `<Parent>` +`<InTag><Value>A</Value></InTag>` +`<InXMLName><Value>B</Value></InXMLName>` +`<InXMLNameTag><Value>C</Value></InXMLNameTag>` +`<InFieldName>D</InFieldName>` +`</Parent>`,MarshalOnly: true,},{Value: &NamePrecedence{XMLName: Name{Local: "Parent"},FromTag: XMLNameWithoutTag{XMLName: Name{Local: "InTag"}, Value: "A"},FromNameVal: XMLNameWithoutTag{XMLName: Name{Local: "FromNameVal"}, Value: "B"},FromNameTag: XMLNameWithTag{XMLName: Name{Local: "InXMLNameTag"}, Value: "C"},InFieldName: "D",},ExpectXML: `<Parent>` +`<InTag><Value>A</Value></InTag>` +`<FromNameVal><Value>B</Value></FromNameVal>` +`<InXMLNameTag><Value>C</Value></InXMLNameTag>` +`<InFieldName>D</InFieldName>` +`</Parent>`,UnmarshalOnly: true,},// xml.Name works in a plain field as well.{Value: &NameInField{Name{Space: "ns", Local: "foo"}},ExpectXML: `<NameInField><foo xmlns="ns"></foo></NameInField>`,},{Value: &NameInField{Name{Space: "ns", Local: "foo"}},ExpectXML: `<NameInField><foo xmlns="ns"><ignore></ignore></foo></NameInField>`,UnmarshalOnly: true,},// Marshaling zero xml.Name uses the tag or field name.{Value: &NameInField{},ExpectXML: `<NameInField><foo xmlns="ns"></foo></NameInField>`,MarshalOnly: true,},// Test attributes{Value: &AttrTest{Int: 8,Lower: 9,Float: 23.5,Uint8: 255,Bool: true,Str: "s",},ExpectXML: `<AttrTest Int="8" int="9" Float="23.5" Uint8="255" Bool="true" Str="s"></AttrTest>`,},// Test ",any"{ExpectXML: `<a><nested><value>known</value></nested><other><sub>unknown</sub></other></a>`,Value: &AnyTest{Nested: "known",AnyField: AnyHolder{XMLName: Name{Local: "other"},XML: "<sub>unknown</sub>",},},UnmarshalOnly: true,},{Value: &AnyTest{Nested: "known", AnyField: AnyHolder{XML: "<unknown/>"}},ExpectXML: `<a><nested><value>known</value></nested></a>`,MarshalOnly: true,},// Test recursive types.{Value: &RecurseA{A: "a1",B: &RecurseB{A: &RecurseA{"a2", nil},B: "b1",},},ExpectXML: `<RecurseA><A>a1</A><B><A><A>a2</A></A><B>b1</B></B></RecurseA>`,},// Test ignoring fields via "-" tag{ExpectXML: `<IgnoreTest></IgnoreTest>`,Value: &IgnoreTest{},},{ExpectXML: `<IgnoreTest></IgnoreTest>`,Value: &IgnoreTest{PublicSecret: "can't tell"},MarshalOnly: true,},{ExpectXML: `<IgnoreTest><PublicSecret>ignore me</PublicSecret></IgnoreTest>`,Value: &IgnoreTest{},UnmarshalOnly: true,},}func TestMarshal(t *testing.T) {for idx, test := range marshalTests {if test.UnmarshalOnly {continue}data, err := Marshal(test.Value)if err != nil {t.Errorf("#%d: Error: %s", idx, err)continue}if got, want := string(data), test.ExpectXML; got != want {if strings.Contains(want, "\n") {t.Errorf("#%d: marshal(%#v):\nHAVE:\n%s\nWANT:\n%s", idx, test.Value, got, want)} else {t.Errorf("#%d: marshal(%#v):\nhave %#q\nwant %#q", idx, test.Value, got, want)}}}}var marshalErrorTests = []struct {Value interface{}Err stringKind reflect.Kind}{{Value: make(chan bool),Err: "xml: unsupported type: chan bool",Kind: reflect.Chan,},{Value: map[string]string{"question": "What do you get when you multiply six by nine?","answer": "42",},Err: "xml: unsupported type: map[string]string",Kind: reflect.Map,},{Value: map[*Ship]bool{nil: false},Err: "xml: unsupported type: map[*xml.Ship]bool",Kind: reflect.Map,},{Value: &Domain{Comment: []byte("f--bar")},Err: `xml: comments must not contain "--"`,},}func TestMarshalErrors(t *testing.T) {for idx, test := range marshalErrorTests {_, err := Marshal(test.Value)if err == nil || err.Error() != test.Err {t.Errorf("#%d: marshal(%#v) = [error] %v, want %v", idx, test.Value, err, test.Err)}if test.Kind != reflect.Invalid {if kind := err.(*UnsupportedTypeError).Type.Kind(); kind != test.Kind {t.Errorf("#%d: marshal(%#v) = [error kind] %s, want %s", idx, test.Value, kind, test.Kind)}}}}// Do invertibility testing on the various structures that we testfunc TestUnmarshal(t *testing.T) {for i, test := range marshalTests {if test.MarshalOnly {continue}if _, ok := test.Value.(*Plain); ok {continue}vt := reflect.TypeOf(test.Value)dest := reflect.New(vt.Elem()).Interface()err := Unmarshal([]byte(test.ExpectXML), dest)switch fix := dest.(type) {case *Feed:fix.Author.InnerXML = ""for i := range fix.Entry {fix.Entry[i].Author.InnerXML = ""}}if err != nil {t.Errorf("#%d: unexpected error: %#v", i, err)} else if got, want := dest, test.Value; !reflect.DeepEqual(got, want) {t.Errorf("#%d: unmarshal(%q):\nhave %#v\nwant %#v", i, test.ExpectXML, got, want)}}}func BenchmarkMarshal(b *testing.B) {for i := 0; i < b.N; i++ {Marshal(atomValue)}}func BenchmarkUnmarshal(b *testing.B) {xml := []byte(atomXml)for i := 0; i < b.N; i++ {Unmarshal(xml, &Feed{})}}
